Queue and UI fixes

This commit is contained in:
2026-03-05 11:04:20 +00:00
parent 23acea4773
commit e3d890c071
103 changed files with 11400 additions and 2010 deletions

View File

@@ -564,6 +564,49 @@ class HistoryService {
}));
}
async getJobsByIds(jobIds = []) {
const ids = Array.isArray(jobIds)
? jobIds
.map((value) => Number(value))
.filter((value) => Number.isFinite(value) && value > 0)
.map((value) => Math.trunc(value))
: [];
if (ids.length === 0) {
return [];
}
const db = await getDb();
const placeholders = ids.map(() => '?').join(', ');
const rows = await db.all(
`SELECT * FROM jobs WHERE id IN (${placeholders})`,
ids
);
const byId = new Map(rows.map((row) => [Number(row.id), row]));
return ids
.map((id) => byId.get(id))
.filter(Boolean)
.map((job) => ({
...enrichJobRow(job),
log_count: hasProcessLogFile(job.id) ? 1 : 0
}));
}
async getRunningJobs() {
const db = await getDb();
const rows = await db.all(
`
SELECT *
FROM jobs
WHERE status IN ('RIPPING', 'ENCODING')
ORDER BY updated_at ASC, id ASC
`
);
return rows.map((job) => ({
...enrichJobRow(job),
log_count: hasProcessLogFile(job.id) ? 1 : 0
}));
}
async getJobWithLogs(jobId, options = {}) {
const db = await getDb();
const job = await db.get('SELECT * FROM jobs WHERE id = ?', [jobId]);

File diff suppressed because it is too large Load Diff

View File

@@ -71,18 +71,23 @@ function spawnTrackedProcess({
});
});
let cancelCalled = false;
const cancel = () => {
if (child.killed) {
if (cancelCalled) {
return;
}
cancelCalled = true;
logger.warn('spawn:cancel:requested', { cmd, args, context, pid: child.pid });
child.kill('SIGINT');
setTimeout(() => {
if (!child.killed) {
try {
process.kill(child.pid, 0);
logger.warn('spawn:cancel:force-kill', { cmd, args, context, pid: child.pid });
child.kill('SIGKILL');
} catch (_e) {
// Process already terminated
}
}, 3000);
};

View File

@@ -70,6 +70,20 @@ function normalizeTrackIds(rawList) {
return output;
}
function normalizeNonNegativeInteger(rawValue) {
if (rawValue === null || rawValue === undefined) {
return null;
}
if (typeof rawValue === 'string' && rawValue.trim() === '') {
return null;
}
const value = Number(rawValue);
if (!Number.isFinite(value) || value < 0) {
return null;
}
return Math.trunc(value);
}
function removeSelectionArgs(extraArgs) {
const args = Array.isArray(extraArgs) ? extraArgs : [];
const filtered = [];
@@ -554,7 +568,7 @@ class SettingsService {
? 'backup'
: 'mkv';
const sourceArg = this.resolveSourceArg(map, deviceInfo);
const rawSelectedTitleId = Number(options?.selectedTitleId);
const rawSelectedTitleId = normalizeNonNegativeInteger(options?.selectedTitleId);
const parsedExtra = splitArgs(map.makemkv_rip_extra_args);
let extra = [];
let baseArgs = [];
@@ -574,7 +588,7 @@ class SettingsService {
} else {
extra = parsedExtra;
const minLength = Number(map.makemkv_min_length_minutes || 60);
const hasExplicitTitle = Number.isFinite(rawSelectedTitleId) && rawSelectedTitleId >= 0;
const hasExplicitTitle = rawSelectedTitleId !== null;
const targetTitle = hasExplicitTitle ? String(Math.trunc(rawSelectedTitleId)) : 'all';
if (hasExplicitTitle) {
baseArgs = [