Send folder as a zip. Handle multiple files.

This commit is contained in:
amla70
2010-08-05 21:00:08 +00:00
parent 453d368c47
commit e6f84dba5d
7 changed files with 151 additions and 42 deletions

View File

@@ -108,51 +108,67 @@ sendtophone.checkDrag = function(event)
sendtophone.doDrop = function(event) sendtophone.doDrop = function(event)
{ {
var types = event.dataTransfer.types; var dt = event.dataTransfer
var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/x-moz-url", "text/plain"]; var types = dt.types;
var supportedTypes = ["application/x-moz-file", "text/x-moz-url", "text/uri-list", "text/plain"];
types = supportedTypes.filter(function (value) types.contains(value)); types = supportedTypes.filter(function (value) types.contains(value));
if (types.length)
var plainText = event.dataTransfer.getData(types[0]);
var mozUrlArray = event.dataTransfer.getData(types[1]).split("\n");
var mozUrl = mozUrlArray[0];
var mozTitle = mozUrlArray[1];
event.preventDefault(); event.preventDefault();
switch (types[0]) switch (types[0])
{ {
case "text/plain": case "text/plain":
var plainText = dt.getData(types[0]);
sendtophoneCore.send("Selection", "http://google.com", plainText); sendtophoneCore.send("Selection", "http://google.com", plainText);
break; break;
case "text/uri-list":
case "text/x-moz-url": case "text/x-moz-url":
var mozUrlArray = dt.getData(types[1]).split("\n");
var mozUrl = mozUrlArray[0];
var mozTitle = mozUrlArray[1] || '';
sendtophoneCore.send(mozTitle, mozUrl, ""); sendtophoneCore.send(mozTitle, mozUrl, "");
break; break;
case "application/x-moz-file": case "text/uri-list":
var file = event.dataTransfer.mozGetDataAt("application/x-moz-file", 0); var mozUrl = dt.getData(types[0]);
if (file instanceof Components.interfaces.nsIFile && file.isFile() ) sendtophoneCore.send("", mozUrl, "");
{ break;
var url = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
sendtophoneCore.send("", url, ""); case "application/x-moz-file":
for (var i = 0; i < dt.mozItemCount; i++)
{
var file = dt.mozGetDataAt("application/x-moz-file", i);
if (file instanceof Components.interfaces.nsIFile )
{
sendtophoneCore.sendFile(file);
}
else
this.alert(this.strings.getString("InvalidFile"));
} }
else break;
this.alert(this.strings.getString("InvalidFile"));
} }
} }
sendtophone.sendFile = function() sendtophone.pickFile = function(folder)
{ {
var fp = Cc["@mozilla.org/filepicker;1"] var fp = Cc["@mozilla.org/filepicker;1"]
.createInstance(Ci.nsIFilePicker); .createInstance(Ci.nsIFilePicker);
fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpen); if (folder)
fp.init(window, this.strings.getString("SendFolderToPhone"), Ci.nsIFilePicker.modeGetFolder);
else
fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpenMultiple);
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages); fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages);
var rv = fp.show(); var rv = fp.show();
if (rv == Ci.nsIFilePicker.returnOK) if (rv == Ci.nsIFilePicker.returnOK)
sendtophoneCore.send('', fp.fileURL.spec, ''); {
var files = fp.files;
while (files.hasMoreElements())
{
var file = files.getNext().QueryInterface(Ci.nsILocalFile);
sendtophoneCore.sendFile( file );
}
}
} }

View File

@@ -13,7 +13,10 @@
<popup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();"> <popup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();">
<menuitem label="&sendtophoneContextSendFile.label;" <menuitem label="&sendtophoneContextSendFile.label;"
accesskey="&sendtophoneContextSendFile.accesskey;" accesskey="&sendtophoneContextSendFile.accesskey;"
oncommand="sendtophone.sendFile()" id="sendtophoneContextMenuSendFile"/> oncommand="sendtophone.pickFile(false)" id="sendtophoneContextMenuSendFile"/>
<menuitem label="&sendtophoneContextSendFolder.label;"
accesskey="&sendtophoneContextSendFolder.accesskey;"
oncommand="sendtophone.pickFile(true)" id="sendtophoneContextMenuSendFolder"/>
<menu label="&sendtophoneProtocols.label;"> <menu label="&sendtophoneProtocols.label;">
<menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)"> <menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)">
<menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/> <menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/>

View File

@@ -12,5 +12,7 @@
<!ENTITY sendtophoneContextLogout.accesskey "L"> <!ENTITY sendtophoneContextLogout.accesskey "L">
<!ENTITY sendtophoneOptions.title "Send to Phone Preferences"> <!ENTITY sendtophoneOptions.title "Send to Phone Preferences">
<!ENTITY sendtophoneProtocols.label "Protocols"> <!ENTITY sendtophoneProtocols.label "Protocols">
<!ENTITY sendtophoneContextSendFile.label "Send file..."> <!ENTITY sendtophoneContextSendFile.label "Send files...">
<!ENTITY sendtophoneContextSendFile.accesskey "S"> <!ENTITY sendtophoneContextSendFile.accesskey "S">
<!ENTITY sendtophoneContextSendFolder.label "Send folder...">
<!ENTITY sendtophoneContextSendFolder.accesskey "F">

View File

@@ -14,4 +14,5 @@ mmsLink=MMS Number
mmstoLink=MMS Number mmstoLink=MMS Number
telLink=Telephone Number telLink=Telephone Number
InvalidFile=Not a valid file InvalidFile=Not a valid file
SendFileToPhone=Send a file to your phone SendFileToPhone=Send files to your phone.
SendFolderToPhone=Send a folder to your phone.

View File

@@ -12,5 +12,7 @@
<!ENTITY sendtophoneContextLogout.accesskey "L"> <!ENTITY sendtophoneContextLogout.accesskey "L">
<!ENTITY sendtophoneOptions.title "Opciones de Send to Phone"> <!ENTITY sendtophoneOptions.title "Opciones de Send to Phone">
<!ENTITY sendtophoneProtocols.label "Protocolos"> <!ENTITY sendtophoneProtocols.label "Protocolos">
<!ENTITY sendtophoneContextSendFile.label "Enviar fichero..."> <!ENTITY sendtophoneContextSendFile.label "Enviar ficheros...">
<!ENTITY sendtophoneContextSendFile.accesskey "E"> <!ENTITY sendtophoneContextSendFile.accesskey "E">
<!ENTITY sendtophoneContextSendFolder.label "Enviar carpeta...">
<!ENTITY sendtophoneContextSendFolder.accesskey "C">

View File

@@ -14,4 +14,5 @@ mmsLink=Número MMS
mmstoLink=Número MMS mmstoLink=Número MMS
telLink=Número de teléfono telLink=Número de teléfono
InvalidFile=Solo se puede enviar un fichero cada vez. InvalidFile=Solo se puede enviar un fichero cada vez.
SendFileToPhone=Envía un fichero al teléfono. SendFileToPhone=Envía ficheros al teléfono.
SendFolderToPhone=Envía una carpeta al teléfono.

View File

@@ -87,12 +87,9 @@ var sendtophoneCore = {
processXHR: function(url, method, data, callback) processXHR: function(url, method, data, callback)
{ {
if (!this.req) var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
this.req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest); .createInstance(Ci.nsIXMLHttpRequest);
var req = this.req;
req.open(method, url, true); req.open(method, url, true);
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
@@ -155,7 +152,12 @@ var sendtophoneCore = {
// Local files: upload them to a web server // Local files: upload them to a web server
if ((/^file:/i).test(url)) if ((/^file:/i).test(url))
{ {
this.sendFile(url); var nsFile = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler)
.getFileFromURLSpec(url);
this.sendFile(nsFile);
return; return;
} }
@@ -281,16 +283,28 @@ var sendtophoneCore = {
return data + converter.Finish(); return data + converter.Finish();
}, },
sendFile: function(fileURL) sendFile: function( nsFile, callback )
{ {
var nsFile = Cc["@mozilla.org/network/io-service;1"] if (!this.prefs)
.getService(Ci.nsIIOService) this.init();
.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler) if (nsFile.isDirectory())
.getFileFromURLSpec(fileURL); {
// Compress the contents to a zip file
zipFolder(nsFile, function(nsZip)
{
// Send the zip and delete it afterwards
sendtophoneCore.sendFile(nsZip, function() {/* nsZip.remove(false)*/ });
}
)
return;
}
if (!nsFile.isFile()) if (!nsFile.isFile())
{
this.alert(this.getString("InvalidFile"));
return; return;
}
var uploadName = nsFile.leafName; var uploadName = nsFile.leafName;
// Try to determine the MIME type of the file // Try to determine the MIME type of the file
@@ -350,12 +364,16 @@ var sendtophoneCore = {
if (body && (uploads = body.documentElement.getElementsByTagName("upload"))) if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
{ {
sendtophoneCore.send(uploadName, uploads[0].firstChild.data, ""); sendtophoneCore.send(uploadName, uploads[0].firstChild.data, "");
return // If there's a callback (to delete temporary files) we call it now
if (callback)
callback();
return;
} }
// error. // error.
sendtophoneCore.alert(event.target.responseText); sendtophoneCore.alert(uri + "\r\n" + event.target.responseText);
} }
/* /*
if required for cookies... don't think so.
try { try {
req.channel.QueryInterface(Ci.nsIHttpChannelInternal). req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
forceAllowThirdPartyCookie = true; forceAllowThirdPartyCookie = true;
@@ -367,3 +385,69 @@ var sendtophoneCore = {
}; };
/* Zipping functions */
const PR_RDONLY = 0x01;
const PR_WRONLY = 0x02;
const PR_RDWR = 0x04;
const PR_CREATE_FILE = 0x08;
const PR_APPEND = 0x10;
const PR_TRUNCATE = 0x20;
const PR_SYNC = 0x40;
const PR_EXCL = 0x80;
/**
* folder is a nsFile pointing to a folder
* callback is a function that it's called after the zip is created. It has one parameter: the nsFile created
*/
function zipFolder(folder, callback)
{
// get TMP directory
var nsFile = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("TmpD", Ci.nsIFile);
// Create a new file
nsFile.append( folder.leafName + ".zip");
nsFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
var zipWriter = Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
var zipW = new zipWriter();
zipW.open(nsFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
addFolderContentsToZip(zipW, folder, "");
// We don't want to block the main thread, so the zipping is done asynchronously
// and here we get the notification that it has finished
var observer = {
onStartRequest: function(request, context) {},
onStopRequest: function(request, context, status)
{
zipW.close();
// Notify that we're done. Now it must be sent and deleted afterwards
callback(nsFile);
}
}
zipW.processQueue(observer, null);
}
/**
* function to add the contents of a folder recursively
* zipW a nsIZipWriter object
* folder a nsFile object pointing to a folder
* root a string defining the relative path for this folder in the zip
*/
function addFolderContentsToZip(zipW, folder, root)
{
var entries = folder.directoryEntries;
while(entries.hasMoreElements())
{
var entry = entries.getNext();
entry.QueryInterface(Ci.nsIFile);
zipW.addEntryFile(root + entry.leafName, Ci.nsIZipWriter.COMPRESSION_DEFAULT, entry, true);
if (entry.isDirectory())
addFolderContentsToZip(zipW, entry, root + entry.leafName + "/");
}
}