Skip to content

Instantly share code, notes, and snippets.

@Constellation
Created January 15, 2009 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Constellation/47437 to your computer and use it in GitHub Desktop.
Save Constellation/47437 to your computer and use it in GitHub Desktop.
// FTP Upload for Tombloo
//
(function(){
var ProxyService = getService("/network/protocol-proxy-service;1", Ci.nsIProtocolProxyService);
var DNSService = getService("/network/dns-service;1", Ci.nsIDNSService);
var SocketService = getService("/network/socket-transport-service;1", Ci.nsISocketTransportService);
var ServerSocket = createConstructor("/network/server-socket;1", "nsIServerSocket", "init");
models.register({
name: 'FTPUpload',
ICON: 'data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABGdBTUEAAK%2FINwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUg'+
'SW1hZ2VSZWFkeXHJZTwAAANCSURBVBgZBcHbT1t1AMDx72lPKS29UCiz0BUMQxwwJptMSIAZzRgu6oOJ%2BjKjkQdjTAx%2FgI9m'+
'ezAmJkb3ppKYqHsxe9oMOh0ZODd3xYVtFOLK1dG0pYWensvv4udjaK0BAACYmp8cAz4GjgEtgAmUgeta6XNfjn33CwAAgKG1BmBq'+
'ftIEpoE3X8%2BcCCZCLVSsBiwXhLQRPOHy1iUhhfxVCPn2N6d%2B2gMwtNZMzU8GgD8Gk30jJzMvUbGDOLgsVwzqdJCCpdDCJYTF'+
'lnOVm5s3F4Qnjv%2Fw1oWyDwCYPtrcPTLaNkhRung%2BAyF81EQdFnUUnSDbdoj1coD2yAsMpp497DrejwD%2B0vjqKPDZ6e7X%2'+
'FPdllS1q1JRgz45QdAJUbMhu7FKuVgkmChjxLMPJg1xevNH5%2FfXpe%2F6hySNfTLQNHTL8IbZ8AvQ%2BWmWEW0%2F81Gwfixt7'+
'qPoSwY5HOLEseVXCLEkONWd8tx4%2FbDKBY5lYmrvWJvl6H73%2BAygEuW0X264RT2kqTTMsqx1wNI0iSDbvcOLpo3iO6DeB5rDZ'+
'QM7aZNuxiIY72XGjlEqKeIvNvoRFXg6QvnMOaVfJZw5S3AkTCUXxXNHo01obhgbXqaCtVkxPcukvD6M%2BxNayydpqjDYnhPA0%2'+
'B5M9BJfv4Nk10BohhGFKoYoVt5Ju9jcSrX%2BO9byJ7QVoVR8RD0ucDY%2FdnCDd1EVPaohdu8rC%2Bu8UqxNIocqm8MTtx8XVdF'+
'c4w2%2F%2FzdMY7qLOn0Eol%2FG%2B95BaIZVEodksr9G%2Ff4Q9t8YnFz4Euh%2F4PFd89fPDWdERacG0NigX%2FiSRcLCFi9SK'+
'XCHLv4UlVvKL7NQK5IorDGTGeCb1PLuBe6O%2Bb189P%2BM63sWZxVleTA8Q9zeQiChsYSOk4KlYO6lYB63xTgL%2BEC3RNLfX5r'+
'm2csOyXGImgOd471zJ3p1zau7hiSPHebRt8o9wmL72Oa5ysYXLgWQvw50n%2BTs3x5WlWScs23uWz2ZrhtYagFe%2BfjkqPHFeeH'+
'L83ZH3TWQKrcMYPoNkvMKnF0%2FT1zrM1aW53Qbd3rtwZmkdwNBaAwAAMHJm6A0p5AdSqn4lVQIAKO%2F47yeFIlBTMrB9VgsAgP'+
'8BON24AjtZfcoAAAAASUVORK5CYII%3D',
check: function(ps){
return ps.type == 'photo';
},
post: function(ps){
// あらかじめ必要.
var host = getPrefValue('extensions.tombloo.ftp.host');
var user = getPrefValue('extensions.tombloo.ftp.user');
var pass = getPrefValue('extensions.tombloo.ftp.pass');
var path = getPrefValue('extensions.tombloo.ftp.path') || '/';
if(host && user && pass){
var uri = createURI(ps.itemUrl);
//log(uri);
var fileName = validateFileName(uri.fileName);
var file = getTempDir(fileName);
clearCollision(file);
return succeed().addCallback(function(){
if(ps.file){
ps.file.copyTo(file.parent, file.leafName);
return file;
} else {
return download(ps.itemUrl, file);
}
}).addCallback(function(file){
return FTPUpload(host, user, pass, path, file);
});
}
}
});
// FTP + Mochikit Deferred
function FTPUpload(host, user, pass, path, file){
var d = new Deferred();
var data = "";
var port = 21;
var socket = SocketService.createTransport(null, 0, host, port, FTPUpload.getProxyInfo());
var ostream = socket.openOutputStream(0, 1024*1024, 1);
var istream = socket.openInputStream(0, 1024*1024, 1);
var bstream = new BinaryInputStream(istream);
var pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(Ci.nsIInputStreamPump);
pump.init(istream, -1, -1, 0, 0, false);
var callback = function(){ setTimeout(function(){d.callback()}, 0) };
var start = false;
var code = 220;
pump.asyncRead({
onStartRequest: function(request, context){ },
onStopRequest: function(request, context, status){
bstream.close();
istream.close();
ostream.close();
pump = null;
},
onDataAvailable: function(request, context, input, offset, count){
data = bstream.readBytes(count);
var l = data.match(/(\d+)/)[1];
//log(data, code, l);
if(code && code == l && callback) callback(data);
}
}, null);
function write(command, _os, stat){
var self = this;
var os = (_os)? _os : ostream;
function _write() {
try {
//get count
var count = os.write(command, command.length);
//Async Write
if(count < command.length){
command = command.substr(count);
os.QueryInterface(Ci.nsIAsyncOutputStream);
os.asyncWait(
{ onOutputStreamReady: _write }, 0, 0, null);
} else{
//finish
if(stat){
if(typeof stat == 'function'){
setTimeout(stat, 0);
} else {
code = stat;
}
}
os.write("\r\n", 2);
}
}
catch(e) { }
}
_write();
}
// USER + PASS
function login(user, pass){
var _d = new Deferred();
callback = function(){
callback = null;
callback = function(){
callback = null;
setTimeout(function(){_d.callback()}, 0);
}
write('PASS '+pass, null, 230);
}
write('USER '+user, null, 331);
return _d;
}
// CWD
function cd(path){
var _d = new Deferred();
callback = function(){
callback = null;
setTimeout(function(){_d.callback()}, 0);
}
write('CWD '+path, null, 250);
return _d;
}
function type(t){
var _d = new Deferred();
callback = function(){
callback = null;
setTimeout(function(){_d.callback()}, 0);
}
write('TYPE '+t, null, 200);
return _d;
}
function quit(){
var _d = new Deferred();
callback = function(){
callback = null;
setTimeout(function(){_d.callback()}, 0);
}
write('QUIT', null, 221);
return _d;
}
// PASV + LIST
function list(res){
var _d = new Deferred();
callback = function(){
callback = null;
var ary = data.match(/(\d+,\d+,\d+,\d+),(\d+),(\d+)/);
if(!ary) throw "FTP: PASV Error";
var ip = ary[1].replace(/,/g, '.');
var port = (ary[2]*256-0)+(ary[3]-0);
var temp = "";
var data_socket = SocketService.createTransport(null, 0, ip, port, FTPUpload.getProxyInfo());
var data_ostream = data_socket.openOutputStream(0, 1024*1024, 1);
var data_istream = data_socket.openInputStream(0, 1024*1024, 1);
var data_bstream = new BinaryInputStream(data_istream);
var data_pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(Ci.nsIInputStreamPump);
data_pump.init(data_istream, -1, -1, 0, 0, false);
var listener = {
onStartRequest: function(request, context){
},
onStopRequest: function(request, context, status){
try{
data_bstream.close();
data_istream.close();
data_ostream.close();
data_pump = null;
callback = function(){
setTimeout(function(){_d.callback(temp)}, 0);
}
} catch(e) { }
},
onDataAvailable: function(request, context, input, offset, count){
try{
temp += data_bstream.readBytes(count)
} catch(e) { }
}
};
data_pump.asyncRead(listener, null);
//write('LIST');
write('NLST', null, 226);
}
write('PASV', null, 227);
return _d;
}
// PASV + STOR
function put(file){
var _d = new Deferred();
callback = function(){
callback = null;
var ary = data.match(/(\d+,\d+,\d+,\d+),(\d+),(\d+)/);
if(!ary) throw "FTP: PASV Error";
var ip = ary[1].replace(/,/g, '.');
var port = (ary[2]*256-0)+(ary[3]-0);
var flag = false;
var data_socket = SocketService.createTransport(null, 0, ip, port, FTPUpload.getProxyInfo());
var data_ostream = data_socket.openOutputStream(0, 1024*1024, 1);
var fistream = new FileInputStream(file, -1, -1, false);
var fbstream = new BinaryInputStream(fistream);
var read_data = fbstream.readBytes(fbstream.available());
callback = function(){
callback = function(){
callback = null;
setTimeout(function(){ _d.callback() }, 0);
}
data_ostream.QueryInterface(Ci.nsIAsyncOutputStream);
data_ostream.asyncWait({ onOutputStreamReady: function(){
write(read_data, data_ostream, function(){
code = 226;
data_ostream.close();
});
} }, 0, 0, null);
}
write('STOR '+file.leafName, null, 150);
}
write('PASV', null, 227);
return _d;
}
return d.addCallback(function(){
return login(user, pass);
}).addCallback(function(){
return cd(path);
}).addCallback(function(){
return type('A').addCallback(function(){
return list();
});
}).addCallback(function(res){
FTPUpload.clearCollisionOnFTP(res, file);
return type('I').addCallback(function(){
return put(file);
});
}).addCallback(function(){
return quit();
});
}
FTPUpload.getProxyInfo = function() {
if(getPrefValue("network.proxy.type") == 1){
var proxyHost = getPrefValue("network.proxy.socks");
var proxyPort = getPrefValue("network.proxy.socks_port");
if(proxyHost && proxyPort){
return ProxyService.newProxyInfo("socks", proxyHost, proxyPort, 0, 30, null);
}
}
}
FTPUpload.getHostName = function() {
return DNSService.myHostName;
}
FTPUpload.getHostIP = function(){
return DNSService.resolve(FTPUpload.getHostName(), 1).getNextAddrAsString();
}
FTPUpload.clearCollisionOnFTP = function(res, file){
var lines = res.split(/\r\n|\r|\n/).map(function(line){
return line.replace(/^\s*/, '').replace(/\s*$/, '');
});
var name = file.leafName;
for(var count = 2; ~lines.indexOf(name); count++)
name = name.replace(/(.*)\./, '$1('+count+').');
file.leafName = name;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment