Compare commits
No commits in common. "a3e956e085f2ba3552b83470abe9b9d54f487794" and "a75aa857125e6ee5a1b01ce6ed60b02cacde3383" have entirely different histories.
a3e956e085
...
a75aa85712
@ -698,18 +698,13 @@ class UploadManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addJobs(tasks) {
|
addJobs(tasks) {
|
||||||
if (!this.running || !tasks || tasks.length === 0) {
|
if (!this.running || !tasks || tasks.length === 0) return 0;
|
||||||
return { added: 0, alreadyInBatchJobIds: [] };
|
|
||||||
}
|
|
||||||
const { signal } = this.abortController;
|
const { signal } = this.abortController;
|
||||||
const results = this._batchResults || new Map();
|
const results = this._batchResults || new Map();
|
||||||
const addResult = { added: 0, alreadyInBatchJobIds: [] };
|
let added = 0;
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
// Skip if this job is already being processed (prevent duplicates)
|
// Skip if this job is already being processed (prevent duplicates)
|
||||||
if (task.jobId && this.jobAbortControllers.has(task.jobId)) {
|
if (task.jobId && this.jobAbortControllers.has(task.jobId)) continue;
|
||||||
addResult.alreadyInBatchJobIds.push(task.jobId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const fileName = path.basename(task.file);
|
const fileName = path.basename(task.file);
|
||||||
if (!results.has(task.file)) {
|
if (!results.has(task.file)) {
|
||||||
let size = 0;
|
let size = 0;
|
||||||
@ -717,9 +712,9 @@ class UploadManager extends EventEmitter {
|
|||||||
results.set(task.file, { name: fileName, size, results: [] });
|
results.set(task.file, { name: fileName, size, results: [] });
|
||||||
}
|
}
|
||||||
this._additionalPromises.push(this._runJob(task, results, signal));
|
this._additionalPromises.push(this._runJob(task, results, signal));
|
||||||
addResult.added++;
|
added++;
|
||||||
}
|
}
|
||||||
return addResult;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelJobs(jobIds) {
|
cancelJobs(jobIds) {
|
||||||
|
|||||||
24
main.js
24
main.js
@ -785,26 +785,10 @@ ipcMain.handle('add-jobs-to-batch', (_event, payload) => {
|
|||||||
const config = configStore.load();
|
const config = configStore.load();
|
||||||
const jobs = payload && Array.isArray(payload.jobs) ? payload.jobs : [];
|
const jobs = payload && Array.isArray(payload.jobs) ? payload.jobs : [];
|
||||||
const tasks = buildUploadTasksFromJobs(config, jobs);
|
const tasks = buildUploadTasksFromJobs(config, jobs);
|
||||||
const taskJobIds = new Set(tasks.map(t => t.jobId).filter(Boolean));
|
if (tasks.length === 0) return { added: 0 };
|
||||||
const skippedJobs = jobs
|
const added = uploadManager.addJobs(tasks);
|
||||||
.filter(j => j && j.id && !taskJobIds.has(j.id))
|
debugLog(`add-jobs-to-batch: ${added} of ${tasks.length} tasks added (${tasks.length - added} already in batch)`);
|
||||||
.map(j => ({ jobId: j.id, hoster: j.hoster, reason: 'Kein gültiger Account für diesen Hoster' }));
|
return { added };
|
||||||
|
|
||||||
if (tasks.length === 0) {
|
|
||||||
debugLog(`add-jobs-to-batch: 0 tasks built (${skippedJobs.length} skipped: no account)`);
|
|
||||||
return { added: 0, skippedJobs, alreadyInBatchJobIds: [] };
|
|
||||||
}
|
|
||||||
|
|
||||||
const addResult = uploadManager.addJobs(tasks);
|
|
||||||
const added = typeof addResult === 'number' ? addResult : (addResult && addResult.added) || 0;
|
|
||||||
const alreadyInBatchJobIds = (addResult && Array.isArray(addResult.alreadyInBatchJobIds))
|
|
||||||
? addResult.alreadyInBatchJobIds
|
|
||||||
: [];
|
|
||||||
|
|
||||||
debugLog(
|
|
||||||
`add-jobs-to-batch: ${added} of ${tasks.length} tasks added (${alreadyInBatchJobIds.length} already in batch, ${skippedJobs.length} skipped)`
|
|
||||||
);
|
|
||||||
return { added, skippedJobs, alreadyInBatchJobIds };
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('finish-after-active', () => {
|
ipcMain.handle('finish-after-active', () => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.6.3",
|
"version": "2.6.2",
|
||||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1363,44 +1363,20 @@ async function startSelectedUpload() {
|
|||||||
j.bytesUploaded = 0; j.speedKbs = 0; j.progress = 0; j.uploadId = null;
|
j.bytesUploaded = 0; j.speedKbs = 0; j.progress = 0; j.uploadId = null;
|
||||||
});
|
});
|
||||||
renderQueueTable();
|
renderQueueTable();
|
||||||
let result = null;
|
const result = await window.api.addJobsToBatch({
|
||||||
try {
|
jobs: addable.map(j => ({ id: j.id, file: j.file, fileName: j.fileName, hoster: j.hoster }))
|
||||||
result = await window.api.addJobsToBatch({
|
});
|
||||||
jobs: addable.map(j => ({ id: j.id, file: j.file, fileName: j.fileName, hoster: j.hoster }))
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
showCopyToast(`Jobs konnten nicht hinzugefuegt werden: ${err.message}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the batch ended between UI-state and IPC call, start a fresh batch immediately
|
|
||||||
if (result && result.error === 'Kein Upload aktiv') {
|
|
||||||
uploading = false;
|
|
||||||
updateQueueActionButtons();
|
|
||||||
updateStatusBar();
|
|
||||||
await startSelectedUpload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_markSkippedJobs(result);
|
_markSkippedJobs(result);
|
||||||
persistQueueStateSoon();
|
persistQueueStateSoon();
|
||||||
const added = Number(result && result.added) || 0;
|
const added = result && result.added || 0;
|
||||||
// Use ASCII-only toast text here to avoid encoding artifacts on some systems.
|
const alreadyInBatch = addable.length - added;
|
||||||
const skipped = Array.isArray(result && result.skippedJobs) ? result.skippedJobs.length : 0;
|
if (added > 0 && alreadyInBatch > 0) {
|
||||||
const alreadyInBatch = Array.isArray(result && result.alreadyInBatchJobIds)
|
showCopyToast(`${added} Jobs hinzugefügt, ${alreadyInBatch} waren schon im Batch`);
|
||||||
? result.alreadyInBatchJobIds.length
|
} else if (added > 0) {
|
||||||
: Math.max(0, addable.length - added - skipped);
|
showCopyToast(`${added} Jobs zum laufenden Upload hinzugefügt`);
|
||||||
const toastParts = [];
|
|
||||||
if (added > 0) toastParts.push(`${added} hinzugefuegt`);
|
|
||||||
if (alreadyInBatch > 0) toastParts.push(`${alreadyInBatch} bereits im Batch`);
|
|
||||||
if (skipped > 0) toastParts.push(`${skipped} ohne gueltigen Account`);
|
|
||||||
if (result && result.error) {
|
|
||||||
showCopyToast(`Jobs konnten nicht hinzugefuegt werden: ${result.error}`);
|
|
||||||
} else if (toastParts.length > 0) {
|
|
||||||
showCopyToast(`Jobs: ${toastParts.join(', ')}`);
|
|
||||||
} else {
|
} else {
|
||||||
showCopyToast('Keine Jobs hinzugefuegt');
|
showCopyToast(`${addable.length} Jobs sind bereits im laufenden Batch`);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -242,55 +242,6 @@ describe('UploadManager', () => {
|
|||||||
assert.ok(statuses.some((entry) => entry.jobId === 'selected-job' && entry.status === 'aborted'));
|
assert.ok(statuses.some((entry) => entry.jobId === 'selected-job' && entry.status === 'aborted'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('addJobs returns duplicate info and still runs newly queued jobs', async () => {
|
|
||||||
let releaseFirst = null;
|
|
||||||
|
|
||||||
mockUploadFile.mock.mockImplementation(async (hoster, filePath, apiKey, onProgress, signal) => {
|
|
||||||
if (filePath.endsWith('/first.mp4')) {
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
releaseFirst = resolve;
|
|
||||||
if (signal) {
|
|
||||||
signal.addEventListener('abort', () => reject(new Error('Aborted')), { once: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
||||||
}
|
|
||||||
if (onProgress) onProgress(fakeFileSize, fakeFileSize);
|
|
||||||
return { download_url: 'https://test/ok', embed_url: null, file_code: 'ok' };
|
|
||||||
});
|
|
||||||
|
|
||||||
const mgr = new UploadManager({
|
|
||||||
'doodstream.com': { retries: 0, parallelCount: 1, maxSpeedKbs: 0, restartBelowKbs: 0, timeIntervalSec: 0, maxSizeMb: 0 }
|
|
||||||
});
|
|
||||||
const statuses = [];
|
|
||||||
mgr.on('progress', (data) => statuses.push({ jobId: data.jobId, status: data.status }));
|
|
||||||
|
|
||||||
const batchPromise = mgr.startBatch([
|
|
||||||
{ jobId: 'job-first', file: '/test/first.mp4', hoster: 'doodstream.com', apiKey: 'key1' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
for (let i = 0; i < 50 && !releaseFirst; i++) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
||||||
}
|
|
||||||
assert.equal(typeof releaseFirst, 'function', 'first job should be running before addJobs');
|
|
||||||
|
|
||||||
const addResult = mgr.addJobs([
|
|
||||||
{ jobId: 'job-first', file: '/test/first.mp4', hoster: 'doodstream.com', apiKey: 'key1' },
|
|
||||||
{ jobId: 'job-second', file: '/test/second.mp4', hoster: 'doodstream.com', apiKey: 'key1' },
|
|
||||||
{ jobId: 'job-third', file: '/test/third.mp4', hoster: 'doodstream.com', apiKey: 'key1' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.equal(addResult.added, 2);
|
|
||||||
assert.deepEqual(addResult.alreadyInBatchJobIds, ['job-first']);
|
|
||||||
|
|
||||||
releaseFirst();
|
|
||||||
await batchPromise;
|
|
||||||
|
|
||||||
assert.ok(statuses.some((entry) => entry.jobId === 'job-second' && entry.status === 'done'));
|
|
||||||
assert.ok(statuses.some((entry) => entry.jobId === 'job-third' && entry.status === 'done'));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('_combineSignals propagates abort from either source', () => {
|
it('_combineSignals propagates abort from either source', () => {
|
||||||
const mgr = new UploadManager({});
|
const mgr = new UploadManager({});
|
||||||
const ac1 = new AbortController();
|
const ac1 = new AbortController();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user