Files
Daan MeijerandClaude Opus 5.5 2dbca9b152
Test and deploy / test (push) Successful in 1m49s
Test and deploy / deploy (push) Successful in 2m15s
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>
2026-10-06 11:17:02 +02:00

37 lines
1.4 KiB
TypeScript

import db from '@adonisjs/lucid/services/db'
import { sevenZipVolume } from '#lib/sevenzip/index'
/**
* The database side of 7z listings (CONCEPT.md D19): which volumes make up
* an archive. Listing itself (first segment, tail, bsdtar) is
* lib/sevenzip/list.ts, run by inspection here or on a node.
*/
class SevenZipService {
/**
* The volumes of the archive `file` belongs to, in order, when all of them
* up to the highest number seen are there; null otherwise. An unsplit (or
* unnamed) archive is its own only volume.
*/
async volumes(file: any): Promise<any[] | null> {
const name = String(file.real_name ?? file.filename)
const volume = sevenZipVolume(name)
if (!volume) return [file]
if (!file.release_id) return null
const base = name.replace(/\.\d+$/, '').toLowerCase()
const rows = await db
.from('files')
.where('release_id', file.release_id)
.whereRaw(`lower(coalesce(real_name, filename)) LIKE ? ESCAPE '\\'`, [`${base.replace(/[\\%_]/g, '\\$&')}.%`])
const byNumber = new Map<number, any>()
for (const row of rows) {
const n = sevenZipVolume(String(row.real_name ?? row.filename))
if (n && !byNumber.has(n)) byNumber.set(n, row)
}
const max = Math.max(0, ...byNumber.keys())
const ordered = Array.from({ length: max }, (_, i) => byNumber.get(i + 1))
return max > 0 && ordered.every(Boolean) ? ordered : null
}
}
export default new SevenZipService()