Skip to content

Commit

Permalink
refactor download code to support pause/resume
Browse files Browse the repository at this point in the history
  • Loading branch information
Tairraos committed Aug 21, 2022
1 parent c6dc8e1 commit 1481c2a
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 166 deletions.
8 changes: 4 additions & 4 deletions domutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function genTaskBox(task) {
`<div class="task-title"></div>`,
`<div class="task-download">`,
`<span class="task-size"></span>`,
`<span class="task-processbar hide"><span class="task-process"></span></span>`,
`<span class="task-progressbar hide"><span class="task-progress"></span></span>`,
`</div></div>`,
`<div class="task-status"></div>`,
`</div>`
Expand All @@ -83,9 +83,9 @@ function updateTaskBoxUI(domId, data) {
$(`${container} .task-status`).innerText = i18n.get(data.status);
$(`${container} .task-status`).setAttribute("data-i18n", `innerText%${data.status}`);
}
if (data.process) {
$(`${container} .task-processbar`).classList.remove("hide");
$(`${container} .task-process`).style.width = `${+data.process * 2}px`;
if (data.progress) {
$(`${container} .task-progressbar`).classList.remove("hide");
$(`${container} .task-progress`).style.width = `${+data.progress * 2}px`;
}
updateFooterStatUI();
}
Expand Down
88 changes: 53 additions & 35 deletions downloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ async function manageTask() {
const taskId = taskStore.newTaskId++,
task = {
taskId,
videoUrl: parsed.videoUrl,
videoUrl: parsed.videoUrl,
type: parsed.type,
shareId: parsed.shareId,
domId: shareId
Expand All @@ -105,12 +105,14 @@ async function manageTask() {
// step 3: parse videoId to get video info
const data = await parseVideoInfo(task);
if (data.success) {
const title = `${data.author} - ${data.date} - ${data.title}`
.replace(/[/\\:*?"<>|\n]/g, "")
.replace(/&[^;]{3,5};/g, " ")
.replace(/#[^ ]+( |$)/g, "")
.trim(),
filename = `${title.replace(/^(.{60}[\w]+.).*/, "$1")}.mp4`;
const title = data.title
.replace(/[/\\:*?"<>|\n]/g, "") //remove invalid chars
.replace(/&[^;]{3,5};/g, " ") //remove html entities
.replace(/#[^ ]+( |$)/g, "") //remove #tags
.trim()
.replace(/^(.{60}[\w]+.).*/, "$1") //truncate title to 60 chars + last word
.replace(/^(.{80}).*/, "$1"), //truncate title to 80 chars
filename = `${data.author} - ${data.date} - ${title || i18n.get("untitled")}.mp4`;
task.step = STEP_WAITING;
updateTaskBoxUI(task.domId, {
status: STEP_WAITING,
Expand Down Expand Up @@ -148,34 +150,6 @@ function downloadWaitingTask() {
}
}

function onDownloadUpdated(data) {
taskQueue[data.taskId].step = STEP_DOWNLOADING;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_DOWNLOADING,
size: data.size,
process: ((data.received / data.size) * 100).toFixed(1)
});
}

function onDownloadCompleted(data) {
if (data.state === "completed") {
taskQueue[data.taskId].step = STEP_DOWNLOADED;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_DOWNLOADED
});
config.record.push(taskQueue[data.taskId].videoId);
utils.setSetting("record", config.record);
} else {
taskQueue[data.taskId].step = STEP_FAILED;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_FAILED,
title: data.state
});
}
taskStore.isDownloadBusy = false;
downloadWaitingTask();
}

function updateTaskCounter() {
const result = {};
for (let key in taskQueue) {
Expand Down Expand Up @@ -247,3 +221,47 @@ async function fetchURL(url) {

return response.redirected ? response : await response.json();
}

/**
* Put download event handler here, will be bind to IPC in renderer.js
*/
const downloadEventHandler = {
downloadStart: function (data) {
taskQueue[data.taskId].step = STEP_DOWNLOADING;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_DOWNLOADING,
size: data.size
});
},

downloadProgress: function (data) {
taskQueue[data.taskId].step = STEP_DOWNLOADING;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_DOWNLOADING,
progress: data.progress
});
},

downloadError: function (data) {
taskQueue[data.taskId].step = STEP_FAILED;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_FAILED,
title: data.message
});
},

downloadEnd: function (data) {
if (data.isSuccess) {
taskQueue[data.taskId].step = STEP_DOWNLOADED;
updateTaskBoxUI(taskQueue[data.taskId].domId, {
status: STEP_DOWNLOADED
});
config.record.push(taskQueue[data.taskId].videoId);
utils.setSetting("record", config.record);
} else {
onDownloadError(data);
}
taskStore.isDownloadBusy = false;
downloadWaitingTask();
}
};
3 changes: 2 additions & 1 deletion i18n/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
"You have changed the download folder.": "您更改了下载文件夹。",
"You have changed the display language.": "您更改了显示语言。",
"The same task is already in the download list.": "下载列表里已经有相同的任务。",
"This video was once downloaded, requires a manual launch.": "这个视频曾经下载过,需要手动启动。"
"This video was once downloaded, requires a manual launch.": "这个视频曾经下载过,需要手动启动。",
"untitled": "无标题"
}
49 changes: 23 additions & 26 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const os = require("os");
const path = require("path");
const settings = require("electron-settings");
const { app, BrowserWindow, ipcMain, dialog } = require("electron");
const config = { taskStore: {} };
const { DownloaderHelper } = require("node-downloader-helper");

/**
* Add setting here
Expand Down Expand Up @@ -58,34 +58,32 @@ function initIPC() {
});

ipcMain.handle("download", (event, data) => {
config.taskStore[data.taskId] = data;
config.mainWindow.webContents.downloadURL(data.fileurl + "#" + data.taskId);
});

ipcMain.handle("resize", (event, w, h) => {
config.mainWindow.setSize(w, h, true);
});
}

function initDownloadMonitor() {
config.mainWindow.webContents.session.on("will-download", (event, item, webContents) => {
const taskId = item.getURL().match(/(\d+)$/)[0],
task = config.taskStore[taskId];

item.setSavePath(path.join(config.target, task.filename));
const taskId = data.taskId;

item.on("updated", (event, state) => {
config.mainWindow.send("download updated", {
taskId: taskId,
received: item.getReceivedBytes(),
size: item.getTotalBytes(),
state
});
const dl = new DownloaderHelper(data.fileurl, config.target, {
fileName: data.filename
});

item.once("done", (event, state) => {
config.mainWindow.send("download done", { taskId: taskId, state });
dl.on("end", (info) => {
config.mainWindow.send("downloadEnd", { taskId, isSuccess: !info.incomplete });
});
dl.on("error", (info) => {
config.mainWindow.send("downloadError", { taskId, message: info.message });
});
dl.on("download", (info) => {
config.mainWindow.send("downloadStart", { taskId, size: info.totalSize });
});
dl.on("progress", (info) => {
config.mainWindow.send("downloadProgress", { taskId, progress: info.progress });
});
dl.start().catch((info) => {
config.mainWindow.send("downloadError", { taskId, message: info.message });
});
// config.mainWindow.webContents.downloadURL(data.fileurl + "#" + data.taskId);
});

ipcMain.handle("resize", (event, w, h) => {
config.mainWindow.setSize(w, h, true);
});
}

Expand Down Expand Up @@ -117,7 +115,6 @@ app.on("ready", () => {
}

initIPC();
initDownloadMonitor();
});

app.on("second-instance", () => config.mainWindow.show());
Expand Down
Loading

0 comments on commit 1481c2a

Please sign in to comment.