From the first corpus sweep (183 ranges):
- A stray quote took the last quote pair ('"x.mp3" "Album_BY_WaRLoRD',
'"x.nfo" " yEnc', '"x.nzb" yEnc"'): the last quoted part with an
extension is the name. Each file was a release of its own.
- A single-quoted name at the end ("… [001/106] 'You, Me And Dupree.nfo'"),
not the host before it (www.x2l.nl).
- Text ending in a host ("… www.libranews.nl") is no file name; a name in
brackets comes first ("[01/77][LIBRATEAM_M2219009.par2]",
"-^-[Mnozil Brass - Seven.nzb]-^-").
- A leading date is no item number ("09-30-2008_BAK_JRS.r00": a daily
show's 32,621 files were one release under the poster's tag).
- The file name repeated elsewhere in the subject goes too
("(NELET11.par2) [01/58] - "NELET11.par2"").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
6.0 KiB
TypeScript
103 lines
6.0 KiB
TypeScript
import { test } from '@japa/runner'
|
|
import { fileKey, parseSubject } from '#lib/headers/index'
|
|
import { parseXrefGroups } from '#lib/nntp/index'
|
|
|
|
test.group('subject / parseSubject', () => {
|
|
test('parses file counter, filename and segment counter', ({ assert }) => {
|
|
assert.deepEqual(parseSubject('. - [09/51] - "obrMkrDeLmbhaouwYO34.part08.rar" yEnc (56/274)'), {
|
|
name: 'obrMkrDeLmbhaouwYO34.part08.rar',
|
|
segment: 56,
|
|
totalSegments: 274,
|
|
fileIndex: 9,
|
|
fileTotal: 51,
|
|
base: '. - [09/51] - "obrMkrDeLmbhaouwYO34.part08.rar" yEnc',
|
|
})
|
|
})
|
|
|
|
test('handles a file size after the segment counter', ({ assert }) => {
|
|
const subject = '[8/9] - "x.tar.zst.vol063+064.par2" yEnc (37/72) 51315352'
|
|
const parsed = parseSubject(subject)!
|
|
assert.equal(parsed.segment, 37)
|
|
assert.equal(parsed.totalSegments, 72)
|
|
assert.equal(parsed.base, '[8/9] - "x.tar.zst.vol063+064.par2" yEnc 51315352')
|
|
})
|
|
|
|
test('ignores counters inside the filename', ({ assert }) => {
|
|
const parsed = parseSubject('"Show (1/2) Special.mkv" yEnc (3/10)')!
|
|
assert.equal(parsed.name, 'Show (1/2) Special.mkv')
|
|
assert.equal(parsed.segment, 3)
|
|
assert.equal(parsed.totalSegments, 10)
|
|
})
|
|
|
|
test('the base is equal for all segments of one file', ({ assert }) => {
|
|
const a = parseSubject('[1/9] - "a.tar.zst" yEnc (253/1000) 716554110')!
|
|
const b = parseSubject('[1/9] - "a.tar.zst" yEnc (254/1000) 716554110')!
|
|
assert.equal(a.base, b.base)
|
|
})
|
|
|
|
test('returns null for obfuscated or invalid subjects', ({ assert }) => {
|
|
assert.isNull(parseSubject('GZFDJc0hB3Y0FwwAznkk'))
|
|
assert.isNull(parseSubject('"name.rar" yEnc'))
|
|
assert.isNull(parseSubject('"name.rar" yEnc (0/5)'))
|
|
assert.isNull(parseSubject('"name.rar" yEnc (6/5)'))
|
|
assert.isNull(parseSubject('"" yEnc (1/5)'))
|
|
// A counter but no file name: still obfuscated.
|
|
assert.isNull(parseSubject('[7w] - 9BbEV2MrTi59GBTEFlVrssBrXNwXf2SK9cQEeDjg yEnc (1/12432)'))
|
|
assert.isNull(parseSubject('Re: Will somebody answer the question? (1/2)'))
|
|
})
|
|
|
|
test('a quoted text without an extension gives way to a file name beside it (nameBesideQuotes)', ({ assert }) => {
|
|
assert.equal(parseSubject("My \"Official\" remaining set's of Inna, Please help up to #69 if you can 025.jpg [25/74] - yEnc (1/1)")!.name, '025.jpg')
|
|
assert.equal(parseSubject('"Dr. Lust" - Lily Marlene, Vanessa Del Rio, Scorpio? - yEnc - [12/21] - Ed_DRL_VDR_LM.part09.rar (1/80)')!.name, 'Ed_DRL_VDR_LM.part09.rar')
|
|
assert.equal(parseSubject('Unknown Model - Cleaning The Hard Drive ~ lr140x16.jpg ( file 046 of 922) "yEnc" (1/1)')!.name, 'lr140x16.jpg')
|
|
// A random quoted name with no file name beside it keeps its name.
|
|
assert.equal(parseSubject('77cd6d03d19281a775f5bdc5 [2/8] - "1f0554e5fec14b8b05ca" yEnc (14/567)')!.name, '1f0554e5fec14b8b05ca')
|
|
})
|
|
|
|
test('finds the file name of subjects without a quoted one (unquotedName)', ({ assert }) => {
|
|
const cases: [string, string, number, number, number?][] = [
|
|
['DVDFab 8.2.0.5.rar (006/332)', 'DVDFab 8.2.0.5.rar', 6, 332],
|
|
['q3B9OrpKiCxUnzgtUGnp.part023.rar (104/137)', 'q3B9OrpKiCxUnzgtUGnp.part023.rar', 104, 137],
|
|
['New_Super_Mario_Bros._[Keygen].exe (1/2)', 'New_Super_Mario_Bros._[Keygen].exe', 1, 2],
|
|
['Emily_18_-_Bed.part01.rar Emily 18 bed video FULL NUDE (01/24)', 'Emily_18_-_Bed.part01.rar', 1, 24],
|
|
['[33/117] 674a37548b09.dat (1/1)', '674a37548b09.dat', 1, 1, 33],
|
|
['A Strange Light from the East - Eastern Influenced Western Music (1965-72) - CD2 - 07 - Rascals - Sattva.mp3 (1/43)', '07 - Rascals - Sattva.mp3', 1, 43],
|
|
["pal! [Mivina high(1).wmv\" yEnc] (323/349)", 'Mivina high(1).wmv', 323, 349],
|
|
['[03/21 Geroellheimer - S03E16.part01.rar" yEnc (1/50)', 'Geroellheimer - S03E16.part01.rar', 1, 50],
|
|
['<Group> FP -> {EXL01~P~004} -> Alexia (3) -> VF -> [0001 of 0076] -> Exclusive-tgirls_000000-lg.jpg (1/1)', 'Exclusive-tgirls_000000-lg.jpg', 1, 1],
|
|
["<abm> <Duke> here's a little thanksgiving present: AB: part2 0573-1002 043.jpg (1/1)", '043.jpg', 1, 1],
|
|
["xlady post You, Me And Dupree www.x2l.nl [001/106] 'You, Me And Dupree.nfo' (1/1)", 'You, Me And Dupree.nfo', 1, 1],
|
|
['[01/77][LIBRATEAM_M2219009.par2] Onbeperkt downloaden met een snelheid van 1,22 MB p.s. en dat voor maar 7,95 p.m. www.libranews.nl (1/1)', 'LIBRATEAM_M2219009.par2', 1, 1],
|
|
['patensas post -^-[Mnozil Brass - Seven.nzb]-^-www.usenet2day.cc -^-[000/107]-^-www.libranews.nl-^- yEnc (1/1)', 'Mnozil Brass - Seven.nzb', 1, 1],
|
|
['(01/26) "01 Time Machine (You Are The Master Of Time-Age).mp3" "Silicon Dream - Time Machine_BY_WaRLoRD```` yEnc (1/1)', '01 Time Machine (You Are The Master Of Time-Age).mp3', 1, 1],
|
|
['Bondage-xxx-DVDRIP-XviD_By_GARM (02/74) "Bondage-xxx-DVDRIP-XviD.nfo" " yEnc (1/1)', 'Bondage-xxx-DVDRIP-XviD.nfo', 1, 1],
|
|
['W44-K14-TheMan @ D4D.cc (sjappie45) Op [000/103] - "W44-K14-TheMan @ D4D.cc (sjappie45) Op.nzb" yEnc" (1/1)', 'W44-K14-TheMan @ D4D.cc (sjappie45) Op.nzb', 1, 1],
|
|
]
|
|
for (const [subject, name, segment, total, fileIndex] of cases) {
|
|
const parsed = parseSubject(subject)
|
|
assert.include(parsed, { name, segment, totalSegments: total }, subject)
|
|
if (fileIndex) assert.equal(parsed!.fileIndex, fileIndex)
|
|
}
|
|
})
|
|
})
|
|
|
|
test.group('subject / fileKey', () => {
|
|
test('differs per poster and per segment count, is stable otherwise', ({ assert }) => {
|
|
const key = fileKey('poster@a', '"x.rar" yEnc', 10)
|
|
assert.lengthOf(key, 40)
|
|
assert.equal(key, fileKey('poster@a', '"x.rar" yEnc', 10))
|
|
assert.notEqual(key, fileKey('poster@b', '"x.rar" yEnc', 10))
|
|
assert.notEqual(key, fileKey('poster@a', '"x.rar" yEnc', 11))
|
|
})
|
|
})
|
|
|
|
test.group('nntp / parseXrefGroups', () => {
|
|
test('extracts crossposted groups', ({ assert }) => {
|
|
assert.deepEqual(
|
|
parseXrefGroups('news.eweka.nl alt.binaries.nl:35801424104 alt.binaries.test:27275430913'),
|
|
['alt.binaries.nl', 'alt.binaries.test']
|
|
)
|
|
assert.deepEqual(parseXrefGroups(undefined), [])
|
|
})
|
|
})
|