Files
usenet-indexer/tests/unit/release/identity.spec.ts
T
Daan MeijerandClaude Opus 5.5 c624a624df
Test and deploy / test (push) Successful in 55s
Test and deploy / edge (push) Successful in 1m57s
Test and deploy / deploy (push) Successful in 2m13s
Take the image set head back out of the subject key
f1c5af5's set head (an image's name up to its first number) split sets whose
images aren't named alike: "a1.jpg" beside "a1 (2).jpg", and "468_1000.jpg"
whose first number is the image's (1 release became 211 and 161 on the
corpus). The random volume stem stays. Tests keep both sets whole.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:14:17 +02:00

576 lines
41 KiB
TypeScript

import { test } from '@japa/runner'
import { fileStem, releaseIdentity, runOn, sizeAfterName, subjectRemainder } from '#lib/release/index'
import { looksLikeFilename, weakFileKey } from '#lib/headers/index'
test.group('release / fileStem', () => {
test('reduces all files of a set to the same stem', ({ assert }) => {
const names = [
'1790546808_nicovideo_jp_watch_sm26679715.tar.zst',
'1790546808_nicovideo_jp_watch_sm26679715.tar.zst.par2',
'1790546808_nicovideo_jp_watch_sm26679715.tar.zst.vol03+04.par2',
]
assert.deepEqual(new Set(names.map(fileStem)), new Set(['1790546808_nicovideo_jp_watch_sm26679715']))
})
test('handles rar, split and par2 volume naming', ({ assert }) => {
assert.equal(fileStem('lJzuoIKA3T8xjzAD3vqtw0.part036.rar'), 'lJzuoIKA3T8xjzAD3vqtw0')
assert.equal(fileStem('Some.Movie.2024.r07'), 'Some.Movie.2024')
assert.equal(fileStem('Some.Movie.2024.mkv.001'), 'Some.Movie.2024')
assert.equal(fileStem('Some.Movie.2024.2160p.WEB-DL.H.265.mkv'), 'Some.Movie.2024.2160p.WEB-DL.H.265')
assert.equal(fileStem('Some.Movie.2024.H.264.nzb'), 'Some.Movie.2024.H.264')
assert.equal(fileStem('Some.Movie.2024.vol127-128.par2'), 'Some.Movie.2024')
assert.equal(fileStem('Some.Movie.2024.nfo'), 'Some.Movie.2024')
assert.equal(fileStem('00-artist-album-web-2026.m3u'), '00-artist-album-web-2026')
assert.equal(fileStem('f6dd6b156692a52b.bin'), 'f6dd6b156692a52b')
})
test('never reduces a name to nothing', ({ assert }) => {
assert.equal(fileStem('.par2'), '.par2')
})
})
test.group('release / subjectRemainder', () => {
test('is empty when the subject only has counters, filename and size', ({ assert }) => {
assert.equal(subjectRemainder('[1/4] - "x.tar.zst" yEnc 15411409'), '')
assert.equal(subjectRemainder('. - [00/88] - "60SHkTQSvn5RZGExwju2.nzb" yEnc'), '')
})
test('keeps a release name written outside the quotes', ({ assert }) => {
assert.equal(
subjectRemainder('Some.Show.S01E02.1080p [03/40] - "abc.part02.rar" yEnc'),
'Some Show S01E02 1080p'
)
})
})
test.group('release / releaseIdentity', () => {
test('groups a par2 set with its archive by stem, per poster', ({ assert }) => {
const base = { poster: 'p', weak: false }
const a = releaseIdentity({ ...base, subject: '[1/4] - "x.tar.zst" yEnc 1', name: 'x.tar.zst' })!
const b = releaseIdentity({ ...base, subject: '[3/4] - "x.tar.zst.vol01+02.par2" yEnc 2', name: 'x.tar.zst.vol01+02.par2' })!
assert.equal(a.key, b.key)
assert.equal(a.name, 'x')
assert.equal(a.fileTotal, 4)
const other = releaseIdentity({ ...base, poster: 'q', subject: '[1/4] - "x.tar.zst" yEnc 1', name: 'x.tar.zst' })!
assert.notEqual(a.key, other.key)
})
test('a par2 index posted without [i/M] counter joins its release', ({ assert }) => {
const base = { poster: 'nicovideo_archiver', weak: false }
const archive = releaseIdentity({ ...base, subject: '[1/6] - "x.tar.zst" yEnc 105054576', name: 'x.tar.zst' })!
const index = releaseIdentity({ ...base, subject: '"x.tar.zst.par2" yEnc 3100', name: 'x.tar.zst.par2' })!
assert.equal(index.key, archive.key)
assert.equal(archive.fileTotal, 6)
assert.isUndefined(index.fileTotal)
})
test('uses the subject text when it names the release', ({ assert }) => {
const base = { poster: 'p', weak: false }
const a = releaseIdentity({ ...base, subject: 'My.Release [01/40] - "abc.part01.rar" yEnc', name: 'abc.part01.rar' })!
const b = releaseIdentity({ ...base, subject: 'My.Release [40/40] - "abc.par2" yEnc', name: 'abc.par2' })!
assert.equal(a.key, b.key)
assert.equal(a.name, 'My Release')
})
test('obfuscated volumes group by stem regardless of the random poster', ({ assert }) => {
const a = releaseIdentity({ poster: '3Uzx7TTSFpLzz@ngPost.com', subject: '"lJzu.part033.rar" yEnc', name: 'lJzu.part033.rar', weak: true })!
const b = releaseIdentity({ poster: 'bGLd1oaXRdrK1@ngPost.com', subject: '"lJzu.part034.rar" yEnc', name: 'lJzu.part034.rar', weak: true })!
assert.equal(a.key, b.key)
})
test('capitals and digits switching all over a token are random', async ({ assert }) => {
const { looksRandom } = await import('#lib/release/index')
assert.isTrue(looksRandom('51294P1CUKR2R35X'))
assert.isTrue(looksRandom('51294P1CUKR2R35X.part01.rar'.replace(/\.part01\.rar$/, '')))
assert.isFalse(looksRandom('COD4MW2REMASTERED'))
assert.isFalse(looksRandom('BEATLES1964REMASTER'))
assert.isFalse(looksRandom('HDTV1080P'))
})
test('random extensionless names cannot be grouped by name', ({ assert }) => {
const name = '204b914a977e5f891590ff1099c7a8caf1a0be537bfa5bf7f3a8b1213231'
assert.isNull(releaseIdentity({ poster: 'x', subject: `"${name}" yEnc`, name, weak: true }))
})
})
test.group('subject / weakFileKey', () => {
test('ignores random per-article names, keeps real filenames', ({ assert }) => {
assert.isFalse(looksLikeFilename('204b914a977e5f891590ff1099c7a8caf1a0be537bfa5bf7f3a8b1213231'))
assert.isTrue(looksLikeFilename('lJzuoIKA3T8xjzAD3vqtw0.part033.rar'))
// Same file, different random names per article: same key.
assert.equal(weakFileKey('aaaa1111', 5000, 7), weakFileKey('bbbb2222', 5000, 7))
// Equal-sized volumes with real names: different keys.
assert.notEqual(weakFileKey('x.part01.rar', 5000, 7), weakFileKey('x.part02.rar', 5000, 7))
assert.notEqual(weakFileKey('aaaa1111', 5000, 7), weakFileKey('aaaa1111', 5001, 7))
})
})
test.group('release / rarReleaseIdentity', () => {
test('groups volumes by the shared top-level directory', async ({ assert }) => {
const { rarReleaseIdentity } = await import('#lib/release/index')
const first = rarReleaseIdentity([
{ name: 'LASZR_-_DYING_ALIVE-(PRO094)-WEB-2026-DIM/00-cover.jpg', size: 589382 },
{ name: 'LASZR_-_DYING_ALIVE-(PRO094)-WEB-2026-DIM/01-track.flac', size: 30_000_000 },
])!
const later = rarReleaseIdentity([{ name: 'LASZR_-_DYING_ALIVE-(PRO094)-WEB-2026-DIM/03-track.flac', size: 29_000_000 }])!
assert.equal(first.key, later.key)
assert.equal(first.name, 'LASZR_-_DYING_ALIVE-(PRO094)-WEB-2026-DIM')
assert.equal(first.source, 'rar')
})
test('without a directory, volumes of one file share its first entry', async ({ assert }) => {
const { rarReleaseIdentity } = await import('#lib/release/index')
const a = rarReleaseIdentity([{ name: 'Some.Show.S01E01.1080p.mkv', size: 3_000_000_000 }])!
const b = rarReleaseIdentity([{ name: 'Some.Show.S01E01.1080p.mkv', size: 3_000_000_000 }])!
assert.equal(a.key, b.key)
assert.equal(a.name, 'Some.Show.S01E01.1080p')
assert.isNull(rarReleaseIdentity([]))
})
})
test.group('release / namesRelease', () => {
test('random per-file tags and poster ids are not a release name', async ({ assert }) => {
const { namesRelease, subjectRemainder, releaseIdentity } = await import('#lib/release/index')
const subject = 'elys-de81bcabef5faf6a - [Nyh5Q07Y] "JkpNIFg7En50zU1U" yEnc'
assert.isFalse(namesRelease(subjectRemainder(subject)))
const a = releaseIdentity({ poster: 'elys', subject, name: 'JkpNIFg7En50zU1U', weak: false })!
assert.equal(a.source, 'stem')
assert.isTrue(namesRelease(subjectRemainder('Some.Show.S01E02.1080p [03/40] - "abc.part02.rar" yEnc')))
assert.isTrue(namesRelease('My Release'))
})
})
test.group('release / post id', () => {
test('groups random-named files of one post by poster, post id and file count', async ({ assert }) => {
const { releaseIdentity, isPostToken } = await import('#lib/release/index')
const base = { poster: 'jW344UtC8R2bZEegrVLz@x', weak: false }
const a = releaseIdentity({ ...base, subject: '83110629-n [10/18] - "eiae6fulpolas2adfts6o8643n3e6j6ct8d3219aau0jc33ol9r50tohncgr46evpl0dqoqktfb7k" yEnc', name: 'eiae6fulpolas2adfts6o8643n3e6j6ct8d3219aau0jc33ol9r50tohncgr46evpl0dqoqktfb7k' })!
const b = releaseIdentity({ ...base, subject: '83110629-n [01/18] - "2ef0vm4kb618nv17kn0qsb0j1ofh7pgqtk5a3v5lkqqf1f7g6ed0" yEnc', name: '2ef0vm4kb618nv17kn0qsb0j1ofh7pgqtk5a3v5lkqqf1f7g6ed0' })!
assert.equal(a.key, b.key)
assert.equal(a.source, 'post')
assert.equal(a.fileTotal, 18)
const other = releaseIdentity({ ...base, subject: '83110630-n [01/18] - "x" yEnc', name: 'x' })!
assert.notEqual(a.key, other.key)
assert.isTrue(isPostToken('83110629 n'))
assert.isFalse(isPostToken('PRiVATE'))
assert.isFalse(isPostToken(''))
// Without a counter there is nothing to bound the post: fall back to the stem.
assert.equal(releaseIdentity({ ...base, subject: '83110629-n - "x.bin" yEnc', name: 'x.bin' })!.source, 'stem')
})
})
test.group('release / par2 names', () => {
test('names a season pack after what its episodes share', async ({ assert }) => {
const { par2ReleaseName } = await import('#lib/release/index')
const eps = Array.from({ length: 20 }, (_, i) =>
`SEAL.Team.S03E${String(i + 1).padStart(2, '0')}.1080p.AMZN.WEB-DL.AAC2.0.H.265.DUAL-nitrato.mkv`)
assert.equal(par2ReleaseName(eps), 'SEAL.Team.S03.1080p.AMZN.WEB-DL.AAC2.0.H.265.DUAL-nitrato')
// Movie plus sample and nfo: the movie's (longest) name.
assert.equal(
par2ReleaseName(['Some.Movie.2024.1080p.BluRay.x264-GRP.mkv', 'Some.Movie.2024.1080p.BluRay.x264-GRP.nfo', 'sample.mkv']),
'Some.Movie.2024.1080p.BluRay.x264-GRP'
)
// Numbered parts: the shared name without the part number.
assert.equal(par2ReleaseName(['Album.Name-2024-GRP.part01.rar', 'Album.Name-2024-GRP.part02.rar']), 'Album.Name-2024-GRP')
assert.equal(par2ReleaseName(['only.one.file.2024.mkv']), 'only.one.file.2024')
})
test('a random poster per file is no part of the key; a real poster is', async ({ assert }) => {
const { randomPoster } = await import('#lib/release/identity')
const ftd = '-Alight_Upon_the_Lake_(Live_at_the_Jazz_Showcase_Jun_1975)-WEB-2026-FTD'
const a = releaseIdentity({ poster: 'N9vplIaavBCz@aCTVoAsk.JSE', subject: `[1/6] - "Yusef_Lateef${ftd}.par2" yEnc 1744`, name: `Yusef_Lateef${ftd}.par2`, weak: false })!
const b = releaseIdentity({ poster: 'FVWWHku0fGAg@QfaTz0g0.RVH', subject: `[3/6] - "Yusef_Lateef${ftd}.part2.rar" yEnc 104857600`, name: `Yusef_Lateef${ftd}.part2.rar`, weak: false })!
assert.equal(a.key, b.key)
assert.isTrue(randomPoster('N9vplIaavBCz@aCTVoAsk.JSE'))
assert.isFalse(randomPoster('Captain Salvo <Capt@Salvo.com>'))
assert.isFalse(randomPoster('Poster49118 <Poster49118@generic.mail>'))
assert.isFalse(randomPoster('w.merklein@freenet.de (muffin)'))
})
test('album tracks with unquoted names are one release per disc', async ({ assert }) => {
const { parseSubject } = await import('#lib/headers/index')
const id = (subject: string) => releaseIdentity({ poster: 'Hannah_Qe@hotmail.com (Spidey)', subject: subject.replace(/ \(\d+\/\d+\)$/, ''), name: parseSubject(subject)!.name, weak: false })!
const album = 'A Strange Light from the East - Eastern Influenced Western Music (1965-72) - CD2'
assert.equal(id(`${album} - 07 - Rascals - Sattva.mp3 (1/43)`).key, id(`${album} - 08 - Incredible String Band - Koeeoaddi There.mp3 (1/47)`).key)
})
test('more splits from the re-index: spaces in unquoted names, audio tracks, sizes before yEnc, posters with separators', async ({ assert }) => {
const { parseSubject } = await import('#lib/headers/index')
const { randomPoster } = await import('#lib/release/identity')
// As the edge worker: the subject without its counter and with collapsed spaces, the name as parsed.
const id = (poster: string, subject: string) => {
const name = parseSubject(subject)!.name
const base = subject.replace(/\(\d+\/\d+\)\s*$/, '').replace(/\s+/g, ' ').trim()
return releaseIdentity({ poster, subject: base, name, weak: false })!
}
const makz = 'Makz@BlueRadiance.uni (makz)'
assert.equal(id(makz, 'G:\\posting\\thegoodnudes\\lara_bath 15of19 larabath_2.5.jpg (1/1)').key, id(makz, 'G:\\posting\\thegoodnudes\\lara_bath 16of19 larabath_2.6.jpg (1/1)').key)
const mara = 'Mara <guest@cox.net>'
assert.equal(id(mara, 'RP - File 268 of 295 - yEnc "Elizabeth Peters - (Peabody 09) Seeing A Large Cat - D11.16-22.mp3" (1/3)').key, id(mara, 'RP - File 269 of 295 - yEnc "Elizabeth Peters - (Peabody 09) Seeing A Large Cat - D11.17-22.mp3" (1/3)').key)
const mb = 'misterb@sure.com (MisterB)'
assert.equal(id(mb, 'Herb Ernst@256 - NMR -[07/17] "Herb Ernst - Dreamflight II - 05 - The Light of Forever.mp3" - 8123 yEnc (1/9)').key, id(mb, 'Herb Ernst@256 - NMR -[08/17] "Herb Ernst - Dreamflight II - 06 - Other.mp3" - 9001 yEnc (1/9)').key)
assert.isTrue(randomPoster('SOFZRw1-OTEd@EEFUbh.srG'))
assert.isTrue(randomPoster('vMgGYlZB9ZcTNk8WxYFGV_OOW@x6YR.abc'))
assert.isFalse(randomPoster('w.merklein@freenet.de (muffin)'))
})
test('image sets by their numbered name, digits kept; names without numbers name no set', ({ assert }) => {
const silver = (n: string) => releaseIdentity({ poster: 'p', subject: `The excellent STIRILING SILVER - Always popular - "${n}" yEnc 320794 bytes`, name: n, weak: false })!
assert.equal(silver('stp250x001.jpg').key, silver('stp250x002.jpg').key)
assert.notEqual(silver('stp250x001.jpg').key, silver('stp305x001.jpg').key)
const mint = (n: string) => releaseIdentity({ poster: 'Cert', subject: `I'm not a breath mint, but I am not all there either. [${n}" yEnc]`, name: n, weak: false })!
assert.equal(mint('JimAndJoey Kindly Husband-to-Be.JPG').key, mint('Oops OnlyOneMore.JPG').key)
})
test("an image's set: suffixes that don't count the images go first", async ({ assert }) => {
const { imageSet } = await import('#lib/release/identity')
for (const [stem, set] of [
['stp250x001', 'stp250x'],
['cutie-071-032', 'cutie-071-'],
['katelg010_10', 'katelg'],
['kate112lg035_35', 'kate112lg'],
['!!hgrscans1097_2009', '!!hgrscans'],
['pj02kristina_24of40_1600', 'pj02kristina_'],
['keira_s04_l keira_s04_0040_l', 'keira_s04_l keira_s04_'],
['IMG_2676', 'IMG_'],
['2877-041', '2877-'],
['051 - White leather kate054001_1_1', '051 - White leather kate'],
['108 - Schoolwall kate108lg029_28', '108 - Schoolwall kate108lg'],
['kurozo-2006-7-26-15-21', ''],
['bwp2_037_5', 'bwp2_'],
['Set 008 10of63 new0464', 'Set 008 '],
['202/430 princess-079-058', ''],
['( 098 /500) 002 148', ''],
['New Folder (17) sexypattycake_0903040445[1]', 'New Folder ('],
['092_081_2000x1500', '092_'],
['KP0027_197_00', 'KP'],
['01079-106-2048px', '01079-'],
['diana-050-052[1][1]', 'diana-050-'],
['sss-70556-3474182-23-10825418-pc', ''],
['Alena p 26663_alena-p-2-8323_123_39lo', ''],
['she has sensual legs 172 _ 172', 'she has sensual legs '],
['jamie.lee.curtis_the.tailor.of.panama_17_123_244lo', 'jamie.lee.curtis_the.tailor.of.panama_'],
['JimAndJoey Kindly Husband-to-Be', ''],
]) assert.equal(imageSet(stem), set, stem)
})
test("a set's number before the closing yEnc is no size", ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const destiny = (set: number, i: number) => {
const name = `destiny-${String(set).padStart(3, '0')}-${String(i).padStart(3, '0')}.jpg`
return id(`Newstar Destiny I set ${set} [${i} of 60] "${name}" yEnc`, name)
}
assert.equal(destiny(1, 1).key, destiny(1, 2).key)
assert.notEqual(destiny(1, 1).key, destiny(63, 34).key)
assert.equal(destiny(63, 34).name, 'Newstar Destiny I set 63')
})
test('other quoted text and text separators name the release', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const cc = (name: string, n: string) =>
id(`>>> CREATIVE COMMONS NZB <<< "${name} " - File 1 of 9: "creative_commons_nzb_${n}.rar" yEnc`, `creative_commons_nzb_${n}.rar`)
assert.notEqual(cc('0190 alarm 5.0', '0190_alarm_5.0_').key, cc('portable irfanview 4.22', 'portable_irfanview_4.22').key)
const vlad = (dir: string, total: number, n: string) =>
id(`Posting & deleting, read 0 file "E:\\VladModels\\y038_Irina\\${dir}" Day 5/6 [01/${total}] - ${n} yEnc`, n)
assert.equal(vlad('185', 77, 'P8250001.JPG').source, 'subject')
assert.notEqual(vlad('185', 77, 'P8250001.JPG').key, vlad('234', 77, 'P5300085.JPG').key)
})
test('per-file hex ids go; dated stems are specific; season packs under a bare counter', ({ assert }) => {
const id = (poster: string, subject: string, name: string) => releaseIdentity({ poster, subject, name, weak: false })!
const nz = (hex: string, i: number, n: string) =>
id('nEwZ', `[PRiVATE] Rosewood.S02E08.SPANiSH.1080p.HDTV.x264-FCC [${hex}] [newzNZB] [${String(i).padStart(2, '0')}/22] - "${n}" yEnc`, n)
assert.equal(nz('1f1793f68d5321', 1, '[05cbdb538a]_x.nfo').key, nz('65e6464bc03cad', 2, '[e8a4e2c182]_x.r03').key)
const show = (n: string) => id('#sterntuary <aa@aa.com>', `#sterntuary - Coast To Coast Radio Show - "${n}" yEnc`, n)
assert.equal(show('09-30-2008_CTC.nfo').key, show('09-30-2008_CTC.r00').key)
assert.notEqual(show('09-30-2008_CTC.r00').key, show('10-01-2008_CTC.r00').key)
const ep = (i: number, n: string) => id('p', `[${String(i).padStart(2, '0')}/36] "${n}"`, n)
assert.equal(ep(1, 'Pokemon - S02E01 - Pallet Party Panic.mkv').key, ep(2, 'Pokemon - S02E02 - Gotta Catch Ya Later.mkv').key)
assert.equal(ep(1, 'Pokemon - S02E01 - Pallet Party Panic.mkv').name, 'Pokemon S02')
assert.notEqual(ep(1, 'Pokemon - S02E01 - Pallet Party Panic.mkv').key, ep(1, 'Pokemon - S03E01 - x.mkv').key)
})
test('spaces at a dash are no part of a stem key', ({ assert }) => {
const id = (i: string, n: string) => releaseIdentity({ poster: 'JBinUp', subject: `[${i}/58] - Summer Power Up - "${n}" yEnc`, name: n, weak: false })!
assert.equal(id('01', 'www.realmom.info - XVID- Farbiges Krabbeltier.r00').key, id('54', 'www.realmom.info - XVID-Farbiges Krabbeltier.vol03+04.par2').key)
})
test("a scene index's files go with the release: no case, no 00-", ({ assert }) => {
const id = (n: string) => releaseIdentity({ poster: 'SavageCobra <x@y.nhc>', subject: n, name: n, weak: false })!
const a = id('00-laura_van_dam_-_capture_radio_113-cable-10-10-2026-talion.m3u')
const b = id('Laura_van_Dam_-_Capture_Radio_113-CABLE-10-10-2026-TALiON.vol000+001.par2')
assert.equal(a.key, b.key)
assert.equal(b.name, 'Laura_van_Dam_-_Capture_Radio_113-CABLE-10-10-2026-TALiON')
})
test('old rar volumes, recovery volumes, a part\'s par2, BCArchive volumes; a size after an unquoted name', ({ assert }) => {
assert.equal(fileStem('BD_NoTHing018.s41'), 'BD_NoTHing018')
assert.equal(fileStem('x8ZRmX5N83mrokOwqJtoIGHTrqXQrgCyj.s00'), 'x8ZRmX5N83mrokOwqJtoIGHTrqXQrgCyj')
// A season stays.
assert.equal(fileStem('the.office.us.s01.rar'), 'the.office.us.s01')
assert.equal(fileStem('Some.Show.S01'), 'Some.Show.S01')
assert.equal(fileStem('Electric.Rain.Swift.3D.PS.v1.0.142.x64'), 'Electric.Rain.Swift.3D.PS.v1.0.142.x64')
assert.equal(fileStem('App.x86'), 'App.x86')
assert.equal(fileStem('Licence 700790900887990.z18'), 'Licence 700790900887990')
assert.equal(fileStem('Licence 077887994400668.x12'), 'Licence 077887994400668')
assert.equal(fileStem('Reply 987986177631730.x004'), 'Reply 987986177631730')
assert.equal(fileStem('goh1Phoz5ahXu.par.vol006+08.par2'), 'goh1Phoz5ahXu')
assert.equal(fileStem('brSWc0Q2KWblQpogOmgbn9.part.par2'), 'brSWc0Q2KWblQpogOmgbn9')
assert.equal(fileStem('x.parts.par2'), 'x.parts')
assert.equal(fileStem('Some.Movie.2010.x264'), 'Some.Movie.2010.x264')
assert.equal(runOn('lois 1258 Billy Joel - Extremes.part01.rar lois 1258 Billy Joel - Extremes '), 'lois 1258 Billy Joel - Extremes.part01.rar')
assert.equal(runOn('GrooveCoverage.part26.rarGrooveCoveragebestof'), 'GrooveCoverage.part26.rar')
assert.equal(runOn('Goga Sekulic.part134.rar - Goga Sekulic - Diskografija (2000-2014).'), 'Goga Sekulic.part134.rar')
assert.equal(runOn('HASf293jLAIWUELvhaG3.part091.rar HASf293jLAIWUELvhaG3'), 'HASf293jLAIWUELvhaG3.part091.rar')
assert.equal(runOn('Movie.rar.Collection.mkv'), 'Movie.rar.Collection.mkv')
assert.equal(runOn('Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar'), 'Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar')
assert.equal(runOn('x.part01.rar'), 'x.part01.rar')
const lois = (i: string, n: string) => releaseIdentity({ poster: 'p', subject: `(thnx to original poster) [${i}/92] - "${n}" yEnc`, name: n, weak: false })!
assert.equal(lois('02', 'lois 1258 Billy Joel - Extremes.part01.rar lois 1258 Billy Joel - Extremes ').key, lois('01', 'lois 1258 Billy Joel - Extremes.par2 lois 1258 Billy Joel - Extremes ').key)
assert.equal(fileStem('chappelle1.part02.rev'), 'chappelle1')
assert.equal(fileStem('chappelle1.rev'), 'chappelle1')
assert.equal(fileStem('VwE3i90MVX9dqMFuDfzdS7Q6.part1.par2'), 'VwE3i90MVX9dqMFuDfzdS7Q6')
assert.equal(fileStem('VwE3i90MVX9dqMFuDfzdS7Q6.part1.vol00+34.par2'), 'VwE3i90MVX9dqMFuDfzdS7Q6')
assert.equal(fileStem('Movie.Part1.mkv'), 'Movie.Part1')
assert.equal(fileStem('NZPECQUztWOponTpCratvvTPDBXBjvHIULOUPvSH.180.bc'), 'NZPECQUztWOponTpCratvvTPDBXBjvHIULOUPvSH')
assert.equal(sizeAfterName('(Hot MILF getting banged hard)[27/70] - 2407.jpg - 28', '2407.jpg'), '(Hot MILF getting banged hard)[27/70] - 2407.jpg')
assert.equal(sizeAfterName('Show [01/10] - "a.jpg" - 28', 'a.jpg'), 'Show [01/10] - "a.jpg" - 28')
assert.equal(sizeAfterName('Show - Episode 05', 'x.mkv'), 'Show - Episode 05')
const milf = (i: string, n: string, kb: string) => releaseIdentity({ poster: 'p', subject: `(Hot MILF getting banged hard)[${i}/70] - ${n} - ${kb}`, name: n, weak: false })!
assert.equal(milf('27', '2407.jpg', '28').key, milf('28', '2408.jpg', '31').key)
})
test("split rar volumes; a file's size in brackets after its counter", ({ assert }) => {
assert.equal(fileStem('rld-gtre.r13.002'), 'rld-gtre')
const k = (i: number, size: number, n: string) =>
releaseIdentity({ poster: 'Kingdn', subject: `Buffy The Vampire Slayer s02e04 [${i}/32] - [${size}] "${n}" yEnc`, name: n, weak: false })!
assert.equal(k(26, 4929, 'Buffy s02e04 xvid-tns.part24.rar').key, k(27, 400, 'Buffy s02e04 xvid-tns.vol00+01.PAR2').key)
})
test('a total padded wider than its index is no counter', ({ assert }) => {
const who = (i: number, n: string) =>
releaseIdentity({ poster: 'p', subject: `Very Best Of The Who [${String(i).padStart(2, '0')}/${String(i * 10).padStart(3, '0')}] - "${n}" yEnc`, name: n, weak: false })!
assert.equal(who(3, "The Who - 01 - I Can't Explain.mp3").key, who(4, 'The Who - 02 - Anyway.mp3').key)
assert.isUndefined(who(3, "The Who - 01 - I Can't Explain.mp3").fileTotal)
})
test('a leading date numbers no item; a file name repeated in the subject goes everywhere', ({ assert }) => {
const id = (subject: string, name: string, poster = 'p') => releaseIdentity({ poster, subject, name, weak: false })!
const show = (n: string) => id(`#sterntuary - Jeff Rense Radio Program - "${n}" yEnc`, n, '#sterntuary <aa@aa.com>')
assert.equal(show('09-30-2008_BAK_JRS.nfo').key, show('09-30-2008_BAK_JRS.r00').key)
assert.notEqual(show('09-30-2008_BAK_JRS.r00').key, show('10-01-2008_BAK_JRS.r00').key)
const nelet = (n: string, i: number) => id(`(${n}) [${String(i).padStart(2, '0')}/58] - "${n}" yEnc`, n)
assert.equal(nelet('NELET11.par2', 1).key, nelet('NELET11.part01.rar', 2).key)
const wl = (n: string) => id(`(01/26) "${n}" "Silicon Dream - Time Machine_BY_WaRLoRD\`\`\`\` yEnc`, n)
assert.equal(wl('01 Time Machine.mp3').key, wl('02 Jimmy Dean Loved Marilyn.mp3').key)
})
test('hashed stems under a tag, volume numbers as extensions, scene tracks under a bare counter', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const u4e = (n: string) => id(`Seit 1753 Tagen - usenet4ever.info - "${n}" yEnc`, n)
assert.equal(u4e('055631a1_b6c820bc_a856086c_85112a5-u4e.part01.rar').key, u4e('055631a1_b6c820bc_a856086c_85112a5-u4e.par2').key)
assert.notEqual(u4e('055631a1_b6c820bc_a856086c_85112a5-u4e.part01.rar').key, u4e('4cc7c4c6_d3c2fecf_0bff51d6_d10df86-u4e.part01.rar').key)
const gb = (n: string) => id(`German Board - [Usenet4ever.info] und [SecretUsenet.com] - "${n}" yEnc`, n)
assert.equal(gb('6c57319fbae505679737bd46a76193a1-u4e.part6.rar').key, gb('6c57319fbae505679737bd46a76193a1-u4e.par2').key)
assert.notEqual(gb('6c57319fbae505679737bd46a76193a1-u4e.part6.rar').key, gb('6fc0ff192a355703b3e81557893013b1-u4e.part6.rar').key)
assert.notEqual(gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar').key, gb('Ice.Age.4.Voll.verschoben.2012.BDRip.AC3.German.XviD-POE.part01.rar').key)
assert.equal(gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar').key, gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.par2').key)
const mac = (i: string, n: string) => id(`[1598]-[FULL]-[#a.b.teevee@EFNet]-[ MacGyver.S01E03.DVDRip.XviD-MEDiEVAL ]-[${i}/38] - "${n}" yEnc`, n)
assert.equal(mac('04', 'sample.macgy.s01e03-med.avi').key, mac('05', 'macgy.s01e03-med.r00').key)
const pck = (i: string, n: string) => id(`(????) [${i}/2195] - "${n}" yEnc`, n)
assert.equal(pck('0659', 'DN.VPL PCK.1508').key, pck('0660', 'DN.VPL PCK.1509').key)
assert.equal(pck('0659', 'DN.VPL PCK.1508').name, 'DN.VPL PCK.1508')
const movie = (i: string, n: string) => id(`[${i}/30] - "${n}" yEnc`, n)
assert.notEqual(movie('01', 'Movie.2008').key, movie('02', 'Movie.2009').key)
const track = (i: string, n: string) => id(`[${i}/14] - "${n}" yEnc`, n)
assert.equal(track('06', '02-repiet_-_dont_think_twice_(extended_mix).mp3').key, track('07', '03-repiet_-_other_song.mp3').key)
assert.equal(track('06', '02-repiet_-_dont_think_twice_(extended_mix).mp3').name, 'repiet')
assert.equal(track('01', '01-2bm_mq-real_rap_(intro).mp3').name, '2bm_mq')
const meow = (i: string, n: string) => id(`[${i}/13] - "${n}" yEnc`, n)
const tracks = meow('05', '01-ammar-turk_uit_de_kroeg.mp3').key
for (const n of ['00-ammar-turk_uit_de_kroeg-single-web-nl-2022-cover.jpg', '00-ammar-turk_uit_de_kroeg-single-web-nl-2022.nfo', '00-ammar-turk_uit_de_kroeg-single-web-nl-2022.sfv']) {
assert.equal(meow('01', n).key, tracks, n)
}
assert.notEqual(meow('01', '00-frank_van_etten-wie_heeft_jouw_lach_gestolen-single-web-nl-2022-cover.jpg').key, tracks)
const blaise = (i: string, n: string) => id(`[${i}/14] - "${n}" yEnc`, n)
assert.equal(blaise('07', 'blaise_mc-in_hellstill_3-ep-web-2022-known.par2').key, blaise('03', '00-blaise_mc-in_hellstill_3-ep-web-2022.nfo').key)
assert.equal(blaise('09', 'blaise_mc-in_hellstill_3-ep-web-2022-known.vol000+01.par2').key, blaise('05', '01-blaise_mc-intro.mp3').key)
// A rar upload keeps its full name: albums by artist and total would merge.
const hou = (i: string, n: string) => id(`[${i}/20] - "${n}" - 181.46 MB www.house-of-usenet.com yEnc`, n)
assert.notEqual(hou('03', 'VA - Best Of Shamania Pro 2K16-(SHB 006)-WEB-2016-ZzZz.part01.rar').key, hou('03', 'VA - Other Album-(SHB 007)-WEB-2016-ZzZz.part01.rar').key)
assert.equal(blaise('01', 'Ace_Of_Base-Wheel_Of_Fortune-(861_545-2)-CDM-FLAC-1992-REETKEVER.par2').key, blaise('02', 'Ace_Of_Base-Wheel_Of_Fortune-(861_545-2)-CDM-FLAC-1992-REETKEVER.part1.rar').key)
assert.notEqual(blaise('01', 'Ace_Of_Base-Wheel_Of_Fortune-(861_545-2)-CDM-FLAC-1992-REETKEVER.par2').key, blaise('01', 'Ace_Of_Base-Other-(861_546-2)-CDM-FLAC-1993-REETKEVER.par2').key)
// A film isn't a scene music release.
assert.equal(blaise('01', 'Some.Movie.2010.1080p.BluRay.x264-GRP.par2').source, 'stem')
assert.equal(blaise('01', 'Some.Movie.2010.1080p.BluRay.x264-GRP.par2').name, 'Some.Movie.2010.1080p.BluRay.x264-GRP')
})
test('a host and a sponsor without a counter name no upload', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const tn = (tag: string, n: string) => id(`(www.Thunder-News.org) >${tag}< <Sponsored by Secretusenet> - "${n}" yEnc`, n)
assert.equal(tn('XXX', 'ps-itb10b.r00').key, tn('XXX', 'ps-itb10b.par2').key)
assert.notEqual(tn('XXX', 'ps-itb10b.r00').key, tn('XXX', 'swe6-legsa.r00').key)
assert.equal(tn('XXX', 'ps-itb10b.r00').source, 'stem')
const named = tn('For.Rent.XXX.720p.Bluray.x264-DPXXXHD', 'dp-for.rent.720p.x264.r00')
assert.equal(named.source, 'subject')
assert.equal(named.key, tn('For.Rent.XXX.720p.Bluray.x264-DPXXXHD', 'dp-for.rent.720p.x264.par2').key)
assert.equal(named.name, '>For Rent XXX 720p Bluray x264 DPXXXHD<')
// With a counter the subject stays as it was: the total bounds it.
assert.equal(id('(www.Thunder-News.org) >XXX< [01/20] - "ps-itb10b.r00" yEnc', 'ps-itb10b.r00').source, 'subject')
})
test('an image under a post token is keyed by the post too', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const mdg = (post: string, i: string, n: string) => id(`${post} - (${i}/90) "${n}" - 16,14 MB - yEnc`, n)
assert.equal(mdg('MDG005b', '01', 'IMG_2307.JPG').key, mdg('MDG005b', '02', 'IMG_2308.jpg').key)
assert.notEqual(mdg('MDG005b', '01', 'IMG_2307.JPG').key, mdg('MDG006a', '01', 'IMG_4410.JPG').key)
// A size isn't a post token.
// The whole text before "(1/1)" is the name; the size follows the segment counter.
const alexi = (i: string, size: string) => {
const n = `${i}of37 ## Alexi uses strange toys to make herself come ## alexis0${i}.jpg`
return id(`${n} ${size}`, n)
}
assert.equal(alexi('01', '57295b').key, alexi('02', '32202b').key)
})
test('a set named by its prefix alone is bounded by its counter', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const lop = (i: string, total: string, n: string) => id(`[${i}/${total}] - "${n}" yEnc`, n)
assert.equal(lop('001', '559', 'lop1001.jpg').key, lop('002', '559', 'lop1002.jpg').key)
assert.notEqual(lop('001', '559', 'lop1001.jpg').key, lop('001', '1018', 'lop5001.jpg').key)
const r = (i: string, total: string, n: string) => id(`[${i}/${total}] - "${n}" yEnc`, n)
assert.equal(r('022', '457', "r86_022 - Gwen Guthrie - Ain't Nothing Going on but the Rent.mp3").key, r('085', '457', "r88_085 - Gregory Abbott - I'll Prove It to You.mp3").key)
assert.notEqual(r('022', '457', "r86_022 - Gwen Guthrie - Ain't Nothing Going on but the Rent.mp3").key, r('022', '333', "r98_333 - Jellie - Roller Coaster.mp3").key)
})
test("under a constant tag an upload's random stem bounds the subject", ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'Kim <Jong-Un@town.ag>', subject, name, weak: false })!
const town = (i: string, n: string) => id(`[ TOWN ] [ www.town.ag ] [ TV ] [${i}/20] - "${n}" yEnc`, n)
assert.equal(town('01', 'Z3mMTMPsoT4ikE_Di3fKnNF21.part01.rar').key, town('18', 'Z3mMTMPsoT4ikE_Di3fKnNF21.vol4+4.par2').key)
assert.equal(town('01', 'Z3mMTMPsoT4ikE_Di3fKnNF21.part01.rar').name, town('01', 'i3DpbaTUJT4L6V48fEBdbVV46.part01.rar').name)
assert.notEqual(town('01', 'Z3mMTMPsoT4ikE_Di3fKnNF21.part01.rar').key, town('01', 'i3DpbaTUJT4L6V48fEBdbVV46.part01.rar').key)
// A scene name keeps the subject's key, so its nfo stays with it.
const show = (i: string, n: string) => id(`Some.Show.S01E01 [${i}/20] - "${n}" yEnc`, n)
assert.equal(show('01', 'The.Big.Bang.Theory.S01E01.part01.rar').key, show('20', 'The.Big.Bang.Theory.S01E01.nfo').key)
// An image set under one subject stays one release whatever its images are named ("a1.jpg", "a1 (2).jpg"; "468_1000.jpg").
const tender = (i: string, n: string) => id(`Tender TEEN SEX in HD - File ${i} of 435 - ${n}`, n)
assert.equal(tender('001', 'a1 (2).jpg').key, tender('002', 'a1.jpg').key)
assert.equal(tender('003', 'a2 (2).jpg').key, tender('002', 'a1.jpg').key)
})
test('an image without words around it is keyed by its set', ({ assert }) => {
const id = (name: string, counter: string) => releaseIdentity({ poster: 'p', subject: `##[ "${name}" (${counter})`, name, weak: false })!
assert.equal(id('diana-040-001.jpg', '01/68').key, id('diana-040-002.jpg', '02/68').key)
assert.notEqual(id('diana-040-001.jpg', '01/68').key, id('diana-407-081.jpg', '81/82').key)
})
test('an unquoted file name is no file counter', ({ assert }) => {
const shy = (name: string) => releaseIdentity({ poster: 'p', subject: `${name} hardcore SHYLA STYLEZ & SHY LOVE`, name, weak: false })!
assert.equal(shy('shyla-shy-09-0195.jpg').key, shy('shyla-shy-09-0766.jpg').key)
assert.isUndefined(shy('shyla-shy-09-0195.jpg').fileTotal)
})
test('dates are no file counters', async ({ assert }) => {
const { counterTotal } = await import('#lib/release/identity')
assert.isUndefined(counterTotal('Avira AntiVir Rescue System 08-29-2011.rar'))
assert.isUndefined(counterTotal('Android Apps and Games Pack 27-02-2011.rar'))
assert.isUndefined(counterTotal('Supernova-clubbin (slamfm)-cable-18-08-2012-1king.rar'))
assert.equal(counterTotal('Some.Album [03/12] - "x.mp3"'), 12)
assert.equal(counterTotal('File 07390 of 19411 "x.epub"'), 19411)
})
test('split parts with two-digit numbers share a stem', ({ assert }) => {
assert.equal(fileStem('Admiral.EP05.2008.720p.Rus.HDCLUB.mkv.21'), fileStem('Admiral.EP05.2008.720p.Rus.HDCLUB.mkv.22'))
assert.equal(fileStem('Naslednica_po_prjamoy_DVDRip.avi.05'), 'Naslednica_po_prjamoy_DVDRip')
})
test('image sets: sizes in brackets and one-word set names', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
assert.equal(id('Aletta Ocean - "100628-035.jpg" yEnc [347K]', '100628-035.jpg').key, id('Aletta Ocean - "100628-036.jpg" yEnc [298K]', '100628-036.jpg').key)
const corie = id('Corie - "2877-041.jpg" yEnc [290K]', '2877-041.jpg')
assert.equal(corie.key, id('Corie - "2877-042.jpg" yEnc [301K]', '2877-042.jpg').key)
assert.equal(corie.name, 'Corie')
})
test('numbered items of a set stay one release under the set name (a course, not a poster tag)', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'Poster49118 <Poster49118@generic.mail>', subject, name, weak: false })!
const a = id('ai-engineer-complete [401/465] - "003 Defining Tools with JSON Schema.mp4" yEnc', '003 Defining Tools with JSON Schema.mp4')
const b = id('ai-engineer-complete [422/465] - "006 ai-lesson-4-5-web-search-tools.zip" yEnc', '006 ai-lesson-4-5-web-search-tools.zip')
assert.equal(a.key, b.key)
assert.equal(a.name, 'ai engineer complete')
// Karaoke discs: a disc code before the track number.
const sc = (track: string) => releaseIdentity({ poster: 'p', subject: `Spotlight - 83xx's [16/19] - "${track}.zip" yEnc`, name: `${track}.zip`, weak: false })!
assert.equal(sc('SC8367-12 - Wynette, Tammy - Singing My Song').key, sc('SC8367-13 - Jones, George - He Stopped Loving Her Today').key)
})
test("a poster's constant tag doesn't make one release of all their uploads", ({ assert }) => {
const id = (poster: string, subject: string, name: string) => releaseIdentity({ poster, subject, name, weak: false })!
// [KiLL…] tag on every upload: each album by its stem, its nfo included.
const kill = 'www.ggb.6x.to <darkness@earth.de>'
const a = id(kill, '[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (03/10) "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].r00" yEnc', 'Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].r00')
const aNfo = id(kill, '[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (01/10) "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].nfo" yEnc', 'Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].nfo')
const b = id(kill, '[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (03/10) "Shnarph.-.Lautlos.2008[[g.6x.to]].r00" yEnc', 'Shnarph.-.Lautlos.2008[[g.6x.to]].r00')
assert.equal(a.key, aNfo.key)
assert.notEqual(a.key, b.key)
assert.equal(a.source, 'stem')
// A tag taken for a post id: "(PowBeertje80 Posted)" with the same [i/M] on every album.
const pow = (album: string) => id('pow', `(PowBeertje80 Posted) [01/026] - "${album}.part01.rar" yEnc`, `${album}.part01.rar`)
assert.notEqual(pow('Bravo Hits Vol.14 2CD -1996-').key, pow('Bravo Hits Vol.33 2CD -2001-').key)
})
test('the text outside the quotes still groups when it describes the files, or is a per-post id', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
// A word in common ("ketchup"): one album of many track files.
const t1 = id('!!!!! FTA www.ftaclub.net BodyCrew Presents VA-Ketchup_Dance2008 !!!!! [01/28] - "fta-01-a_track-2008.mp3" yEnc', 'fta-01-a_track-2008.mp3')
const t2 = id('!!!!! FTA www.ftaclub.net BodyCrew Presents VA-Ketchup_Dance2008 !!!!! [02/28] - "fta-02-coyote-ketchup_mix.mp3" yEnc', 'fta-02-coyote-ketchup_mix.mp3')
assert.equal(t1.key, t2.key)
assert.equal(t1.source, 'subject')
// A number in common ("35"), and a per-post id ("FTD769997").
assert.equal(id('[Audiofiles_DIE_ZEIT_35] [01/24] - "35_China_dl.mp3" yEnc', '35_China_dl.mp3').key, id('[Audiofiles_DIE_ZEIT_35] [02/24] - "35_Bamberg_dl.mp3" yEnc', '35_Bamberg_dl.mp3').key)
assert.equal(id('FTD769997 [01/23] - "Prison.Break.S04E02.720p.part01.rar" yEnc', 'Prison.Break.S04E02.720p.part01.rar').key, id('FTD769997 [23/23] - "Prison.Break.S04E02.720p.part.par2" yEnc', 'Prison.Break.S04E02.720p.part.par2').key)
// Without a counter a long number is the board's, not a post's: a dump of separate releases.
const kere = (n: string) => id(`<kere.ws/illuminatenboard.org> - ID - 1855891249 - ${n}`, n)
assert.notEqual(kere('Along.The.Ridge.2006.Limited.PAL.DVDr-TWCiSO.rar').key, kere('Altera.QUARTUS.II.DSP.Builder.v7.2.SP1-SHooTERS.rar').key)
// A scene name with abbreviated file names, and a generically named sidecar.
const scene = id('Some.Movie.2008.DVDRip.XviD-GRP [01/40] - "grp-sm.part01.rar" yEnc', 'grp-sm.part01.rar')
assert.equal(scene.name, 'Some Movie 2008 DVDRip XviD GRP')
assert.equal(id('Better.Jpeg.v2.0-DOA [02/10] - "file_id.diz" yEnc', 'file_id.diz').key, id('Better.Jpeg.v2.0-DOA [03/10] - "doa-bj20.zip" yEnc', 'doa-bj20.zip').key)
})
test('image sets: counters written out, sizes and the set by its counter or name', ({ assert }) => {
const id = (subject: string, name: string, poster = 'p') => releaseIdentity({ poster, subject, name, weak: false })!
// "File 027 of 132": one set, not a release per image; another set of the same title apart by its total.
const a = id('What about this? - File 027 of 132: "DSC_027.jpg" yEnc', 'DSC_027.jpg')
const b = id('What about this? - File 028 of 132: "DSC_028.jpg" yEnc', 'DSC_028.jpg')
const other = id('What about this? - File 001 of 90: "DSC_001.jpg" yEnc', 'DSC_001.jpg')
assert.equal(a.key, b.key)
assert.notEqual(a.key, other.key)
assert.equal(a.name, 'What about this?')
// No counter: the image's name up to its last number.
const k1 = id('Proud to be a poster "Kitchen Hottie 1 set233-76-lg.jpg" yEnc', 'Kitchen Hottie 1 set233-76-lg.jpg')
const k2 = id('Proud to be a poster "Kitchen Hottie 1 set233-77-lg.jpg" yEnc', 'Kitchen Hottie 1 set233-77-lg.jpg')
const k3 = id('Proud to be a poster "Office Chair set12-01-lg.jpg" yEnc', 'Office Chair set12-01-lg.jpg')
assert.equal(k1.key, k2.key)
assert.notEqual(k1.key, k3.key)
// Per-file sizes and other counter forms don't split a post.
assert.equal(subjectRemainder('Minutemen (001/104) "x.cbr" - 76.88 MB - yEnc'), 'Minutemen')
assert.equal(subjectRemainder('Babes P A R T 3 ("Charlotte 03 16.jpg" 0097-1574 156.87 kB-273.03 MB) yEnc'), 'Babes P A R T 3')
assert.equal(subjectRemainder('*MaryKate* - OfficeChair [23of61] - "OfficeChair023.jpg" yEnc 187924 bytes'), '*MaryKate* OfficeChair')
assert.equal(subjectRemainder('Adventure Comics [1948-12] - "x.rar"'), 'Adventure Comics [1948 12]')
})
test('documents are a release each; audio tracks stay with their album', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
const c1 = id('cw-horror&mystery [10/28] "Vampirella Magazine 061.cbr" yEnc', 'Vampirella Magazine 061.cbr')
const c2 = id('cw-horror&mystery [11/28] "Mystery Tales 12.cbr" yEnc', 'Mystery Tales 12.cbr')
assert.notEqual(c1.key, c2.key)
assert.equal(c2.name, 'Mystery Tales 12')
const t1 = id('(Geisterjäger John Sinclair Hörspiele Vol. 2) [04/59] - "042 - 011 - Der unheimliche Bogenschütze.mp3 - by DeckaR" yEnc', '042 - 011 - Der unheimliche Bogenschütze.mp3 - by DeckaR')
const t2 = id('(Geisterjäger John Sinclair Hörspiele Vol. 2) [34/59] - "072 - 027 - Die Teufelsuhr.MP3 - by DeckaR" yEnc', '072 - 027 - Die Teufelsuhr.MP3 - by DeckaR')
const par2 = id('(Geisterjäger John Sinclair Hörspiele Vol. 2) [59/59] - "Hörspiele Vol. 2.par2" yEnc', 'Hörspiele Vol. 2.par2')
assert.equal(t1.key, t2.key)
assert.equal(t1.key, par2.key)
// A cover without words around it joins its stem's archive.
assert.equal(id('[2/6] - "x.jpg" yEnc', 'x.jpg').key, id('[1/6] - "x.part01.rar" yEnc', 'x.part01.rar').key)
})
})