summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwiki <wiki@proton.parabola.nu>2016-08-02 21:10:30 +0100
committerwiki <wiki@proton.parabola.nu>2016-08-02 21:10:30 +0100
commitd386934962c15a79703588812dc5815f32d70cbf (patch)
tree1251b086744a5305855c107eacbcf3e96005ab6e
parenta5f917bbc55e295896b8084f6657eb8b6abaf8a8 (diff)
files were sitting here on productionemulatorman/master
-rw-r--r--StatsdData.php102
-rw-r--r--StatsdDataFactoryTest.php97
-rw-r--r--StatsdDataInterface.php47
-rw-r--r--StatsdDataTest.php27
-rw-r--r--elasticsearch.service229
-rw-r--r--example_helpers.php58
-rw-r--r--gen_doc6
-rw-r--r--lessc191
-rw-r--r--make-blobs14
-rw-r--r--provision.sh63
-rw-r--r--push_ghpage12
-rw-r--r--run7
-rw-r--r--run-tests.sh38
-rw-r--r--runphp2
-rw-r--r--travis_push60
15 files changed, 953 insertions, 0 deletions
diff --git a/StatsdData.php b/StatsdData.php
new file mode 100644
index 00000000..2f030859
--- /dev/null
+++ b/StatsdData.php
@@ -0,0 +1,102 @@
+<?php
+
+namespace Liuggio\StatsdClient\Entity;
+
+use Liuggio\StatsdClient\Entity\StatsdDataInterface;
+
+class StatsdData implements StatsdDataInterface
+{
+
+ private $key;
+ private $value;
+ private $metric;
+ private $sampleRate = 1;
+
+ /**
+ * @param string $key
+ */
+ public function setKey($key)
+ {
+ $this->key = $key;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * @param int $value
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * @return int
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+
+ public function setMetric($metric)
+ {
+ $this->metric = $metric;
+ }
+
+ public function getMetric()
+ {
+ return $this->metric;
+ }
+
+ /**
+ * @param float $sampleRate
+ */
+ public function setSampleRate($sampleRate)
+ {
+ $this->sampleRate = $sampleRate;
+ }
+
+ /**
+ * @return float
+ */
+ public function getSampleRate()
+ {
+ return $this->sampleRate;
+ }
+
+ /**
+ * @param bool $withMetric
+ *
+ * @return string
+ */
+ public function getMessage($withMetric = true)
+ {
+ if (!$withMetric) {
+ $result = sprintf('%s:%s', $this->getKey(), $this->getValue());
+ } else {
+ $result = sprintf('%s:%s|%s', $this->getKey(), $this->getValue(), $this->getMetric());
+ }
+
+ $sampleRate = $this->getSampleRate();
+ if($sampleRate < 1){
+ $result.= "|@$sampleRate";
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/StatsdDataFactoryTest.php b/StatsdDataFactoryTest.php
new file mode 100644
index 00000000..144f629c
--- /dev/null
+++ b/StatsdDataFactoryTest.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Liuggio\StatsdClient\Factory;
+
+use Liuggio\StatsdClient\Factory\StatsdDataFactory;
+
+class StatsDataFactoryTest extends \PHPUnit_Framework_TestCase
+{
+ private $statsDataFactory;
+
+ public function setUp()
+ {
+ $this->statsDataFactory = new StatsdDataFactory('\Liuggio\StatsdClient\Entity\StatsdData');
+ }
+
+ public function testProduceStatsdData()
+ {
+ $key = 'key';
+ $value='val';
+
+ $obj = $this->statsDataFactory->produceStatsdData($key, $value);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($value, $obj->getValue());
+ }
+
+ public function testTiming()
+ {
+ $key = 'key';
+ $value = microtime();
+ $valueFloat = (string) floatval($value);
+
+ $obj = $this->statsDataFactory->timing($key, $value);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertContains($valueFloat, $obj->getValue());
+ $this->assertContains('ms', $obj->getMetric());
+ }
+
+ public function testProduceStatsdDataDecrement()
+ {
+ $key = 'key';
+ $value = -1;
+ $stringValue = intval($value);
+
+ $obj = $this->statsDataFactory->produceStatsdData($key, $value);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($stringValue, $obj->getValue());
+ $this->assertEquals('c', $obj->getMetric());
+ }
+
+ public function testGauge()
+ {
+ $key = 'key';
+ $value = 1000;
+ $stringValue = (string) intval($value);
+
+ $obj = $this->statsDataFactory->gauge($key, $value);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($stringValue, $obj->getValue());
+ $this->assertEquals('g', $obj->getMetric());
+ }
+
+ public function testDecrement()
+ {
+ $key = 'key';
+ $value = -1;
+ $stringValue = intval($value);
+
+ $obj = $this->statsDataFactory->decrement($key);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($stringValue, $obj->getValue());
+ $this->assertEquals('c', $obj->getMetric());
+ }
+
+ public function testcreateStatsdDataIncrement()
+ {
+ $key = 'key';
+ $value = 1;
+ $stringValue = intval($value);
+
+ $obj = $this->statsDataFactory->increment($key);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($stringValue, $obj->getValue());
+ $this->assertEquals('c', $obj->getMetric());
+ }
+
+ public function testCreateStatsdDataUpdateCount()
+ {
+ $key = 'key';
+ $value = 10;
+ $stringValue = intval($value);
+
+ $obj = $this->statsDataFactory->updateCount($key, 10);
+ $this->assertEquals($key, $obj->getKey());
+ $this->assertEquals($stringValue, $obj->getValue());
+ $this->assertEquals('c', $obj->getMetric());
+ }
+}
diff --git a/StatsdDataInterface.php b/StatsdDataInterface.php
new file mode 100644
index 00000000..d7b07a80
--- /dev/null
+++ b/StatsdDataInterface.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Liuggio\StatsdClient\Entity;
+
+interface StatsdDataInterface
+{
+ CONST STATSD_METRIC_TIMING = 'ms';
+ CONST STATSD_METRIC_GAUGE = 'g';
+ CONST STATSD_METRIC_SET = 's';
+ CONST STATSD_METRIC_COUNT = 'c';
+
+ /**
+ * @abstract
+ * @return string
+ */
+ function getKey();
+
+ /**
+ * @abstract
+ * @return mixed
+ */
+ function getValue();
+
+ /**
+ * @abstract
+ * @return string
+ */
+ function getMetric();
+
+ /**
+ * @abstract
+ * @return string
+ */
+ function getMessage();
+
+ /**
+ * @abstract
+ * @return float
+ */
+ function getSampleRate();
+
+ /**
+ * @abstract
+ * @return string
+ */
+ function __toString();
+}
diff --git a/StatsdDataTest.php b/StatsdDataTest.php
new file mode 100644
index 00000000..fad9175c
--- /dev/null
+++ b/StatsdDataTest.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Liuggio\StatsdClient\Entity;
+
+use Liuggio\StatsdClient\Entity\StatsdData;
+
+
+class StatsdDataTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetMessage()
+ {
+ $statsdData = new StatsdData();
+ $statsdData->setKey('key');
+ $statsdData->setValue('value');
+ $statsdData->setMetric('c');
+
+ $this->assertEquals($statsdData->getMessage(), 'key:value|c');
+
+ $statsdData = new StatsdData();
+ $statsdData->setKey('key');
+ $statsdData->setValue(-1);
+ $statsdData->setMetric('c');
+
+ $this->assertEquals($statsdData->getMessage(), 'key:-1|c');
+
+ }
+}
diff --git a/elasticsearch.service b/elasticsearch.service
new file mode 100644
index 00000000..0268e230
--- /dev/null
+++ b/elasticsearch.service
@@ -0,0 +1,229 @@
+#!/bin/sh
+#
+# /etc/init.d/elasticsearch -- startup script for Elasticsearch
+#
+# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
+# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Modified for Tomcat by Stefan Gybas <sgybas@debian.org>.
+# Modified for Tomcat6 by Thierry Carrez <thierry.carrez@ubuntu.com>.
+# Additional improvements by Jason Brittain <jason.brittain@mulesoft.com>.
+# Modified by Nicolas Huray for Elasticsearch <nicolas.huray@gmail.com>.
+# Modified by Igor Denisenko for Elastica <im.denisenko@yahoo.com>
+#
+### BEGIN INIT INFO
+# Provides: elasticsearch
+# Required-Start: $network $remote_fs $named
+# Required-Stop: $network $remote_fs $named
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Starts elasticsearch
+# Description: Starts elasticsearch using start-stop-daemon
+### END INIT INFO
+
+PATH="/bin:/usr/bin:/sbin:/usr/sbin"
+NAME="elasticsearch"
+DESC="Elasticsearch Server"
+
+if [ `id -u` -ne 0 ]; then
+ echo "You need root privileges to run this script"
+ exit 1
+fi
+
+
+. /lib/lsb/init-functions
+
+if [ -r /etc/default/rcS ]; then
+ . /etc/default/rcS
+fi
+
+
+# Run Elasticsearch as this user ID and group ID
+ES_USER="elasticsearch"
+ES_GROUP="elasticsearch"
+
+# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined)
+JDK_DIRS="/usr/lib/jvm/java-8-oracle/ /usr/lib/jvm/j2sdk1.8-oracle/ /usr/lib/jvm/jdk-7-oracle-x64 /usr/lib/jvm/java-7-oracle /usr/lib/jvm/j2sdk1.7-oracle/ /usr/lib/jvm/java-7-openjdk /usr/lib/jvm/java-7-openjdk-amd64/ /usr/lib/jvm/java-7-openjdk-armhf /usr/lib/jvm/java-7-openjdk-i386/ /usr/lib/jvm/default-java"
+
+# Look for the right JVM to use
+for jdir in $JDK_DIRS; do
+ if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
+ JAVA_HOME="$jdir"
+ fi
+done
+export JAVA_HOME
+
+# Directory where the Elasticsearch binary distribution resides
+ES_HOME="/usr/share/$NAME"
+
+# Heap size defaults to 256m min, 1g max
+# Be modest. Entire cluster will allocate (3*ES_HEAP_SIZE) memory
+ES_HEAP_SIZE="256m"
+export ES_HEAP_SIZE
+
+# Heap new generation
+# ES_HEAP_NEWSIZE=
+# export ES_HEAP_NEWSIZE
+
+# max direct memory
+# ES_DIRECT_SIZE=
+# export ES_DIRECT_SIZE
+
+# Additional Java OPTS
+ES_JAVA_OPTS="-server"
+export ES_JAVA_OPTS
+
+# Maximum number of open files
+MAX_OPEN_FILES="65535"
+
+# Maximum amount of locked memory
+MAX_LOCKED_MEMORY="unlimited"
+
+# Elasticsearch log directory
+LOG_DIR="/var/log/$NAME"
+
+# Elasticsearch data directory
+DATA_DIR="/var/lib/$NAME"
+
+# Elasticsearch work directory
+WORK_DIR="/tmp/$NAME"
+
+# Elasticsearch configuration directory
+CONF_DIR="/etc/$NAME"
+
+# Define other required variables
+DAEMON="$ES_HOME/bin/elasticsearch"
+
+# Check DAEMON exists
+if [ ! -x $DAEMON ]; then
+ exit 0
+fi
+
+checkJava() {
+ if [ -x "$JAVA_HOME/bin/java" ]; then
+ JAVA="$JAVA_HOME/bin/java"
+ else
+ JAVA=`which java`
+ fi
+
+ if [ ! -x "$JAVA" ]; then
+ echo "Could not find any executable java binary. Please install java in your PATH or set JAVA_HOME"
+ exit 1
+ fi
+}
+
+case "$1" in
+ start)
+ checkJava
+
+ if [ -n "$MAX_LOCKED_MEMORY" -a -z "$ES_HEAP_SIZE" ]; then
+ log_failure_msg "MAX_LOCKED_MEMORY is set - ES_HEAP_SIZE must also be set"
+ exit 1
+ fi
+
+
+ mkdir -p "$LOG_DIR" "$DATA_DIR" "$WORK_DIR"
+ chown "$ES_USER":"$ES_GROUP" "$LOG_DIR" "$DATA_DIR" "$WORK_DIR"
+
+ if [ -n "$MAX_OPEN_FILES" ];then
+ ulimit -n $MAX_OPEN_FILES
+ fi
+
+ if [ -n "$MAX_LOCKED_MEMORY" ];then
+ ulimit -l $MAX_LOCKED_MEMORY
+ fi
+
+ ulimit -s 1024
+
+ for node in 0 1; do
+ log_daemon_msg "Starting elasticsearch node #$node"
+
+ PID_FILE="/var/run/$NAME-$node.pid"
+ CONF_FILE="$CONF_DIR/config-$node.yml"
+
+ DAEMON="$ES_HOME/bin/elasticsearch"
+ DAEMON_OPTS="
+ -Des.config=$CONF_FILE \
+ -Des.path.home=$ES_HOME \
+ -Des.path.logs=$LOG_DIR \
+ -Des.path.data=$DATA_DIR \
+ -Des.path.work=$WORK_DIR \
+ -Des.path.conf=$CONF_DIR \
+ -p $PID_FILE
+ "
+
+ pid=`pidofproc -p $PID_FILE elasticsearch`
+ if [ -n "$pid" ] ; then
+ log_begin_msg "Elasticsearch node #$node already running"
+ continue
+ fi
+
+ touch "$PID_FILE"
+ chown "$ES_USER":"$ES_GROUP" "$PID_FILE"
+
+ # Start Daemon
+ start-stop-daemon --start -b --user "$ES_USER" -c "$ES_USER" --pidfile "$PID_FILE" --exec "$DAEMON" -- "$DAEMON_OPTS"
+ return=$?
+ if [ $return -eq 0 ]; then
+ i=0
+ timeout=10
+ # Wait for the process to be properly started before exiting
+ until { cat "$PID_FILE" | xargs kill -0; } >/dev/null 2>&1
+ do
+ sleep 1
+ i=$(($i + 1))
+ [ $i -gt $timeout ] && log_end_msg 1
+ done
+ else
+ log_end_msg $return
+ fi
+ done
+ ;;
+ stop)
+ for node in 0 1; do
+ log_daemon_msg "Stopping elasticsearch node #$node"
+
+ PID_FILE="/var/run/$NAME-$node.pid"
+
+ if [ -f "$PID_FILE" ]; then
+ start-stop-daemon --stop --pidfile "$PID_FILE" \
+ --user "$ES_USER" \
+ --retry=TERM/20/KILL/5 >/dev/null
+ if [ $? -eq 1 ]; then
+ log_progress_msg "$DESC is not running but pid file exists, cleaning up"
+ elif [ $? -eq 3 ]; then
+ PID="`cat $PID_FILE`"
+ log_failure_msg "Failed to stop $DESC (pid $PID)"
+ exit 1
+ fi
+ rm -f "$PID_FILE"
+ else
+ log_progress_msg "(not running)"
+ fi
+ done
+
+ log_end_msg 0
+ ;;
+ status)
+ for node in 0 1; do
+ PID_FILE="/var/run/$NAME-$node.pid"
+ status_of_proc -p $PID_FILE "Elasticsearch node #$node" "Elasticsearch node #$node"
+ done
+ exit 0
+ ;;
+ restart|force-reload)
+ for node in 0 1; do
+ PID_FILE="/var/run/$NAME-$node.pid"
+ if [ -f "$PID_FILE" ]; then
+ $0 stop
+ sleep 1
+ fi
+ done
+ $0 start
+ ;;
+ *)
+ log_success_msg "Usage: $0 {start|stop|restart|force-reload|status}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/example_helpers.php b/example_helpers.php
new file mode 100644
index 00000000..f5e67d6f
--- /dev/null
+++ b/example_helpers.php
@@ -0,0 +1,58 @@
+<?php
+
+// Custom Helper Interface ... noname arguments
+// Template: {{helper1 article.url article.text}}
+function helper1 ($args, $named) {
+ $u = (isset($args[0])) ? $args[0] : 'undefined';
+ $t = (isset($args[1])) ? $args[1] : 'undefined';
+ return "<a href=\"{$u}\">{$t}</a>";
+}
+
+// Custom Helper Interface ... named arguments
+// Template: {{helper1 url=article.url text=article.text [ur"l]=article.extra}}
+function helper2 ($args, $named) {
+ $u = isset($named['url']) ? jsraw($named['url']) : 'undefined';
+ $t = isset($named['text']) ? jsraw($named['text']) : 'undefined';
+ $x = isset($named['ur"l']) ? $named['ur"l'] : 'undefined';
+ return "<a href=\"{$u}\">{$t}</a>({$x})";
+}
+
+// Block Custom Helper Interface ...
+// Template: {{helper3 articles}}
+function helper3 ($cx, $args, $named) {
+ return Array('test1', 'test2', 'test3');
+}
+
+// Block Custom Helper Interface ...
+// Template: {{helper3 val=values odd=enable_odd}}
+function helper4 ($cx, $args, $named) {
+ if (isset($named['val']) && is_array($cx)) {
+ $cx['helper4_value'] = $named['val'] % 2;
+ return $cx;
+ }
+ if (isset($named['odd'])) {
+ return Array(1,3,5,7,9);
+ }
+}
+
+// Handlebars.js Custom Helper Interface ...
+// Template: {{#myeach articles}}Article: ....{{/myeach}}
+function myeach ($list, $options) {
+ foreach ($list as $item) {
+ $ret .= $options['fn']($item);
+ }
+ return $ret;
+}
+
+// Simulate Javascript toString() behaviors
+function jsraw ($i) {
+ if ($i === true) {
+ return 'true';
+ }
+ if ($i === false) {
+ return 'false';
+ }
+ return $i;
+}
+
+?>
diff --git a/gen_doc b/gen_doc
new file mode 100644
index 00000000..807bc21a
--- /dev/null
+++ b/gen_doc
@@ -0,0 +1,6 @@
+#!/bin/sh
+curl -O https://cloud.github.com/downloads/ApiGen/ApiGen/ApiGen-2.8.0-standalone.zip
+unzip -oq ApiGen-2.8.0-standalone.zip
+rm ApiGen-2.8.0-standalone.zip
+php -dopen_basedir=/ apigen/apigen.php --source src/ --destination build/result/docs/ --template-config apigen/templates/bootstrap/config.neon --deprecated yes
+rm -rf apigen
diff --git a/lessc b/lessc
new file mode 100644
index 00000000..fa1fb958
--- /dev/null
+++ b/lessc
@@ -0,0 +1,191 @@
+#!/usr/bin/env php
+<?php
+
+require_once dirname(__FILE__) . '/../lib/Less/Autoloader.php';
+Less_Autoloader::register();
+
+// Create our environment
+$env = array('compress' => false, 'relativeUrls' => false);
+$silent = false;
+$watch = false;
+$rootpath = '';
+
+// Check for arguments
+array_shift($argv);
+if (!count($argv)) {
+ $argv[] = '-h';
+}
+
+// parse arguments
+foreach ($argv as $key => $arg) {
+ if (preg_match('/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i', $arg, $matches)) {
+ $option = $matches[1];
+ $value = isset($matches[2]) ? $matches[2] : false;
+ unset($argv[$key]);
+
+ switch ($option) {
+ case 'h':
+ case 'help':
+ echo <<<EOD
+Usage: lessc [options] sources [destination]
+
+ -h, --help Print help (this message) and exit.
+ -s, --silent Suppress output of error messages.
+ -v, --version Print version number and exit.
+ -x, --compress Compress output by removing some whitespaces.
+ --include-path=PATHS Set include paths. Separated by `:'. Use `;' on Windows.
+ --strict-imports Force evaluation of imports.
+ -sm=on|off Turn on or off strict math, where in strict mode, math
+ --strict-math=on|off requires brackets. This option may default to on and then
+ be removed in the future.
+ -su=on|off Allow mixed units, e.g. 1px+1em or 1px*1px which have units
+ --strict-units=on|off that cannot be represented.
+ -ru, --relative-urls re-write relative urls to the base less file.
+ -rp, --rootpath=URL Set rootpath for url rewriting in relative imports and urls.
+ Works with or without the relative-urls option.
+ -w, --watch Watch input files for changes.
+
+
+EOD;
+ exit;
+ case 's':
+ case 'silent':
+ $silent = true;
+ break;
+
+ case 'w':
+ case 'watch':
+ $watch = true;
+ break;
+
+ case 'v':
+ case 'version':
+ echo "lessc " . Less_Version::version . " (less.php)\n\n";
+ exit;
+
+ case 'rp':
+ case 'rootpath':
+ $rootpath = $value;
+ break;
+
+
+ //parser options
+ case 'compress':
+ $env['compress'] = true;
+ break;
+
+ case 'ru':
+ case 'relative-urls':
+ $env['relativeUrls'] = true;
+ break;
+
+ case 'su':
+ case 'strict-units':
+ $env['strictUnits'] = ($value === 'on');
+ break;
+
+ case 'sm':
+ case 'strict-math':
+ $env['strictMath'] = ($value === 'on');
+ break;
+
+ case 'x':
+ case 'include-path':
+ $env['import_dirs'] = preg_split('#;|\:#', $value);
+ break;
+
+ }
+ }
+}
+
+if (count($argv) > 1) {
+ $output = array_pop($argv);
+ $inputs = $argv;
+}
+else {
+ $inputs = $argv;
+ $output = false;
+}
+
+if (!count($inputs)) {
+ echo("lessc: no input files\n");
+ exit;
+}
+
+if ($watch) {
+ if (!$output) {
+ echo("lessc: you must specify the output file if --watch is given\n");
+ exit;
+ }
+
+ $lastAction = 0;
+
+ echo("lessc: watching input files\n");
+
+ while (1) {
+ clearstatcache();
+
+ $updated = false;
+ foreach ($inputs as $input) {
+ if ($input == '-') {
+ if (count($inputs) == 1) {
+ echo("lessc: during watching files is not possible to watch stdin\n");
+ exit;
+ }
+ else {
+ continue;
+ }
+ }
+
+ if (filemtime($input) > $lastAction) {
+ $updated = true;
+ break;
+ }
+ }
+
+ if ($updated) {
+ $lastAction = time();
+ $parser = new Less_Parser($env);
+ foreach ($inputs as $input) {
+ try {
+ $parser->parseFile($input, $rootpath);
+ }
+ catch (Exception $e) {
+ echo("lessc: " . $e->getMessage() . " \n");
+ continue; // Invalid processing
+ }
+ }
+
+ file_put_contents($output, $parser->getCss());
+ echo("lessc: output file recompiled\n");
+ }
+
+ sleep(1);
+ }
+}
+else {
+ $parser = new Less_Parser($env);
+ foreach ($inputs as $input) {
+ if ($input == '-') {
+ $content = file_get_contents('php://stdin');
+ $parser->parse($content);
+ }
+ else {
+ try {
+ $parser->parseFile($input);
+ }
+ catch (Exception $e) {
+ if (!$silent) {
+ echo("lessc: " . ((string)$e) . " \n");
+ }
+ }
+ }
+ }
+
+ if ($output) {
+ file_put_contents($output, $parser->getCss());
+ }
+ else {
+ echo $parser->getCss();
+ }
+}
diff --git a/make-blobs b/make-blobs
new file mode 100644
index 00000000..16dcb672
--- /dev/null
+++ b/make-blobs
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+if [ -z $2 ];then
+ echo 'Usage: make-blobs <server> <db> [<table name>]'
+ exit 1
+fi
+if [ -z $3 ]; then
+ table=blobs
+else
+ table=$3
+fi
+
+echo "CREATE DATABASE $2" | mysql -u wikiadmin -p`wikiadmin_pass` -h $1 && \
+sed "s/blobs\>/$table/" blobs.sql | mysql -u wikiadmin -p`wikiadmin_pass` -h $1 $2
diff --git a/provision.sh b/provision.sh
new file mode 100644
index 00000000..6ea8e575
--- /dev/null
+++ b/provision.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -o xtrace
+
+install_ansible() {
+ sudo apt-get update
+ sudo apt-get install python python-pip python-dev -y
+ sudo pip install ansible==1.8.2
+ sudo mkdir -p /etc/ansible/
+ echo "localhost" | sudo tee /etc/ansible/hosts
+}
+
+run_playbook() {
+ # Write to stdout directly
+ export PYTHONUNBUFFERED=1
+
+ # No cows >_<
+ export ANSIBLE_NOCOWS=1
+
+ # Root of git repo
+ if [ -z "$ES_PROJECT_ROOT" ]; then
+ export ES_PROJECT_ROOT="$(dirname $(dirname $(readlink -f $0)))"
+ fi
+
+ if [ ! -x $(which ansible-playbook) ]; then
+ echo "Ansible is not installed"
+ return 1
+ fi
+
+ ansible-playbook $ES_PROJECT_ROOT/ansible/es-playbook.yml -v | tee /tmp/ansible-playbook-progress
+
+ if grep -q "FATAL\|ERROR" /tmp/ansible-playbook-progress; then
+ return 1
+ fi
+}
+
+check_cluster() {
+ curl -m 5 -s -o /dev/null "http://localhost:9200" &&
+ curl -m 5 -s -o /dev/null "http://localhost:9201"
+ return $?
+}
+
+travis_retry() {
+ # We don't use builtin Travis CI function, because this script is also used for vagrant provision.
+ # But main idea of restarts is so simple, so lets override it without name change.
+
+ $@ && return 0
+
+ echo "The command $@ failed. Retrying, 2 of 3"
+ sleep 60s && $@ && return 0
+
+ echo "The command $@ failed. Retrying, 3 of 3"
+ sleep 60s && $@ && return 0
+
+ echo "The command $@ failed."
+ return 1
+}
+
+travis_retry install_ansible || exit 1
+
+travis_retry run_playbook || exit 1
+
+travis_retry check_cluster || exit 1
diff --git a/push_ghpage b/push_ghpage
new file mode 100644
index 00000000..de64e2b9
--- /dev/null
+++ b/push_ghpage
@@ -0,0 +1,12 @@
+#!/bin/sh
+git checkout -B gh-pages
+git pull origin gh-pages
+rm *
+rm -rf src
+rm -rf test
+cp -r build/result/docs/* .
+rm -rf build
+rm .travis.yml
+git add .
+git commit -a -m "New documents on github"
+git push origin gh-pages
diff --git a/run b/run
new file mode 100644
index 00000000..247500c7
--- /dev/null
+++ b/run
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+set -e
+cd $(cd $(dirname $0)/..; pwd)
+set -x
+./vendor/bin/parallel-lint --exclude vendor .
+./vendor/bin/phpunit --configuration test/phpunit.xml
+./vendor/bin/phpcs . --standard=./test/codesniffer --ignore=vendor/* --report=full -s --tab-width=4
diff --git a/run-tests.sh b/run-tests.sh
new file mode 100644
index 00000000..d37c30fd
--- /dev/null
+++ b/run-tests.sh
@@ -0,0 +1,38 @@
+
+#!/usr/bin/env bash
+gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
+if [ $? -ne 0 ]; then
+ echo -e "\033[33mDownloading PGP Public Key...\033[0m"
+ gpg --recv-keys D8406D0D82947747293778314AA394086372C20A
+ # Sebastian Bergmann <sb@sebastian-bergmann.de>
+ gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
+ if [ $? -ne 0 ]; then
+ echo -e "\033[31mCould not download PGP public key for verification\033[0m"
+ exit
+ fi
+fi
+
+# Let's grab the latest release and its signature
+if [ ! -f phpunit.phar ]; then
+ wget https://phar.phpunit.de/phpunit.phar
+fi
+if [ ! -f phpunit.phar.asc ]; then
+ wget https://phar.phpunit.de/phpunit.phar.asc
+fi
+
+# Verify before running
+gpg --verify phpunit.phar.asc phpunit.phar
+if [ $? -eq 0 ]; then
+ echo
+ echo -e "\033[33mBegin Unit Testing\033[0m"
+ # Run the testing suite
+ php --version
+ php phpunit.phar --configuration phpunit.xml.dist
+else
+ echo
+ chmod -x phpunit.phar
+ mv phpunit.phar /tmp/bad-phpunit.phar
+ mv phpunit.phar.asc /tmp/bad-phpunit.phar.asc
+ echo -e "\033[31mSignature did not match! PHPUnit has been moved to /tmp/bad-phpunit.phar\033[0m"
+ exit 1
+fi
diff --git a/runphp b/runphp
new file mode 100644
index 00000000..aa694de3
--- /dev/null
+++ b/runphp
@@ -0,0 +1,2 @@
+#!/bin/sh
+php -dopen_basedir=/ $1 $2
diff --git a/travis_push b/travis_push
new file mode 100644
index 00000000..b51e4dcc
--- /dev/null
+++ b/travis_push
@@ -0,0 +1,60 @@
+#!/bin/sh
+echo "DEBUG ENV: ${TRAVIS_JOB_NUMBER} , ${TRAVIS_BUILD_NUMBER} , ${TRAVIS_PULL_REQUEST} ..."
+
+if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then
+ echo "This is a PR, skip push."
+ exit 0
+fi
+
+if [ "${TRAVIS_BUILD_NUMBER}.1" != "${TRAVIS_JOB_NUMBER}" ]; then
+ echo "Only push documents 1 time... quit."
+ exit 0
+fi
+
+# Push coverage report
+wget https://scrutinizer-ci.com/ocular.phar
+php ocular.phar code-coverage:upload --format=php-clover coverage.clover
+
+# Set for all push in this script.
+git config --global user.name "Travis-CI"
+git config --global user.email "zordius@yahoo-inc.com"
+
+# Generate ANSI sample
+git clone https://github.com/fcambus/ansilove
+php tests/example_debug.php > example_debug
+php ansilove/ansilove example_debug
+git add example_debug.png
+
+# Push new tests back to this branch
+git commit -a -m "Auto generated tests from Travis [ci skip]"
+git push "https://${GHTK}@github.com/zordius/lightncandy.git" HEAD:${TRAVIS_BRANCH} > /dev/null 2>&1
+
+# Update hash in HandlebarsTest and push back, trigger new tests there.
+git clone https://github.com/zordius/HandlebarsTest
+cd HandlebarsTest
+echo ${TRAVIS_COMMIT} > lightncandy
+git add lightncandy
+git commit -a -m "Auto test on zordius/lightncandy@${TRAVIS_COMMIT}"
+git push "https://${GHTK}@github.com/zordius/HandlebarsTest.git" > /dev/null 2>&1
+cd ..
+
+# Generate documents for this branch
+build/gen_doc
+cd build/result/docs
+
+if [ "${TRAVIS_BRANCH}" != "master" ]; then
+ echo "Document will be pushed here: http://zordius.github.io/lightncandy/${TRAVIS_BRANCH}/"
+ cd ..
+ git init
+ git pull --quiet "https://${GHTK}@github.com/zordius/lightncandy.git" gh-pages:master > /dev/null 2>&1
+ rm -rf $TRAVIS_BRANCH
+ mv docs $TRAVIS_BRANCH
+ git add $TRAVIS_BRANCH
+else
+ echo "Document will be pushed here: http://zordius.github.io/lightncandy/"
+ git init
+ git add .
+fi
+
+git commit -m "Auto deployed to Github Pages from branch ${TRAVIS_BRANCH} @${TRAVIS_COMMIT} [ci skip]"
+git push --force --quiet "https://${GHTK}@github.com/zordius/lightncandy.git" master:gh-pages > /dev/null 2>&1