Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
})
// There's a bit of a pickle here. Whilst asking the user where to save
// they may have omitted the file extension. At the same time they may chosen
// a filename that is already taken. We don't have any in-built ui to handle
// this so the least destructive way is to find a filename that is not
// in use and just save to there. In any case if the user picks a path and
// that file does already exist we should remove it
if (pickedSavePath) {
// Remove existing file - save dialog prompts before allowing user to choose pre-existing name
try { fs.removeSync(pickedSavePath) } catch (ex) { /* no-op */ }
// User didn't add file extension
if (!path.extname(pickedSavePath)) {
pickedSavePath += path.extname(item.getFilename())
pickedSavePath = unusedFilename.sync(pickedSavePath)
}
savePath = pickedSavePath
}
}
// Check we still want to save
if (!savePath) {
item.cancel()
return
}
// Set the save - will prevent dialog showing up
const downloadPath = unusedFilename.sync(savePath + '.wmaildownload') // just-in-case
item.setSavePath(downloadPath)
// Report the progress to the window to display it
.then((pickedSavePath) => {
// This means we finished the download before we could pick the save path.
// Artificually fire the finish event
const didFinishBeforePicked = item.isFinished()
downloadPath = unusedFilename.sync(pickedSavePath)
this[privUser].lastPath = path.dirname(downloadPath)
item.setSavePath(downloadPath)
if (didFinishBeforePicked) {
if (item.finishedState() === 'completed') {
this._handleUserDownloadFinished(item.downloadId, item, downloadPath)
} else {
this._handleUserDownloadFailed(item.downloadId, item, downloadPath)
}
}
})
.catch((ex) => { /* no-op */ })
this._handleUserDownloadFinished(item.downloadId, item, downloadPath)
} else {
this._handleUserDownloadFailed(item.downloadId, item, downloadPath)
}
}
})
.catch((ex) => { /* no-op */ })
} else {
// Find out where to save the file
let savePath
if (!settingsState.os.alwaysAskDownloadLocation && settingsState.os.defaultDownloadLocation) {
const folderLocation = settingsState.os.defaultDownloadLocation
// Check the containing folder exists
fs.ensureDirSync(folderLocation)
savePath = unusedFilename.sync(path.join(folderLocation, item.getFilename()))
} else {
const lastPath = this[privUser].lastPath
const parentWindow = BrowserWindow.fromWebContents(wc.hostWebContents ? wc.hostWebContents : wc)
let pickedSavePath = dialog.showSaveDialog(parentWindow, {
title: 'Download',
defaultPath: path.join(lastPath || app.getPath('downloads'), item.getFilename())
})
// There's a bit of a pickle here. Whilst asking the user where to save
// they may have omitted the file extension. At the same time they may chosen
// a filename that is already taken. We don't have any in-built ui to handle
// this so the least destructive way is to find a filename that is not
// in use and just save to there. In any case if the user picks a path and
// that file does already exist we should remove it
if (pickedSavePath) {
// Remove existing file - save dialog prompts before allowing user to choose pre-existing name
if (!path.extname(pickedSavePath)) {
pickedSavePath += path.extname(item.getFilename())
pickedSavePath = unusedFilename.sync(pickedSavePath)
}
savePath = pickedSavePath
}
}
// Check we still want to save
if (!savePath) {
item.cancel()
return
}
// Set the save - will prevent dialog showing up
const downloadPath = unusedFilename.sync(savePath + '.wmaildownload') // just-in-case
item.setSavePath(downloadPath)
// Report the progress to the window to display it
const totalBytes = item.getTotalBytes()
const id = uuid.v4()
item.on('updated', () => {
this.updateDownloadProgress(id, item.getReceivedBytes(), totalBytes)
})
item.on('done', (e, state) => {
if (state === 'completed') {
// Download item will get destroyed before move callback completes. If
// you need any info from it grab it before calling fs.move
fs.move(downloadPath, savePath, () => {
this.downloadFinished(id)
const saveName = path.basename(savePath)
this.mailboxWindow.downloadCompleted(savePath, saveName)
// Store a reference to res
this._response = res;
let fileName = this._response.headers["content-disposition"];
// Extract filename from header. Assumption is that the
// header is exactly as returned by the http service.
// Might throw errors for other headers
fileName = fileName.replace(`inline; filename="`, "");
// Remove trailing double quote
fileName = fileName.slice(0, fileName.length - 1);
// Get full file path
let filePath = Path.join(this.directory, fileName);
// Get unused filename
UnusedFileName(filePath)
.then(unusedpath => {
// Assign the file name to instance
this._filepath = unusedpath;
})
.then(() => {
// No point wrapping this in promise. Communication with
// outside world occurs through events
// Extract file size from header
this._size = parseInt(
this._response.headers["content-length"],
10
);
// Keep track of bytes downloaded
this._bytesDownloaded = 0;
if (/^#!?\/?$/.test(hash)) {
hash = '';
}
stream.filename = filename({
crop: options.crop ? '-cropped' : '',
date: easydate('Y-M-d'),
time: easydate('h-m-s'),
size,
width: sizes[0],
height: sizes[1],
url: filenamifyUrl(uri) + filenamify(hash)
});
if (options.incrementalName) {
stream.filename = unusedFilename.sync(stream.filename);
}
return stream;
}
let hostWebContents = webContents;
if (webContents.getType() === 'webview') {
({hostWebContents} = webContents);
}
const win = BrowserWindow.fromWebContents(hostWebContents);
const dir = options.directory || app.getPath('downloads');
let filePath;
if (options.filename) {
filePath = path.join(dir, options.filename);
} else {
const filename = item.getFilename();
const name = path.extname(filename) ? filename : getFilenameFromMime(filename, item.getMimeType());
filePath = unusedFilename.sync(path.join(dir, name));
}
const errorMessage = options.errorMessage || 'The download of {filename} was interrupted';
const errorTitle = options.errorTitle || 'Download Error';
if (!options.saveAs) {
item.setSavePath(filePath);
}
if (typeof options.onStarted === 'function') {
options.onStarted(item);
}
item.on('updated', () => {
receivedBytes = [...downloadItems].reduce((receivedBytes, item) => {
receivedBytes += item.getReceivedBytes();
let hostWebContents = webContents;
if (webContents.getType() === 'webview') {
hostWebContents = webContents.hostWebContents;
}
const win = electron.BrowserWindow.fromWebContents(hostWebContents);
const dir = opts.directory || app.getPath('downloads');
let filePath;
if (opts.filename) {
filePath = path.join(dir, opts.filename);
} else {
const filename = item.getFilename();
const name = path.extname(filename) ? filename : getFilenameFromMime(filename, item.getMimeType());
filePath = unusedFilename.sync(path.join(dir, name));
}
const errorMessage = opts.errorMessage || 'The download of {filename} was interrupted';
const errorTitle = opts.errorTitle || 'Download Error';
if (!opts.saveAs) {
item.setSavePath(filePath);
}
item.on('updated', () => {
receivedBytes = [...downloadItems].reduce((receivedBytes, item) => {
receivedBytes += item.getReceivedBytes();
return receivedBytes;
}, completedBytes);
if (['darwin', 'linux'].includes(process.platform)) {
const shouldShowMessage = openFolderWhenDone;
try {
const directory = await defineDownloadDirectory({
downloadType,
metadataKey
});
const filePath = path.join(directory, filename);
if (checkIfExists(filePath)) {
if (downloadType === 'inline') return filePath;
const previousFileSize = getFilesizeInBytes(filePath);
if (previousFileSize === filesize) {
shell.showItemInFolder(filePath);
return;
}
filename = path.basename(unusedFilename.sync(filePath));
}
const downloadedItem = await download(
BrowserWindow.getFocusedWindow(),
url,
{
directory,
filename,
openFolderWhenDone
}
);
return downloadedItem.getSavePath();
} catch (e) {
if (shouldShowMessage)
mailboxWindow.send('display-message-error-download');
}
}