<commit_before>/******************************************************************************
 * Copyright 2012 Intel Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/*****************************************************************************/

var dbus = { // hook object for dbus types not translated by python-json
		Double: function(value, level) {
			return value;
		}
};

/*****************************************************************************/

var cloudeebus = window.cloudeebus = {
		version: "0.4.0",
		minVersion: "0.3.2"
};

cloudeebus.reset = function() {
	cloudeebus.sessionBus = null;
	cloudeebus.systemBus = null;
	cloudeebus.wampSession = null;
	cloudeebus.uri = null;
};

cloudeebus.log = function(msg) {
};

cloudeebus.versionCheck = function(version) {
	var ver = version.split(".");
	var min = cloudeebus.minVersion.split(".");
	for (var i=0; i<ver.length; i++) {
		if (Number(ver[i]) > Number(min[i]))
			return true;
		if (Number(ver[i]) < Number(min[i]))
			return false;
	}
	return true;
};

cloudeebus.connect = function(uri, manifest, successCB, errorCB) {
	cloudeebus.reset();
	cloudeebus.uri = uri;

	function onCloudeebusVersionCheckCB(version) {
		if (cloudeebus.versionCheck(version)) {
			cloudeebus.log("Connected to " + cloudeebus.uri);
			if (successCB)
				successCB();
		} else {
			var errorMsg = "Cloudeebus server version " + version + " unsupported, need version " + cloudeebus.minVersion + " or superior";
			cloudeebus.log(errorMsg);
			if (errorCB)
				errorCB(errorMsg);
		}
	}

	function onWAMPSessionAuthErrorCB(error) {
		cloudeebus.log("Authentication error: " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	function onWAMPSessionAuthenticatedCB(permissions) {
		cloudeebus.sessionBus = new cloudeebus.BusConnection("session", cloudeebus.wampSession);
		cloudeebus.systemBus = new cloudeebus.BusConnection("system", cloudeebus.wampSession);
		cloudeebus.wampSession.call("getVersion").then(onCloudeebusVersionCheckCB, errorCB);
	}

	function onWAMPSessionChallengedCB(challenge) {
		var signature = cloudeebus.wampSession.authsign(challenge, manifest.key);
		cloudeebus.wampSession.auth(signature).then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionConnectedCB(session) {
		cloudeebus.wampSession = session;
		if (manifest)
			cloudeebus.wampSession.authreq(
					manifest.name,
					{permissions: manifest.permissions}
				).then(onWAMPSessionChallengedCB, onWAMPSessionAuthErrorCB);
		else
			cloudeebus.wampSession.authreq().then(function() {
				cloudeebus.wampSession.auth().then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
				}, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionErrorCB(code, reason) {
		if (code == ab.CONNECTION_UNSUPPORTED) {
			cloudeebus.log("Browser is not supported");
		}
		else {
			cloudeebus.log("Failed to open session, code = " + code + ", reason = " + reason);
		}
		if (errorCB)
			errorCB(reason);
	}

	return ab.connect(cloudeebus.uri, onWAMPSessionConnectedCB, onWAMPSessionErrorCB);
};

cloudeebus.SessionBus = function() {
	return cloudeebus.sessionBus;
};

cloudeebus.SystemBus = function() {
	return cloudeebus.systemBus;
};

/*****************************************************************************/

cloudeebus.BusConnection = function(name, session) {
	this.name = name;
	this.wampSession = session;
	return this;
};

cloudeebus.BusConnection.prototype.getObject = function(busName, objectPath, introspectCB, errorCB) {
	var proxy = new cloudeebus.ProxyObject(this.wampSession, this, busName, objectPath);
	if (introspectCB)
		proxy._introspect(introspectCB, errorCB);
	return proxy;
};

/*****************************************************************************/

cloudeebus.Request = function(proxy, onsuccess, onerror) {
	this.proxy = proxy;
	this.readyState = "pending";
	this.error = null;
	this.result = null;
	this.onsuccess = onsuccess;
	this.onerror = onerror;
    return this;
};

cloudeebus.Request.prototype.then = function(onsuccess, onerror) {
	this.onsuccess = onsuccess;
	this.onerror = onerror;
	return this;
};

/*****************************************************************************/

cloudeebus.ProxyObject = function(session, busConnection, busName, objectPath) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.busName = busName;
	this.objectPath = objectPath;
	this.interfaceProxies = {};
	return this;
};

cloudeebus.ProxyObject.prototype.getInterface = function(ifName) {
	return this.interfaceProxies[ifName];
};

cloudeebus.ProxyObject.prototype._introspect = function(successCB, errorCB) {

	var self = this;

	function getAllPropertiesSuccessCB(props) {
		var ifProxy = self.interfaceProxies[self.propInterfaces[self.propInterfaces.length-1]];
		for (var prop in props)
			ifProxy[prop] = self[prop] = props[prop];
		getAllPropertiesNextInterfaceCB();
	}

	function getAllPropertiesNextInterfaceCB() {
		self.propInterfaces.pop();
		if (self.propInterfaces.length > 0)
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces[self.propInterfaces.length-1]]).then(getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	function introspectSuccessCB(str) {
		var parser = new DOMParser();
		var xmlDoc = parser.parseFromString(str, "text/xml");
		var interfaces = xmlDoc.getElementsByTagName("interface");
		self.propInterfaces = [];
		var supportDBusProperties = false;
		for (var i=0; i < interfaces.length; i++) {
			var ifName = interfaces[i].attributes.getNamedItem("name").value;
			self.interfaceProxies[ifName] = new cloudeebus.ProxyObject(self.wampSession, self.busConnection, self.busName, self.objectPath);
			if (ifName == "org.freedesktop.DBus.Properties")
				supportDBusProperties = true;
			var hasProperties = false;
			var ifChild = interfaces[i].firstChild;
			while (ifChild) {
				if (ifChild.nodeName == "method") {
					var nArgs = 0;
					var signature = "";
					var metChild = ifChild.firstChild;
					while (metChild) {
						if (metChild.nodeName == "arg" &&
							metChild.attributes.getNamedItem("direction").value == "in") {
								signature += metChild.attributes.getNamedItem("type").value;
								nArgs++;
						}
						metChild = metChild.nextSibling;
					}
					var metName = ifChild.attributes.getNamedItem("name").value;
					if (!self[metName])
						self._addMethod(ifName, metName, nArgs, signature);
					self.interfaceProxies[ifName]._addMethod(ifName, metName, nArgs, signature);
				}
				else if (ifChild.nodeName == "property") {
					if (!hasProperties)
						self.propInterfaces.push(ifName);
					hasProperties = true;
				}
				ifChild = ifChild.nextSibling;
			}
		}
		if (supportDBusProperties && self.propInterfaces.length > 0) {
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces[self.propInterfaces.length-1]]).then(getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		}
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	// call Introspect on self
	self.callMethod("org.freedesktop.DBus.Introspectable", "Introspect", []).then(introspectSuccessCB, errorCB);
};

cloudeebus.ProxyObject.prototype._addMethod = function(ifName, method, nArgs, signature) {

	var self = this;

	self[method] = function() {
		var args = [];
		for (var i=0; i < nArgs; i++ )
			args.push(arguments[i]);
		return self.callMethod(ifName, method, args, signature);
	};
};

cloudeebus.ProxyObject.prototype.callMethod = function(ifName, method, args, signature) {

	var self = this;
	var request = new cloudeebus.Request(this);

	function callMethodSuccessCB(str) {
		request.readyState = "done";
		try { // calling dbus hook object function for un-translated types
			var result = eval(str);
			request.result = result[0];
			if (request.onsuccess)
				request.onsuccess.apply(request, result);
		}
		catch (e) {
			cloudeebus.log("Method callback exception: " + e);
			request.error = e;
			if (request.onerror)
				request.onerror.apply(request, [request.error]);
		}
	}

	function callMethodErrorCB(error) {
		cloudeebus.log("Error calling method: " + method + " on object: " + self.objectPath + " : " + error.desc);
		request.readyState = "done";
		request.error = error.desc;
		if (request.onerror)
			request.onerror.apply(request, [request.error]);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		method,
		JSON.stringify(args)
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusSend", arglist).then(callMethodSuccessCB, callMethodErrorCB);
	return request;
};

cloudeebus.ProxyObject.prototype.connectToSignal = function(ifName, signal, successCB, errorCB) {

	var self = this;

	function signalHandler(id, data) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(data));
			}
			catch (e) {
				cloudeebus.log("Signal handler exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function connectToSignalSuccessCB(str) {
		try {
			self.wampSession.subscribe(str, signalHandler);
		}
		catch (e) {
			cloudeebus.log("Subscribe error: " + e);
		}
	}

	function connectToSignalErrorCB(error) {
		cloudeebus.log("Error connecting to signal: " + signal + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		signal
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusRegister", arglist).then(connectToSignalSuccessCB, connectToSignalErrorCB);
};

cloudeebus.ProxyObject.prototype.disconnectSignal = function(ifName, signal) {
	try {
		this.wampSession.unsubscribe(this.busConnection.name + "#" + this.busName + "#" + this.objectPath + "#" + ifName + "#" + signal);
	}
	catch (e) {
		cloudeebus.log("Unsubscribe error: " + e);
	}
};
<commit_msg>implement basic DOM Future and FutureResolver mechanism<commit_after>/******************************************************************************
 * Copyright 2012 Intel Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/*****************************************************************************/

var dbus = { // hook object for dbus types not translated by python-json
		Double: function(value, level) {
			return value;
		}
};

/*****************************************************************************/

var cloudeebus = window.cloudeebus = {
		version: "0.4.0",
		minVersion: "0.3.2"
};

cloudeebus.reset = function() {
	cloudeebus.sessionBus = null;
	cloudeebus.systemBus = null;
	cloudeebus.wampSession = null;
	cloudeebus.uri = null;
};

cloudeebus.log = function(msg) {
};

cloudeebus.versionCheck = function(version) {
	var ver = version.split(".");
	var min = cloudeebus.minVersion.split(".");
	for (var i=0; i<ver.length; i++) {
		if (Number(ver[i]) > Number(min[i]))
			return true;
		if (Number(ver[i]) < Number(min[i]))
			return false;
	}
	return true;
};

cloudeebus.connect = function(uri, manifest, successCB, errorCB) {
	cloudeebus.reset();
	cloudeebus.uri = uri;

	function onCloudeebusVersionCheckCB(version) {
		if (cloudeebus.versionCheck(version)) {
			cloudeebus.log("Connected to " + cloudeebus.uri);
			if (successCB)
				successCB();
		} else {
			var errorMsg = "Cloudeebus server version " + version + " unsupported, need version " + cloudeebus.minVersion + " or superior";
			cloudeebus.log(errorMsg);
			if (errorCB)
				errorCB(errorMsg);
		}
	}

	function onWAMPSessionAuthErrorCB(error) {
		cloudeebus.log("Authentication error: " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	function onWAMPSessionAuthenticatedCB(permissions) {
		cloudeebus.sessionBus = new cloudeebus.BusConnection("session", cloudeebus.wampSession);
		cloudeebus.systemBus = new cloudeebus.BusConnection("system", cloudeebus.wampSession);
		cloudeebus.wampSession.call("getVersion").then(onCloudeebusVersionCheckCB, errorCB);
	}

	function onWAMPSessionChallengedCB(challenge) {
		var signature = cloudeebus.wampSession.authsign(challenge, manifest.key);
		cloudeebus.wampSession.auth(signature).then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionConnectedCB(session) {
		cloudeebus.wampSession = session;
		if (manifest)
			cloudeebus.wampSession.authreq(
					manifest.name,
					{permissions: manifest.permissions}
				).then(onWAMPSessionChallengedCB, onWAMPSessionAuthErrorCB);
		else
			cloudeebus.wampSession.authreq().then(function() {
				cloudeebus.wampSession.auth().then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
				}, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionErrorCB(code, reason) {
		if (code == ab.CONNECTION_UNSUPPORTED) {
			cloudeebus.log("Browser is not supported");
		}
		else {
			cloudeebus.log("Failed to open session, code = " + code + ", reason = " + reason);
		}
		if (errorCB)
			errorCB(reason);
	}

	return ab.connect(cloudeebus.uri, onWAMPSessionConnectedCB, onWAMPSessionErrorCB);
};

cloudeebus.SessionBus = function() {
	return cloudeebus.sessionBus;
};

cloudeebus.SystemBus = function() {
	return cloudeebus.systemBus;
};

/*****************************************************************************/

cloudeebus.BusConnection = function(name, session) {
	this.name = name;
	this.wampSession = session;
	return this;
};

cloudeebus.BusConnection.prototype.getObject = function(busName, objectPath, introspectCB, errorCB) {
	var proxy = new cloudeebus.ProxyObject(this.wampSession, this, busName, objectPath);
	if (introspectCB)
		proxy._introspect(introspectCB, errorCB);
	return proxy;
};

/*****************************************************************************/

function _processWrappers(wrappers, value) {
	for (var i=0; i<wrappers.length; i++)
		wrappers[i](value);
}

function _processWrappersAsync(wrappers, value) {
	var taskid = -1;
	function processAsyncOnce() {
		_processWrappers(wrappers, value);
		clearInterval(taskid);
	}
	taskid = setInterval(processAsyncOnce, 200);
}

/*****************************************************************************/

cloudeebus.FutureResolver = function(future) {
	this.future = future;
	this.resolved = null;
    return this;
};

cloudeebus.FutureResolver.prototype.resolve = function(value, sync) {
	if (this.resolved)
		return;

	try {
		this.accept(value, sync);
	}
	catch (e) {
		this.reject(e, sync);
	}
};

cloudeebus.FutureResolver.prototype.accept = function(value, sync) {
	if (this.resolved)
		return;

	var future = this.future;
	future.state = "accepted";
	future.result = value;

	this.resolved = true;
	if (sync)
		_processWrappers(future._acceptWrappers, value);
	else
		_processWrappersAsync(future._acceptWrappers, value);
};

cloudeebus.FutureResolver.prototype.reject = function(value, sync) {
	if (this.resolved)
		return;

	var future = this.future;
	future.state = "rejected";
	future.result = value;

	this.resolved = true;
	if (sync)
		_processWrappers(future._rejectWrappers, value);
	else
		_processWrappersAsync(future._rejectWrappers, value);
};

/*****************************************************************************/

cloudeebus.Future = function(init) {
	this.state = "pending";
	this.result = null;
	this._acceptWrappers = [];
	this._rejectWrappers = [];
	this.resolver = new cloudeebus.FutureResolver(this);
	if (init) {
		try {
			init.apply(this, [this.resolver]);
		}
		catch (e) {
			this.resolver.reject(e, true);
		}
	}
    return this;
};

cloudeebus.Future.prototype.appendWrappers = function(acceptWrapper, rejectWrapper) {
	this._acceptWrappers.push(acceptWrapper);
	this._rejectWrappers.push(rejectWrapper);
	if (this.state == "accepted")
		_processWrappersAsync(this._acceptWrappers, this.result);
	if (this.state == "rejected")
		_processWrappersAsync(this._rejectWrappers, this.result);
};

cloudeebus.Future.prototype.then = function(acceptCB, rejectCB) {
	var future = new cloudeebus.Future();
	var resolver = future.resolver;
	var acceptWrapper, rejectWrapper;

	if (acceptCB)
		acceptWrapper = function(arg) {
			try {
				var value = acceptCB.apply(future, [arg]);
				resolver.accept(value, true);
			}
			catch (e) {
				resolver.reject(e, true);
			}
		};
	else
		acceptWrapper = function(arg) {
			resolver.accept(arg, true);
		};

	if (rejectCB)
		rejectWrapper = function(arg) {
			try {
				var value = rejectCB.apply(future, [arg]);
				resolver.reject(value, true);
			}
			catch (e) {
				resolver.reject(e, true);
			}
		};
	else
		rejectWrapper = function(arg) {
			resolver.reject(arg, true);
		};

	this.appendWrappers(acceptWrapper,rejectWrapper);
	return future;
};

/*****************************************************************************/

cloudeebus.ProxyObject = function(session, busConnection, busName, objectPath) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.busName = busName;
	this.objectPath = objectPath;
	this.interfaceProxies = {};
	return this;
};

cloudeebus.ProxyObject.prototype.getInterface = function(ifName) {
	return this.interfaceProxies[ifName];
};

cloudeebus.ProxyObject.prototype._introspect = function(successCB, errorCB) {

	var self = this;

	function getAllPropertiesSuccessCB(props) {
		var ifProxy = self.interfaceProxies[self.propInterfaces[self.propInterfaces.length-1]];
		for (var prop in props)
			ifProxy[prop] = self[prop] = props[prop];
		getAllPropertiesNextInterfaceCB();
	}

	function getAllPropertiesNextInterfaceCB() {
		self.propInterfaces.pop();
		if (self.propInterfaces.length > 0)
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces[self.propInterfaces.length-1]]).then(getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	function introspectSuccessCB(str) {
		var parser = new DOMParser();
		var xmlDoc = parser.parseFromString(str, "text/xml");
		var interfaces = xmlDoc.getElementsByTagName("interface");
		self.propInterfaces = [];
		var supportDBusProperties = false;
		for (var i=0; i < interfaces.length; i++) {
			var ifName = interfaces[i].attributes.getNamedItem("name").value;
			self.interfaceProxies[ifName] = new cloudeebus.ProxyObject(self.wampSession, self.busConnection, self.busName, self.objectPath);
			if (ifName == "org.freedesktop.DBus.Properties")
				supportDBusProperties = true;
			var hasProperties = false;
			var ifChild = interfaces[i].firstChild;
			while (ifChild) {
				if (ifChild.nodeName == "method") {
					var nArgs = 0;
					var signature = "";
					var metChild = ifChild.firstChild;
					while (metChild) {
						if (metChild.nodeName == "arg" &&
							metChild.attributes.getNamedItem("direction").value == "in") {
								signature += metChild.attributes.getNamedItem("type").value;
								nArgs++;
						}
						metChild = metChild.nextSibling;
					}
					var metName = ifChild.attributes.getNamedItem("name").value;
					if (!self[metName])
						self._addMethod(ifName, metName, nArgs, signature);
					self.interfaceProxies[ifName]._addMethod(ifName, metName, nArgs, signature);
				}
				else if (ifChild.nodeName == "property") {
					if (!hasProperties)
						self.propInterfaces.push(ifName);
					hasProperties = true;
				}
				ifChild = ifChild.nextSibling;
			}
		}
		if (supportDBusProperties && self.propInterfaces.length > 0) {
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces[self.propInterfaces.length-1]]).then(getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		}
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	// call Introspect on self
	self.callMethod("org.freedesktop.DBus.Introspectable", "Introspect", []).then(introspectSuccessCB, errorCB);
};

cloudeebus.ProxyObject.prototype._addMethod = function(ifName, method, nArgs, signature) {

	var self = this;

	self[method] = function() {
		var args = [];
		for (var i=0; i < nArgs; i++ )
			args.push(arguments[i]);
		return self.callMethod(ifName, method, args, signature);
	};
};

cloudeebus.ProxyObject.prototype.callMethod = function(ifName, method, args, signature) {

	var self = this;

	var future = new cloudeebus.Future(function (resolver) {
		function callMethodSuccessCB(str) {
			try { // calling dbus hook object function for un-translated types
				var result = eval(str);
				resolver.accept(result[0]);
			}
			catch (e) {
				cloudeebus.log("Method callback exception: " + e);
				resolver.reject(e);
			}
		}

		function callMethodErrorCB(error) {
			cloudeebus.log("Error calling method: " + method + " on object: " + self.objectPath + " : " + error.desc);
			resolver.reject(error.desc);
		}

		var arglist = [
			self.busConnection.name,
			self.busName,
			self.objectPath,
			ifName,
			method,
			JSON.stringify(args)
		];

		// call dbusSend with bus type, destination, object, message and arguments
		self.wampSession.call("dbusSend", arglist).then(callMethodSuccessCB, callMethodErrorCB);
	});

	return future;
};

cloudeebus.ProxyObject.prototype.connectToSignal = function(ifName, signal, successCB, errorCB) {

	var self = this;

	function signalHandler(id, data) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(data));
			}
			catch (e) {
				cloudeebus.log("Signal handler exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function connectToSignalSuccessCB(str) {
		try {
			self.wampSession.subscribe(str, signalHandler);
		}
		catch (e) {
			cloudeebus.log("Subscribe error: " + e);
		}
	}

	function connectToSignalErrorCB(error) {
		cloudeebus.log("Error connecting to signal: " + signal + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		signal
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusRegister", arglist).then(connectToSignalSuccessCB, connectToSignalErrorCB);
};

cloudeebus.ProxyObject.prototype.disconnectSignal = function(ifName, signal) {
	try {
		this.wampSession.unsubscribe(this.busConnection.name + "#" + this.busName + "#" + this.objectPath + "#" + ifName + "#" + signal);
	}
	catch (e) {
		cloudeebus.log("Unsubscribe error: " + e);
	}
};
<|endoftext|>


<commit_before>/*global describe it before after apf bar = */

"use client";

require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai) {
    var expect = chai.expect;

    expect.setupArchitectTest([
        {
            packagePath: "plugins/c9.core/c9",
            workspaceId: "ubuntu/ip-10-35-77-180",
            startdate: new Date(),
            debug: true,
            hosted: true,
            local: false,
            davPrefix: "/"
        },

        "plugins/c9.core/ext",
        "plugins/c9.core/http-xhr",
        "plugins/c9.core/util",
        "plugins/c9.ide.ui/lib_apf",
        "plugins/c9.ide.ui/menus",
        {
            packagePath: "plugins/c9.core/settings",
            testing: true
        },
        "plugins/c9.core/api.js",
        {
            packagePath: "plugins/c9.ide.ui/ui",
            staticPrefix: "plugins/c9.ide.ui"
        },
        "plugins/c9.ide.editors/document",
        "plugins/c9.ide.editors/undomanager",
        {
            packagePath: "plugins/c9.ide.editors/editors",
            defaultEditor: "ace"
        },
        "plugins/c9.ide.editors/editor",
        "plugins/c9.ide.editors/tabmanager",
        "plugins/c9.ide.ui/focus",
        "plugins/c9.ide.editors/pane",
        "plugins/c9.ide.editors/tab",
        "plugins/c9.ide.ace/ace",
        {
            packagePath: "plugins/c9.ide.ace.statusbar/statusbar",
            staticPrefix: "plugins/c9.ide.layout.classic"
        },
        "plugins/c9.ide.keys/commands",
        "plugins/c9.fs/proc",
        "plugins/c9.vfs.client/vfs_client",
        "plugins/c9.vfs.client/endpoint",
        "plugins/c9.ide.auth/auth",
        "plugins/c9.fs/fs",

        // Mock plugins
        {
            consumes: ["apf", "ui", "Plugin"],
            provides: [
                "commands", "menus", "layout", "watcher",
                "save", "preferences", "anims", "gotoline", "clipboard",
                "dialog.alert", "auth.bootstrap", "info", "ace.gotoline",
                "dialog.error"
            ],
            setup: expect.html.mocked
        },
        {
            consumes: ["tabManager", "ace"],
            provides: [],
            setup: main
        }
    ], architect);

    function main(options, imports, register) {
        var tabs = imports.tabManager;
        var ace = imports.ace;

        function getTabHtml(tab) {
            return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
        }

        expect.html.setConstructor(function(tab) {
            if (typeof tab == "object")
                return tab.$ext;
        });

        describe('statusbar', function() {
            before(function(done) {
                apf.config.setProperty("allow-select", false);
                apf.config.setProperty("allow-blur", false);

                bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
                bar.$ext.style.position = "fixed";
                bar.$ext.style.left = "20px";
                bar.$ext.style.right = "20px";
                bar.$ext.style.bottom = "20px";
                bar.$ext.style.height = "33%";

                document.body.style.marginBottom = "33%";

                tabs.once("ready", function() {
                    tabs.getPanes()[0].focus();
                    done();
                });
            });

            describe("open", function() {
                this.timeout(10000);

                it('should open a pane with just an editor', function(done) {
                    tabs.openFile("/file.txt", function(err, tab) {
                        expect(!err);
                        expect(tabs.getTabs()).length(1);
                        // statusbar is added only after editor draw event
                        // TODO make this api easier to use
                        setTimeout(function() {
                            var sb = tab.document.getSession().statusBar;
                            var bar = sb.getElement("bar");
                            expect.html(bar, "rowcol").text("1:1");

                            tab.document.editor.ace.selectAll();
                            setTimeout(function() {
                                expect.html(bar, "rowcol sel").text("2:1");
                                expect.html(bar, "sel").text("23 Bytes");

                                done();
                            }, 10);
                        });
                    });
                });
                it('should handle multiple documents in the same pane', function(done) {
                    tabs.openFile("/listing.json", function(err, tab) {
                        expect(!err);
                        expect(tabs.getTabs()).length(2);

                        tab.activate();

                        setTimeout(function() {
                            var sb = tab.document.getSession().statusBar;
                            expect.html(sb.getElement("bar"), "caption").text("1:1");

                            done();
                        }, 10);
                    });
                });
            });
            describe("split(), pane.unload()", function() {
                it('should split a pane horizontally, making the existing pane the left one', function(done) {
                    var pane = tabs.focussedTab.pane;
                    var righttab = pane.hsplit(true);
                    tabs.focussedTab.attachTo(righttab);

                    setTimeout(function() {
                        expect.html(pane.aml, "pane").text("2:1");
                        expect.html(righttab.aml, "righttab").text("1:1");

                        done();
                    }, 100);
                });
//                it('should remove the left pane from a horizontal split', function(done) {
//                    var pane = tabs.getPanes()[0];
//                    var tab = tabs.getPanes()[1].getTab();
//                    pane.unload();
//                    expect(tabs.getPanes()).length(1);
//                    expect(tabs.getTabs()).length(2);
//                    tabs.focusTab(tab);
//                    done();
//                });
            });
//            describe("Change Theme", function(){
//                this.timeout(10000);
//
//                it('should change a theme', function(done) {
//                    var editor = tabs.focussedTab.editor;
//                    ace.on("themeInit", function setTheme(){
//                        ace.off("theme.init", setTheme);
//                        expect.html(getTabHtml(tabs.focussedTab).childNodes[1]).className("ace-monokai");
//                        editor.setOption("theme", "ace/theme/textmate");
//                        done();
//                    });
//                    editor.setOption("theme", "ace/theme/monokai");
//                });
//            });

            // @todo test split api and menu

           if (!onload.remain) {
               after(function(done) {
                   tabs.unload();

                   document.body.style.marginBottom = "";
                   done();
               });
           }
        });

        onload && onload();
    }
});<commit_msg>remove unnecessary html.mocked calls<commit_after>/*global describe it before after apf bar = */

"use client";

require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai) {
    var expect = chai.expect;

    expect.setupArchitectTest([
        {
            packagePath: "plugins/c9.core/c9",
            workspaceId: "ubuntu/ip-10-35-77-180",
            startdate: new Date(),
            debug: true,
            hosted: true,
            local: false,
            davPrefix: "/"
        },

        "plugins/c9.core/ext",
        "plugins/c9.core/http-xhr",
        "plugins/c9.core/util",
        "plugins/c9.ide.ui/lib_apf",
        "plugins/c9.ide.ui/menus",
        {
            packagePath: "plugins/c9.core/settings",
            testing: true
        },
        "plugins/c9.core/api.js",
        {
            packagePath: "plugins/c9.ide.ui/ui",
            staticPrefix: "plugins/c9.ide.ui"
        },
        "plugins/c9.ide.editors/document",
        "plugins/c9.ide.editors/undomanager",
        {
            packagePath: "plugins/c9.ide.editors/editors",
            defaultEditor: "ace"
        },
        "plugins/c9.ide.editors/editor",
        "plugins/c9.ide.editors/tabmanager",
        "plugins/c9.ide.ui/focus",
        "plugins/c9.ide.editors/pane",
        "plugins/c9.ide.editors/tab",
        "plugins/c9.ide.ace/ace",
        {
            packagePath: "plugins/c9.ide.ace.statusbar/statusbar",
            staticPrefix: "plugins/c9.ide.layout.classic"
        },
        "plugins/c9.ide.keys/commands",
        "plugins/c9.fs/proc",
        "plugins/c9.vfs.client/vfs_client",
        "plugins/c9.vfs.client/endpoint",
        "plugins/c9.ide.auth/auth",
        "plugins/c9.fs/fs",

        {
            consumes: ["tabManager", "ace"],
            provides: [],
            setup: main
        }
    ], architect);

    function main(options, imports, register) {
        var tabs = imports.tabManager;
        var ace = imports.ace;

        function getTabHtml(tab) {
            return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
        }

        expect.html.setConstructor(function(tab) {
            if (typeof tab == "object")
                return tab.$ext;
        });

        describe('statusbar', function() {
            before(function(done) {
                apf.config.setProperty("allow-select", false);
                apf.config.setProperty("allow-blur", false);

                bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
                bar.$ext.style.position = "fixed";
                bar.$ext.style.left = "20px";
                bar.$ext.style.right = "20px";
                bar.$ext.style.bottom = "20px";
                bar.$ext.style.height = "33%";

                document.body.style.marginBottom = "33%";

                tabs.once("ready", function() {
                    tabs.getPanes()[0].focus();
                    done();
                });
            });

            describe("open", function() {
                this.timeout(10000);

                it('should open a pane with just an editor', function(done) {
                    tabs.openFile("/file.txt", function(err, tab) {
                        expect(!err);
                        expect(tabs.getTabs()).length(1);
                        // statusbar is added only after editor draw event
                        // TODO make this api easier to use
                        setTimeout(function() {
                            var sb = tab.document.getSession().statusBar;
                            var bar = sb.getElement("bar");
                            expect.html(bar, "rowcol").text("1:1");

                            tab.document.editor.ace.selectAll();
                            setTimeout(function() {
                                expect.html(bar, "rowcol sel").text("2:1");
                                expect.html(bar, "sel").text("23 Bytes");

                                done();
                            }, 10);
                        });
                    });
                });
                it('should handle multiple documents in the same pane', function(done) {
                    tabs.openFile("/listing.json", function(err, tab) {
                        expect(!err);
                        expect(tabs.getTabs()).length(2);

                        tab.activate();

                        setTimeout(function() {
                            var sb = tab.document.getSession().statusBar;
                            expect.html(sb.getElement("bar"), "caption").text("1:1");

                            done();
                        }, 10);
                    });
                });
            });
            describe("split(), pane.unload()", function() {
                it('should split a pane horizontally, making the existing pane the left one', function(done) {
                    var pane = tabs.focussedTab.pane;
                    var righttab = pane.hsplit(true);
                    tabs.focussedTab.attachTo(righttab);

                    setTimeout(function() {
                        expect.html(pane.aml, "pane").text("2:1");
                        expect.html(righttab.aml, "righttab").text("1:1");

                        done();
                    }, 100);
                });
//                it('should remove the left pane from a horizontal split', function(done) {
//                    var pane = tabs.getPanes()[0];
//                    var tab = tabs.getPanes()[1].getTab();
//                    pane.unload();
//                    expect(tabs.getPanes()).length(1);
//                    expect(tabs.getTabs()).length(2);
//                    tabs.focusTab(tab);
//                    done();
//                });
            });
//            describe("Change Theme", function(){
//                this.timeout(10000);
//
//                it('should change a theme', function(done) {
//                    var editor = tabs.focussedTab.editor;
//                    ace.on("themeInit", function setTheme(){
//                        ace.off("theme.init", setTheme);
//                        expect.html(getTabHtml(tabs.focussedTab).childNodes[1]).className("ace-monokai");
//                        editor.setOption("theme", "ace/theme/textmate");
//                        done();
//                    });
//                    editor.setOption("theme", "ace/theme/monokai");
//                });
//            });

            // @todo test split api and menu

           if (!onload.remain) {
               after(function(done) {
                   tabs.unload();

                   document.body.style.marginBottom = "";
                   done();
               });
           }
        });

        onload && onload();
    }
});<|endoftext|>


<commit_before>'use strict';
var ok = require('assert').ok;
var CodeGenerator = require('./CodeGenerator');
var CompileContext = require('./CompileContext');
var createError = require('raptor-util/createError');

const FLAG_TRANSFORMER_APPLIED = 'transformerApply';

function transformNode(node, context) {
    try {
        context.taglibLookup.forEachNodeTransformer(node, function (transformer) {
            if (!node.isTransformerApplied(transformer)) {
                //Check to make sure a transformer of a certain type is only applied once to a node
                node.setTransformerApplied(transformer);
                //Mark the node as have been transformed by the current transformer
                context.setFlag(FLAG_TRANSFORMER_APPLIED);
                //Set the flag to indicate that a node was transformed
                // node.compiler = this;
                var transformerFunc = transformer.getFunc();
                transformerFunc.call(transformer, node, context);    //Have the transformer process the node (NOTE: Just because a node is being processed by the transformer doesn't mean that it has to modify the parse tree)
            }
        });
    } catch (e) {
        throw createError(new Error('Unable to compile template at path "' + context.filename + '". Error: ' + e.message), e);
    }
}

function transformTreeHelper(node, context) {
    transformNode(node, context);

    /*
     * Now process the child nodes by looping over the child nodes
     * and transforming the subtree recursively
     *
     * NOTE: The length of the childNodes array might change as the tree is being performed.
     *       The checks to prevent transformers from being applied multiple times makes
     *       sure that this is not a problem.
     */
    node.forEachChild(function (childNode) {
        if (childNode.isDetached()) {
            return;    //The child node might have been removed from the tree
        }
        transformTreeHelper(childNode, context);
    });
}

function transformTree(rootNode, context) {
    /*
     * The tree is continuously transformed until we go through an entire pass where
     * there were no new nodes that needed to be transformed. This loop makes sure that
     * nodes added by transformers are also transformed.
     */
    do {
        context.clearFlag(FLAG_TRANSFORMER_APPLIED);
        //Reset the flag to indicate that no transforms were yet applied to any of the nodes for this pass
        transformTreeHelper(rootNode, context);    //Run the transforms on the tree
    } while (context.isFlagSet(FLAG_TRANSFORMER_APPLIED));

    return rootNode;
}

class Compiler {
    constructor(options) {
        ok(options, '"options" is required');

        this.builder = options.builder;
        this.parser = options.parser;

        ok(this.builder, '"options.builder" is required');
        ok(this.parser, '"options.parser" is required');
    }

    compile(src, filename) {
        ok(src);
        ok(filename);

        var context = new CompileContext(src, filename, this.builder);

        // STAGE 1: Parse the template to produce the initial AST
        var ast = this.parser.parse(src, context);
        // console.log('ROOT', JSON.stringify(ast, null, 2));

        // STAGE 2: Transform the initial AST to produce the final AST
        var transformedAST = transformTree(ast, context);
        // console.log('transformedAST', JSON.stringify(ast, null, 2));

        // STAGE 3: Generate the code using the final AST
        var codeGenerator = new CodeGenerator(context);
        codeGenerator.generateCode(transformedAST);

        // If there were any errors then compilation failed.
        if (context.hasErrors()) {
            var errors = context.getErrors();

            var message = 'An error occurred while trying to compile template at path "' + filename + '". Error(s) in template:\n';
            for (var i = 0, len = errors.length; i < len; i++) {
                let error = errors[i];
                message += (i + 1) + ') ' + error.toString() + '\n';
            }
            var error = new Error(message);
            error.errors = errors;
            throw error;
        }

        // Return the generated code as the compiled output:
        var compiledSrc = codeGenerator.getCode();
        return compiledSrc;
    }
}

module.exports = Compiler;<commit_msg>Marko v3: Improved assertions<commit_after>'use strict';
var ok = require('assert').ok;
var CodeGenerator = require('./CodeGenerator');
var CompileContext = require('./CompileContext');
var createError = require('raptor-util/createError');

const FLAG_TRANSFORMER_APPLIED = 'transformerApply';

function transformNode(node, context) {
    try {
        context.taglibLookup.forEachNodeTransformer(node, function (transformer) {
            if (!node.isTransformerApplied(transformer)) {
                //Check to make sure a transformer of a certain type is only applied once to a node
                node.setTransformerApplied(transformer);
                //Mark the node as have been transformed by the current transformer
                context.setFlag(FLAG_TRANSFORMER_APPLIED);
                //Set the flag to indicate that a node was transformed
                // node.compiler = this;
                var transformerFunc = transformer.getFunc();
                transformerFunc.call(transformer, node, context);    //Have the transformer process the node (NOTE: Just because a node is being processed by the transformer doesn't mean that it has to modify the parse tree)
            }
        });
    } catch (e) {
        throw createError(new Error('Unable to compile template at path "' + context.filename + '". Error: ' + e.message), e);
    }
}

function transformTreeHelper(node, context) {
    transformNode(node, context);

    /*
     * Now process the child nodes by looping over the child nodes
     * and transforming the subtree recursively
     *
     * NOTE: The length of the childNodes array might change as the tree is being performed.
     *       The checks to prevent transformers from being applied multiple times makes
     *       sure that this is not a problem.
     */
    node.forEachChild(function (childNode) {
        if (childNode.isDetached()) {
            return;    //The child node might have been removed from the tree
        }
        transformTreeHelper(childNode, context);
    });
}

function transformTree(rootNode, context) {
    /*
     * The tree is continuously transformed until we go through an entire pass where
     * there were no new nodes that needed to be transformed. This loop makes sure that
     * nodes added by transformers are also transformed.
     */
    do {
        context.clearFlag(FLAG_TRANSFORMER_APPLIED);
        //Reset the flag to indicate that no transforms were yet applied to any of the nodes for this pass
        transformTreeHelper(rootNode, context);    //Run the transforms on the tree
    } while (context.isFlagSet(FLAG_TRANSFORMER_APPLIED));

    return rootNode;
}

class Compiler {
    constructor(options) {
        ok(options, '"options" is required');

        this.builder = options.builder;
        this.parser = options.parser;

        ok(this.builder, '"options.builder" is required');
        ok(this.parser, '"options.parser" is required');
    }

    compile(src, filename) {
        ok(typeof src === 'string', '"src" argument should be a string');
        ok(filename, '"filename" argument is required');
        ok(typeof filename === 'string', '"filename" argument should be a string');

        var context = new CompileContext(src, filename, this.builder);

        // STAGE 1: Parse the template to produce the initial AST
        var ast = this.parser.parse(src, context);
        // console.log('ROOT', JSON.stringify(ast, null, 2));

        // STAGE 2: Transform the initial AST to produce the final AST
        var transformedAST = transformTree(ast, context);
        // console.log('transformedAST', JSON.stringify(ast, null, 2));

        // STAGE 3: Generate the code using the final AST
        var codeGenerator = new CodeGenerator(context);
        codeGenerator.generateCode(transformedAST);

        // If there were any errors then compilation failed.
        if (context.hasErrors()) {
            var errors = context.getErrors();

            var message = 'An error occurred while trying to compile template at path "' + filename + '". Error(s) in template:\n';
            for (var i = 0, len = errors.length; i < len; i++) {
                let error = errors[i];
                message += (i + 1) + ') ' + error.toString() + '\n';
            }
            var error = new Error(message);
            error.errors = errors;
            throw error;
        }

        // Return the generated code as the compiled output:
        var compiledSrc = codeGenerator.getCode();
        return compiledSrc;
    }
}

module.exports = Compiler;<|endoftext|>


<commit_before>'use strict'

class LocalDecoder {
  solidityLocals (vmtraceIndex, internalTreeCall, stack, memory) {
    var scope = this.internalTreeCall.findScope(vmtraceIndex)
    var locals = {}
    for (var local of scope.locals) {
      if (local.type.decodeLocals) {
        locals[local.name] = local.type.decodeLocals(local.stackHeight, stack, memory)
      }
    }
    return locals
  }
}

module.exports = LocalDecoder
<commit_msg>fix localdecoder<commit_after>'use strict'

function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory) {
  var scope = internalTreeCall.findScope(vmtraceIndex)
  var locals = {}
  for (var local in scope.locals) {
    let variable = scope.locals[local]
    if (variable.type.decodeLocals) {
      locals[variable.name] = variable.type.decodeLocals(variable.stackHeight, stack, memory)
    } else {
      locals[variable.name] = ''
    }
  }
  return locals
}

module.exports = {
  solidityLocals: solidityLocals
}
<|endoftext|>


<commit_before>foam.CLASS({
  package: 'foam.nanos.fs.fileDropZone',
  name: 'FilePreview',
  extends: 'foam.u2.View',

  documentation: 'iframe for file preview',

  properties: [
    {
      class: 'String',
      name: 'fileSrc'
    }
  ],

  methods: [
    function initE() {
      this.SUPER();
      this.data$.sub(() => this.showData());
    },

    function showData() {
      var iFrame = document.getElementById('file-iframe');
      if ( !iFrame ){
        this
          .start('iframe')
            .attrs({
                data: URL.createObjectURL(this.data[0].data.blob),
                id: 'file-iframe',
                name: 'file-iframe',
            })
         .end();
      } else {
        iFrame.src = URL.createObjectURL(this.data[0].data.blob);
      }
    }
  ]
})
<commit_msg>Add header and css<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.fs.fileDropZone',
  name: 'FilePreview',
  extends: 'foam.u2.View',

  documentation: 'iframe for file preview',

  properties: [
    {
      class: 'String',
      name: 'fileSrc'
    }
  ],

  css: `
    #file-iframe {
      height: 100%;
      width: 100%;
    }
  `,

  methods: [
    function initE() {
      this.SUPER();
      this.data$.sub(() => this.showData());
    },

    function showData() {
      var iFrame = document.getElementById('file-iframe');
      if ( !iFrame ){
        this
          .start('iframe')
            .attrs({
                data: URL.createObjectURL(this.data[0].data.blob),
                id: 'file-iframe',
                name: 'file-iframe',
            })
         .end();
      } else {
        iFrame.src = URL.createObjectURL(this.data[0].data.blob);
      }
    }
  ]
})
<|endoftext|>


<commit_before>/**
 * A simple WebDAV server.
 */

var pronto = require('pronto');
var webdav = require('./lib');
var fsdav = require('./lib/fs');

var register = new pronto.Registry();
var initialContext = new pronto.Context({
  baseURI: '/test'
});

register
  // Set up the logger
  .logger(pronto.logging.ConsoleLogger, {colors: true})
  // Operations common across the board.
  .route('@bootstrap')
    .does(webdav.http.GetNormalizedPath, 'path')
      .using('baseURI').from('cxt:baseURI')
    .does(fsdav.LoadFSBridge, 'bridge')
      .using('root', './data')
  // ================================================================
  // HTTP Operations.
  // ================================================================
  .route('OPTIONS')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleOptions, 'options')
      .using('resource').from('cxt:resource')
    .does(pronto.commands.HTTPResponse)
      .using('headers').from('cxt:options')
      .using('code', 200)

  .route('GET')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
      .using('addDatasource', true) // It's magic!
    .does(webdav.http.HandleGet, 'get')
      .using('resource').from('cxt:resource')
    .does(webdav.http.StreamedHTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:get')
      .using('stream').from('resource:stream')

  .route('HEAD')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleHead, 'head')
      .using('resource').from('cxt:resource')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:head')

  .route('DELETE')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleDelete, 'delete')
      .using('resourceBridge').from('cxt:bridge')
      .using('resource').from('cxt:resource')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:delete')

  .route('PUT')
    .does(pronto.commands.BufferRequest, 'input')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandlePut, 'put')
      .using('resourceBridge').from('cxt:bridge')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('readStream').from('cxt:input')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:put')

  .route('PROPFIND')
    .includes('@bootstrap')
    .does(webdav.xml.ParseXML, 'xml')
      // XXX: Currently, we're not buffering this.
      //.using('input').from('cxt:input')
    .does(webdav.http.HandlePropfind, 'propfind')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('xml').from('cxt:xml')
    .does(webdav.xml.SerializeXML, 'body')
      .using('xml').from('cxt:propfind')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 207).from('cxt:httpStatus')
      .using('body').from('cxt:body')

  // Since we support extended-mkcol, this can return
  // 201 or 207, with our without a body.
  .route('MKCOL')
    .includes('@bootstrap')
    .does(webdav.http.HandleMkcol, 'mkcol')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('xml').from('cxt:xml')
    .does(webdav.xml.SerializeXML, 'body')
      .using('xml').from('cxt:extendedMkcol')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 201).from('cxt:mkcol')
      .using('body').from('cxt:body')

  .route('PROPPATCH')
    .includes('@bootstrap')
  .route('COPY')
    .includes('@bootstrap')
  .route('MOVE')
    .includes('@bootstrap')
  .route('REPORT')
    .includes('@bootstrap')
    .does(webdav.http.HandleReport, 'report')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:report')

  // ================================================================
  // Error Routes
  // ================================================================
  .route('@304')
    // 304 should never have a body. It is up to the app to put
    // one of Date, ETag, Expires, Vary, and so on.
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 304)

  .route('@403')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Forbidden')
      .using('2', 'Forbidden')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 403)
      .using('body').from('cxt:body')

  .route('@404')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Not Found')
      .using('2', 'Not Found')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 404)
      .using('body').from('cxt:body')

  .route('@405')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Method Not Allowed')
      .using('2', 'Method Not Allowed').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 405)
      .using('body').from('cxt:body')
  .route('@409')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Conflict')
      .using('2', 'Conflict').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 409)
      .using('body').from('cxt:body')

  .route('@412')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Precondition Failed')
      .using('2', 'Precondition Failed').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 412)
      .using('body').from('cxt:body')

  .route('@415')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Unsupported Media Type')
      .using('2', 'Unsupported Media Type').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 415)
      .using('body').from('cxt:body')

  .route('@500')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Internal Server Error')
      .using('2', 'Internal Server Error').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 500)
      .using('body').from('cxt:body')

  .route('@501')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Not Implemented')
      .using('2', 'Not Implemented').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 501)
      .using('body').from('cxt:body')

  .route('@507')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Insufficient Storage')
      .using('2', 'Insufficient Storage').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 507)
      .using('body').from('cxt:body')
;

// TODO: Need top-level error handling.
var resolver = new webdav.http.MethodBasedRequestResolver()
var server = pronto.HTTPServer.createServer(register, initialContext);
server.setResolver(resolver);
server.listen(8000, 'localhost');
process.on('SIGINT', function () {server.close();});
<commit_msg>Added 424 route.<commit_after>/**
 * A simple WebDAV server.
 */

var pronto = require('pronto');
var webdav = require('./lib');
var fsdav = require('./lib/fs');

var register = new pronto.Registry();
var initialContext = new pronto.Context({
  baseURI: '/test'
});

register
  // Set up the logger
  .logger(pronto.logging.ConsoleLogger, {colors: true})
  // Operations common across the board.
  .route('@bootstrap')
    .does(webdav.http.GetNormalizedPath, 'path')
      .using('baseURI').from('cxt:baseURI')
    .does(fsdav.LoadFSBridge, 'bridge')
      .using('root', './data')
  // ================================================================
  // HTTP Operations.
  // ================================================================
  .route('OPTIONS')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleOptions, 'options')
      .using('resource').from('cxt:resource')
    .does(pronto.commands.HTTPResponse)
      .using('headers').from('cxt:options')
      .using('code', 200)

  .route('GET')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
      .using('addDatasource', true) // It's magic!
    .does(webdav.http.HandleGet, 'get')
      .using('resource').from('cxt:resource')
    .does(webdav.http.StreamedHTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:get')
      .using('stream').from('resource:stream')

  .route('HEAD')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleHead, 'head')
      .using('resource').from('cxt:resource')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:head')

  .route('DELETE')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandleDelete, 'delete')
      .using('resourceBridge').from('cxt:bridge')
      .using('resource').from('cxt:resource')
    .does(webdav.xml.SerializeXML, 'body')
      .using('xml').from('cxt:multistatus')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:delete')
      .using('body', '').from('cxt:body')

  .route('PUT')
    .does(pronto.commands.BufferRequest, 'input')
    .includes('@bootstrap')
    .does(webdav.backend.LoadResource, 'resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('name').from('cxt:path')
    .does(webdav.http.HandlePut, 'put')
      .using('resourceBridge').from('cxt:bridge')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('readStream').from('cxt:input')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:put')

  .route('PROPFIND')
    .includes('@bootstrap')
    .does(webdav.xml.ParseXML, 'xml')
      // XXX: Currently, we're not buffering this.
      //.using('input').from('cxt:input')
    .does(webdav.http.HandlePropfind, 'propfind')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('xml').from('cxt:xml')
    .does(webdav.xml.SerializeXML, 'body')
      .using('xml').from('cxt:propfind')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 207).from('cxt:httpStatus')
      .using('body').from('cxt:body')

  // Since we support extended-mkcol, this can return
  // 201 or 207, with our without a body.
  .route('MKCOL')
    .includes('@bootstrap')
    .does(webdav.http.HandleMkcol, 'mkcol')
      .using('path').from('cxt:path')
      .using('resource').from('cxt:resource')
      .using('resourceBridge').from('cxt:bridge')
      .using('xml').from('cxt:xml')
    .does(webdav.xml.SerializeXML, 'body')
      .using('xml').from('cxt:extendedMkcol')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 201).from('cxt:mkcol')
      .using('body').from('cxt:body')

  .route('PROPPATCH')
    .includes('@bootstrap')
  .route('COPY')
    .includes('@bootstrap')
  .route('MOVE')
    .includes('@bootstrap')
  .route('REPORT')
    .includes('@bootstrap')
    .does(webdav.http.HandleReport, 'report')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 404).from('cxt:report')

  // ================================================================
  // Error Routes
  // ================================================================
  .route('@304')
    // 304 should never have a body. It is up to the app to put
    // one of Date, ETag, Expires, Vary, and so on.
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}).from('cxt:httpHeaders')
      .using('code', 304)

  .route('@403')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Forbidden')
      .using('2', 'Forbidden')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 403)
      .using('body').from('cxt:body')

  .route('@404')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Not Found')
      .using('2', 'Not Found')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 404)
      .using('body').from('cxt:body')

  .route('@405')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Method Not Allowed')
      .using('2', 'Method Not Allowed').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 405)
      .using('body').from('cxt:body')
  .route('@409')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Conflict')
      .using('2', 'Conflict').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 409)
      .using('body').from('cxt:body')

  .route('@412')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Precondition Failed')
      .using('2', 'Precondition Failed').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 412)
      .using('body').from('cxt:body')

  .route('@415')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Unsupported Media Type')
      .using('2', 'Unsupported Media Type').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 415)
      .using('body').from('cxt:body')

  .route('@424')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Failed Dependency')
      .using('2', 'Failed Dependency').from('cxt:body')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 424)
      .using('body').from('cxt:body')

  .route('@500')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Internal Server Error')
      .using('2', 'Internal Server Error').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 500)
      .using('body').from('cxt:body')

  .route('@501')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Not Implemented')
      .using('2', 'Not Implemented').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 501)
      .using('body').from('cxt:body')

  .route('@507')
    .does(pronto.commands.SPrintF, 'body')
      .using('format', pronto.commands.SPrintF.HTML5)
      .using('1', 'Insufficient Storage')
      .using('2', 'Insufficient Storage').from('cxt:httpError')
    .does(pronto.commands.HTTPResponse)
      .using('headers', {}) //.from('cxt:httpHeaders')
      .using('code', 507)
      .using('body').from('cxt:body')
;

// TODO: Need top-level error handling.
var resolver = new webdav.http.MethodBasedRequestResolver()
var server = pronto.HTTPServer.createServer(register, initialContext);
server.setResolver(resolver);
server.listen(8000, 'localhost');
process.on('SIGINT', function () {server.close();});
<|endoftext|>


<commit_before>var port = process.env.PORT || 4000,
    app = require('./app').init(port),
    utils = require('./utils'),
    conf = require('./conf'),
    request = require('request'),
    pageSize = 20;

app.get('/', function(req, res){

    request.get({url:'/api/templates'},function(e,r,b){

        res.render("index",{templates:b.templates,utils:utils});

    });

});

app.get('/:page?', function(req,res){

    var offset = 0
    var page = (req.params.page)||1;

    if (page>1) {
        offset = ((page*pageSize)+1)-pageSize ;
    }

    console.log("page.......");

    request.get({url:'https://api.parse.com/1/classes/Post',json:true,qs:{limit:pageSize,count:1,skip:offset,order:"-createdAt"},headers:{'X-Parse-Application-Id':conf.parse.appKey,'X-Parse-REST-API-Key':conf.parse.restKey}},function(e,r,b){
        if (b.results) {
            res.render("index",{stories:b.results,count:b.count,page:page,utils:utils});
        }
        else {
            //next();
            res.json({error:"no results"});
        }
    });

});

app.get('/tag/:tag/:page?', function(req,res){

    console.log("/tag");

    var tag = req.params.tag;
    var whereClause = {tags:{"$all":[tag]}};
    var offset = 0;
    var page = (req.params.page)||1;

    if (page>1) {
        offset = ((page*pageSize)+1)-pageSize;
    }

    request.get({url:'https://api.parse.com/1/classes/Post',json:true,qs:{limit:pageSize,count:1,where:JSON.stringify(whereClause)},headers:{'X-Parse-Application-Id':conf.parse.appKey,'X-Parse-REST-API-Key':conf.parse.restKey}},function(e,r,b){
        if (b.results && b.results.length>0) {
            res.render("index",{stories:b.results,count:b.count,page:page,utils:utils});
        }
        else {
            res.json({error:"no results for tag"+tag});
            //console.log("no /tag get next");
        }
    });
});

app.get('/api/templates', function(req, res){
    var fs = require('fs');

    //fs.readFile('./static/templates.json', 'utf8', function (err, data) {
    //    res.json(data);
    //});

    //var fileJSON = require('./static/templates.json');
    //res.send(fileJSON);

    //fs.readFile('./templates.json', 'utf8', function (err, data) {
    //    res.json(data);
    //});

    fs.createReadStream('templates.json').pipe(res);

});

app.post("/post",function(req, res){

    console.log("post /post..");

    var p = req.body;

    request.post({url:'http://in1-api.herokuapp.com/post',json:true,
        body:p}, function (e,r,b){
        console.log("wrote post to in1 api....."+e);

        if (e) {
            res.json({error:"no write"});
        }
        else {
            //var objectId = b.objectId;
            res.json({status:1});
        }

    });
});

/* The 404 Route (ALWAYS Keep this as the last route) */
app.get('/*', function(req, res){
    res.render('404.ejs');
});

<commit_msg>fix json<commit_after>var port = process.env.PORT || 4000,
    app = require('./app').init(port),
    utils = require('./utils'),
    conf = require('./conf'),
    request = require('request'),
    pageSize = 20;

app.get('/', function(req, res){

    request.get({url:'/api/templates'},function(e,r,b){

        res.render("index",{templates:{},utils:utils});

    });

});

app.get('/:page?', function(req,res){

    var offset = 0
    var page = (req.params.page)||1;

    if (page>1) {
        offset = ((page*pageSize)+1)-pageSize ;
    }

    console.log("page.......");

    request.get({url:'https://api.parse.com/1/classes/Post',json:true,qs:{limit:pageSize,count:1,skip:offset,order:"-createdAt"},headers:{'X-Parse-Application-Id':conf.parse.appKey,'X-Parse-REST-API-Key':conf.parse.restKey}},function(e,r,b){
        if (b.results) {
            res.render("index",{stories:b.results,count:b.count,page:page,utils:utils});
        }
        else {
            //next();
            res.json({error:"no results"});
        }
    });

});

app.get('/tag/:tag/:page?', function(req,res){

    console.log("/tag");

    var tag = req.params.tag;
    var whereClause = {tags:{"$all":[tag]}};
    var offset = 0;
    var page = (req.params.page)||1;

    if (page>1) {
        offset = ((page*pageSize)+1)-pageSize;
    }

    request.get({url:'https://api.parse.com/1/classes/Post',json:true,qs:{limit:pageSize,count:1,where:JSON.stringify(whereClause)},headers:{'X-Parse-Application-Id':conf.parse.appKey,'X-Parse-REST-API-Key':conf.parse.restKey}},function(e,r,b){
        if (b.results && b.results.length>0) {
            res.render("index",{stories:b.results,count:b.count,page:page,utils:utils});
        }
        else {
            res.json({error:"no results for tag"+tag});
            //console.log("no /tag get next");
        }
    });
});

app.get('/api/templates', function(req, res){
    var fs = require('fs');

    //fs.readFile('./static/templates.json', 'utf8', function (err, data) {
    //    res.json(data);
    //});

    //var fileJSON = require('./static/templates.json');
    //res.send(fileJSON);

    //fs.readFile('./templates.json', 'utf8', function (err, data) {
    //    res.json(data);
    //});

    fs.createReadStream('templates.json').pipe(res);

});

app.post("/post",function(req, res){

    console.log("post /post..");

    var p = req.body;

    request.post({url:'http://in1-api.herokuapp.com/post',json:true,
        body:p}, function (e,r,b){
        console.log("wrote post to in1 api....."+e);

        if (e) {
            res.json({error:"no write"});
        }
        else {
            //var objectId = b.objectId;
            res.json({status:1});
        }

    });
});

/* The 404 Route (ALWAYS Keep this as the last route) */
app.get('/*', function(req, res){
    res.render('404.ejs');
});

<|endoftext|>


<commit_before>var Hapi = require('hapi');
var Boom = require('boom');
var Good = require('good');
var GoodFile = require('good-file');
var GoodConsole = require('good-console');
var os = require('os');
var dns = require('dns');
var rimraf = require('rimraf');
var mkdirp = require('mkdirp');
var path = require('path');
var tempDir = os.tmpdir();
var readTorrent = require('read-torrent');
var uuid = require('node-uuid');
var fs = require('fs');
var kickass = require('kickass-torrent');
var peerflix = require('peerflix');
var omx = require('omxctrl');

// Configs
var PORT = process.argv[2] || 8080;
var LOG_ENABLED = true;

// Params
var connection;
var states = ['Playing', 'Paused', 'Idle'];
var omxCtrlMap = {
  'pause': 'pause',
  'speedup': 'increaseSpeed',
  'speeddown': 'decreaseSpeed',
  'nextaudio': 'nextAudioStream',
  'prevaudio': 'previousAudioStream',
  'nextsubtitle': 'nextSubtitleStream',
  'prevsubtitle': 'previousSubtitleStream',
  'togglesubtitle': 'toggleSubtitles',
  'volumeup': 'increaseVolume',
  'volumedown': 'decreaseVolume',
  'forward': 'seekForward',
  'backward': 'seekBackward',
  'fastforward': 'seekFastForward',
  'fastbackward': 'seekFastBackward'
};

// Helper Methods
var clearTorrentCache = function() {
  fs.readdir(tempDir, function(err, files) {
    if (err) {
      console.log(err);
      return;
    }
    files.forEach(function(file) {
      if (file.substr(0, 9) === 'peerflix-') {
        rimraf.sync(path.join(tempDir, file));
      }
    });
  });
};

var stop = function() {
  if (!connection) { return; }
  connection.destroy();
  connection = null;
  omx.stop();
  clearTorrentCache();
};

omx.on('ended', function() {
  stop();
});

// Server Setup
var server = new Hapi.Server();
server.connection({ port: PORT });

if (LOG_ENABLED) {
  var options = { logRequestPayload: true };
  var opsPath = path.normalize(__dirname +  '/logs/operations');
  var errsPath = path.normalize(__dirname + '/logs/errors');
  var reqsPath = path.normalize(__dirname + '/logs/requests');
  mkdirp.sync(opsPath);
  mkdirp.sync(errsPath);
  mkdirp.sync(reqsPath);
  var configWithPath = function(path) {
    return { path: path, extension: 'log', rotate: 'daily', format: 'YYYY-MM-DD-X', prefix:'peerflix-web' };
  };
  var consoleReporter = new GoodConsole({ log: '*', response: '*' });
  var opsReporter = new GoodFile(configWithPath(opsPath), { log: '*', ops: '*' });
  var errsReporter = new GoodFile(configWithPath(errsPath), { log: '*', error: '*' });
  var reqsReporter = new GoodFile(configWithPath(reqsPath), { log: '*', response: '*' });
  options.reporters = [ consoleReporter, opsReporter, errsReporter, reqsReporter ];
  server.register({ register: Good, options: options}, function(err) { if (err) { throw(err); } });
}

server.start(function () {
  clearTorrentCache();
  dns.lookup(os.hostname(), function (err, address) {
    if (err) { console.log('Peerflix web running at http://localhost:' + server.info.port); }
    else { console.log('Peerflix web running at: http://' + address + ':' + server.info.port); }
  });
});

// Routes
server.route({
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply.file(path.join(__dirname, '/index.html'));
  }
});

server.route({
  method: 'POST',
  path: '/play',
  handler: function (request, reply) {
    var torrentUrl = request.payload.url;
    if (torrentUrl) {
      readTorrent(torrentUrl, function(err, torrent) {
        if (err) { return reply(Boom.badRequest(err)); }
        if (connection) { stop(); }

        connection = peerflix(torrent, {
          connections: 100,
          path: path.join(tempDir, 'peerflix-' + uuid.v4()),
          buffer: (1.5 * 1024 * 1024).toString()
        });

        connection.server.on('listening', function() {
          omx.play('http://127.0.0.1:' + connection.server.address().port + '/');
          return reply();
        });
      });
    }
    else {
      return reply(Boom.badRequest('Torrent URL Required'));
    }
  }
});

server.route({
  method: 'POST',
  path: '/stop',
  handler: function (request, reply) {
    stop();
    return reply();
  }
});

server.route({
  method: 'GET',
  path: '/status',
  handler: function (request, reply) {
    return reply(states[omx.getState()]);
  }
});

server.route({
  method: 'GET',
  path: '/query',
  handler: function (request, reply) {
    var query = request.query.q;
    if (query) {
      kickass(query, function(err, response){
        if (err) { return reply(Boom.badRequest(err)); }
        var filteredResults = [];
        response.list.forEach(function(result) {
          if (result.category === 'TV' || result.category === 'Movies') {
            filteredResults.push(result);
          }
        });
        return reply(filteredResults);
      });
    }
    else { return reply(Boom.badRequest('Torrent query string must be present')); }
  }
});

server.route({
  method: 'POST',
  path: '/{omx_command}',
  handler: function (request, reply) {
    var omxCommand = request.params.omx_command;
    var actualCommand = omxCtrlMap[omxCommand];
    if (actualCommand) {
      omx[actualCommand]();
      return reply();
    }
    else { return reply(Boom.badRequest('Invalid OMX Player command')); }
  }
});
<commit_msg>black background for omxplayer<commit_after>var Hapi = require('hapi');
var Boom = require('boom');
var Good = require('good');
var GoodFile = require('good-file');
var GoodConsole = require('good-console');
var os = require('os');
var dns = require('dns');
var rimraf = require('rimraf');
var mkdirp = require('mkdirp');
var path = require('path');
var tempDir = os.tmpdir();
var readTorrent = require('read-torrent');
var uuid = require('node-uuid');
var fs = require('fs');
var kickass = require('kickass-torrent');
var peerflix = require('peerflix');
var omx = require('omxctrl');

// Configs
var PORT = process.argv[2] || 8080;
var LOG_ENABLED = true;

// Params
var connection;
var states = ['Playing', 'Paused', 'Idle'];
var omxCtrlMap = {
  'pause': 'pause',
  'speedup': 'increaseSpeed',
  'speeddown': 'decreaseSpeed',
  'nextaudio': 'nextAudioStream',
  'prevaudio': 'previousAudioStream',
  'nextsubtitle': 'nextSubtitleStream',
  'prevsubtitle': 'previousSubtitleStream',
  'togglesubtitle': 'toggleSubtitles',
  'volumeup': 'increaseVolume',
  'volumedown': 'decreaseVolume',
  'forward': 'seekForward',
  'backward': 'seekBackward',
  'fastforward': 'seekFastForward',
  'fastbackward': 'seekFastBackward'
};

// Helper Methods
var clearTorrentCache = function() {
  fs.readdir(tempDir, function(err, files) {
    if (err) {
      console.log(err);
      return;
    }
    files.forEach(function(file) {
      if (file.substr(0, 9) === 'peerflix-') {
        rimraf.sync(path.join(tempDir, file));
      }
    });
  });
};

var stop = function() {
  if (!connection) { return; }
  connection.destroy();
  connection = null;
  omx.stop();
  clearTorrentCache();
};

omx.on('ended', function() {
  stop();
});

// Server Setup
var server = new Hapi.Server();
server.connection({ port: PORT });

if (LOG_ENABLED) {
  var options = { logRequestPayload: true };
  var opsPath = path.normalize(__dirname +  '/logs/operations');
  var errsPath = path.normalize(__dirname + '/logs/errors');
  var reqsPath = path.normalize(__dirname + '/logs/requests');
  mkdirp.sync(opsPath);
  mkdirp.sync(errsPath);
  mkdirp.sync(reqsPath);
  var configWithPath = function(path) {
    return { path: path, extension: 'log', rotate: 'daily', format: 'YYYY-MM-DD-X', prefix:'peerflix-web' };
  };
  var consoleReporter = new GoodConsole({ log: '*', response: '*' });
  var opsReporter = new GoodFile(configWithPath(opsPath), { log: '*', ops: '*' });
  var errsReporter = new GoodFile(configWithPath(errsPath), { log: '*', error: '*' });
  var reqsReporter = new GoodFile(configWithPath(reqsPath), { log: '*', response: '*' });
  options.reporters = [ consoleReporter, opsReporter, errsReporter, reqsReporter ];
  server.register({ register: Good, options: options}, function(err) { if (err) { throw(err); } });
}

server.start(function () {
  clearTorrentCache();
  dns.lookup(os.hostname(), function (err, address) {
    if (err) { console.log('Peerflix web running at http://localhost:' + server.info.port); }
    else { console.log('Peerflix web running at: http://' + address + ':' + server.info.port); }
  });
});

// Routes
server.route({
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply.file(path.join(__dirname, '/index.html'));
  }
});

server.route({
  method: 'POST',
  path: '/play',
  handler: function (request, reply) {
    var torrentUrl = request.payload.url;
    if (torrentUrl) {
      readTorrent(torrentUrl, function(err, torrent) {
        if (err) { return reply(Boom.badRequest(err)); }
        if (connection) { stop(); }

        connection = peerflix(torrent, {
          connections: 100,
          path: path.join(tempDir, 'peerflix-' + uuid.v4()),
          buffer: (1.5 * 1024 * 1024).toString()
        });

        connection.server.on('listening', function() {
          omx.play('http://127.0.0.1:' + connection.server.address().port + '/', '-b');
          return reply();
        });
      });
    }
    else {
      return reply(Boom.badRequest('Torrent URL Required'));
    }
  }
});

server.route({
  method: 'POST',
  path: '/stop',
  handler: function (request, reply) {
    stop();
    return reply();
  }
});

server.route({
  method: 'GET',
  path: '/status',
  handler: function (request, reply) {
    return reply(states[omx.getState()]);
  }
});

server.route({
  method: 'GET',
  path: '/query',
  handler: function (request, reply) {
    var query = request.query.q;
    if (query) {
      kickass(query, function(err, response){
        if (err) { return reply(Boom.badRequest(err)); }
        var filteredResults = [];
        response.list.forEach(function(result) {
          if (result.category === 'TV' || result.category === 'Movies') {
            filteredResults.push(result);
          }
        });
        return reply(filteredResults);
      });
    }
    else { return reply(Boom.badRequest('Torrent query string must be present')); }
  }
});

server.route({
  method: 'POST',
  path: '/{omx_command}',
  handler: function (request, reply) {
    var omxCommand = request.params.omx_command;
    var actualCommand = omxCtrlMap[omxCommand];
    if (actualCommand) {
      omx[actualCommand]();
      return reply();
    }
    else { return reply(Boom.badRequest('Invalid OMX Player command')); }
  }
});
<|endoftext|>