parent
09b2b4be10
commit
9925dec0f4
@ -57,7 +57,7 @@ type Header = {name: string; value: string};
|
||||
|
||||
export interface DownloadOptions {
|
||||
conflictAction: string;
|
||||
filename: string;
|
||||
filename?: string;
|
||||
saveAs: boolean;
|
||||
url: string;
|
||||
method?: string;
|
||||
@ -85,6 +85,7 @@ interface Downloads {
|
||||
onCreated: ExtensionListener;
|
||||
onChanged: ExtensionListener;
|
||||
onErased: ExtensionListener;
|
||||
onDeterminingFilename?: ExtensionListener;
|
||||
}
|
||||
|
||||
interface WebRequest {
|
||||
|
@ -22,7 +22,8 @@ import {
|
||||
RUNNING,
|
||||
RETRYING
|
||||
} from "./state";
|
||||
import { Preroller } from "./preroller";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { Preroller, PrerollResults } from "./preroller";
|
||||
|
||||
function isRecoverable(error: string) {
|
||||
switch (error) {
|
||||
@ -130,11 +131,13 @@ export class Download extends BaseDownload {
|
||||
}
|
||||
const options: DownloadOptions = {
|
||||
conflictAction: await Prefs.get("conflict-action"),
|
||||
filename: this.dest.full,
|
||||
saveAs: false,
|
||||
url: this.url,
|
||||
headers: [],
|
||||
};
|
||||
if (!CHROME) {
|
||||
options.filename = this.dest.full;
|
||||
}
|
||||
if (!CHROME && this.private) {
|
||||
options.incognito = true;
|
||||
}
|
||||
@ -194,15 +197,7 @@ export class Download extends BaseDownload {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
if (res.mime) {
|
||||
this.mime = res.mime;
|
||||
}
|
||||
if (res.name) {
|
||||
this.serverName = res.name;
|
||||
}
|
||||
if (res.error) {
|
||||
this.cancelAccordingToError(res.error);
|
||||
}
|
||||
this.adoptPrerollResults(res);
|
||||
}
|
||||
catch (ex) {
|
||||
console.error("Failed to preroll", this, ex.toString(), ex.stack, ex);
|
||||
@ -215,6 +210,18 @@ export class Download extends BaseDownload {
|
||||
}
|
||||
}
|
||||
|
||||
adoptPrerollResults(res: PrerollResults) {
|
||||
if (res.mime) {
|
||||
this.mime = res.mime;
|
||||
}
|
||||
if (res.name) {
|
||||
this.serverName = res.name;
|
||||
}
|
||||
if (res.error) {
|
||||
this.cancelAccordingToError(res.error);
|
||||
}
|
||||
}
|
||||
|
||||
resume(forced = false) {
|
||||
if (!(FORCABLE & this.state)) {
|
||||
return;
|
||||
@ -391,4 +398,27 @@ export class Download extends BaseDownload {
|
||||
this.setMissing();
|
||||
}
|
||||
}
|
||||
|
||||
updatefromSuggestion(state: any) {
|
||||
const res: PrerollResults = {};
|
||||
if (state.mime) {
|
||||
res.mime = state.mime;
|
||||
}
|
||||
if (state.filename) {
|
||||
res.name = state.filename;
|
||||
}
|
||||
if (state.finalUrl) {
|
||||
res.finalURL = state.finalUrl;
|
||||
const detected = Preroller.maybeFindNameFromSearchParams(this, res);
|
||||
if (detected) {
|
||||
res.name = detected;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.adoptPrerollResults(res);
|
||||
}
|
||||
finally {
|
||||
this.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,10 @@ export class Manager extends EventEmitter {
|
||||
|
||||
downloads.onChanged.addListener(this.onChanged.bind(this));
|
||||
downloads.onErased.addListener(this.onErased.bind(this));
|
||||
if (CHROME && downloads.onDeterminingFilename) {
|
||||
downloads.onDeterminingFilename.addListener(
|
||||
this.onDeterminingFilename.bind(this));
|
||||
}
|
||||
|
||||
Bus.onPort("manager", (port: Port) => {
|
||||
const mport = new ManagerPort(this, port);
|
||||
@ -157,6 +161,20 @@ export class Manager extends EventEmitter {
|
||||
this.manIds.delete(downloadId);
|
||||
}
|
||||
|
||||
onDeterminingFilename(state: any, suggest: Function) {
|
||||
const download = this.manIds.get(state.id);
|
||||
if (!download) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
download.updatefromSuggestion(state);
|
||||
}
|
||||
finally {
|
||||
const suggestion = {filename: download.dest.full};
|
||||
suggest(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
async resetScheduler() {
|
||||
this.scheduler = null;
|
||||
await this.startNext();
|
||||
|
@ -54,6 +54,9 @@ export class Preroller {
|
||||
}
|
||||
|
||||
get shouldPreroll() {
|
||||
if (CHROME) {
|
||||
return false;
|
||||
}
|
||||
const {uURL, renamer} = this.download;
|
||||
const {pathname, search, host} = uURL;
|
||||
if (PREROLL_NOPE.has(host)) {
|
||||
@ -167,39 +170,15 @@ export class Preroller {
|
||||
rv.mime = type.essence;
|
||||
}
|
||||
|
||||
const {p_ext: ext} = this.download.renamer;
|
||||
const dispHeader = headers.get("content-disposition");
|
||||
if (dispHeader) {
|
||||
const file = CDPARSER.parse(dispHeader);
|
||||
// Sanitize
|
||||
rv.name = sanitizePath(file.replace(/[/\\]+/g, "-"));
|
||||
}
|
||||
else if (!ext || PREROLL_SEARCHEXTS.has(ext.toLocaleLowerCase())) {
|
||||
const {searchParams} = this.download.uURL;
|
||||
let detected = "";
|
||||
for (const [, value] of searchParams) {
|
||||
if (!NAME_TESTER.test(value)) {
|
||||
continue;
|
||||
}
|
||||
const p = parsePath(value);
|
||||
if (!p.base || !p.ext) {
|
||||
continue;
|
||||
}
|
||||
if (!MimeDB.hasExtension(p.ext)) {
|
||||
continue;
|
||||
}
|
||||
if (rv.mime) {
|
||||
const mime = MimeDB.getMime(rv.mime);
|
||||
if (mime && !mime.extensions.has(p.ext.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const sanitized = sanitizePath(p.name);
|
||||
if (sanitized.length <= detected.length) {
|
||||
continue;
|
||||
}
|
||||
detected = sanitized;
|
||||
}
|
||||
else {
|
||||
const detected = Preroller.maybeFindNameFromSearchParams(
|
||||
this.download, rv);
|
||||
if (detected) {
|
||||
rv.name = detected;
|
||||
}
|
||||
@ -231,4 +210,43 @@ export class Preroller {
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static maybeFindNameFromSearchParams(
|
||||
download: Download, res: PrerollResults) {
|
||||
const {p_ext: ext} = download.renamer;
|
||||
if (ext && !PREROLL_SEARCHEXTS.has(ext.toLocaleLowerCase())) {
|
||||
return undefined;
|
||||
}
|
||||
return Preroller.findNameFromSearchParams(download.uURL, res.mime);
|
||||
}
|
||||
|
||||
static findNameFromSearchParams(url: URL, mimetype?: string) {
|
||||
const {searchParams} = url;
|
||||
let detected = "";
|
||||
for (const [, value] of searchParams) {
|
||||
if (!NAME_TESTER.test(value)) {
|
||||
continue;
|
||||
}
|
||||
const p = parsePath(value);
|
||||
if (!p.base || !p.ext) {
|
||||
continue;
|
||||
}
|
||||
if (!MimeDB.hasExtension(p.ext)) {
|
||||
continue;
|
||||
}
|
||||
if (mimetype) {
|
||||
const mime = MimeDB.getMime(mimetype);
|
||||
if (mime && !mime.extensions.has(p.ext.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const sanitized = sanitizePath(p.name);
|
||||
if (sanitized.length <= detected.length) {
|
||||
continue;
|
||||
}
|
||||
detected = sanitized;
|
||||
}
|
||||
return detected;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user