Skip to content

Instantly share code, notes, and snippets.

@thinkerbot
Created March 8, 2009 01:39
Show Gist options
  • Save thinkerbot/75534 to your computer and use it in GitHub Desktop.
Save thinkerbot/75534 to your computer and use it in GitHub Desktop.
ubiquity commands to run a tap server
//////////////////////////////////////////////////////////////////////////////
//
// Tap
//
// Note Ubiquity makes these objects available (the list is incomplete, but
// contains the objects that are used in this script):
//
// - Application:: the FUEL[http://developer.mozilla.org/en/FUEL] Application object
// - jQuery:: http://docs.jquery.com/Main_Page
// - Utils:: Ubiquity utilities
// - CmdUtils:: Ubiquity command utilities
//
//////////////////////////////////////////////////////////////////////////////
var Tap = {
System: {},
Http: {},
/* Sets a persistent tap configuration */
set: function(key, value) {
var variable = Tap.NAMESPACE + key;
if (Application.prefs.has(variable)) {
Application.prefs.get(variable).value = value;
} else {
Application.prefs.setValue(variable, value);
}
},
/* Gets a persistent tap configuration */
get: function(key, default_value) {
var variable = Tap.NAMESPACE + key;
if (Application.prefs.has(variable)) {
return Application.prefs.get(variable).value;
} else {
return default_value;
}
},
/* Stores a temporary tap variable */
store: function(key, value) {
Application.storage.set(Tap.NAMESPACE + key, value);
},
/* Fetches a temporary tap variable */
fetch: function(key, default_value) {
return Application.storage.get(Tap.NAMESPACE + key, default_value);
},
/********** Tap Server ***********/
/* start the server */
start: function() {
try
{
/* Adds an event listener to shutdown the server when the window is unloaded. */
if(!Tap.listener) {
window.addEventListener("unload", function(e) { Tap.stop(); }, false);
Tap.listener = true;
}
if(Tap.server() == false) {
var ruby_path = Tap.get('ruby_path', Tap.DEFAULT_RUBY_PATH);
var root_path = Tap.get('root_path', Tap.DEFAULT_ROOT_PATH);
var initialize_script = "" +
"require 'rubygems';"+
"require 'tap/server';" +
"server = Tap::Server.instantiate('" + root_path + "', true);";
// Determine the uri of the server
var tempfile = Tap.System.tempfile('uri');
var uri_script = initialize_script +
"File.open('" + tempfile.path + "', 'w') {|file| file << server.uri(:server) };";
Tap.System.run(ruby_path, ["-e", uri_script], true);
var uri = Tap.System.read(tempfile.path);
// Check if the server exists
jQuery.ajax({
type: "GET",
dataType: "text",
url: Tap.uri("ping", uri),
success: function(data, textStatus) {
// Server is already runnning
Tap.setup(uri);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
// Server is not running; launch the server
var launch_script = initialize_script + "Tap::Server.run(server);";
Tap.System.run(ruby_path, ["-e", launch_script]);
// Store configurations and check the server was started
Tap.store('server', {uri: uri, checks: 0});
Tap.check_startup();
}
});
} else {
Tap.ping();
}
}
catch(ex){
displayMessage("startup error: " + ex.message);
Tap.stop();
}
},
/* stop the server */
stop: function() {
var server = Tap.server();
if(server.shutdown_key) {
jQuery.ajax({
type: "GET",
url: Tap.uri("shutdown"),
data: server,
success: function(server, textStatus) {
displayMessage("Shutdown tap server");
Tap.store('server', false);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
displayMessage("Server could not be shut down. Redirecting to manual shutdown link...");
var server = Tap.server();
Tap.Http.load(server.uri);
Tap.store('server', false);
}
});
} else {
displayMessage("Deactivated connection to server.");
Tap.store('server', false);
};
},
/* restart the server */
restart: function() {
Tap.stop();
Utils.setTimeout(Tap.start, 1000);
},
/* setup the server to the specified uri, then redirect
* to the server home page. */
setup: function(uri) {
jQuery.ajax({
type: "GET",
dataType: "xml",
url: Tap.uri("config", uri),
success: function(data, textStatus) {
var xml = jQuery('server', data);
var server = {
uri: xml.find('uri').text(),
shutdown_key: xml.find('shutdown_key').text()
};
Tap.store('server', server);
if(server.shutdown_key) {
displayMessage("Started tap server: " + server.uri);
};
Tap.ping();
Tap.Http.load(server.uri);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
displayMessage("Server could not be reached at: " + uri + " (" + textStatus + ")");
Tap.stop();
}
});
},
/* setup a remote server */
ping: function(uri) {
var server = Tap.server();
if(server.uri) {
jQuery.ajax({
type: "GET",
dataType: "text",
url: Tap.uri("ping"),
success: function(data, textStatus) {
displayMessage("Server is active at: " + Tap.server().uri);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
displayMessage("Server could not be reached at: " + Tap.server().uri + " (" + textStatus + ")");
}
});
} else {
displayMessage("No server is set.");
}
},
/**** utility functions ***/
/* fetch the current server config */
server: function() {
return Tap.fetch('server', false);
},
/* returns the uri path to the server action */
uri: function(action, uri) {
if(typeof uri == 'undefined') uri = Tap.server().uri;
if(typeof uri == 'undefined') throw 'could not determine uri';
return uri + "/" + action;
},
/**** callbacks and observers ****/
// requires Tap.server() = {uri: uri, checks: 0}
check_startup: function() {
jQuery.ajax({
type: "GET",
dataType: "text",
url: Tap.uri("ping"),
success: function(data, textStatus) {
var server = Tap.server();
Tap.setup(server.uri);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
var server = Tap.server();
if(server.checks >= 10) {
displayMessage("The server could not be reached and will be shutdown");
Tap.stop();
} else {
displayMessage("Attempting to reach server... (" + server.checks + ")");
server.checks += 1;
Utils.setTimeout(Tap.check_startup, 1000);
}
}
});
},
}
//////////////////////////////////////////////////////////////////////////////
//
// Tap.System utility functions
//
//////////////////////////////////////////////////////////////////////////////
Tap.System = {
/* Returns "WINNT" on Windows Vista, XP, 2000, and NT systems;
* "Linux" on GNU/Linux; and "Darwin" on Mac OS X.
*
* credit: http://developer.mozilla.org/en/Code_snippets/Miscellaneous */
os: function() {
return Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULRuntime).OS;
},
/* Creates a temporary nsIFile.
*
* credit: http://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO */
tempfile: function(basename) {
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
file.append( basename + ".tmp");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
return file;
},
/* Returns an nsIFile for the special directory
*
* Tap.System.directory('Desk') # => nsIFile to the desktop directory
*
* See http://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO for
* a list of special directories. */
directory: function(dir) {
return Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get(dir, Components.interfaces.nsIFile);
},
/* Initializes a new process for cmd (the path to the command)
* using the input arguments.
*
* credit: http://use.perl.org/~perigrin/journal/37300 */
run: function(cmd, args, block) {
if(typeof block == 'undefined') block = false;
// create an nsILocalFile for the executable
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(cmd);
// create an nsIProcess
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
process.run(block, args, args.length);
},
/* Reads and returns the content of the specified file. Returns false if the
* file does not exist. */
read: function(path) {
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(path);
if(!file.exists()) {
return false;
}
return this.read_file(file);
},
read_file: function(file) {
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
var str = sstream.read(4096);
while (str.length > 0) {
data += str;
str = sstream.read(4096);
}
sstream.close();
fstream.close();
return data;
},
/* Loads the content of path as JSON. Returns false if the file does not exit. */
load_json: function(path) {
// TODO: must strip and return false if no content
return eval('(' + this.read(path) + ')');
},
};
//////////////////////////////////////////////////////////////////////////////
//
// Tap.Http utility functions
//
//////////////////////////////////////////////////////////////////////////////
Tap.Http = {
/* Convert the input uri into a URI object that can be used by load
*
* Tap.Utils.convert_to_uri('http://tap.rubyforge.org') # => URI
*
*/
convert_to_uri: function(spec) {
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ios.newURI(spec, null, null);
},
/* Loads the uri in the current tab:
*
* Tap.Utils.load('http://tap.rubyforge.org')
*
*/
load: function(uri) {
Application.activeWindow.activeTab.load(this.convert_to_uri(uri));
},
};
//////////////////////////////////////////////////////////////////////////////
//
// tap commands
//
//////////////////////////////////////////////////////////////////////////////
/* Default values: */
// DEFAULT_RUBY_PATH: the default path to the ruby executable
// DEFAULT_ROOT_PATH: the default path to the server root directory
// (for logs, development, etc)
switch (Tap.System.os()) {
case "WINNT":
Tap.DEFAULT_RUBY_PATH = "C:\\ruby\\bin\\ruby.exe";
Tap.DEFAULT_ROOT_PATH = Tap.System.directory('Desk').path + "\\server";
break;
case "Darwin":
Tap.DEFAULT_RUBY_PATH = "/usr/bin/ruby";
Tap.DEFAULT_ROOT_PATH = Tap.System.directory('Desk').path + "/server";
break;
case "Linux":
Tap.DEFAULT_RUBY_PATH = "/usr/bin/ruby";
Tap.DEFAULT_ROOT_PATH = Tap.System.directory('Desk').path + "/server";
break;
}
// NAMESPACE: the namespace for storing variables
Tap.NAMESPACE = "tap.rubyforge.org.";
Tap.DEFAULT_URI = "http://localhost:8080/server";
CmdUtils.CreateCommand({
name: "tap",
homepage: "http://tap.rubyforge.org",
author: { name: "Simon Chiang", email: "[email protected]"},
license: "MIT",
description: "Launches a Tap server.",
takes: {"what": noun_arb_text},
execute: function(what) {
if(what.text == "start") Tap.start();
if(what.text == "stop") Tap.stop();
if(what.text == "restart") Tap.restart();
if(what.text == "ping") Tap.ping();
if(what.text == "setup") Tap.setup(Tap.DEFAULT_URI);
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment