Content inspection and archive walks on seeding nodes (relay)
Inspection is split into prepare (database), probe (lib/content/probe: downloads, decoding and parsing, no database) and apply (database). worker:collection runs all three; seed:node with SEED_INSPECTORS leases jobs from the same queues through the seed API (BullMQ manual leases), fetches articles through the seed API and posts the probes back. A node now needs only SEED_URL and SEED_TOKEN: the settings the app requires but a node never uses get placeholders for seed:node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
51975fe603
commit
2dbca9b152
22 files changed
+1198
-540
No files matched your search
@@ -6,7 +6,7 @@ import env from '#start/env'
|
||||
import Shutdown from '#services/Shutdown'
|
||||
import QueueService from '#services/QueueService'
|
||||
import NntpService from '#services/NntpService'
|
||||
import ContentService from '#services/ContentService'
|
||||
import ContentService, { describeContent } from '#services/ContentService'
|
||||
import ArchiveWalkService from '#services/ArchiveWalkService'
|
||||
import File from '#models/file'
|
||||
|
||||
@@ -33,31 +33,7 @@ export default class CollectionWorker extends BaseCommand {
|
||||
|
||||
try {
|
||||
const content = await ContentService.inspect(fileId)
|
||||
if (content?.par2) {
|
||||
const { par2 } = content
|
||||
this.logger.info(`Par2 "${file.filename}": release "${par2.releaseName}", ${par2.listed} files listed.`)
|
||||
} else if (content?.archive) {
|
||||
const { info, releaseRenamed, grouped } = content.archive
|
||||
const flags = [info.headersEncrypted && 'encrypted headers', info.entries.some((e) => e.encrypted) && 'encrypted files']
|
||||
.filter(Boolean)
|
||||
.join(', ')
|
||||
this.logger.info(
|
||||
`Archive "${file.filename}": ${info.format}, ${info.entries.length} entries${flags ? ` (${flags})` : ''}` +
|
||||
(grouped ? ', grouped into a release' : '') +
|
||||
(releaseRenamed ? `, release renamed to "${releaseRenamed}"` : '')
|
||||
)
|
||||
}
|
||||
if (content?.named) this.logger.info(`"${file.filename}" got its real name from par2.`)
|
||||
if (content?.contentType === 'nzbe') this.logger.info(`"${file.filename}" is an encrypted NZB container.`)
|
||||
if (content?.contentType === 'rclone') this.logger.info(`"${file.filename}" is rclone-encrypted.`)
|
||||
if (content?.yencName) this.logger.info(`"${file.filename}" is "${content.yencName}" (yEnc name).`)
|
||||
if (content?.nicovideo) this.logger.info(`"${file.filename}" → "${content.nicovideo}".`)
|
||||
if (content?.sfvMoved) this.logger.info(`SFV "${file.filename}" moved ${content.sfvMoved} files into its release.`)
|
||||
if (content?.contentType === 'yencbin') this.logger.info(`"${file.filename}" is a yEncBin encrypted container.`)
|
||||
if (content?.nzb) {
|
||||
const n = content.nzb
|
||||
this.logger.info(`NZB "${file.filename}": ${n.listed} files (${n.known} known, ${n.added} added) → "${n.releaseName}".`)
|
||||
}
|
||||
for (const line of describeContent(file.filename, content)) this.logger.info(line)
|
||||
} catch (error: any) {
|
||||
this.logger.warning(`Content inspection of "${file.filename}" failed: ${error.message}`)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user