Compare commits

...

3 Commits

3 changed files with 90 additions and 76 deletions

View File

@ -16,9 +16,13 @@ samoware-multisave must be reloaded every time Firefox is started.
# Usage
The extension button appears only when browsing a specific domain, and only when a single email is displayed. The extension will download all attachments into the same directory and prefix their filenames with the current date.
The extension button appears only when browsing a specific domain (*TODO: and only when a single email is displayed*). The extension will help you download all email attachments to a single directory. Also, it will automatically suggest filenames that are prefixed with the current date.
Click the button to open a file dialog. Here you can choose the directory you want all attachments to be downloaded into. Click OK. That's it.
When you click the button, a "Save as …" dialog appears for the first file attached to the email (if there are no attachments, nothing happens). The suggested filename is the original filename prefixed with the current date (`yyyymmdd`, single space, original filename). Choose the directory where you want to save the file and click "Save" to start the download.
After the download has started", a new "Save as …" dialog appears for each remaining attachment (if the email has only one attachment, nothing happens). Each dialog will start in the directory you picked for your first file, and each suggested filename will be prefixed in the same way. Assuming that you want to save all attached files to the same directory, all you need to do is click "Save" for each dialog.
That's it.
## Known bugs

View File

@ -1,33 +1,85 @@
console.log("background.js starts now");
console.log("background.js started");
var baseUrl = "";
function getCurrentDate() {
let today = new Date();
let yyyy = today.getFullYear();
let mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
let dd = String(today.getDate()).padStart(2, '0');
return yyyy + mm + dd;
}
function onSuccess(result) {
console.log(`background.js: onSuccess(): Promise resolved with result '${JSON.stringify(result)}'`);
}
function onFailure(error) {
console.log(`background.js: onFailure(): Promise rejected with error '${error}'`);
}
async function downloadFile(url, filename, saveAs=false) {
console.log(`background.js: downloadFile(): url is '${url}' and filename is '${filename}'`);
return browser.downloads.download({
url: new URL(url, baseUrl).toString(),
filename: filename,
saveAs: saveAs // raise a path chooser dialog if true
});
}
async function downloadAllFiles(urlsAndFilenames) {
console.log(`background.js: downloadAllFiles(): started with ${JSON.stringify(urlsAndFilenames)}`);
const currentDate = getCurrentDate();
for (let i = 0; i < urlsAndFilenames.length; i++) {
// prefix filename
let prefixedFilename = currentDate + " " + urlsAndFilenames[i].filename;
console.log(`background.js: downloadAllFiles(): i is ${i}`);
if ( i == 0 ) {
await downloadFile(urlsAndFilenames[i].url, prefixedFilename, true).then(onSuccess, onFailure);
} else {
downloadFile(urlsAndFilenames[i].url, prefixedFilename, true).then(onSuccess, onFailure);
}
}
}
function handlePageactionClick(tab, onClickData) {
console.log("background.js: executing content script");
let executing = browser.scripting.executeScript({
console.log("background.js: handlePageactionClick(): executing content script");
// get base url
browser.tabs.query(
{
currentWindow: true,
active: true
}
)
.then(
tabs => {
console.log(`background.js: handlePageactionClick(): tab query returned ${JSON.stringify(tabs)}`);
baseUrl = tabs[0].url;
}
)
// execute content script
browser.scripting.executeScript(
{
files: [ "/contentscript.js" ],
target: {
target:
{
tabId: tab.id,
allFrames: false
}
});
executing.then(onExecuted, onExecutionError);
}
)
.then(results => {
console.log(`background.js: handlePageactionClick(): content script execution successful with results '${JSON.stringify(results)}'`);
results.forEach(r => downloadAllFiles(r.result));
})
.catch(error =>
console.error(`background.js: handlePageactionClick(): The following error occured while executing a content script: ${error}`)
)
}
function onExecuted(result) {
console.log(`background.js: content script execution successful with result: ${JSON.stringify(result)}`);
}
function onExecutionError(error) {
console.error(`background.js: The following error occured while executing a content script: ${error}`);
}
let gettingAllPermissions = browser.permissions.getAll();
gettingAllPermissions.then((allPermissions) => {
console.log(JSON.stringify(allPermissions))
});
// add listener for the extension button
browser.pageAction.onClicked.addListener(handlePageactionClick);

View File

@ -1,25 +1,15 @@
console.log("contentscript.js started!");
function getCurrentDate() {
let today = new Date();
let yyyy = today.getFullYear();
let mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
let dd = String(today.getDate()).padStart(2, '0');
return yyyy + "-" + mm + "-" + dd;
}
function extractFileUrlsAndNames() {
console.log("contentscript.js: this is extractFileUrlsAndNames()");
function extractUrlsAndFilenames() {
console.log("contentscript.js: this is extractFileUrlsAndNames()");
// get the correct frame
let frame = document.querySelector("iframe.js-mail-content");
// get all divs containing attachments
let divs = frame.contentWindow.document.body.querySelectorAll("div.samoware-mail-message__attach__item[attachment-ref]");
console.log(`contentscript.js: found ${divs.length} div containing attachments`);
let urlsAndFilenames = []
// loop over divs and extract attachment information
let urlsAndFilenames = []
divs.forEach(div => {
let url = div.getAttribute("attachment-ref");
let filename = div.getAttribute("file-name");
@ -31,41 +21,9 @@ console.log("contentscript.js: this is extractFileUrlsAndNames()");
}
urlsAndFilenames.push({url: url, filename: filename});
})
//console.log(`contentscript.js: urlsAndFilenames is ${JSON.stringify(urlsAndFilenames)}`);
return urlsAndFilenames;
}
function onStartedDownload(id) {
console.log(`contentscript.js: Started downloading: ${id}`);
}
function onFailedToStartDownload(error) {
console.log(`contentscript.js: Download failed: ${error}`);
}
// get today's date
let currentDate = getCurrentDate();
console.log(`contentscript.js: currentDate is ${currentDate}`);
let urlsAndFilenames = extractFileUrlsAndNames();
// loop over attachments
for (let i = 0; i < urlsAndFilenames.length; i++) {
// prefix filename
let prefixedFilename = currentDate + " - " + urlsAndFilenames[i].filename;
console.log(`contentscript.js: prefixedFilename is ${prefixedFilename}`);
// start download
let downloading = browser.downloads.download({
url: urlsAndFilenames[i].url,
filename: prefixedFilename,
saveAs: i == 0 // raise a path chooser dialog for the first file only; all later files will (hopefully!) be saved to the same folder
});
console.log(`contentscript.js: downloading is ${downloading}`);
// resolve Promise
downloading.then(onStartedDownload, onFailedToStartDownload);
}
console.log("contentscript.js: has finished");
"contentscript.js: this is the final line";
const urlsAndFilenames = extractUrlsAndFilenames();
console.log(`contentscript.js: done; found ${JSON.stringify(urlsAndFilenames)}`);
urlsAndFilenames;