text:
var express = require('express');
var app = express();
var everyauth = require('everyauth');
var bodyParser = require('body-parser');
var cons = require('consolidate');
var models = require('./models');
var dotenv = require('dotenv');
dotenv.load();

// var usersByTwitId = {};

// function addUser (source, sourceUser) {
//   var user;
//   if (arguments.length === 1) { // password-based
//     user = sourceUser = source;
//     user.id = ++nextUserId;
//     return usersById[nextUserId] = user;
//   } else { // non-password-based
//     user = usersById[++nextUserId] = {id: nextUserId};
//     user[source] = sourceUser;
//   }
//   return user;
// }

// var u = {ben:"true"};

everyauth.everymodule.findUserById( function (userId, callback) {
  models.User.findById(userId, callback);
});

everyauth
  .twitter
    .consumerKey(process.env.CONSUMERKEY)
    .consumerSecret(process.env.CONSUMERSECRET)
    .findOrCreateUser( function (sess, accessToken, accessSecret, twitUser) {
    	var promise = this.Promise();

    	models.User.findOrCreate(
    		{
    			id_str: twitUser.id_str
    		},
    		{
				screen_name: twitUser.screen_name,
				name: twitUser.name,
				location: twitUser.location,
				description: twitUser.description
			},
    		function(err, user, created){
    			if(err) return console.log("error saving user", err);
    			promise.fulfill(user);
    		}
    	);

       return promise;
    })
    .redirectPath('/');

var cookieParser = require('cookie-parser');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);

app.use(bodyParser());
app.use(cookieParser())

var opts = {url:process.env.REDISTOGO_URL}

app.use(session({ store: new RedisStore(opts), secret: process.env.SECRET }))

app.use(everyauth.middleware(app));

app.engine('html', cons.hogan);

// default to html
app.set('view engine', 'html');

app.use(express.static(__dirname + '/static'));

app.get('/', function(req, res){
	if(req.user){
		res.redirect('/users/' + req.user.screen_name)
	}
	console.log("----", req.user)
	  res.render('index.html')
});

app.get('/users/:screen_name', function(req, res, next){

	models.User.findOne({
		screen_name:req.params.screen_name
	},
		function (err, user) {
			if(err) next(err)
			else if(!user) next("not found");
			else {
				models.Album
				.find({ _user: user._id })
				.sort('-_id')
				.exec(function (err, albums) {
				  if (err) return next(err);
				  res.render('play.html', {albums:albums, displayedUser: user})
				})
			}
		}
	)

});

app.post('/users/:screen_name', function(req, res, next){

	if(!req.user || (req.params.screen_name !== req.user.screen_name))
		return next("not authorised")

	models.User.findOne({screen_name:req.params.screen_name}, function (err, user) {
		if(err) next(err)
		else if(!user) next("user not found");
		else {

			var album = new models.Album({
				_user:user._id,
				uri: req.param("uri"),
				prior: req.param("prior")
			});

			album.attempt_populate(function(){
				album.save(function(err, album){
				  if (err) return next(err);
				  res.redirect("/users/" + req.params.screen_name)
				});

			});
		}
	});

});

app.post('/users/:screen_name/:id', function (req, res, next){

	if(!req.user || (req.params.screen_name !== req.user.screen_name))
		return next("not authorised")

	models.User.findOne({screen_name:req.params.screen_name}, function (err, user) {
		if(err) next(err)
		else if(!user) next("user not found");

		// update an element
		if(req.param('destroy')){
			models.Album.remove({
				_id:   req.params.id,
				_user: user._id
			}, function (err){
				if (err) return mext(err);
				res.redirect("/users/" + req.params.screen_name)
			})
		} else {
			models.Album.findOneAndUpdate({
				_id:   req.params.id,
				_user: user._id
			},
			{post: req.param('post')},
			function (err){
				if (err) return mext(err);
				res.redirect("/users/" + req.params.screen_name)
			})
		}

	});

})

// // create a list
// app.post('/', function(req, res, next){
// 	var list = new models.List;

// 	list.save(function(err, list){
// 	  if (err) next(err);
// 	  else res.redirect("/lists/" + list.id)
// 	})
// })

// app.get('/lists/:id', function(req,res, next){
// 	models.List.findById(req.params.id, function (err, list) {
// 		if(err) next(err)
// 		else if(!list) next("not found");
// 		else {
// 			models.Album
// 			.find({ _list: list._id })
// 			.sort('-_id')
// 			.exec(function (err, albums) {
// 			  if (err) return next(err);
// 			  res.render('play.html', {list:list, albums:albums})
// 			})
// 		}
// 	});
// })

// // adding an album
// app.post('/lists/:id', function(req, res, next){

// 	models.List.findById(req.params.id, function (err, list) {
// 		if(err) next(err)
// 		else if(!list) next("list not found");
// 		else {

// 			var album = new models.Album({
// 				_list:list._id,
// 				uri: req.param("uri"),
// 				prior: req.param("prior")
// 			});

// 			album.attempt_populate(function(){
// 				album.save(function(err, album){
// 				  if (err) return next(err);
// 				  res.redirect("/lists/" + req.params.id)
// 				});

// 			});
// 		}
// 	});

// })

// app.post('/lists/:list_id/:id', function (req, res, next){
// 	// update an element
// 	if(req.param('destroy')){
// 		models.Album.remove({
// 			_id:   req.params.id,
// 			_list: req.params.list_id
// 		}, function (err){
// 			if (err) return mext(err);
// 			res.redirect("/lists/" + req.params.list_id)
// 		})
// 	} else {
// 		models.Album.findOneAndUpdate({
// 			_id:   req.params.id,
// 			_list: req.params.list_id
// 		},
// 		{post: req.param('post')},
// 		function (err){
// 			if (err) return mext(err);
// 			res.redirect("/lists/" + req.params.list_id)
// 		})
// 	}

// })

// app.get('/play', function(req, res){
//   res.render('play.html')
// });

app.listen(process.env.PORT || 3000);


text:
layout: post
title: How to
---

Coming soon

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * All routes should start and end with one forward slash character (you could
 * get away with forgetting them, but definitely not with, say, duplicating them).
 *
 * use {param} as a placeholder for url segment parameters.
 * You must include these placeholders where you want them, with the exact number
 * of them that you want, for the route to be parsed correctly.
 *
 * Routes shouldn't contain more than 2 non-params segments, much like
 * most MVC frameworks' '/controller/action/[parameters/...]' formula.
 *
 * Examples:
 * '/' => [
 *     'controllerClass' => 'IndexController',
 *     'controllerAction' => 'index',
 * ],
 * '/shows/' => [
 *     'controllerClass' => 'ShowsController',
 *     'controllerAction' => 'index',
 * ],
 * '/shows/{param}/' => [
 *     'controllerClass' => 'ShowsController',
 *     'controllerAction' => 'details',
 * ]
 */

return [
    '/' => [
        'controllerClass' => 'IndexController',
        'controllerAction' => 'index',
    ],
];


text:
<!DOCTYPE html>

	<title>Integration with StatusBar</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
	<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
	<link rel="stylesheet" type="text/css" href="../../../codebase/fonts/font_roboto/roboto.css"/>
	<link rel="stylesheet" type="text/css" href="../../../codebase/dhtmlx.css"/>


text:
"""Module for setting up e.g. Maxwell-Boltzmann velocity distributions.

Currently, only one function is defined, MaxwellBoltzmannDistribution,
which sets the momenta of a list of atoms according to a
Maxwell-Boltzmann distribution at a given temperature.
"""

import Numeric
import RandomArray

def _maxwellboltzmanndistribution(masses, temp):
    xi = RandomArray.standard_normal(shape=(len(masses),3))
    momenta = xi * Numeric.sqrt(masses * temp)[:,Numeric.NewAxis]
    return momenta

def MaxwellBoltzmannDistribution(atoms, temp):
    """Sets the momenta to a Maxwell-Boltzmann distribution."""
    momenta = _maxwellboltzmanndistribution(atoms.GetMasses(), temp)
    atoms.SetCartesianMomenta(momenta)


text:
title: "Release Notes - Flink 1.10"
---

# Release Notes - Flink 1.10

These release notes discuss important aspects, such as configuration, behavior,
or dependencies, that changed between Flink 1.9 and Flink 1.10. Please read
these notes carefully if you are planning to upgrade your Flink version to 1.10.

### Clusters & Deployment
#### FileSystems should be loaded via Plugin Architecture
##### [FLINK-11956](https://issues.apache.org/jira/browse/FLINK-11956)

s3-hadoop and s3-presto filesystems do no longer use class relocations and need
to be loaded through [plugins]({{< ref "docs/deployment/filesystems/overview" >}}#pluggable-file-systems)
but now seamlessly integrate with all credential providers. Other filesystems
are strongly recommended to be only used as plugins as we will continue to
remove relocations.

#### Flink Client respects Classloading Policy
##### [FLINK-13749](https://issues.apache.org/jira/browse/FLINK-13749)

The Flink client now also respects the configured classloading policy, i.e.,
`parent-first` or `child-first` classloading. Previously, only cluster
components such as the job manager or task manager supported this setting.
This does mean that users might get different behaviour in their programs, in
which case they should configure the classloading policy explicitly to use
`parent-first` classloading, which was the previous (hard-coded) behaviour.

#### Enable spreading out Tasks evenly across all TaskManagers
##### [FLINK-12122](https://issues.apache.org/jira/browse/FLINK-12122)

When
[FLIP-6](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=65147077)
was rolled out with Flink 1.5.0, we changed how slots are allocated from
TaskManagers (TMs). Instead of evenly allocating the slots from all registered
TMs, we had the tendency to exhaust a TM before using another one. To use a
scheduling strategy that is more similar to the pre-FLIP-6 behaviour, where
Flink tries to spread out the workload across all currently available TMs, one
can set `cluster.evenly-spread-out-slots: true` in the `flink-conf.yaml`.

#### Directory Structure Change for highly available Artifacts
##### [FLINK-13633](https://issues.apache.org/jira/browse/FLINK-13633)

All highly available artifacts stored by Flink will now be stored under
`HA_STORAGE_DIR/HA_CLUSTER_ID` with `HA_STORAGE_DIR` configured by
`high-availability.storageDir` and `HA_CLUSTER_ID` configured by
`high-availability.cluster-id`.

#### Resources and JARs shipped via --yarnship will be ordered in the Classpath
##### [FLINK-13127](https://issues.apache.org/jira/browse/FLINK-13127)

When using the `--yarnship` command line option, resource directories and jar
files will be added to the classpath in lexicographical order with resources
directories appearing first.

#### Removal of --yn/--yarncontainer Command Line Options
##### [FLINK-12362](https://issues.apache.org/jira/browse/FLINK-12362)

The Flink CLI no longer supports the deprecated command line options
`-yn/--yarncontainer`, which were used to specify the number of containers to
start on YARN. This option has been deprecated since the introduction of
[FLIP-6](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=65147077).
All Flink users are advised to remove this command line option.

#### Removal of --yst/--yarnstreaming Command Line Options
##### [FLINK-14957](https://issues.apache.org/jira/browse/FLINK-14957)

The Flink CLI no longer supports the deprecated command line options
`-yst/--yarnstreaming`, which were used to disable eager pre-allocation of memory.
All Flink users are advised to remove this command line option.

#### Mesos Integration will reject expired Offers faster
##### [FLINK-14029](https://issues.apache.org/jira/browse/FLINK-14029)

Flink's Mesos integration now rejects all expired offers instead of only 4.
This improves the situation where Fenzo holds on to a lot of expired offers
without giving them back to the Mesos resource manager.

#### Scheduler Rearchitecture
##### [FLINK-14651](https://issues.apache.org/jira/browse/FLINK-14651)

Flink's scheduler was refactored with the goal of making scheduling strategies
customizable in the future. Using the legacy scheduler is discouraged as it will
be removed in a future release. However, users that experience issues related to
scheduling can fallback to the legacy scheduler by setting
`jobmanager.scheduler` to `legacy` in their `flink-conf.yaml` for the time
being. Note, however, that using the legacy scheduler with the [Pipelined Region
Failover Strategy]({{< ref "docs/ops/state/task_failure_recovery" >}}#restart-pipelined-region-failover-strategy)
enabled has the following caveats:

* Exceptions that caused a job to restart will not be shown on the job overview page of the Web UI
##### [FLINK-15917](https://issues.apache.org/jira/browse/FLINK-15917)
.
However, exceptions that cause a job to fail (e.g., when all restart attempts exhausted) will still be shown.
* The `uptime` metric will not be reset after restarting a job due to task failure
##### [FLINK-15918](https://issues.apache.org/jira/browse/FLINK-15918)
.

Note that in the default `flink-conf.yaml`, the Pipelined Region Failover
Strategy is already enabled. That is, users that want to use the legacy
scheduler and cannot accept aforementioned caveats should make sure that
`jobmanager.execution.failover-strategy` is set to `full` or not set at all.

#### Java 11 Support
##### [FLINK-10725](https://issues.apache.org/jira/browse/FLINK-10725)

Beginning from this release, Flink can be compiled and run with Java 11. All
Java 8 artifacts can be also used with Java 11. This means that users that want
to run Flink with Java 11 do not have to compile Flink themselves.

When starting Flink with Java 11, the following warnings may be logged:

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by org.apache.flink.core.memory.MemoryUtils (file:/opt/flink/flink-1.10.0/lib/flink-dist_2.11-1.10.0.jar) to constructor java.nio.DirectByteBuffer(long,int)
    WARNING: Please consider reporting this to the maintainers of org.apache.flink.core.memory.MemoryUtils
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by org.apache.flink.api.java.ClosureCleaner (file:/home/flinkuser/.m2/repository/org/apache/flink/flink-core/1.10.0/flink-core-1.10.0.jar) to field java.lang.String.value
    WARNING: Please consider reporting this to the maintainers of org.apache.flink.api.java.ClosureCleaner
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by org.jboss.netty.util.internal.ByteBufferUtil (file:/home/flinkuser/.m2/repository/io/netty/netty/3.10.6.Final/netty-3.10.6.Final.jar) to method java.nio.DirectByteBuffer.cleaner()
    WARNING: Please consider reporting this to the maintainers of org.jboss.netty.util.internal.ByteBufferUtil
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by com.esotericsoftware.kryo.util.UnsafeUtil (file:/home/flinkuser/.m2/repository/com/esotericsoftware/kryo/kryo/2.24.0/kryo-2.24.0.jar) to constructor java.nio.DirectByteBuffer(long,int,java.lang.Object)
    WARNING: Please consider reporting this to the maintainers of com.esotericsoftware.kryo.util.UnsafeUtil
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release

These warnings are considered harmless and will be addressed in future Flink
releases.

Lastly, note that the connectors for Cassandra, Hive, HBase, and Kafka 0.8--0.11
have not been tested with Java 11 because the respective projects did not
provide Java 11 support at the time of the Flink 1.10.0 release.

### Memory Management
#### New Task Executor Memory Model
##### [FLINK-13980](https://issues.apache.org/jira/browse/FLINK-13980)

With
[FLIP-49](https://cwiki.apache.org/confluence/display/FLINK/FLIP-49%3A+Unified+Memory+Configuration+for+TaskExecutors),
a new memory model has been introduced for the task executor. New configuration
options have been introduced to control the memory consumption of the task
executor process. This affects all types of deployments: standalone, YARN,
Mesos, and the new active Kubernetes integration. The memory model of the job
manager process has not been changed yet but it is planned to be updated as
well.

If you try to reuse your previous Flink configuration without any adjustments,
the new memory model can result in differently computed memory parameters for
the JVM and, thus, performance changes.

Please, check [the user documentation](../deployment/memory/mem_setup.html) for more details.

##### Deprecation and breaking changes
The following options have been removed and have no effect anymore:

      Deprecated/removed config option
      Note

      taskmanager.memory.fraction

        Check also the description of the new option
        taskmanager.memory.managed.fraction
        but it has different semantics and the value of the deprecated option
        usually has to be adjusted

      taskmanager.memory.off-heap
      Support for on-heap managed memory has been removed, leaving off-heap managed memory as the only possibility

      taskmanager.memory.preallocate
      Pre-allocation is no longer supported, and managed memory is always allocated lazily

The following options, if used, are interpreted as other new options in order to
maintain backwards compatibility where it makes sense:

      Deprecated config option
      Interpreted as

      taskmanager.heap.size

taskmanager.memory.flink.size for standalone deployment

taskmanager.memory.process.size for containerized deployments

      taskmanager.memory.size
      taskmanager.memory.managed.size

      taskmanager.network.memory.min
      taskmanager.memory.network.min

      taskmanager.network.memory.max
      taskmanager.memory.network.max

      taskmanager.network.memory.fraction
      taskmanager.memory.network.fraction

The container cut-off configuration options, `containerized.heap-cutoff-ratio`
and `containerized.heap-cutoff-min`, have no effect for task executor processes
anymore but they still have the same semantics for the JobManager process.

#### RocksDB State Backend Memory Control
##### [FLINK-7289](https://issues.apache.org/jira/browse/FLINK-7289)

Together with the introduction of the [new Task Executor Memory
Model](#new-task-executor-memory-model-flink-13980), the memory consumption of the RocksDB state backend will be
limited by the total amount of Flink Managed Memory, which can be configured via
`taskmanager.memory.managed.size` or `taskmanager.memory.managed.fraction`.
Furthermore, users can tune RocksDB's write/read memory ratio
(`state.backend.rocksdb.memory.write-buffer-ratio`, by default `0.5`) and the
reserved memory fraction for indices/filters
(`state.backend.rocksdb.memory.high-prio-pool-ratio`, by default `0.1`). More
details and advanced configuration options can be found in the [Flink user
documentation]({{< ref "docs/ops/state/large_state_tuning" >}}#tuning-rocksdb-memory).

#### Fine-grained Operator Resource Management
##### [FLINK-14058](https://issues.apache.org/jira/browse/FLINK-14058)

Config options `table.exec.resource.external-buffer-memory`,
`table.exec.resource.hash-agg.memory`, `table.exec.resource.hash-join.memory`,
and `table.exec.resource.sort.memory` have been deprecated. Beginning from Flink
1.10, these config options are interpreted as weight hints instead of absolute
memory requirements. Flink choses sensible default weight hints which should
not be adjustment by users.

### Table API & SQL
#### Rename of ANY Type to RAW Type
##### [FLINK-14904](https://issues.apache.org/jira/browse/FLINK-14904)

The identifier `raw` is a reserved keyword now and must be escaped with
backticks when used as a SQL field or function name.

#### Rename of Table Connector Properties
##### [FLINK-14649](https://issues.apache.org/jira/browse/FLINK-14649)

Some indexed properties for table connectors have been flattened and renamed
for a better user experience when writing DDL statements. This affects the
Kafka Connector properties `connector.properties` and
`connector.specific-offsets`. Furthermore, the Elasticsearch Connector
property `connector.hosts` is affected. The aforementioned, old properties are
deprecated and will be removed in future versions. Please consult the [Table
Connectors documentation]({{< ref "docs/connectors/table/overview" >}})
for the new property names.

#### Methods for interacting with temporary Tables & Views
##### [FLINK-14490](https://issues.apache.org/jira/browse/FLINK-14490)

Methods `registerTable()`/`registerDataStream()`/`registerDataSet()` have been
deprecated in favor of `createTemporaryView()`, which better adheres to the
corresponding SQL term.

The `scan()` method has been deprecated in favor of the `from()` method.

Methods `registerTableSource()`/`registerTableSink()` become deprecated in favor
of `ConnectTableDescriptor#createTemporaryTable()`. The `ConnectTableDescriptor`
approach expects only a set of string properties as a description of a
TableSource or TableSink instead of an instance of a class in case of the
deprecated methods. This in return makes it possible to reliably store those
definitions in catalogs.

Method `insertInto(String path, String... pathContinued)` has been removed in
favor of in `insertInto(String path)`.

All the newly introduced methods accept a String identifier which will be
parsed into a 3-part identifier. The parser supports quoting the identifier.
It also requires escaping any reserved SQL keywords.

#### Removal of ExternalCatalog API
##### [FLINK-13697](https://issues.apache.org/jira/browse/FLINK-13697)

The deprecated `ExternalCatalog` API has been dropped. This includes:

* `ExternalCatalog` (and all dependent classes, e.g., `ExternalTable`)
* `SchematicDescriptor`, `MetadataDescriptor`, `StatisticsDescriptor`

Users are advised to use the [new Catalog API]({{< ref "docs/dev/table/catalogs" >}}#catalog-api).

### Configuration
#### Introduction of Type Information for ConfigOptions
##### [FLINK-14493](https://issues.apache.org/jira/browse/FLINK-14493)

Getters of `org.apache.flink.configuration.Configuration` throw
`IllegalArgumentException` now if the configured value cannot be parsed into
the required type. In previous Flink releases the default value was returned
in such cases.

#### Increase of default Restart Delay
##### [FLINK-13884](https://issues.apache.org/jira/browse/FLINK-13884)

The default restart delay for all shipped restart strategies, i.e., `fixed-delay`
and `failure-rate`, has been raised to 1 s (from originally 0 s).

#### Simplification of Cluster-Level Restart Strategy Configuration
##### [FLINK-13921](https://issues.apache.org/jira/browse/FLINK-13921)

Previously, if the user had set `restart-strategy.fixed-delay.attempts` or
`restart-strategy.fixed-delay.delay` but had not configured the option
`restart-strategy`, the cluster-level restart strategy would have been
`fixed-delay`. Now the cluster-level restart strategy is only determined by
the config option `restart-strategy` and whether checkpointing is enabled. See
[_"Task Failure Recovery"_]({{< ref "docs/ops/state/task_failure_recovery" >}})
for details.

#### Disable memory-mapped BoundedBlockingSubpartition by default
##### [FLINK-14952](https://issues.apache.org/jira/browse/FLINK-14952)

The config option `taskmanager.network.bounded-blocking-subpartition-type` has
been renamed to `taskmanager.network.blocking-shuffle.type`. Moreover, the
default value of the aforementioned config option has been changed from `auto`
to `file`. The reason is that TaskManagers running on YARN with `auto`, could
easily exceed the memory budget of their container, due to incorrectly accounted
memory-mapped files memory usage.

#### Removal of non-credit-based Network Flow Control
##### [FLINK-14516](https://issues.apache.org/jira/browse/FLINK-14516)

The non-credit-based network flow control code was removed alongside of the
configuration option `taskmanager.network.credit-model`. Flink will now always
use credit-based flow control.

#### Removal of HighAvailabilityOptions#HA_JOB_DELAY
##### [FLINK-13885](https://issues.apache.org/jira/browse/FLINK-13885)

The configuration option `high-availability.job.delay` has been removed
since it is no longer used.

### State
#### Enable Background Cleanup of State with TTL by default
##### [FLINK-14898](https://issues.apache.org/jira/browse/FLINK-14898)

[Background cleanup of expired state with TTL]({{< ref "docs/dev/datastream/fault-tolerance/state" >}}#cleanup-of-expired-state)
is activated by default now for all state backends shipped with Flink.
Note that the RocksDB state backend implements background cleanup by employing
a compaction filter. This has the caveat that even if a Flink job does not
store state with TTL, a minor performance penalty during compaction is incurred.
Users that experience noticeable performance degradation during RocksDB
compaction can disable the TTL compaction filter by setting the config option
`state.backend.rocksdb.ttl.compaction.filter.enabled` to `false`.

#### Deprecation of StateTtlConfig#Builder#cleanupInBackground()
##### [FLINK-15606](https://issues.apache.org/jira/browse/FLINK-15606)

`StateTtlConfig#Builder#cleanupInBackground()` has been deprecated because the
background cleanup of state with TTL is already enabled by default.

#### Timers are stored in RocksDB by default when using RocksDBStateBackend
##### [FLINK-15637](https://issues.apache.org/jira/browse/FLINK-15637)

The default timer store has been changed from Heap to RocksDB for the RocksDB
state backend to support asynchronous snapshots for timer state and better
scalability, with less than 5% performance cost. Users that find the performance
decline critical can set `state.backend.rocksdb.timer-service.factory` to `HEAP`
in `flink-conf.yaml` to restore the old behavior.

#### Removal of StateTtlConfig#TimeCharacteristic
##### [FLINK-15605](https://issues.apache.org/jira/browse/FLINK-15605)

`StateTtlConfig#TimeCharacteristic` has been removed in favor of
`StateTtlConfig#TtlTimeCharacteristic`.

#### New efficient Method to check if MapState is empty
##### [FLINK-13034](https://issues.apache.org/jira/browse/FLINK-13034)

We have added a new method `MapState#isEmpty()` which enables users to check
whether a map state is empty. The new method is 40% faster than
`mapState.keys().iterator().hasNext()` when using the RocksDB state backend.

#### RocksDB Upgrade
##### [FLINK-14483](https://issues.apache.org/jira/browse/FLINK-14483)

We have again released our own RocksDB build (FRocksDB) which is based on
RocksDB version 5.17.2 with several feature backports for the [Write Buffer
Manager](https://github.com/facebook/rocksdb/wiki/Write-Buffer-Manager) to
enable limiting RocksDB's memory usage. The decision to release our own
RocksDB build was made because later RocksDB versions suffer from a
[performance regression under certain
workloads](https://github.com/facebook/rocksdb/issues/5774).

#### RocksDB Logging disabled by default
##### [FLINK-15068](https://issues.apache.org/jira/browse/FLINK-15068)

Logging in RocksDB (e.g., logging related to flush, compaction, memtable
creation, etc.) has been disabled by default to prevent disk space from being
filled up unexpectedly. Users that need to enable logging should implement their
own `RocksDBOptionsFactory` that creates `DBOptions` instances with
`InfoLogLevel` set to `INFO_LEVEL`.

#### Improved RocksDB Savepoint Recovery
##### [FLINK-12785](https://issues.apache.org/jira/browse/FLINK-12785)

In previous Flink releases users may encounter an `OutOfMemoryError` when
restoring from a RocksDB savepoint containing large KV pairs. For that reason
we introduced a configurable memory limit in the `RocksDBWriteBatchWrapper`
with a default value of 2 MB. RocksDB's WriteBatch will flush before the
consumed memory limit is reached. If needed, the limit can be tuned via the
`state.backend.rocksdb.write-batch-size` config option in `flink-conf.yaml`.

### PyFlink
#### Python 2 Support dropped
##### [FLINK-14469](https://issues.apache.org/jira/browse/FLINK-14469)

Beginning from this release, PyFlink does not support Python 2. This is because [Python 2 has
reached end of life on January 1,
2020](https://www.python.org/doc/sunset-python-2/), and several third-party
projects that PyFlink depends on are also dropping Python 2 support.

### Monitoring
#### InfluxdbReporter skips Inf and NaN
##### [FLINK-12147](https://issues.apache.org/jira/browse/FLINK-12147)

The `InfluxdbReporter` now silently skips values that are unsupported by
InfluxDB, such as `Double.POSITIVE_INFINITY`, `Double.NEGATIVE_INFINITY`,
`Double.NaN`, etc.

### Connectors
#### Kinesis Connector License Change
##### [FLINK-12847](https://issues.apache.org/jira/browse/FLINK-12847)

flink-connector-kinesis is now licensed under the Apache License, Version 2.0,
and its artifacts will be deployed to Maven central as part of the Flink
releases. Users no longer need to build the Kinesis connector from source themselves.

### Miscellaneous Interface Changes
#### ExecutionConfig#getGlobalJobParameters() cannot return null anymore
##### [FLINK-9787](https://issues.apache.org/jira/browse/FLINK-9787)

`ExecutionConfig#getGlobalJobParameters` has been changed to never return
`null`. Conversely,
`ExecutionConfig#setGlobalJobParameters(GlobalJobParameters)` will not accept
`null` values anymore.

#### Change of contract in MasterTriggerRestoreHook interface
##### [FLINK-14344](https://issues.apache.org/jira/browse/FLINK-14344)

Implementations of `MasterTriggerRestoreHook#triggerCheckpoint(long, long,
Executor)` must be non-blocking now. Any blocking operation should be executed
asynchronously, e.g., using the given executor.

#### Client-/ and Server-Side Separation of HA Services
##### [FLINK-13750](https://issues.apache.org/jira/browse/FLINK-13750)

The `HighAvailabilityServices` have been split up into client-side
`ClientHighAvailabilityServices` and cluster-side `HighAvailabilityServices`.
When implementing custom high availability services, users should follow this
separation by overriding the factory method
`HighAvailabilityServicesFactory#createClientHAServices(Configuration)`.
Moreover, `HighAvailabilityServices#getWebMonitorLeaderRetriever()` should no
longer be implemented since it has been deprecated.

#### Deprecation of HighAvailabilityServices#getWebMonitorLeaderElectionService()
##### [FLINK-13977](https://issues.apache.org/jira/browse/FLINK-13977)

Implementations of `HighAvailabilityServices` should implement
`HighAvailabilityServices#getClusterRestEndpointLeaderElectionService()` instead
of `HighAvailabilityServices#getWebMonitorLeaderElectionService()`.

#### Interface Change in LeaderElectionService
##### [FLINK-14287](https://issues.apache.org/jira/browse/FLINK-14287)

`LeaderElectionService#confirmLeadership(UUID, String)` now takes an
additional second argument, which is the address under which the leader will be
reachable. All custom `LeaderElectionService` implementations will need to be
updated accordingly.

#### Deprecation of Checkpoint Lock
##### [FLINK-14857](https://issues.apache.org/jira/browse/FLINK-14857)

The method
`org.apache.flink.streaming.runtime.tasks.StreamTask#getCheckpointLock()` is
deprecated now. Users should use `MailboxExecutor` to run actions that require
synchronization with the task's thread (e.g. collecting output produced by an
external thread). The methods `MailboxExecutor#yield()` or
`MailboxExecutor#tryYield()` can be used for actions that need to give up
control to other actions temporarily, e.g., if the current operator is
blocked. The `MailboxExecutor` can be accessed by using
`YieldingOperatorFactory` (see `AsyncWaitOperator` for an example usage).

#### Deprecation of OptionsFactory and ConfigurableOptionsFactory interfaces
##### [FLINK-14926](https://issues.apache.org/jira/browse/FLINK-14926)

Interfaces `OptionsFactory` and `ConfigurableOptionsFactory` have been
deprecated in favor of `RocksDBOptionsFactory` and
`ConfigurableRocksDBOptionsFactory`, respectively.

#### Incompatibility of serialized JobGraphs
##### [FLINK-14594](https://issues.apache.org/jira/browse/FLINK-14594)

Serialized `JobGraphs` which set the `ResourceSpec` created by Flink versions < `1.10` are no longer compatible with Flink >= `1.10`.
If you want to migrate these jobs to Flink >= `1.10` you will have to stop the job with a savepoint and then resume it from this savepoint on the Flink >= `1.10` cluster.


text:
package catalano.demoapp.animation;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import catalano.demoapp.R;

public class AnimationActivity extends AppCompatActivity {

    private ImageView img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animation);

        //Initialize the imageView
        img = (ImageView)findViewById(R.id.img_animation);

        //region Rotate the view
        Button btnRotate = (Button)findViewById(R.id.btn_animation_rotate);
        btnRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                img.animate().rotationBy(360).setDuration(2000);
            }
        });
        //endregion

        //region Translate the view
        Button btnTranslate = (Button)findViewById(R.id.btn_animation_translate);
        btnTranslate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                img.animate().translationXBy(1000).setDuration(2000);
            }
        });
        //endregion

        //region Alpha effect
        Button btnAlpha = (Button)findViewById(R.id.btn_animation_alpha);
        btnAlpha.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                img.animate().alpha(0).setDuration(2000);
            }
        });
        //endregion

        //region Reload the activity
        Button btnRestart = (Button)findViewById(R.id.btn_animation_restart);
        btnRestart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
                startActivity(getIntent());

                //Reload with no animation between the activities
                overridePendingTransition(0, 0);
            }
        });
        //endregion

    }
}


text:
namespace WhatsAppTagCloud.ViewModel
{
    using System.ComponentModel;

    public abstract class AbstractViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


text:
"""
Phil Adams http://philadams.net

habitica: commandline interface for http://habitica.com
http://github.com/philadams/habitica

TODO:philadams add logging to .api
TODO:philadams get logger named, like requests!
"""

from bisect import bisect
import json
import logging
import os.path
from time import sleep
from webbrowser import open_new_tab

from docopt import docopt

from . import api

from pprint import pprint

try:
    import ConfigParser as configparser
except:
    import configparser

VERSION = 'habitica version 0.0.16'
TASK_VALUE_BASE = 0.9747  # http://habitica.wikia.com/wiki/Task_Value
HABITICA_REQUEST_WAIT_TIME = 0.5  # time to pause between concurrent requests
HABITICA_TASKS_PAGE = '/#/tasks'
# https://trello.com/c/4C8w1z5h/17-task-difficulty-settings-v2-priority-multiplier
PRIORITY = {'easy': 1,
            'medium': 1.5,
            'hard': 2}
AUTH_CONF = os.path.expanduser('~') + '/.config/habitica/auth.cfg'
CACHE_CONF = os.path.expanduser('~') + '/.config/habitica/cache.cfg'

SECTION_CACHE_QUEST = 'Quest'
checklists_on = False

DEFAULT_PARTY = 'Not currently in a party'
DEFAULT_QUEST = 'Not currently on a quest'
DEFAULT_PET = 'No pet currently'
DEFAULT_MOUNT = 'Not currently mounted'

def load_auth(configfile):
    """Get authentication data from the AUTH_CONF file."""

    logging.debug('Loading habitica auth data from %s' % configfile)

    try:
        cf = open(configfile)
    except IOError:
        logging.error("Unable to find '%s'." % configfile)
        exit(1)

    config = configparser.SafeConfigParser({'checklists': False})
    config.readfp(cf)

    cf.close()

    # Get data from config
    rv = {}
    try:
        rv = {'url': config.get('Habitica', 'url'),
              'checklists': config.get('Habitica', 'checklists'),
              'x-api-user': config.get('Habitica', 'login'),
              'x-api-key': config.get('Habitica', 'password')}

    except configparser.NoSectionError:
        logging.error("No 'Habitica' section in '%s'" % configfile)
        exit(1)

    except configparser.NoOptionError as e:
        logging.error("Missing option in auth file '%s': %s"
                      % (configfile, e.message))
        exit(1)

    # Return auth data as a dictionnary
    return rv

def load_cache(configfile):
    logging.debug('Loading cached config data (%s)...' % configfile)

    defaults = {'quest_key': '',
                'quest_s': 'Not currently on a quest'}

    cache = configparser.SafeConfigParser(defaults)
    cache.read(configfile)

    if not cache.has_section(SECTION_CACHE_QUEST):
        cache.add_section(SECTION_CACHE_QUEST)

    return cache

def update_quest_cache(configfile, **kwargs):
    logging.debug('Updating (and caching) config data (%s)...' % configfile)

    cache = load_cache(configfile)

    for key, val in kwargs.items():
        cache.set(SECTION_CACHE_QUEST, key, val)

    with open(configfile, 'wb') as f:
        cache.write(f)

    cache.read(configfile)

    return cache

def get_task_ids(tids):
    """
    handle task-id formats such as:
        habitica todos done 3
        habitica todos done 1,2,3
        habitica todos done 2 3
        habitica todos done 1-3,4 8
    tids is a seq like (last example above) ('1-3,4' '8')
    """
    logging.debug('raw task ids: %s' % tids)
    task_ids = []
    for raw_arg in tids:
        for bit in raw_arg.split(','):
            if '-' in bit:
                start, stop = [int(e) for e in bit.split('-')]
                task_ids.extend(range(start, stop + 1))
            else:
                task_ids.append(int(bit))
    return [e - 1 for e in set(task_ids)]

def updated_task_list(tasks, tids):
    for tid in sorted(tids, reverse=True):
        del(tasks[tid])
    return tasks

def cl_done_count(task):
    items = task['checklist']
    count = 0
    for li in items:
        if li['completed'] == True:
            count = count + 1
    return count

def cl_item_count(task):
    if 'checklist' in task:
        return len(task['checklist'])
    else:
        return 0

def print_task_list(tasks):
    for i, task in enumerate(tasks):
        completed = 'x' if task['completed'] else ' '
        task_line = '[%s] %s %s' % (completed,
                                    i + 1,
                                    task['text'])
        checklist_available = cl_item_count(task) > 0
        if checklist_available:
            task_line += ' (%s/%s)' % (str(cl_done_count(task)),
                                       str(cl_item_count(task)))
        print(task_line)
        if checklists_on and checklist_available:
            for c, check in enumerate(task['checklist']):
                completed = 'x' if check['completed'] else ' '
                print('    [%s] %s' % (completed,
                                       check['text']))

def qualitative_task_score_from_value(value):
    # task value/score info: http://habitica.wikia.com/wiki/Task_Value
    scores = ['*', '**', '***', '****', '*****', '******', '*******']
    breakpoints = [-20, -10, -1, 1, 5, 10]
    return scores[bisect(breakpoints, value)]

def set_checklists_status(auth, args):
    """Set display_checklist status, toggling from cli flag"""
    global checklists_on

    if auth['checklists'] == "true":
        checklists_on = True
    else:
        checklists_on = False

    # reverse the config setting if specified by the CLI option
    if args['--checklists']:
        checklists_on = not checklists_on

    return

def cli():
    """Habitica command-line interface.

    Usage: habitica [--version] [--help]
                    <command> [<args>...] [--difficulty=<d>]
                    [--verbose | --debug] [--checklists]

    Options:
      -h --help         Show this screen
      --version         Show version
      --difficulty=<d>  (easy | medium | hard) [default: easy]
      --verbose         Show some logging information
      --debug           Some all logging information
      -c --checklists   Toggle displaying checklists on or off

    The habitica commands are:
      status                  Show HP, XP, GP, and more
      habits                  List habit tasks
      habits up <task-id>     Up (+) habit <task-id>
      habits down <task-id>   Down (-) habit <task-id>
      dailies                 List daily tasks
      dailies done            Mark daily <task-id> complete
      dailies undo            Mark daily <task-id> incomplete
      todos                   List todo tasks
      todos done <task-id>    Mark one or more todo <task-id> completed
      todos add <task>        Add todo with description <task>
      todos delete <task-id>  Delete one or more todo <task-id>
      server                  Show status of Habitica service
      home                    Open tasks page in default browser

    For `habits up|down`, `dailies done|undo`, `todos done`, and `todos
    delete`, you can pass one or more <task-id> parameters, using either
    comma-separated lists or ranges or both. For example, `todos done
    1,3,6-9,11`.

    To show checklists with "todos" and "dailies" permanently, set
    'checklists' in your auth.cfg file to `checklists = true`.
    """

    # set up args
    args = docopt(cli.__doc__, version=VERSION)

    # set up logging
    if args['--verbose']:
        logging.basicConfig(level=logging.INFO)
    if args['--debug']:
        logging.basicConfig(level=logging.DEBUG)

    logging.debug('Command line args: {%s}' %
                  ', '.join("'%s': '%s'" % (k, v) for k, v in args.items()))

    # Set up auth
    auth = load_auth(AUTH_CONF)

    # Prepare cache
    cache = load_cache(CACHE_CONF)

    # instantiate api service
    hbt = api.Habitica(auth=auth)

    # Flag checklists as on if true in the config
    set_checklists_status(auth, args)

    # GET server status
    if args['<command>'] == 'server':
        server = hbt.status()
        if server['status'] == 'up':
            print('Habitica server is up')
        else:
            print('Habitica server down... or your computer cannot connect')

    # open HABITICA_TASKS_PAGE
    elif args['<command>'] == 'home':
        home_url = '%s%s' % (auth['url'], HABITICA_TASKS_PAGE)
        print('Opening %s' % home_url)
        open_new_tab(home_url)

    # GET user
    elif args['<command>'] == 'status':

        # gather status info
        user = hbt.user()
        stats = user.get('stats', '')
        items = user.get('items', '')
        food_count = sum(items['food'].values())
        group = hbt.groups(type='party')
        party = DEFAULT_PARTY
        quest = DEFAULT_QUEST
        mount = DEFAULT_MOUNT

        # if in a party, grab party info
        if group:
            party_id = group[0]['id']
            party_title = group[0]['name']

            # if on a quest with the party, grab quest info
            quest_data = getattr(hbt.groups, party_id)()['quest']
            if quest_data and quest_data['active']:
                quest_key = quest_data['key']

                if cache.get(SECTION_CACHE_QUEST, 'quest_key') != quest_key:
                    # we're on a new quest, update quest key
                    logging.info('Updating quest information...')
                    content = hbt.content()
                    quest_type = ''
                    quest_max = '-1'
                    quest_title = content['quests'][quest_key]['text']

                    # if there's a content/quests/<quest_key/collect,
                    # then drill into .../collect/<whatever>/count and
                    # .../collect/<whatever>/text and get those values
                    if content.get('quests', {}).get(quest_key,
                                                     {}).get('collect'):
                        logging.debug("\tOn a collection type of quest")
                        qt = 'collect'
                        clct = content['quests'][quest_key][qt].values()[0]
                        quest_max = clct['count']
                    # else if it's a boss, then hit up
                    # content/quests/<quest_key>/boss/hp
                    elif content.get('quests', {}).get(quest_key,
                                                       {}).get('boss'):
                        logging.debug("\tOn a boss/hp type of quest")
                        qt = 'hp'
                        quest_max = content['quests'][quest_key]['boss'][qt]

                    # store repr of quest info from /content
                    cache = update_quest_cache(CACHE_CONF,
                                               quest_key=str(quest_key),
                                               quest_type=str(qt),
                                               quest_max=str(quest_max),
                                               quest_title=str(quest_title))

                # now we use /party and quest_type to figure out our progress!
                quest_type = cache.get(SECTION_CACHE_QUEST, 'quest_type')
                if quest_type == 'collect':
                    qp_tmp = quest_data['progress']['collect']
                    quest_progress = qp_tmp.values()[0]
                else:
                    quest_progress = quest_data['progress']['hp']

                quest = '%s/%s "%s"' % (
                        str(int(quest_progress)),
                        cache.get(SECTION_CACHE_QUEST, 'quest_max'),
                        cache.get(SECTION_CACHE_QUEST, 'quest_title'))

        # prepare and print status strings
        title = 'Level %d %s' % (stats['lvl'], stats['class'].capitalize())
        health = '%d/%d' % (stats['hp'], stats['maxHealth'])
        xp = '%d/%d' % (int(stats['exp']), stats['toNextLevel'])
        mana = '%d/%d' % (int(stats['mp']), stats['maxMP'])
        currentPet = items.get('currentPet', '')
        if not currentPet:
            currentPet = DEFAULT_PET
        pet = '%s (%d food items)' % (currentPet, food_count)
        mount = items.get('currentMount', '')
        if not mount:
            mount = DEFAULT_MOUNT
        summary_items = ('health', 'xp', 'mana', 'quest', 'pet', 'mount')
        len_ljust = max(map(len, summary_items)) + 1
        print('-' * len(title))
        print(title)
        print('-' * len(title))
        print('%s %s' % ('Health:'.rjust(len_ljust, ' '), health))
        print('%s %s' % ('XP:'.rjust(len_ljust, ' '), xp))
        print('%s %s' % ('Mana:'.rjust(len_ljust, ' '), mana))
        print('%s %s' % ('Pet:'.rjust(len_ljust, ' '), pet))
        print('%s %s' % ('Mount:'.rjust(len_ljust, ' '), mount))
        print('%s %s' % ('Party:'.rjust(len_ljust, ' '), party))
        print('%s %s' % ('Quest:'.rjust(len_ljust, ' '), quest))

    # GET/POST habits
    elif args['<command>'] == 'habits':
        habits = hbt.user.tasks(type='habits')
        if 'up' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                tval = habits[tid]['value']
                hbt.user.tasks(_id=habits[tid]['id'],
                               _direction='up', _method='post')
                print('incremented task \'%s\''
                      % habits[tid]['text'].encode('utf8'))
                habits[tid]['value'] = tval + (TASK_VALUE_BASE ** tval)
                sleep(HABITICA_REQUEST_WAIT_TIME)
        elif 'down' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                tval = habits[tid]['value']
                hbt.user.tasks(_id=habits[tid]['id'],
                               _direction='down', _method='post')
                print('decremented task \'%s\''
                      % habits[tid]['text'].encode('utf8'))
                habits[tid]['value'] = tval - (TASK_VALUE_BASE ** tval)
                sleep(HABITICA_REQUEST_WAIT_TIME)
        for i, task in enumerate(habits):
            score = qualitative_task_score_from_value(task['value'])
            print('[%s] %s %s' % (score, i + 1, task['text'].encode('utf8')))

    # GET/PUT tasks:daily
    elif args['<command>'] == 'dailies':
        dailies = hbt.user.tasks(type='dailys')
        if 'done' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                hbt.user.tasks(_id=dailies[tid]['id'],
                               _direction='up', _method='post')
                print('marked daily \'%s\' completed'
                      % dailies[tid]['text'].encode('utf8'))
                dailies[tid]['completed'] = True
                sleep(HABITICA_REQUEST_WAIT_TIME)
        elif 'undo' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                hbt.user.tasks(_id=dailies[tid]['id'],
                               _method='put', completed=False)
                print('marked daily \'%s\' incomplete'
                      % dailies[tid]['text'].encode('utf8'))
                dailies[tid]['completed'] = False
                sleep(HABITICA_REQUEST_WAIT_TIME)
        print_task_list(dailies)

    # GET tasks:todo
    elif args['<command>'] == 'todos':
        todos = [e for e in hbt.user.tasks(type='todos')
                 if not e['completed']]
        if 'done' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                hbt.user.tasks(_id=todos[tid]['id'],
                               _direction='up', _method='post')
                print('marked todo \'%s\' complete'
                      % todos[tid]['text'].encode('utf8'))
                sleep(HABITICA_REQUEST_WAIT_TIME)
            todos = updated_task_list(todos, tids)
        elif 'add' in args['<args>']:
            ttext = ' '.join(args['<args>'][1:])
            hbt.user.tasks(type='todo',
                           text=ttext,
                           priority=PRIORITY[args['--difficulty']],
                           _method='post')
            todos.insert(0, {'completed': False, 'text': ttext})
            print('added new todo \'%s\'' % ttext)
        elif 'delete' in args['<args>']:
            tids = get_task_ids(args['<args>'][1:])
            for tid in tids:
                hbt.user.tasks(_id=todos[tid]['id'],
                               _method='delete')
                print('deleted todo \'%s\''
                      % todos[tid]['text'])
                sleep(HABITICA_REQUEST_WAIT_TIME)
            todos = updated_task_list(todos, tids)
        print_task_list(todos)

if __name__ == '__main__':
    cli()


text:
#ifndef _XRES_H
#define _XRES_H

#include <X11/Xfuncproto.h>

typedef struct {
  XID resource_base;
  XID resource_mask;
} XResClient;

typedef struct {
  Atom resource_type;
  unsigned int count;
} XResType;

_XFUNCPROTOBEGIN

Bool XResQueryExtension (
   Display *dpy,
   int *event_base_return,
   int *error_base_return
);

Status XResQueryVersion (
   Display *dpy,
   int *major_version_return,
   int *minor_version_return
);

Status XResQueryClients (
   Display *dpy,
   int *num_clients,
   XResClient **clients
);

Status XResQueryClientResources (
   Display *dpy,
   XID xid,
   int *num_types,
   XResType **types
);

Status XResQueryClientPixmapBytes (
   Display *dpy,
   XID xid,
   unsigned long *bytes
);

_XFUNCPROTOEND

#endif /* _XRES_H */


text:
package blue.lapis.pore.impl.entity;

import blue.lapis.pore.converter.wrapper.WrapperConverter;

import org.apache.commons.lang.NotImplementedException;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TNTPrimed;
import org.spongepowered.api.entity.explosive.PrimedTNT;

public class PoreTNTPrimed extends PoreEntity implements TNTPrimed {

    public static PoreTNTPrimed of(PrimedTNT handle) {
        return WrapperConverter.of(PoreTNTPrimed.class, handle);
    }

    protected PoreTNTPrimed(PrimedTNT handle) {
        super(handle);
    }

    @Override
    public PrimedTNT getHandle() {
        return (PrimedTNT) super.getHandle();
    }

    @Override
    public EntityType getType() {
        return EntityType.PRIMED_TNT;
    }

    @Override
    public void setFuseTicks(int fuseTicks) {
        getHandle().setFuseDuration(fuseTicks);
    }

    @Override
    public int getFuseTicks() {
        return getHandle().getFuseDuration();
    }

    @Override
    public Entity getSource() {
        return getHandle().getDetonator().isPresent() ? of(getHandle().getDetonator().get()) : null;
    }

    @Override
    public void setYield(float yield) {
        throw new NotImplementedException(); //TODO
    }

    @Override
    public float getYield() {
        throw new NotImplementedException(); //TODO
    }

    @Override
    public void setIsIncendiary(boolean isIncendiary) {
        throw new NotImplementedException(); //TODO
    }

    @Override
    public boolean isIncendiary() {
        throw new NotImplementedException(); //TODO
    }
}


text:
'''
Copyright 2016, EMC, Inc.

Author(s):
George Paulos

OnRack/RackHD Functional Integration Test (FIT) library
This is the main common function library for OnRack/RackHD FIT tests.
'''

# Standard imports
import os
import sys
import json
import subprocess
import time, datetime
import unittest
import signal
import re
import requests
import pexpect
import shutil

# Globals

# Pull arguments from environment into ARGS_LIST
ARGS_LIST = \
    {
    "v": os.getenv("VERBOSITY", "0"),
    "config":  os.getenv("CONFIG", "config"),
    "stack": os.getenv("STACK", "None"), # Stack label
    "ora": os.getenv("ORA", "localhost"), # Appliance IP or hostname
    "bmc": "None", # BMC IP or hostname
    "sku": os.getenv("SKU", "all"), # node SKU name
    "obmmac": os.getenv("OBMMAC", "all"), # node OBM MAC address
    "nodeid": os.getenv("NODEID", "None"), # node ID
    "hyper": "None", # hypervisor address
    "version": os.getenv("VERSION", "onrack-devel"), # code version
    "template": os.getenv("TEMPLATE", "None"), # path or URL link to OVA for deployment
    "xunit": os.getenv("XUNIT", False), # XUNIT output
    "list": os.getenv("LIST", False), # list tests
    "group": os.getenv("GROUP", "all"), # test group
    "http": os.getenv("HTTP", "False"), # force http api protocol
    "https": os.getenv("HTTPS", "False"), # force https api protocol
    "port": os.getenv("PORT", "None") # port number override
}

# Get top level path via git
TEST_PATH = subprocess.check_output("git rev-parse --show-toplevel", shell=True).rstrip("\n") + "/test/fit_tests/"
CONFIG_PATH = TEST_PATH + ARGS_LIST["config"] + "/"
if ARGS_LIST["config"] != 'config':
    print "**** Using config file path:", ARGS_LIST["config"]
VERBOSITY = int(os.getenv("VERBOSITY", "1"))
GLOBAL_CONFIG = []
STACK_CONFIG = []
API_PORT = "None"
API_PROTOCOL = "None"
AUTH_TOKEN = "None"
REDFISH_TOKEN = "None"

# List of BMC IP addresses
BMC_LIST = []

# Global Config files
try:
    GLOBAL_CONFIG = json.loads(open(CONFIG_PATH + "global_config.json").read())
except:
    print "**** Global Config file: " + CONFIG_PATH + "global_config.json" + " missing or corrupted! Exiting...."
    sys.exit(255)
try:
    STACK_CONFIG = json.loads(open(CONFIG_PATH + "stack_config.json").read())
except:
    print "**** Stack Config file:" + CONFIG_PATH + "stack_config.json" + " missing or corrupted! Creating empty stack file...."
    STACK_CONFIG = []

# apply stack detail files from config dir to STACK_CONFIG dict
for entry in os.listdir(CONFIG_PATH):
    if entry != "global_config.json" and entry != "stack_config.json" and ".json" in entry:
        try:
            detailfile = json.loads(open(CONFIG_PATH + entry).read())
        except:
            print "**** Invalid JSON file:", CONFIG_PATH + entry
        else:
            STACK_CONFIG.update(detailfile)

# This section derives default stack configuration data from STACK-CONFIG, use environment to override
ARGS_LIST.update(
    {
        "usr": GLOBAL_CONFIG['credentials']['ora'][0]['username'],
        "pwd": GLOBAL_CONFIG['credentials']['ora'][0]['password']
    }
)

if ARGS_LIST["stack"] != "None":
    if "ora" in STACK_CONFIG[ARGS_LIST["stack"]]:
        ARGS_LIST["ora"] = STACK_CONFIG[ARGS_LIST["stack"]]['ora']
    else:
        ARGS_LIST["ora"] = "localhost"
    if "bmc" in STACK_CONFIG[ARGS_LIST["stack"]]:
        ARGS_LIST["bmc"] = STACK_CONFIG[ARGS_LIST["stack"]]['bmc']
    if "hyper" in STACK_CONFIG[ARGS_LIST["stack"]]:
        ARGS_LIST["hyper"] = STACK_CONFIG[ARGS_LIST["stack"]]['hyper']

# set api port and protocol from command line
if ARGS_LIST['port'] != "None":
    API_PORT = ARGS_LIST['port']
if ARGS_LIST['http'] == "True":
    API_PROTOCOL = "http"
    if API_PORT == "None":
        API_PORT = GLOBAL_CONFIG['ports']['http']
if ARGS_LIST['https'] == "True":
    API_PROTOCOL = "https"
    if API_PORT == "None":
        API_PORT = GLOBAL_CONFIG['ports']['https']
if ARGS_LIST["ora"] == "localhost":
    if API_PROTOCOL == "None":
        API_PROTOCOL = 'http'
    if API_PORT == "None":
        API_PORT = '8080'
# set OVA template from command line
if ARGS_LIST["template"] == "None":
    ARGS_LIST["template"] = GLOBAL_CONFIG['repos']['install']['template']

def timestamp(): # return formatted current timestamp
    return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())

# This routine executes a sleep with countdown
def countdown(sleep_time, sleep_interval=1):
    sys.stdout.write("Sleeping for " + str(sleep_time * sleep_interval)
                     + " seconds.")
    sys.stdout.flush()
    for _ in range(0, sleep_time):
        time.sleep(sleep_interval)
        sys.stdout.write(".")
        sys.stdout.flush()
    print "Waking!"
    return

def remote_shell(shell_cmd, expect_receive="", expect_send="", timeout=300, address=ARGS_LIST['ora'], user=ARGS_LIST['usr'], password=ARGS_LIST['pwd']):
    '''
    Run ssh based shell command on a remote machine at ARGS_LIST["ora"]

    :param shell_cmd: string based command
    :param expect_receive:
    :param expect_send:
    :param timeout: in seconds
    :param address: IP or hostname of remote host
    :param user: username of remote host
    :param password: password of remote host
    :return: dict = {'stdout': str:ouput, 'exitcode': return code}
    '''

    logfile_redirect = None
    if VERBOSITY >= 4:
        print "remote_shell: Host =", address
        print "remote_shell: Command =", shell_cmd

    if VERBOSITY >= 9:
        print "remote_shell: STDOUT =\n"
        logfile_redirect = sys.stdout

    # if localhost just run the command local
    if ARGS_LIST['ora'] == 'localhost':
        (command_output, exitstatus) = \
            pexpect.run("sudo bash -c \"" + shell_cmd + "\"",
                        withexitstatus=1,
                        events={"assword": password + "\n"},
                        timeout=timeout, logfile=logfile_redirect)
        return {'stdout':command_output, 'exitcode':exitstatus}

    # this clears the ssh key from ~/.ssh/known_hosts
    subprocess.call(["touch ~/.ssh/known_hosts;ssh-keygen -R "
                     + address  + " -f ~/.ssh/known_hosts >/dev/null 2>&1"], shell=True)

    shell_cmd.replace("'", "\\\'")
    if expect_receive == "" or expect_send == "":
        (command_output, exitstatus) = \
            pexpect.run("ssh -q -o StrictHostKeyChecking=no -t " + user + "@"
                        + address + " sudo bash -c \\\"" + shell_cmd + "\\\"",
                        withexitstatus=1,
                        events={"assword": password + "\n"},
                        timeout=timeout, logfile=logfile_redirect)
    else:
        (command_output, exitstatus) = \
            pexpect.run("ssh -q -o StrictHostKeyChecking=no -t " + user + "@"
                        + address + " sudo bash -c \\\"" + shell_cmd + "\\\"",
                        withexitstatus=1,
                        events={"assword": password + "\n",
                                expect_receive: expect_send + "\n"},
                        timeout=timeout, logfile=logfile_redirect)
    if VERBOSITY >= 4:
        print shell_cmd, "\nremote_shell: Exit Code =", exitstatus

    return {'stdout':command_output, 'exitcode':exitstatus}

def scp_file_to_ora(src_file_name):
    '''
    scp the given file over to the ORA and place it in onrack's
    home directory.

    :param src_file_name: name of file to copy over. May include path
    :type src_file_name: basestring
    :return: just name of file on target (no path)
    :rtype: basestring
    '''

    logfile_redirect = file('/dev/null', 'w')
    just_fname = os.path.basename(src_file_name)
    # if localhost just copy to home dir
    if ARGS_LIST['ora'] == 'localhost':
        remote_shell('cp ' + src_file_name + ' ~/' + src_file_name)
        return src_file_name

    scp_target = ARGS_LIST['usr'] + '@{0}:'.format(ARGS_LIST["ora"])
    cmd = 'scp -o StrictHostKeyChecking=no {0} {1}'.format(src_file_name, scp_target)
    if VERBOSITY >= 4:
        print "scp_file_to_ora: '{0}'".format(cmd)

    if VERBOSITY >= 9:
        logfile_redirect = sys.stdout

    (command_output, ecode) = pexpect.run(
        cmd, withexitstatus=1,
        events={'(?i)assword: ':ARGS_LIST['pwd'] + '\n'},
        logfile=logfile_redirect)
    if VERBOSITY >= 4:
        print "scp_file_to_ora: Exit Code = {0}".format(ecode)

    assert ecode == 0, \
        'failed "{0}" because {1}. Output={2}'.format(cmd, ecode, command_output)
    return just_fname

def get_auth_token():
    # This is run once to get an auth token which is set to global AUTH_TOKEN and used for rest of session
    global AUTH_TOKEN
    global REDFISH_TOKEN
    api_login = {"username": GLOBAL_CONFIG["api"]["admin_user"], "password": GLOBAL_CONFIG["api"]["admin_pass"]}
    redfish_login = {"UserName": GLOBAL_CONFIG["api"]["admin_user"], "Password": GLOBAL_CONFIG["api"]["admin_pass"]}
    try:
        restful("https://" + ARGS_LIST['ora'] + ":" + str(API_PORT) +
                       "/login", rest_action="post", rest_payload=api_login, rest_timeout=2)
    except:
        AUTH_TOKEN = "Unavailable"
        return False
    else:
        api_data = restful("https://" + ARGS_LIST['ora'] + ":" + str(API_PORT) +
                           "/login", rest_action="post", rest_payload=api_login, rest_timeout=2)
        if api_data['status'] == 200:
            AUTH_TOKEN = str(api_data['json']['token'])
            redfish_data = restful("https://" + ARGS_LIST['ora'] + ":" + str(API_PORT) +
                               "/redfish/v1/SessionService/Sessions", rest_action="post", rest_payload=redfish_login, rest_timeout=2)
            if 'x-auth-token' in redfish_data['headers']:
                REDFISH_TOKEN =  redfish_data['headers']['x-auth-token']
                return True
            else:
                print "WARNING: Redfish API token not available."
        else:
            AUTH_TOKEN = "Unavailable"
            return False

def rackhdapi(url_cmd, action='get', payload=[], timeout=None, headers={}):
    '''
    This routine will build URL for RackHD API, enable port, execute, and return data
    Example: rackhdapi('/api/current/nodes') - simple 'get' command
    Example: rackhdapi("/api/current/nodes/ID/dhcp/whitelist", action="post")

    :param url_cmd: url command for monorail api
    :param action: rest action (get/put/post/delete)
    :param payload: rest payload
    :param timeout: rest timeout
    :param headers: rest_headers

    :return: {'json':result_data.json(), 'text':result_data.text,
                'status':result_data.status_code,
                'headers':result_data.headers.get('content-type'),
                'timeout':False}
    '''

    # Automatic protocol selection: unless protocol is specified, test protocols, save settings globally
    global API_PROTOCOL
    global API_PORT

    if API_PROTOCOL == "None":
        if API_PORT == "None":
            API_PORT = str(GLOBAL_CONFIG['ports']['http'])
        if restful("http://" + ARGS_LIST['ora'] + ":" + str(API_PORT) + "/", rest_timeout=2)['status'] == 0:
            API_PROTOCOL = 'https'
            API_PORT = str(GLOBAL_CONFIG['ports']['https'])
        else:
            API_PROTOCOL = 'http'
            API_PORT = str(GLOBAL_CONFIG['ports']['http'])

    # Retrieve authentication token for the session
    if AUTH_TOKEN == "None":
        get_auth_token()

    return restful(API_PROTOCOL + "://" + ARGS_LIST['ora'] + ":" + str(API_PORT) + url_cmd,
                       rest_action=action, rest_payload=payload, rest_timeout=timeout, rest_headers=headers)

def restful(url_command, rest_action='get', rest_payload=[], rest_timeout=None, sslverify=False, rest_headers={}):
    '''
    This routine executes a rest API call to the host.

    :param url_command: the full URL for the command
    :param rest_action: what the restful do (get/post/put/delete)
    :param rest_payload: payload for rest request
    :param rest_headers: headers (JSON dict)
    :param rest_timeout: timeout for rest request
    :param sslverify: ssl Verify (True/False)
    :return:    {'json':result_data.json(), 'text':result_data.text,
                'status':result_data.status_code,
                'headers':result_data.headers,
                'timeout':False}
    '''

    result_data = None

    # print URL and action
    if VERBOSITY >= 4:
        print "restful: Action = ", rest_action, ", URL = ", url_command

    # prepare payload for XML output
    payload_print = []
    try:
        json.dumps(rest_payload)
    except:
        payload_print = []
    else:
        payload_print = json.dumps(rest_payload, sort_keys=True, indent=4,)
        if len(payload_print) > 4096:
            payload_print = payload_print[0:4096] + '\n...truncated...\n'
        if VERBOSITY >= 7 and rest_payload != []:
            print "restful: Payload =\n", payload_print

    rest_headers.update({"Content-Type": "application/json"})
    if VERBOSITY >= 5:
         print "restful: Request Headers =", rest_headers, "\n"

    # If AUTH_TOKEN is set, add to header
    if AUTH_TOKEN != "None" and AUTH_TOKEN != "Unavailable" and "authorization" not in rest_headers:
        rest_headers.update({"authorization": "JWT " + AUTH_TOKEN, "X-Auth-Token": REDFISH_TOKEN})
    # Perform rest request
    try:
        if rest_action == "get":
            result_data = requests.get(url_command,
                                       timeout=rest_timeout,
                                       verify=sslverify,
                                       headers=rest_headers)
        if rest_action == "delete":
            result_data = requests.delete(url_command,
                                          data=json.dumps(rest_payload),
                                          timeout=rest_timeout,
                                          verify=sslverify,
                                          headers=rest_headers)
        if rest_action == "put":
            result_data = requests.put(url_command,
                                       data=json.dumps(rest_payload),
                                       headers=rest_headers,
                                       timeout=rest_timeout,
                                       verify=sslverify,
                                       )
        if rest_action == "binary-put":
            rest_headers.update({"Content-Type": "application/x-www-form-urlencoded"})
            result_data = requests.put(url_command,
                                       data=rest_payload,
                                       headers=rest_headers,
                                       timeout=rest_timeout,
                                       verify=sslverify,
                                       )
        if rest_action == "text-put":
            rest_headers.update({"Content-Type": "text/plain"})
            result_data = requests.put(url_command,
                                       data=rest_payload,
                                       headers=rest_headers,
                                       timeout=rest_timeout,
                                       verify=sslverify,
                                       )
        if rest_action == "post":
            result_data = requests.post(url_command,
                                        data=json.dumps(rest_payload),
                                        headers=rest_headers,
                                        timeout=rest_timeout,
                                        verify=sslverify
                                        )
        if rest_action == "binary-post":
            rest_headers.update({"Content-Type": "application/x-www-form-urlencoded"})
            result_data = requests.post(url_command,
                                        data=rest_payload,
                                        headers=rest_headers,
                                        timeout=rest_timeout,
                                        verify=sslverify
                                        )
        if rest_action == "text-post":
            rest_headers.update({"Content-Type": "text/plain"})
            result_data = requests.post(url_command,
                                        data=rest_payload,
                                        headers=rest_headers,
                                        timeout=rest_timeout,
                                        verify=sslverify
                                        )
        if rest_action == "patch":
            result_data = requests.patch(url_command,
                                         data=json.dumps(rest_payload),
                                         headers=rest_headers,
                                         timeout=rest_timeout,
                                         verify=sslverify
                                         )
    except requests.exceptions.Timeout:
        return {'json':'', 'text':'',
                'status':0,
                'headers':'',
                'timeout':True}

    try:
        result_data.json()
    except ValueError:

        if VERBOSITY >= 9:
            print "restful: TEXT =\n"
            print result_data.text
        if VERBOSITY >= 6:
            print "restful: Response Headers =", result_data.headers, "\n"
        if VERBOSITY >= 4:
            print "restful: Status code =", result_data.status_code, "\n"
        return {'json':{}, 'text':result_data.text, 'status':result_data.status_code,
                'headers':result_data.headers,
                'timeout':False}
    else:

        if VERBOSITY >= 9:
            print "restful: JSON = \n"
            print json.dumps(result_data.json(), sort_keys=True, indent=4)
        if VERBOSITY >= 6:
            print "restful: Response Headers =", result_data.headers, "\n"
        if VERBOSITY >= 4:
            print "restful: Status code =", result_data.status_code, "\n"
        return {'json':result_data.json(), 'text':result_data.text,
                'status':result_data.status_code,
                'headers':result_data.headers,
                'timeout':False}

# Get the list of BMC IP addresses that we can find
def get_bmc_ips():
    idlist = [] # list of unique dcmi node IDs
    # If we have already done this, use that list
    if len(BMC_LIST) == 0:
        ipscan = remote_shell('arp')['stdout'].split()
        for ipaddr in ipscan:
            if ipaddr[0:3] == "172" and remote_shell('ping -c 1 -w 5 ' + ipaddr)['exitcode'] == 0:
                # iterate through all known IPMI users
                for item in GLOBAL_CONFIG['credentials']['bmc']:
                    # check BMC credentials
                    ipmicheck = remote_shell('ipmitool -I lanplus -H ' + ipaddr + ' -U ' + item['username'] \
                                               + ' -P ' + item['password'] + ' -R 1 -N 3 chassis power status')
                    if ipmicheck['exitcode'] == 0:
                        # retrieve the ID string
                        return_code = remote_shell('ipmitool -I lanplus -H ' + ipaddr + ' -U ' + item['username'] \
                                                   + ' -P ' + item['password'] + ' -R 1 -N 3 dcmi get_mc_id_string')
                        bmc_info = {"ip": ipaddr, "user": item['username'], "pw": item['password']}
                        if return_code['exitcode'] == 0 and return_code['stdout'] not in idlist:
                            # add to list if unique
                            idlist.append(return_code['stdout'])
                            BMC_LIST.append(bmc_info)
                            break
                        else:
                            # simulated nodes don't yet support dcmi, remove this else branch when supported
                            BMC_LIST.append(bmc_info)
                            break
        if VERBOSITY >= 6:
            print "get_bmc_ips: "
            print "**** BMC IP node count =", len(BMC_LIST), "****"

    return len(BMC_LIST)

# power on/off all compute nodes in the stack via the BMC
def power_control_all_nodes(state):
    if state != "on" and state != "off":
        print "power_control_all_nodes:  invalid state " + state
        return

    # Get the list of BMCs that we know about
    node_count = get_bmc_ips()

    # Send power on/off to all of them
    for bmc in BMC_LIST:
        return_code = remote_shell('ipmitool -I lanplus -H ' + bmc['ip'] \
                                   + ' -U ' + bmc['user'] + ' -P ' \
                                   + bmc['pw'] + ' -R 4 -N 3 chassis power ' + state)
        if return_code['exitcode'] != 0:
            print "Error powering " + state + " node: " + bmc['ip']

    return node_count

def mongo_reset():
    # clears the Mongo database on ORA to default, returns 0 if successful
    remote_shell('service onrack-conductor stop')
    remote_shell('/opt/onrack/bin/monorail stop')
    remote_shell("mongo pxe --eval 'db.dropDatabase\\\(\\\)'")
    remote_shell('rm -f /var/lib/dhcp/dhcpd.leases')
    remote_shell('rm -f /var/log/onrack-conductor-event.log')
    remote_shell('/opt/onrack/bin/monorail start')
    if remote_shell('service onrack-conductor start')['exitcode'] > 0:
        return 1
    return 0

def appliance_reset():
    return_code = subprocess.call("ipmitool -I lanplus -H " + ARGS_LIST["bmc"] \
                                  + " -U root -P 1234567 chassis power reset", shell=True)
    return return_code

def node_select():
    # returns a list with valid compute node IDs that match ARGS_LIST["sku"] in 'Name' or 'Model' field
    # and matches node BMC MAC address in ARGS_LIST["obmmac"] if specified
    # Otherwise returns list of all IDs that are not 'Unknown' or 'Unmanaged'
    nodelist = []
    skuid = "None"
    # check if user specified a single nodeid to run against
    # user must know the nodeid and any check for a valid nodeid is skipped
    if ARGS_LIST["nodeid"] != 'None':
        nodelist.append(ARGS_LIST["nodeid"])
        return nodelist
    else:
        # Find SKU ID
        skumap = rackhdapi('/api/2.0/skus')
        if skumap['status'] != 200:
            print '**** Unable to retrieve SKU list via API.\n'
            sys.exit(255)
        for skuentry in skumap['json']:
            if str(ARGS_LIST['sku']) in json.dumps(skuentry):
                skuid = skuentry['id']
        # Collect node IDs
        catalog = rackhdapi('/api/2.0/nodes')
        if skumap['status'] != 200:
            print '**** Unable to retrieve node list via API.\n'
            sys.exit(255)
        # Select node by SKU
        for nodeentry in catalog['json']:
            if ARGS_LIST["sku"] == 'all':
                # Select only managed compute nodes
                if nodeentry['type'] == 'compute':
                    nodelist.append(nodeentry['id'])
            else:
                if 'sku' in nodeentry and skuid in json.dumps(nodeentry['sku']):
                    nodelist.append(nodeentry['id'])
        # Select by node BMC MAC addr
        if ARGS_LIST["obmmac"] != 'all':
            idlist = nodelist
            nodelist = []
            for member in idlist:
                nodeentry = rackhdapi('/api/2.0/nodes/' + member)
                if ARGS_LIST["obmmac"] in json.dumps(nodeentry['json']):
                    nodelist = [member]
                    break
    if VERBOSITY >= 6:
        print "Node List:"
        print nodelist, '\n'
    if len(nodelist) == 0:
        print '**** Empty node list.\n'
    return nodelist

def list_skus():
    # return list of installed SKU names
    skunames = []
    api_data = rackhdapi('/api/2.0/skus')['json']
    for item in api_data:
        skunames.append(item['name'])
    return skunames

def get_node_sku(nodeid):
    # return name field of node SKU if available
    nodetype = ""
    sku = ""
    # get node info
    mondata = rackhdapi("/api/2.0/nodes/" + nodeid)
    if mondata['status'] == 200:
        # get the sku id contained in the node
        sku = mondata['json'].get("sku")
        if sku:
            skudata = rackhdapi(sku)
            if skudata['status'] == 200:
                nodetype = skudata['json'].get("name")
            else:
                if VERBOSITY >= 2:
                    errmsg = "Error: SKU API failed {}, return code {} ".format(sku, skudata['status'])
                    print errmsg
                    return "unknown"
        else:
            return "unknown"
    return nodetype

def check_active_workflows(nodeid):
    # Return True if active workflows are found on node
    workflows = rackhdapi('/api/2.0/nodes/' + nodeid + '/workflows')['json']
    for item in workflows:
        if '_status' in item:
            if item['_status'] in ['running', 'pending']:
                return True
        if 'status' in item:
            if item['status'] in ['running', 'pending']:
                return True
        else:
            return False
    return False

def cancel_active_workflows(nodeid):
    # cancel all active workflows on node
    exitstatus = True
    apistatus = rackhdapi('/api/2.0/nodes/' + nodeid + '/workflows/action',
                          action='put', payload={"command": "cancel"})['status']
    if apistatus != 202:
       exitstatus = False
    return exitstatus

def apply_obm_settings(retry=30):
    # New routine to install OBM credentials via workflows in parallel
    count = 0
    for creds in GLOBAL_CONFIG['credentials']['bmc']:
        # greate graph for setting OBM credentials
        payload = \
        {
            "friendlyName": "IPMI" + str(count),
            "injectableName": 'Graph.Obm.Ipmi.CreateSettings' + str(count),
            "options": {
                "obm-ipmi-task":{
                    "user": creds["username"],
                    "password": creds["password"]
                }
            },
            "tasks": [
                {
                    "label": "obm-ipmi-task",
                    "taskName": "Task.Obm.Ipmi.CreateSettings"
                }
        ]
        }
        api_data = rackhdapi("/api/2.0/workflows/graphs", action="put", payload=payload)
        if api_data['status'] != 201:
            print "**** OBM workflow failed to load!"
            return False
        count += 1
    # Setup additional OBM settings for nodes that currently use RMM port (still same bmc username/password used)
    count = 0
    for creds in GLOBAL_CONFIG['credentials']['bmc']:
        # greate graph for setting OBM credentials for RMM
        payload = \
        {
            "friendlyName": "RMM.IPMI" + str(count),
            "injectableName": 'Graph.Obm.Ipmi.CreateSettings.RMM' + str(count),
            "options": {
                "obm-ipmi-task":{
                    "ipmichannel": "3",
                    "user": creds["username"],
                    "password": creds["password"]
                }
            },
            "tasks": [
                {
                    "label": "obm-ipmi-task",
                    "taskName": "Task.Obm.Ipmi.CreateSettings"
                }
        ]
        }
        api_data = rackhdapi("/api/2.0/workflows/graphs", action="put", payload=payload)
        if api_data['status'] != 201:
            print "**** OBM workflow failed to load!"
            return False
        count += 1

    # run each OBM credential workflow on each node in parallel until success
    nodestatus = {} # dictionary with node IDs and status of each node
    for dummy in range(0, retry):
        nodelist = node_select()
        for node in nodelist:
            if node not in nodestatus:
                nodestatus[node] = {"status": "pending", "instanceId": "", "sku": get_node_sku(node), "retry": 0}
        for num in range(0, count):
            for node in nodelist:
                # try workflow
                if nodestatus[node]['status'] == "pending":
                    skuid = rackhdapi('/api/2.0/nodes/' + node)['json'].get("sku")
                    if skuid:
                        if nodestatus[node]['sku'] == "unknown":
                            nodestatus[node].update({"sku": get_node_sku(node)})
                        skudata = rackhdapi(skuid)['text']
                        if "rmm.data.MAC" in skudata:
                            workflow = {"name": 'Graph.Obm.Ipmi.CreateSettings.RMM' + str(num)}
                        else:
                            workflow = {"name": 'Graph.Obm.Ipmi.CreateSettings' + str(num)}
                        result = rackhdapi("/api/2.0/nodes/"  + node + "/workflows", action="post", payload=workflow)
                        if result['status'] == 201:
                            nodestatus[node].update({"status": "running", "instanceId": result['json']["instanceId"]})
            for node in nodelist:
                # check OBM workflow status
                if nodestatus[node]['status'] == "running":
                    nodestatus[node]['retry'] += 1
                    state_data = rackhdapi("/api/2.0/workflows/" + nodestatus[node]['instanceId'])
                    if state_data['status'] == 200:
                        if "_status" in state_data['json']:
                            state = state_data['json']['_status']
                        else:
                            state = state_data['json']['status']
                        if state == "succeeded":
                            nodestatus[node]['status'] = "succeeded"
                        if state in ["failed", "cancelled", "timeout"]:
                            nodestatus[node]['status'] = "pending"
                            # if the workflow left an invalid OBM, delete it
                            result = rackhdapi("/api/2.0/nodes/" + node)
                            if result['status'] == 200:
                                if result['json']['obms']:
                                    for ref in result['json']['obms']:
                                        obmref = ref.get('ref')
                                        if obmref:
                                            rackhdapi(obmref, action="delete")

        if VERBOSITY >= 4:
            print "**** Node(s) OBM status:\n", json.dumps(nodestatus, sort_keys=True, indent=4,)
        if "pending" not in str(nodestatus) and "running" not in str(nodestatus):
            # All OBM settings successful
            return True
        time.sleep(30)
    # Failures occurred
    print "**** Node(s) OBM settings failed."
    return False

def apply_obm_settings_seq():
    # legacy routine to install OBM credentials via workflows sequentially one-at-a-time
    count = 0
    for creds in GLOBAL_CONFIG['credentials']['bmc']:
        # greate graph for setting OBM credentials
        payload = \
        {
            "friendlyName": "IPMI" + str(count),
            "injectableName": 'Graph.Obm.Ipmi.CreateSettings' + str(count),
            "options": {
                "obm-ipmi-task":{
                    "user": creds["username"],
                    "password": creds["password"]
                }
            },
            "tasks": [
                {
                    "label": "obm-ipmi-task",
                    "taskName": "Task.Obm.Ipmi.CreateSettings"
                }
        ]
        }
        api_data = rackhdapi("/api/2.0/workflows/graphs", action="put", payload=payload)
        if api_data['status'] != 201:
            print "**** OBM workflow failed to load!"
            return False
        count += 1
    # Setup additional OBM settings for nodes that currently use RMM port (still same bmc username/password used)
    count = 0
    for creds in GLOBAL_CONFIG['credentials']['bmc']:
        # greate graph for setting OBM credentials for RMM
        payload = \
        {
            "friendlyName": "RMM.IPMI" + str(count),
            "injectableName": 'Graph.Obm.Ipmi.CreateSettings.RMM' + str(count),
            "options": {
                "obm-ipmi-task":{
                    "ipmichannel": "3",
                    "user": creds["username"],
                    "password": creds["password"]
                }
            },
            "tasks": [
                {
                    "label": "obm-ipmi-task",
                    "taskName": "Task.Obm.Ipmi.CreateSettings"
                }
        ]
        }
        api_data = rackhdapi("/api/2.0/workflows/graphs", action="put", payload=payload)
        if api_data['status'] != 201:
            print "**** OBM workflow failed to load!"
            return False
        count += 1

    # run each OBM workflow against each node until success
    nodelist = node_select()
    failedlist = []
    for node in nodelist:
        for num in range(0, count):
            nodestatus = ""
            wfstatus = ""
            skuid = rackhdapi('/api/2.0/nodes/' + node)['json'].get("sku")
            # Check is sku is empty
            sku = skuid.rstrip("/api/2.0/skus/")
            if sku:
                skudata = rackhdapi(skuid)['text']
                if "rmm.data.MAC" in skudata:
                    workflow = {"name": 'Graph.Obm.Ipmi.CreateSettings.RMM' + str(num)}
                else:
                    workflow = {"name": 'Graph.Obm.Ipmi.CreateSettings' + str(num)}
            else:
                print "*** SKU not set for node ", node
                nodestatus = "failed"
                break

            # wait for existing workflow to complete
            for dummy in range(0, 60):
                print "*** Using workflow: ", workflow
                result = rackhdapi("/api/2.0/nodes/"  + node + "/workflows", action="post", payload=workflow)
                if result['status'] != 201:
                    time.sleep(5)
                elif dummy == 60:
                    print "*** Workflow failed to start"
                    wfstatus = "failed"
                else:
                    break

            if wfstatus != "failed":
                # wait for OBM workflow to complete
                counter = 0
                for counter in range(0, 60):
                    time.sleep(10)
                    state_data = rackhdapi("/api/2.0/workflows/" + result['json']["instanceId"])
                    if state_data['status'] == 200:
                        if "_status" in state_data['json']:
                            nodestatus = state_data['json']['_status']
                        else:
                            nodestatus = state_data['json']['status']
                        if nodestatus != "running" and nodestatus != "pending":
                            break
                if nodestatus == "succeeded":
                    print "*** Succeeded on workflow ", workflow
                    break
                if counter == 60:
                    #print "Timed out status", nodestatus
                    nodestatus = "failed"
                    print "*** Node failed OBM settings - timeout:", node
                    print "*** Failed on workflow ", workflow

        # check final loop status for node workflow
        if wfstatus == "failed" or nodestatus == "failed":
            failedlist.append(node)

    # cleanup failed nodes OBM settings on nodes, need to remove failed settings
    for node in failedlist:
        result = rackhdapi("/api/2.0/nodes/"  + node)
        if result['status'] == 200:
            if result['json']['obms']:
                obms = result['json']['obms'][0]
                obmref = obms.get('ref')
                if obmref:
                    result = rackhdapi(obmref, action="delete")
                    if result['status'] != 204:
                        print "*** Warning: failed to delete invalid OBM setting ", obmref

    if len(failedlist) > 0:
        print "**** Nodes failed OBM settings:", failedlist
        return False
    return True

def run_nose(nosepath):
    # this routine runs nosetests from wrapper using path spec 'nosepath'
    def _noserunner(pathspec):
        xmlfile = str(time.time()) + ".xml" # XML report file name
        return subprocess.call(
                         [
                             'export VERBOSITY=' + str(ARGS_LIST['v']) + ';' +
                             'export ORA=' + str(ARGS_LIST['ora']) + ';' +
                             'export STACK=' + str(ARGS_LIST['stack']) + ';' +
                             'export SKU="' + str(ARGS_LIST['sku']) + '";' +
                             'export NODEID=' + str(ARGS_LIST['nodeid']) + ';' +
                             'export OBMMAC=' + str(ARGS_LIST['obmmac']) + ';' +
                             'export VERSION=' + str(ARGS_LIST['version']) + ';' +
                             'export TEMPLATE=' + str(ARGS_LIST['template']) + ';' +
                             'export XUNIT=' + str(ARGS_LIST['xunit']) + ';' +
                             'export GROUP=' + str(ARGS_LIST['group']) + ';' +
                             'export CONFIG=' + str(ARGS_LIST['config']) + ';' +
                             'export HTTP=' + str(ARGS_LIST['http']) + ';' +
                             'export HTTPS=' + str(ARGS_LIST['https']) + ';' +
                             'export PORT=' + str(ARGS_LIST['port']) + ';' +
                             'nosetests ' + noseopts + ' --xunit-file ' + xmlfile + ' ' + pathspec
                         ], shell=True)
    exitcode = 0
    # set nose options
    noseopts = ' --exe '
    if ARGS_LIST['group'] != 'all' and ARGS_LIST['group'] != '':
        noseopts += ' -a ' + str(ARGS_LIST['group']) + ' '
    if ARGS_LIST['list'] == True or ARGS_LIST['list'] == "True":
        noseopts += ' -v --collect-only '
        ARGS_LIST['v'] = 0
        print "\nTest Listing for:", ARGS_LIST['test']
        print "----------------------------------------------------------------------"
    if ARGS_LIST['xunit'] == True or ARGS_LIST['xunit'] == "True":
        noseopts += ' --with-xunit '
    else:
        noseopts += ' -s '
    # if nosepath is a directory, recurse through subdirs else run single test file
    if os.path.isdir(nosepath):
        cmdline = ""
        for subdir, dirs, files in os.walk(nosepath):
            cmdline += " " + subdir
        exitcode += _noserunner(cmdline)
    else:
        exitcode += _noserunner(nosepath)
    return exitcode


text:
v0.9.16
=======

:date: 2013-08-03

This release is a bugfix release, the last one before Python 3 support will be
added. This is the final release of Tastefulpy that is compatible with Django 1.4.

Features
--------

* Added support for Unicode HTTP method names. (SHA: 2ebb362)
* Added a response for HTTP 422 Unprocessable Entity. (SHA: 7aadbf8)
* Added ISO-8601 strict support. (SHA: 3043140)

Bugfixes
--------

* Added a ``None`` value for ``username_field`` in the compat module.
  (SHA: 569a72e)
* Fixed a bug where ``obj_create`` would check authorization twice.
  (SHA: 9a404fa)
* Fixed test case to no longer require a defined object class. (SHA: d8e250f)
* Fixed the signature on ``dehydrate`` in the GIS resource class. (SHA: f724919)
* Fixed a bug involving updating foreign relations on create. (SHA: 50a6741)
* Changed the PUT response code (with ``always_return_data = True``) from 202 to 200.
  (SHA: abc0bef)
* Documentation updates:

    * Added an OAuth 2.0 example to the cookbook. (SHA: 7c93ae2)
    * Added a ``detail_uri_name`` to the Non-PK example in the cookbook.
      (SHA: 1fde565)
    * Added docs warning about ``total_count`` & performance overhead by
      default. (SHA: ebfbb7f)
    * Updated the Nested Resources example in the cookbook. (SHA: d582ead)
    * Added an example of converting a list of objects to JSON in the cookbook.
      (SHA: 2e81342)


text:
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the
// code is regenerated.

package com.microsoft.azure.management.trafficmanager.models;

/**
* Class containing endpoint monitoring settings in a Traffic Manager profile.
*/
public class MonitorConfig {
    private String path;

    /**
    * Required. Gets or sets the path relative to the endpoint domain name used
    * to probe for endpoint health.
    * @return The Path value.
    */
    public String getPath() {
        return this.path;
    }

    /**
    * Required. Gets or sets the path relative to the endpoint domain name used
    * to probe for endpoint health.
    * @param pathValue The Path value.
    */
    public void setPath(final String pathValue) {
        this.path = pathValue;
    }

    private long port;

    /**
    * Required. Gets or sets the TCP port used to probe for endpoint health.
    * @return The Port value.
    */
    public long getPort() {
        return this.port;
    }

    /**
    * Required. Gets or sets the TCP port used to probe for endpoint health.
    * @param portValue The Port value.
    */
    public void setPort(final long portValue) {
        this.port = portValue;
    }

    private String profileMonitorStatus;

    /**
    * Optional. Gets or sets the profile-level monitoring status of the Traffic
    * Manager profile.
    * @return The ProfileMonitorStatus value.
    */
    public String getProfileMonitorStatus() {
        return this.profileMonitorStatus;
    }

    /**
    * Optional. Gets or sets the profile-level monitoring status of the Traffic
    * Manager profile.
    * @param profileMonitorStatusValue The ProfileMonitorStatus value.
    */
    public void setProfileMonitorStatus(final String profileMonitorStatusValue) {
        this.profileMonitorStatus = profileMonitorStatusValue;
    }

    private String protocol;

    /**
    * Required. Gets or sets the protocol (HTTP or HTTPS) used to probe for
    * endpoint health.
    * @return The Protocol value.
    */
    public String getProtocol() {
        return this.protocol;
    }

    /**
    * Required. Gets or sets the protocol (HTTP or HTTPS) used to probe for
    * endpoint health.
    * @param protocolValue The Protocol value.
    */
    public void setProtocol(final String protocolValue) {
        this.protocol = protocolValue;
    }

    /**
    * Initializes a new instance of the MonitorConfig class.
    *
    */
    public MonitorConfig() {
    }

    /**
    * Initializes a new instance of the MonitorConfig class with required
    * arguments.
    *
    * @param protocol Gets or sets the protocol (HTTP or HTTPS) used to probe
    * for endpoint health.
    * @param port Gets or sets the TCP port used to probe for endpoint health.
    * @param path Gets or sets the path relative to the endpoint domain name
    * used to probe for endpoint health.
    */
    public MonitorConfig(String protocol, long port, String path) {
        if (protocol == null) {
            throw new NullPointerException("protocol");
        }
        if (path == null) {
            throw new NullPointerException("path");
        }
        this.setProtocol(protocol);
        this.setPort(port);
        this.setPath(path);
    }
}