Skip to content

Commit

Permalink
Merge pull request #77 from Cl00e9ment/various-fixes
Browse files Browse the repository at this point in the history
Various fixes
  • Loading branch information
StefanLobbenmeier authored Oct 8, 2023
2 parents 5877007 + 3f423bf commit 3ec0052
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 103 deletions.
42 changes: 19 additions & 23 deletions modules/BinaryUpdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,25 @@ class BinaryUpdater {
}
console.log("Checking for a new version of yt-dlp.");
const localVersion = await this.getLocalVersion();
const { remoteUrl, remoteVersion } = await this.getRemoteVersion();
const remoteVersion = await this.getRemoteVersion();
if(remoteVersion == null) {
console.log("Unable to check for new updates, GitHub may be down.");
return
}
if(remoteVersion === localVersion) {
console.log(`Binaries were already up-to-date! Version: ${localVersion}`);
} else if(localVersion == null) {
return;
}
const remoteUrl = this.getBinaryUrl();
if(localVersion == null) {
console.log("Downloading missing yt-dlp binary.");
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Installing yt-dlp version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteUrl, remoteVersion);
this.paths.setPermissions()
} else if(remoteVersion == null) {
console.log("Unable to check for new updates, GitHub may be down.");
} else {
console.log(`New version ${remoteVersion} found. Updating...`);
this.action = "Updating to";
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Updating yt-dlp to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteUrl, remoteVersion);
this.paths.setPermissions()
}
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Updating yt-dlp to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteUrl, remoteVersion);
this.paths.setPermissions()
}

async checkPreInstalled() {
Expand All @@ -53,30 +55,24 @@ class BinaryUpdater {

async getRemoteVersion() {
const releaseUrl = "https://github.com/yt-dlp/yt-dlp/releases/latest/"
const binaryUrl = this.getBinaryUrl()
try {
await axios.get(releaseUrl, {
responseType: 'document',
maxRedirects: 0,
})
responseType: 'document',
maxRedirects: 0,
})
} catch (err) {
const res = err.response;
if (err.response == null) {
console.error('An error occurred while retrieving the latest yt-dlp version data.')
return null;
}
if (res.status === 302) {
const directUrl = res.headers.location;
const versionRegex = directUrl.match(/[0-9]+\.[0-9]+\.[0-9]+/);

return {
remoteVersion: versionRegex ? versionRegex[0] : null,
remoteUrl: binaryUrl,
};
} else {
if (res.status !== 302) {
console.error('Did not get redirect for the latest version link. Status: ' + err.response.status);
return null;
}
const directUrl = res.headers.location;
const versionRegex = directUrl.match(/[0-9]+\.[0-9]+\.[0-9]+/);
return versionRegex ? versionRegex[0] : null;
}
return null;
}
Expand Down
33 changes: 18 additions & 15 deletions modules/FfmpegUpdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,25 @@ class FfmpegUpdater {
console.log("Checking for a new version of ffmpeg.");
const localVersion = await this.getLocalVersion();
const { remoteFfmpegUrl, remoteFfprobeUrl, remoteVersion } = await this.getRemoteVersion();
if(remoteVersion == null) {
console.log("Unable to check for new updates, ffbinaries.com may be down.");
return;
}
if(remoteVersion === localVersion) {
console.log(`ffmpeg was already up-to-date! Version: ${localVersion}`);
} else if(localVersion == null) {
return;
}
if(localVersion == null) {
console.log("Downloading missing ffmpeg binary.");
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Installing ffmpeg version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfmpegUrl, remoteVersion, "ffmpeg" + this.getFileExtension());
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Installing ffprobe version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfprobeUrl, remoteVersion, "ffprobe" + this.getFileExtension());
await this.writeVersionInfo(remoteVersion);
} else if(remoteVersion == null) {
console.log("Unable to check for new updates, ffbinaries.com may be down.");
} else {
console.log(`New version ${remoteVersion} found. Updating...`);
this.action = "Updating to";
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Updating ffmpeg to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfmpegUrl, remoteVersion, "ffmpeg" + this.getFileExtension());
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Updating ffprobe to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfprobeUrl, remoteVersion, "ffprobe" + this.getFileExtension());
await this.writeVersionInfo(remoteVersion);
}
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Installing/Updating ffmpeg to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfmpegUrl, remoteVersion, "ffmpeg" + this.getFileExtension());
this.win.webContents.send("binaryLock", {lock: true, placeholder: `Installing/Updating ffprobe to version: ${remoteVersion}. Preparing...`})
await this.downloadUpdate(remoteFfprobeUrl, remoteVersion, "ffprobe" + this.getFileExtension());
await this.writeVersionInfo(remoteVersion);
}

async checkPreInstalled() {
Expand Down Expand Up @@ -77,7 +76,11 @@ class FfmpegUpdater {
if (err.response != null) {
console.error('Status code: ' + err.response.status);
}
return null;
return {
remoteVersion: null,
remoteFfmpegUrl: null,
remoteFfprobeUrl: null,
}
}
}

Expand Down Expand Up @@ -142,7 +145,7 @@ class FfmpegUpdater {
this.win.webContents.send("binaryLock", {lock: true, placeholder: `${this.action} ${artifact} ${version} - Extracting binaries...`})
const zipFile = new AdmZip(path.join(downloadPath, filename), {});
zipFile.extractEntryTo(filename, this.paths.ffmpeg, false, true, false, filename);
fs.rmdirSync(path.join(this.paths.ffmpeg, "downloads"), { recursive: true, force: true });
fs.rmSync(path.join(this.paths.ffmpeg, "downloads"), { recursive: true, force: true });
}

//Writes the new version number to the ytdlVersion file
Expand Down
2 changes: 1 addition & 1 deletion modules/Filepaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class Filepaths {
const toCopy = ["yt-dlp.exe", "ffmpeg.exe", "ytdlVersion", "ffmpegVersion", "AtomicParsley.exe", "userSettings", "taskList"];
await this.copyFiles(from, this.persistentPath, toCopy);
try {
await fs.promises.rmdir(from, {recursive: true});
await fs.promises.rm(from, {recursive: true});
} catch (e) {
console.error(e);
}
Expand Down
62 changes: 34 additions & 28 deletions modules/download/DownloadQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,42 +164,48 @@ class DownloadQuery extends Query {
let result = null;
try {
result = await this.environment.downloadLimiter.schedule(() => this.start(this.url, args, (liveData) => {
const perLine = liveData.split("\n");
for(const line of perLine) {
this.video.setFilename(line);
if(line.lastIndexOf("[download]") !== line.indexOf("[download]")) {
const splitLines = line.split("[");
for(const splitLine of splitLines) {
if(splitLine.trim() !== "") {
this.environment.logger.log(this.video.identifier, "[" + splitLine.trim());
}
}
} else {
this.environment.logger.log(this.video.identifier, line);
}
}
this.environment.logger.log(this.video.identifier, liveData);
this.video.setFilename(liveData);

if (!liveData.includes("[download]")) return;

if (liveData.includes("Destination")) destinationCount += 1;

if (!initialReset) {
initialReset = true;
this.progressBar.reset();
return;
}

if (liveData.includes("Destination")) destinationCount += 1;
if (destinationCount === 2 && !this.video.audioOnly && !this.video.downloadingAudio) {
this.video.downloadingAudio = true;
this.progressBar.reset();
return;
}

if (destinationCount > 1) {
if (destinationCount === 2 && !this.video.audioOnly && !this.video.downloadingAudio) {
this.video.downloadingAudio = true;
this.progressBar.reset();
}
let liveDataObj;
try {
liveDataObj = JSON.parse(liveData.slice(liveData.indexOf('{')));
} catch(e) {
return;
}
let liveDataArray = liveData.split(" ").filter((el) => {
return el !== ""
});
let percentage = liveDataArray[1];
let speed = liveDataArray[2];
let eta = liveDataArray[3];
this.progressBar.updateDownload(percentage, eta, speed, this.video.audioOnly ? true : this.video.downloadingAudio);

let percentage;
if ("fragment_count" in liveDataObj) {
//When there is multiple fragments, cap the completion percentage to avoid some strange values.
const completion = Math.min(
liveDataObj.downloaded_bytes / liveDataObj.total_bytes_estimate,
(liveDataObj.fragment_index + 1) / liveDataObj.fragment_count
);
percentage = Math.floor(completion * 100) + "." + (Math.floor(completion * 1000) % 10) + "%";
} else {
percentage = liveDataObj._percent_str;
}

const speed = liveDataObj._speed_str;
const eta = liveDataObj.eta >= 0 ? liveDataObj._eta_str : "00:00";

this.progressBar.updateDownload(percentage, eta, speed, this.video.audioOnly || this.video.downloadingAudio);
}));
} catch (exception) {
this.environment.errorHandler.checkError(exception, this.video.identifier);
Expand Down Expand Up @@ -240,7 +246,7 @@ class DownloadQuery extends Query {
removeVideoDataFolder(folderPath) {
if(folderPath != null) {
try {
fs.rmdirSync(folderPath, {recursive : true, force : true});
fs.rmSync(folderPath, {recursive : true, force : true});
} catch(e) {
console.log("No left-over Temp Folder found to remove. (" + folderPath + ")")
}
Expand Down
8 changes: 7 additions & 1 deletion modules/types/Query.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ class Query {
this.process = execa(command, args);
this.process.stdout.setEncoding('utf8');
this.process.stdout.on('data', (data) => {
cb(data.toString());
const lines = data
.toString()
.replace(/\\u[0-9A-Fa-f]{4}/g, escapedUnicode => String.fromCharCode(parseInt(escapedUnicode.slice(2), 16)))
.split("\n");
for(const line of lines) {
cb(line);
}
});
this.process.stdout.on('close', () => {
if(this.process.killed) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Open Video Downloader",
"main": "main.js",
"scripts": {
"start": "electron . --dev",
"start": "electron . --dev --ozone-platform-hint=auto",
"build": "electron-builder",
"lint": "eslint {**/modules/**/*.js,*.js} && eslint renderer/*.js",
"test": "jest --coverage",
Expand Down
1 change: 0 additions & 1 deletion renderer/renderer.css
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ select {
transform: translateY(-50%) scale(1.5);
filter: brightness(55%);
cursor: move;
z-index: 100;
}

.video-card p {
Expand Down
32 changes: 15 additions & 17 deletions renderer/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -832,23 +832,21 @@ function updateProgress(args) {
$(card).find('.progress-bar').attr('aria-valuenow', args.progress.percentage.slice(0,-1)).css('width', args.progress.percentage);
$(card).find('.progress small').html(`${args.progress.percentage} - ${args.progress.done} of ${args.progress.total} `);
} else if(args.progress.percentage != null) {
if(parseFloat(args.progress.percentage.slice(0, -1)) > parseFloat($(card).find('.progress-bar').attr("aria-valuenow"))) {
$(card).find('.progress-bar').attr('aria-valuenow', args.progress.percentage.slice(0,-1)).css('width', args.progress.percentage);
if(args.progress.percentage.slice(0, -1) === "100.0") {
$(card).find('.progress-bar').addClass("progress-bar-striped")
$(card).find('.progress small').html("Converting with FFmpeg");
} else {
if (args.progress.isAudio == null) $(card).find('.progress small').html("Downloading item - " + args.progress.percentage);
else $(card).find('.progress small').html((args.progress.isAudio ? "Downloading audio" : "Downloading video") + " - " + args.progress.percentage);
}
if(!progressCooldown.includes(args.identifier)) {
progressCooldown.push(args.identifier);
$(card).find('.metadata.right').html('<strong>ETA: </strong>' + args.progress.eta).show();
$(card).find('.metadata.left').html('<strong>Speed: </strong>' + args.progress.speed).show();
setTimeout(() => {
progressCooldown = progressCooldown.filter(item => item !== args.identifier);
}, 200);
}
$(card).find('.progress-bar').attr('aria-valuenow', args.progress.percentage.slice(0,-1)).css('width', args.progress.percentage);
if(args.progress.percentage === "100.0%") {
$(card).find('.progress-bar').addClass("progress-bar-striped")
$(card).find('.progress small').html("Converting with FFmpeg");
} else {
if (args.progress.isAudio == null) $(card).find('.progress small').html("Downloading item - " + args.progress.percentage);
else $(card).find('.progress small').html((args.progress.isAudio ? "Downloading audio" : "Downloading video") + " - " + args.progress.percentage);
}
if(!progressCooldown.includes(args.identifier)) {
progressCooldown.push(args.identifier);
$(card).find('.metadata.right').html('<strong>ETA: </strong>' + args.progress.eta).show();
$(card).find('.metadata.left').html('<strong>Speed: </strong>' + args.progress.speed).show();
setTimeout(() => {
progressCooldown = progressCooldown.filter(item => item !== args.identifier);
}, 200);
}
}
}
Expand Down
20 changes: 9 additions & 11 deletions tests/BinaryUpdater.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe("getLocalVersion", () => {
});

describe('getRemoteVersion', () => {
it('returns a null array when not redirected', () => {
it('returns a null when not redirected', () => {
const axiosGetSpy = jest.spyOn(axios, 'get').mockRejectedValue({response: {status: 200}});
const instance = new BinaryUpdater({platform: "win32"});
instance.platform = "win32";
Expand All @@ -55,7 +55,7 @@ describe('getRemoteVersion', () => {
expect(axiosGetSpy).toBeCalledTimes(1);
});
});
it('returns a null array on error', () => {
it('returns a null on error', () => {
const axiosGetSpy = jest.spyOn(axios, 'get').mockRejectedValue({response: null});
const instance = new BinaryUpdater({platform: "darwin"});
instance.platform = "darwin";
Expand All @@ -65,7 +65,7 @@ describe('getRemoteVersion', () => {
expect(axiosGetSpy).toBeCalledTimes(1);
});
});
it('returns array with the link and the version', () => {
it('returns the link and the version', () => {
const redirectUrl = "https://github.com/yt-dlp/yt-dlp/releases/tag/2021.10.10"
const binaryUrl = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe"
const axiosGetSpy = jest.spyOn(axios, 'get').mockRejectedValue({
Expand All @@ -78,11 +78,9 @@ describe('getRemoteVersion', () => {
});
const instance = new BinaryUpdater({platform: "win32"});
instance.platform = "win32";
expect(instance.getBinaryUrl()).toEqual(binaryUrl);
return instance.getRemoteVersion().then((data) => {
expect(data).toEqual({
remoteUrl: binaryUrl,
remoteVersion: "2021.10.10"
});
expect(data).toEqual("2021.10.10");
expect(axiosGetSpy).toBeCalledTimes(1);
});
});
Expand All @@ -95,7 +93,7 @@ describe('checkUpdate', () => {
const downloadUpdateSpy = jest.spyOn(instance, 'downloadUpdate');
instance.paths.setPermissions = jest.fn();
jest.spyOn(instance, 'getLocalVersion').mockResolvedValue("v2.0.0");
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue(["link", "v2.0.0"]);
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue("v2.0.0");
return instance.checkUpdate().then(() => {
expect(downloadUpdateSpy).not.toBeCalled();
expect(instance.win.webContents.send).not.toBeCalled();
Expand All @@ -107,7 +105,7 @@ describe('checkUpdate', () => {
const downloadUpdateSpy = jest.spyOn(instance, 'downloadUpdate');
instance.paths.setPermissions = jest.fn();
jest.spyOn(instance, 'getLocalVersion').mockResolvedValue("v2.0.0");
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue([null, null]);
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue(null);
return instance.checkUpdate().then(() => {
expect(downloadUpdateSpy).not.toBeCalled();
expect(instance.win.webContents.send).not.toBeCalled();
Expand All @@ -119,7 +117,7 @@ describe('checkUpdate', () => {
const downloadUpdateSpy = jest.spyOn(instance, 'downloadUpdate').mockResolvedValue("");
instance.paths.setPermissions = jest.fn();
jest.spyOn(instance, 'getLocalVersion').mockResolvedValue(null);
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue(["link", "v2.0.0"]);
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue("v2.0.0");
return instance.checkUpdate().then(() => {
expect(downloadUpdateSpy).toBeCalledTimes(1);
expect(instance.win.webContents.send).toBeCalledTimes(1);
Expand All @@ -131,7 +129,7 @@ describe('checkUpdate', () => {
const downloadUpdateSpy = jest.spyOn(instance, 'downloadUpdate').mockResolvedValue("");
instance.paths.setPermissions = jest.fn();
jest.spyOn(instance, 'getLocalVersion').mockResolvedValue("2021.03.10");
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue({ remoteUrl: "link", remoteVersion: "2021.10.10" });
jest.spyOn(instance, 'getRemoteVersion').mockResolvedValue("2021.10.10");
return instance.checkUpdate().then(() => {
expect(downloadUpdateSpy).toBeCalledTimes(1);
expect(instance.win.webContents.send).toBeCalledTimes(1);
Expand Down
Loading

0 comments on commit 3ec0052

Please sign in to comment.