mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 04:40:09 +00:00
bb42281dac
Adds detection of local users for authentication validation and login, prevents role changes for OIDC users, and clarifies user management UI. Enhances active downloads API to include speed and ETA from qBittorrent, and improves file path handling in download monitoring. Also updates torrent tagging and user info returned by APIs.
116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
/**
|
|
* Component: Download Torrent Job Processor
|
|
* Documentation: documentation/phase3/README.md
|
|
*/
|
|
|
|
import { DownloadTorrentPayload, getJobQueueService } from '../services/job-queue.service';
|
|
import { prisma } from '../db';
|
|
import { getQBittorrentService } from '../integrations/qbittorrent.service';
|
|
import { createJobLogger } from '../utils/job-logger';
|
|
|
|
/**
|
|
* Process download torrent job
|
|
* Adds selected torrent to download client and starts monitoring
|
|
*/
|
|
export async function processDownloadTorrent(payload: DownloadTorrentPayload): Promise<any> {
|
|
const { requestId, audiobook, torrent, jobId } = payload;
|
|
|
|
const logger = jobId ? createJobLogger(jobId, 'DownloadTorrent') : null;
|
|
|
|
await logger?.info(`Processing request ${requestId} for "${audiobook.title}"`);
|
|
await logger?.info(`Selected torrent: ${torrent.title}`, {
|
|
size: torrent.size,
|
|
seeders: torrent.seeders,
|
|
format: torrent.format,
|
|
indexer: torrent.indexer,
|
|
});
|
|
|
|
try {
|
|
// Update request status to downloading
|
|
await prisma.request.update({
|
|
where: { id: requestId },
|
|
data: {
|
|
status: 'downloading',
|
|
progress: 0,
|
|
updatedAt: new Date(),
|
|
},
|
|
});
|
|
|
|
// Get qBittorrent service
|
|
const qbt = await getQBittorrentService();
|
|
|
|
// Add torrent to qBittorrent
|
|
await logger?.info(`Adding torrent to qBittorrent`);
|
|
|
|
const torrentHash = await qbt.addTorrent(torrent.downloadUrl, {
|
|
category: 'readmeabook',
|
|
tags: ['audiobook'], // Generic tag for all audiobooks
|
|
sequentialDownload: true, // Download in order for potential streaming
|
|
paused: false, // Start immediately
|
|
});
|
|
|
|
await logger?.info(`Torrent added with hash: ${torrentHash}`);
|
|
|
|
// Create DownloadHistory record
|
|
const downloadHistory = await prisma.downloadHistory.create({
|
|
data: {
|
|
requestId,
|
|
indexerName: torrent.indexer,
|
|
downloadClient: 'qbittorrent',
|
|
downloadClientId: torrentHash,
|
|
torrentName: torrent.title,
|
|
torrentHash: torrent.infoHash || torrentHash,
|
|
torrentSizeBytes: torrent.size,
|
|
seeders: torrent.seeders,
|
|
leechers: torrent.leechers || 0,
|
|
downloadStatus: 'downloading',
|
|
selected: true,
|
|
startedAt: new Date(),
|
|
},
|
|
});
|
|
|
|
await logger?.info(`Created download history record: ${downloadHistory.id}`);
|
|
|
|
// Trigger monitor download job with initial delay
|
|
// qBittorrent needs a few seconds to process the torrent before it's available via API
|
|
const jobQueue = getJobQueueService();
|
|
await jobQueue.addMonitorJob(
|
|
requestId,
|
|
downloadHistory.id,
|
|
torrentHash,
|
|
'qbittorrent',
|
|
3 // Wait 3 seconds before first check to avoid race condition
|
|
);
|
|
|
|
await logger?.info(`Started monitoring job for request ${requestId} (3s initial delay)`);
|
|
|
|
return {
|
|
success: true,
|
|
message: 'Torrent added to download client and monitoring started',
|
|
requestId,
|
|
downloadHistoryId: downloadHistory.id,
|
|
torrentHash,
|
|
torrent: {
|
|
title: torrent.title,
|
|
size: torrent.size,
|
|
seeders: torrent.seeders,
|
|
format: torrent.format,
|
|
},
|
|
};
|
|
} catch (error) {
|
|
await logger?.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
|
|
// Update request status to failed
|
|
await prisma.request.update({
|
|
where: { id: requestId },
|
|
data: {
|
|
status: 'failed',
|
|
errorMessage: error instanceof Error ? error.message : 'Failed to add torrent to download client',
|
|
updatedAt: new Date(),
|
|
},
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
}
|