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)
{
var types = event.dataTransfer.types;
var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/x-moz-url", "text/plain"];
var dt = event.dataTransfer
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));
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();
switch (types[0])
{
case "text/plain":
var plainText = dt.getData(types[0]);
sendtophoneCore.send("Selection", "http://google.com", plainText);
break;
case "text/uri-list":
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, "");
break;
case "application/x-moz-file":
var file = event.dataTransfer.mozGetDataAt("application/x-moz-file", 0);
if (file instanceof Components.interfaces.nsIFile && file.isFile() )
{
var url = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
case "text/uri-list":
var mozUrl = dt.getData(types[0]);
sendtophoneCore.send("", mozUrl, "");
break;
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"));
}
break;
}
}
sendtophone.sendFile = function()
sendtophone.pickFile = function(folder)
{
var fp = Cc["@mozilla.org/filepicker;1"]
.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);
var rv = fp.show();
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();">
<menuitem label="&sendtophoneContextSendFile.label;"
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;">
<menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)">
<menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/>

View File

@@ -12,5 +12,7 @@
<!ENTITY sendtophoneContextLogout.accesskey "L">
<!ENTITY sendtophoneOptions.title "Send to Phone Preferences">
<!ENTITY sendtophoneProtocols.label "Protocols">
<!ENTITY sendtophoneContextSendFile.label "Send file...">
<!ENTITY sendtophoneContextSendFile.label "Send files...">
<!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
telLink=Telephone Number
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 sendtophoneOptions.title "Opciones de Send to Phone">
<!ENTITY sendtophoneProtocols.label "Protocolos">
<!ENTITY sendtophoneContextSendFile.label "Enviar fichero...">
<!ENTITY sendtophoneContextSendFile.label "Enviar ficheros...">
<!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
telLink=Número de teléfono
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)
{
if (!this.req)
this.req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
var req = this.req;
req.open(method, url, true);
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
@@ -155,7 +152,12 @@ var sendtophoneCore = {
// Local files: upload them to a web server
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;
}
@@ -281,16 +283,28 @@ var sendtophoneCore = {
return data + converter.Finish();
},
sendFile: function(fileURL)
sendFile: function( nsFile, callback )
{
var nsFile = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler)
.getFileFromURLSpec(fileURL);
if (!this.prefs)
this.init();
if (nsFile.isDirectory())
{
// 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())
{
this.alert(this.getString("InvalidFile"));
return;
}
var uploadName = nsFile.leafName;
// Try to determine the MIME type of the file
@@ -350,12 +364,16 @@ var sendtophoneCore = {
if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
{
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.
sendtophoneCore.alert(event.target.responseText);
sendtophoneCore.alert(uri + "\r\n" + event.target.responseText);
}
/*
if required for cookies... don't think so.
try {
req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
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 + "/");
}
}