The judge hides scraped celebrity pictures; no ? in its patterns (a raw query takes it for a binding)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7d9a81784e
commit
093d0a71ad
2 files changed
+27
-2
No files matched your search
@@ -8,9 +8,15 @@ const ROUND_MS = 60 * 60 * 1000
|
|||||||
/** A file's first 16 KiB and size in this many releases is one file posted again and again (test files, spam). */
|
/** A file's first 16 KiB and size in this many releases is one file posted again and again (test files, spam). */
|
||||||
const REPEATED_RELEASES = 20
|
const REPEATED_RELEASES = 20
|
||||||
|
|
||||||
/** A name that says it's a film, an episode or music: a resolution, a codec, a rip source, a media extension. */
|
/**
|
||||||
|
* A name that says it's a film, an episode or music: a resolution, a codec, a rip source, a media extension. No "?" in
|
||||||
|
* these patterns: a raw query takes it for a binding ("h[ .]?26[45]" and "web[ .-]?dl" never matched; LOG.md
|
||||||
|
* 2026-10-16 (64)), so {0,1}.
|
||||||
|
*/
|
||||||
const MEDIA =
|
const MEDIA =
|
||||||
`(^|[^a-z0-9])(s[0-9]{1,2}e[0-9]{1,3}|[0-9]{3,4}p|x26[45]|h[ .]?26[45]|hevc|xvid|divx|bluray|bdrip|brrip|web[ .-]?dl|webrip|hdtv|dvdrip|dvdr|remux|mkv|mp4|avi|wmv|m4v|flac|mp3)([^a-z0-9]|$)`
|
`(^|[^a-z0-9])(s[0-9]{1,2}e[0-9]{1,3}|[0-9]{3,4}p|x26[45]|h[ .]{0,1}26[45]|hevc|xvid|divx|bluray|bdrip|brrip|web[ .-]{0,1}dl|webrip|hdtv|dvdrip|dvdr|remux|mkv|mp4|avi|wmv|m4v|flac|mp3)([^a-z0-9]|$)`
|
||||||
|
/** The posters of scraped celebrity pictures. */
|
||||||
|
const SCRAPED_POSTERS = `celeb[-_ ]{0,1}movie|celebwow|celebfx|iluvcelebs|nude[-_ ]{0,1}celebs|celeb-sex-tapes`
|
||||||
/** An executable's name. */
|
/** An executable's name. */
|
||||||
const EXECUTABLE = `\\.(exe|scr|com|bat|cmd|msi|lnk|vbs|js|jar|pif|cpl|hta|ps1|dll)$`
|
const EXECUTABLE = `\\.(exe|scr|com|bat|cmd|msi|lnk|vbs|js|jar|pif|cpl|hta|ps1|dll)$`
|
||||||
|
|
||||||
@@ -52,6 +58,15 @@ export const RULES: Rule[] = [
|
|||||||
sql: `SELECT DISTINCT h.release_id FROM file_hashes h
|
sql: `SELECT DISTINCT h.release_id FROM file_hashes h
|
||||||
JOIN (SELECT hash16k, size FROM file_hashes GROUP BY 1, 2 HAVING count(DISTINCT release_id) >= ${REPEATED_RELEASES}) x USING (hash16k, size)`,
|
JOIN (SELECT hash16k, size FROM file_hashes GROUP BY 1, 2 HAVING count(DISTINCT release_id) >= ${REPEATED_RELEASES}) x USING (hash16k, size)`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'scraped',
|
||||||
|
says: 'celebrity pictures scraped from the web, reposted by one spam family',
|
||||||
|
// "@_CelebMovie_@", "NudeCelebs@CelebMovie.com", "@_CelebWow_@", "@_CelebFX_@", "@_iLuvCelebs_@", "@nude-celebs", …:
|
||||||
|
// a celebrity's scraped pictures as a folder under a typed subject, the same files again and again under other
|
||||||
|
// titles (LOG.md 2026-10-16 (64)). Not Celeborn, CelebTA or other posters with "celeb" in their name.
|
||||||
|
sql: `SELECT r.id FROM releases r
|
||||||
|
WHERE r.poster ~* '${SCRAPED_POSTERS}' AND r.source = 'subject' AND r.file_total IS NULL`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'locked',
|
name: 'locked',
|
||||||
says: 'passworded, and no spot, NZB or title gives the password',
|
says: 'passworded, and no spot, NZB or title gives the password',
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ test.group('ReleaseJudge', (group) => {
|
|||||||
const fakeArchive = await release('Das.A-Team.S02E23.Das.Spiel.ist.aus')
|
const fakeArchive = await release('Das.A-Team.S02E23.Das.Spiel.ist.aus')
|
||||||
await inspect(fakeArchive, 'archive', { type: 'rar4', names: ['Das.A-Team.S02E23.Das.Spiel.ist.aus.exe'], entries: 1 })
|
await inspect(fakeArchive, 'archive', { type: 'rar4', names: ['Das.A-Team.S02E23.Das.Spiel.ist.aus.exe'], entries: 1 })
|
||||||
const fakeFile = await release('Some.Film.2021.1080p.WEB-DL')
|
const fakeFile = await release('Some.Film.2021.1080p.WEB-DL')
|
||||||
|
// Only "H.264" and "WEB-DL" say it's media here (a "?" in the pattern never matched).
|
||||||
|
const fakeCodec = await release('Some.Show.H.264.WEB-DL')
|
||||||
|
await inspect(fakeCodec, 'lone', { type: 'exe', yencName: 'setup.exe' })
|
||||||
await inspect(fakeFile, 'lone', { type: 'exe', yencName: 'Some.Film.2021.1080p.WEB-DL.mkv' })
|
await inspect(fakeFile, 'lone', { type: 'exe', yencName: 'Some.Film.2021.1080p.WEB-DL.mkv' })
|
||||||
// A program under a program's name is software, not fake.
|
// A program under a program's name is software, not fake.
|
||||||
const software = await release('LimeWire 4.19.6')
|
const software = await release('LimeWire 4.19.6')
|
||||||
@@ -53,7 +56,10 @@ test.group('ReleaseJudge', (group) => {
|
|||||||
await db.table('file_hashes').insert({ candidate_id: 20000 + i, release_id: id, hash16k: hash, size: 1073741824 })
|
await db.table('file_hashes').insert({ candidate_id: 20000 + i, release_id: id, hash16k: hash, size: 1073741824 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const scraped = await release('Jamie Lee Curtis Nude Celebrity Pictures', { poster: '@_CelebMovie_@', source: 'subject' })
|
||||||
|
const celeborn = await release('Some.Album.2010', { poster: 'celeborn@not.here (Celeborn)', source: 'subject' })
|
||||||
const locked = await release('Locked.Thing', { passworded: true })
|
const locked = await release('Locked.Thing', { passworded: true })
|
||||||
|
|
||||||
const unlocked = await release('Known.Password', { passworded: true })
|
const unlocked = await release('Known.Password', { passworded: true })
|
||||||
await db.table('release_passwords').insert({ release_id: unlocked, password: 'pw', source: 'spot-text' })
|
await db.table('release_passwords').insert({ release_id: unlocked, password: 'pw', source: 'spot-text' })
|
||||||
|
|
||||||
@@ -68,14 +74,18 @@ test.group('ReleaseJudge', (group) => {
|
|||||||
assert.isUndefined(verdicts.get(halfDead))
|
assert.isUndefined(verdicts.get(halfDead))
|
||||||
assert.equal(verdicts.get(fakeArchive), 'fake')
|
assert.equal(verdicts.get(fakeArchive), 'fake')
|
||||||
assert.equal(verdicts.get(fakeFile), 'fake')
|
assert.equal(verdicts.get(fakeFile), 'fake')
|
||||||
|
assert.equal(verdicts.get(fakeCodec), 'fake')
|
||||||
assert.isUndefined(verdicts.get(software))
|
assert.isUndefined(verdicts.get(software))
|
||||||
assert.deepEqual([...new Set(repeatedIds.map((id) => verdicts.get(id)))], ['repeated'])
|
assert.deepEqual([...new Set(repeatedIds.map((id) => verdicts.get(id)))], ['repeated'])
|
||||||
|
assert.equal(verdicts.get(scraped), 'scraped')
|
||||||
|
assert.isUndefined(verdicts.get(celeborn))
|
||||||
assert.equal(verdicts.get(locked), 'locked')
|
assert.equal(verdicts.get(locked), 'locked')
|
||||||
assert.isUndefined(verdicts.get(unlocked))
|
assert.isUndefined(verdicts.get(unlocked))
|
||||||
assert.equal(verdicts.get(unusable), 'unusable')
|
assert.equal(verdicts.get(unusable), 'unusable')
|
||||||
assert.isUndefined(verdicts.get(fresh))
|
assert.isUndefined(verdicts.get(fresh))
|
||||||
assert.isUndefined(verdicts.get(spotted))
|
assert.isUndefined(verdicts.get(spotted))
|
||||||
assert.equal(round.rules.repeated.added, 20)
|
assert.equal(round.rules.repeated.added, 20)
|
||||||
|
assert.equal(round.rules.scraped.matched, 1)
|
||||||
|
|
||||||
// Search leaves them out, unless asked.
|
// Search leaves them out, unless asked.
|
||||||
const found = await SearchService.search({ q: 'Locked' })
|
const found = await SearchService.search({ q: 'Locked' })
|
||||||
|
|||||||
Reference in new issue
Block a user