Subjects without a quoted file name: the name from the rest of the subject
Most "obfuscated" subjects of older and smaller groups name their file
without quotes ("DVDFab 8.2.0.5.rar (006/332)", fta's "q3B9…part023.rar
(104/137)", "New_Super_Mario_Bros._[Keygen].exe (1/2)") or with one
quote ("[keira_s04_0037_l.jpg\" yEnc] (2/2)"): 100% of ath 2013's and
fta's, 94% of models' (LOG.md 2026-10-11 (5)). With a segment counter and
no quoted name, unquotedName takes the name before a lone quote (after a
"[", else after the last space), else the text when it ends in a file
name (after "] " or " - "), else its first word that is one; a file
counter stuck in a bracket is dropped. The release identity takes such a
name out of the subject as it would quotes (else every image of a set
was a release: 9,130 instead of 267 on the models fixture).
Both implementations; a fourth fixture (fta, 25k lines) and tests; check
identical on all four. Truly random subjects (ngPost hex = message-id,
random tokens) stay obfuscated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
18b9ffdca3
commit
90f30f445d
13 files changed
+174
-25
No files matched your search
+6
-6
@@ -1,4 +1,4 @@
|
||||
import { fileKey } from '../headers/index.js'
|
||||
import { fileKey, unquotedName } from '../headers/index.js'
|
||||
import { releaseIdentity, type ReleaseIdentity } from '../release/index.js'
|
||||
|
||||
/** A file's details, shared by all of its segments (one object per file, not per article). */
|
||||
@@ -112,8 +112,8 @@ export class SegmentScanner {
|
||||
/** A segment from an article's fields, or null when its subject is obfuscated. */
|
||||
segment(articleNumber: number, subject: string, from: string, date: string, messageId: string, bytes: string, xref: string, group: string): EdgeSegment | null {
|
||||
if (!subject || !messageId) return null
|
||||
// After the last quote; without one, anywhere (unquotedName finds the file name).
|
||||
const nameEnd = subject.lastIndexOf('"')
|
||||
if (nameEnd <= 0) return null
|
||||
const counter = findCounter(subject, nameEnd)
|
||||
if (!counter) return null
|
||||
const key = from + '\u0001' + subject.slice(0, counter.index) + '\u0000' + subject.slice(counter.index + counter.length)
|
||||
@@ -137,10 +137,10 @@ export class SegmentScanner {
|
||||
|
||||
/** A file's details from its first article seen (as parseSubject and segmentFromHeader). */
|
||||
private describe(subject: string, nameEnd: number, counter: Counter, from: string, xref: string, group: string): FileMeta | null {
|
||||
const nameStart = subject.lastIndexOf('"', nameEnd - 1)
|
||||
if (nameStart === -1) return null
|
||||
const name = own(subject.slice(nameStart + 1, nameEnd))
|
||||
if (!name || counter.total < 1) return null
|
||||
const nameStart = nameEnd > 0 ? subject.lastIndexOf('"', nameEnd - 1) : -1
|
||||
const found = nameStart !== -1 ? subject.slice(nameStart + 1, nameEnd) : unquotedName(subject.slice(0, counter.index))
|
||||
if (!found || counter.total < 1) return null
|
||||
const name = own(found)
|
||||
const base = own((subject.slice(0, counter.index) + subject.slice(counter.index + counter.length)).replace(/\s+/g, ' ').trim())
|
||||
const poster = own(from)
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user