Image sets: suffixes that don't count the images go first
Test and deploy / test (push) Successful in 44s
Test and deploy / edge (push) Successful in 2m0s
Test and deploy / deploy (push) Successful in 2m1s

The set bound cut at an image name's last number, but in many threads
that's a suffix, so every image was a set ("It does my heart good to see
Red Dog dancing again": 4,683 releases of 4,730 files): a repeat of the
index (katelg010_10), a year (hgrscans1097_2009), a size
(pj02kristina_24of40_1600), an "of" total (24of40). imageSet drops
those, then cuts at the last number (cutie-071-032 stays cutie-071-).
Both implementations; tests; fixtures identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-12 01:45:57 +02:00
1 parent c4f48a6d4c
commit 392ff09910
3 files changed
+93 -7

No files matched your search

+22 -1
View File
@@ -141,6 +141,27 @@ const DOCUMENT = /\.(pdf|epub|mobi|azw3?|djvu|cbr|cbz|cb7|chm|lit|docx?)$/i
/** Dates in names: 2011-08-29, 08-29-2011 or 29.08.2011, 02-2011. */
const DATES = /\b(?:(?:19|20)\d{2}[-._ ](?:0?[1-9]|1[0-2])[-._ ]\d{1,2}|\d{1,2}[-._ ]\d{1,2}[-._ ](?:19|20)\d{2}|\d{1,2}[-._](?:19|20)\d{2})\b/g
/**
* An image's set: its name up to the number that counts the images, digits before it kept ("stp250x001" →
* "stp250x", "cutie-071-032" → "cutie-071-"); empty for a name without numbers. Suffixes after it that don't
* count the images go first: a repeat of the number before (katelg010_10), a year (hgrscans1097_2009), a
* size of 4+ digits (…_24of40_1600), and an "of" total (24of40) (LOG.md 2026-10-12 (3)).
*/
export function imageSet(stem: string): string {
let s = stem.replace(/(\d+)\s*of\s*\d+/gi, '$1')
while (true) {
const m = /[_-](\d+)$/.exec(s)
if (!m) break
const before = s.slice(0, m.index)
const previous = /(\d+)\D*$/.exec(before)
if (!previous) break
const n = m[1]
if (Number(n) === Number(previous[1]) || /^(?:19|20)\d\d$/.test(n) || n.length >= 4) s = before
else break
}
return /\d/.test(s) ? s.replace(/\d+\D*$/, '') : ''
}
export function counterTotal(subject: string): number | undefined {
const s = subject.replace(/"[^"]*"/g, ' ')
const plain = /\[(\d+)\/(\d+)\]|\((\d+)\/(\d+)\)/.exec(s)
@@ -257,7 +278,7 @@ export function releaseIdentity(input: ReleaseInput): ReleaseIdentity | null {
// Without a counter an image's set bounds it: its name up to its last number, digits kept ("stp250x001.jpg"
// → "stp250x": STIRILING SILVER's 300 sets were one release of 44k images); a name without numbers names no
// set ("Kindly Husband-to-Be.JPG": a thread of 1,177 releases), so the subject alone (LOG.md 2026-10-12 (2)).
const set = image && /\d/.test(stem) ? stem.replace(/\d+\D*$/, '') : ''
const set = image ? imageSet(stem) : ''
return {
key: hash('subject', poster, remainder, total ?? set),
name: remainder,