Fold sidecars (.nfo, .sfv, .nzb) apart from their upload into it
"Murdoch Mysteries S8D1 [00/80] - \"….nzb\"" beside its "[01/94]" upload was a release of its own (23k sidecar-only releases on the corpus, 15k with the poster's bigger release within 10 minutes). The settler queues small settled releases (fold_candidates); the merger's third pass folds one whose files are all sidecars into the poster's bigger release in the same group within 10 minutes: the one sharing a 4+ letter word with its subject, else the one under the same counter total, else none (via 'sidecar'). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5897d595cf
commit
329c7a1373
6 files changed
+172
-4
No files matched your search
@@ -2,6 +2,7 @@ import db from '@adonisjs/lucid/services/db'
|
||||
import logger from '@adonisjs/core/services/logger'
|
||||
import { par2ReleaseName } from '#lib/release/index'
|
||||
import { looksRandom } from '#lib/release/random'
|
||||
import { SidecarFolder } from '#services/sidecar_folder'
|
||||
|
||||
/** Releases of a set further apart than this (posted) aren't one upload: a repost is merged separately (decision d). */
|
||||
const MAX_SPREAD_MS = 48 * 3600 * 1000
|
||||
@@ -26,6 +27,8 @@ export interface MergeRound {
|
||||
stems: number
|
||||
stemMerges: number
|
||||
stemReleases: number
|
||||
/** The sidecar fold: candidates looked at, sidecar-only ones among them, folded into their upload. */
|
||||
folded?: { looked: number; sidecars: number; folded: number }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +72,7 @@ interface Member {
|
||||
*/
|
||||
export class Par2Merger {
|
||||
private stopped = false
|
||||
private folder = new SidecarFolder((trx, found, key, via) => this.merge(trx, found, key, via))
|
||||
private since = new Date(0)
|
||||
|
||||
stop() {
|
||||
@@ -82,6 +86,7 @@ export class Par2Merger {
|
||||
const round = await this.round()
|
||||
if (round.merges > 0) logger.info(`Merged ${round.releases} releases into ${round.merges} by par2 set (${round.sets} sets checked).`)
|
||||
if (round.stemMerges > 0) logger.info(`Merged ${round.stemReleases} releases into ${round.stemMerges} by inner name (${round.stems} stems checked).`)
|
||||
if (round.folded?.folded) logger.info(`Folded ${round.folded.folded} sidecars into their uploads (${round.folded.sidecars} sidecar-only of ${round.folded.looked} small releases).`)
|
||||
} catch (error: any) {
|
||||
logger.error(`Par2 merge round failed: ${error.message}`)
|
||||
}
|
||||
@@ -129,6 +134,8 @@ export class Par2Merger {
|
||||
round.stemReleases += merged + 1
|
||||
}
|
||||
}
|
||||
// Third: sidecars (.nfo, .sfv, .nzb) apart from their upload join it.
|
||||
if (!this.stopped) round.folded = await this.folder.round()
|
||||
this.since = now[0].at
|
||||
return round
|
||||
}
|
||||
@@ -207,7 +214,7 @@ export class Par2Merger {
|
||||
* Merges the found releases into the one with the most files (named by the par2 set's files when none
|
||||
* is readable); how many went into it. Each merge is kept in release_merges, with its set or stem.
|
||||
*/
|
||||
private async merge(trx: any, found: Map<string, Member>, key: string, via: 'par2' | 'inner'): Promise<number> {
|
||||
private async merge(trx: any, found: Map<string, Member>, key: string, via: 'par2' | 'inner' | 'sidecar'): Promise<number> {
|
||||
{
|
||||
// Locked in id order (the batch store and other rounds take the same rows).
|
||||
const { rows: locked } = await trx.rawQuery(`SELECT id FROM releases WHERE id = ANY(?) ORDER BY id FOR UPDATE`, [[...found.keys()]])
|
||||
|
||||
Reference in new issue
Block a user