OxFF/OxFF/components/OxFF.js
2010-08-05 20:30:40 +02:00

352 lines
10 KiB
JavaScript

// -*- coding: utf-8 -*-
// vi:si:et:sw=2:sts=4:ts=2
/*
OxFF - local extension for pan.do/ra
http://pan.do/ra
2009-2010 - GPL 3.0
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/AddonManager.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://ox/utils.jsm");
Components.utils.import("resource://ox/oxff.jsm");
var OxFFFactory =
{
createInstance: function (outer, iid)
{
if (outer != null)
throw NS_ERROR_NO_AGGREGATION;
return (new OxFF()).QueryInterface(iid);
}
};
function OxFF() {
var _this = this;
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var nsWindow = windowMediator.getMostRecentWindow("navigator:browser");
this._window = nsWindow.content;
this._window.addEventListener("unload", function() { _this.logout() }, false);
this.app = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);
this._site = this._window.document.location.hostname;
if(!this._site) {
this._site = 'localhost';
}
this.access();
if(!oxff.get('username')) {
oxff.set('username', ox.makeRandomString(8));
oxff.set('password', ox.makeRandomString(8));
}
this.username = oxff.get('username');
this.password = oxff.get('password');
AddonManager.getAddonByID('firefogg@firefogg.org', function(addon) {
if (addon.hasResource('bin')) {
var resource = addon.getResourceURI('bin');
var file = resource.QueryInterface(Ci.nsIFileURL).file.QueryInterface(Ci.nsILocalFile);
file.append('ffmpeg2theora');
_this._ffmpeg2theora = file.path;
}
});
}
OxFF.prototype = {
classDescription: "OxFF pan.do/ra Firefox extension",
classID: Components.ID("{32e2138b-2026-4cac-87c7-4f97ac4cf1c5}"),
contractID: "@pan.do/ra_extension;1",
extensionID: "OxFF@pan.do",
_xpcom_factory : OxFFFactory,
_xpcom_categories : [{
category: "JavaScript global constructor",
entry: "OxFF"
}],
_prefs : Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch),
_window : null,
_icon : null,
_protocolCallbacks : {},
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIOxFF,
Ci.nsISecurityCheckedComponent,
Ci.nsISupportsWeakReference,
Ci.nsIClassInfo]),
// nsIClassInfo
implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
flags: Ci.nsIClassInfo.DOM_OBJECT,
getInterfaces: function getInterfaces(aCount) {
var interfaces = [Ci.nsIOxFF,
Ci.nsISecurityCheckedComponent,
Ci.nsISupportsWeakReference,
Ci.nsIClassInfo];
aCount.value = interfaces.length;
return interfaces;
},
getHelperForLanguage: function getHelperForLanguage(aLanguage) {
return null;
},
//nsISecurityCheckedComponent
canCallMethod: function canCallMethod(iid, methodName) {
Components.utils.reportError(methodName);
return "AllAccess";
},
canCreateWrapper: function canCreateWrapper(iid) {
return "AllAccess";
},
canGetProperty: function canGetProperty(iid, propertyName) {
Components.utils.reportError(propertyName);
return "AllAccess";
},
canSetProperty: function canSetProperty(iid, propertyName) {
Components.utils.reportError(propertyName);
return "NoAccess";
},
debug: function() {
var msg = "OxFF: ";
for(var i=0;i<arguments.length;i++) {
msg += arguments[i];
if(i+1<arguments.length)
msg += ', ';
}
this.app.console.log(msg);
},
base: 'http://127.0.0.1:2620/',
_user: null,
//nsIOxFF
version: "bzr",
access: function(request) {
if (typeof(request) == 'undefined') request = false;
var _this = this;
var conn = oxff.getDB();
var q = conn.createStatement("SELECT access FROM site WHERE site = :site");
q.params.site = this._site;
this._access = false;
while(q.executeStep()) {
if(q.row.access == 1) {
this._access = true;
}
}
q.finalize();
if(request && !this._access) {
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var nsWindow = windowMediator.getMostRecentWindow("navigator:browser");
var box = nsWindow.gBrowser.getNotificationBox();
var buttons = [{
label : "Allow",
accessKey : "A",
callback : function() { _this.permitAccess(); }
},
{
label : "Deny",
accessKey : "D",
callback : function() { _this.denyAccess(); }
}];
box.appendNotification("Do you wnat to allow "+_this._site+" to manage archvies on your computer",
'oxff_permission' , null , box.PRIORITY_INFO_MEDIUM , buttons);
}
return this._access;
},
api: function(action, data, callback) {
var _this = this;
if (typeof(data) == 'function') {
callback = data;
data = {};
}
if(!this._access) {
this.debug('permission deinied', action, data);
return false;
}
if(!this._user) {
this.debug('login first', action, data);
return false;
}
data["site"] = this._site;
data["user"] = this._user;
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
req.addEventListener("error", function(e) {
_this.startDaemon();
ox.setTimeout(function() { _this.api(action, data, callback); }, 500);
}, false);
req.addEventListener("load", function(e) {
//links should have base prefixed or whatever proxy is used to access them, i.e. some api call
//var data = JSON.parse(e.target.responseText);
//callback(data);
callback(e.target.responseText);
}, false);
var base = this.base; //later base can not be a public property
var url = base + action;
var formData = Cc["@mozilla.org/files/formdata;1"]
.createInstance(Ci.nsIDOMFormData);
if (data) {
for(key in data) {
formData.append(key, data[key]);
}
}
//req.open("POST", url, true, this.username, this.password);
req.open("POST", url, true);
req.send(formData);
return true;
},
extract: function(oshash, media, callback) {
return this.api('extract', {'oshash': oshash, 'media': media}, callback);
},
files: function(volume, callback) {
return this.api('files', {'volume': volume}, callback.callback);
},
get: function(oshash, media, callback) {
return this.api('get', {'oshash': oshash, 'media': media}, callback.callback);
},
login: function(user) {
if(this._user==null) {
this._user = user;
return true;
}
return false;
},
logout: function(user) {
var _this = this;
this.api('stop', function() {
_this._user = null;
_this._daemon = null;
});
return true;
},
update: function(callback) {
this.api('update', callback.callback);
return true;
},
addVolume: function() {
if(!this._access) {
return false;
}
const nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(this._window, "Add Volume to " + this._site, nsIFilePicker.modeGetFolder);
fp.appendFilters(nsIFilePicker.filterAll);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var new_location = fp.file.path;
this.api('add_volume', {'path': new_location}, function(result) {});
return true;
}
return false;
},
volumes: function(callback) {
return this.api('volumes', callback.callback);
},
//private functions
permitAccess: function() {
this._access = true;
var conn = oxff.getDB();
var q = conn.createStatement("INSERT OR REPLACE INTO site values (:site, 1)");
q.params.site = this._site;
q.executeStep();
q.finalize();
},
denyAccess: function() {
this._access = false;
var conn = oxff.getDB();
var q = conn.createStatement("INSERT OR REPLACE INTO site values (:site, 0)");
q.params.site = this._site;
q.executeStep();
q.finalize();
},
startDaemon: function() {
var _this = this;
//if daemon is already running to not start it again
if(this._daemon && this._daemon.isRunning) {
this.debug('daemon is still starting up, not starting again');
return false;
}
var osString = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
var daemon = "";
if (osString == "WINNT")
daemon = 'oxd.exe';
else
daemon = 'oxd.py';
function runDaemon(file) {
try {
file.permissions = 0755;
} catch (e) {}
_this._daemon = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
_this._daemon.init(file);
var args = [oxff.getDBFile().path, _this._ffmpeg2theora];
_this._daemon.runw(false, args, args.length);
}
AddonManager.getAddonByID(this.extensionID, function(addon) {
if (addon.hasResource('bin')) {
var resource = addon.getResourceURI('bin');
var file = resource.QueryInterface(Ci.nsIFileURL).file.QueryInterface(Ci.nsILocalFile);
file.append(daemon);
runDaemon(file);
}
});
},
getFormatInfo: function(filename, callback) {
var that = this;
var get_json = function(data) {
var json = {"format": "unknown"};
try {
json = JSON.parse(data);
} catch(e) {
json = {"format": "unknown"};
}
var source_file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
source_file.initWithPath(filename);
// Try to determine the MIME type of the file
//json.contentType = that.getMimeType(source_file);
return json;
}
var info_callback = function(data) {
callback(get_json(data));
}
var options = [filename, '--info'];
if (callback) {
ox.subprocess(this.bin('ffmpeg2theora'), options, callback);
return;
}
data = ox.subprocess(this.bin('ffmpeg2theora'), options, false);
return get_json(data);
},
bin: function(cmd) {
this._cmd_name = '/usr/local/bin/_cmd_';
return this._cmd_name.replace('_cmd_', cmd);
},
}
//4.0 only
var NSGetFactory = XPCOMUtils.generateNSGetFactory([OxFF]);