51 lines
2.1 KiB
TypeScript
51 lines
2.1 KiB
TypeScript
/**
|
|
* Extract a JAV product code from a filename.
|
|
* Handles common patterns: "SSIS-001.jpg", "[ABC] DEF-123.png", "ssis001 cover.jpg",
|
|
* "abp-456_cover.jpeg", and pre-fixes like "FHD-MIDV-123.jpg".
|
|
*
|
|
* Returns the canonical "PREFIX-NUMBER" form (uppercased), or null if no match.
|
|
*/
|
|
|
|
// Prefix must start with a letter and may contain digits (e.g. "T28", "ABP",
|
|
// "MIAA"). Total prefix length 2-6 alphanumerics. The numeric tail is 3-5
|
|
// digits, with an optional single-letter suffix for variant releases —
|
|
// "IBW-610z" (z-version / re-cut), "ABP-456a" (part-a), etc. Suffix is
|
|
// preserved in the canonical form so e.g. IBW-610 and IBW-610Z stay
|
|
// distinct (they're different versions of the same release).
|
|
const CODE_RE = /\b([A-Za-z][A-Za-z0-9]{1,5})[-_ ]?(\d{3,5})([a-zA-Z])?\b/;
|
|
const QUALITY_PREFIXES = new Set(["fhd", "hd", "sd", "uhd", "4k", "1080p", "720p", "480p", "hevc", "x265", "x264"]);
|
|
|
|
/**
|
|
* Canonicalise an already-known code to "PREFIX-NUMBER" with the number
|
|
* left-padded to a minimum of 3 digits and the prefix uppercased. Inputs
|
|
* coming from NFO `<id>` tags can arrive in any of "MIAA-291", "miaa291",
|
|
* "MIAA-00291", etc.; we want them all to compare equal so the collision
|
|
* detector isn't fooled by formatting drift.
|
|
*/
|
|
export function normalizeCode(raw: string | null | undefined): string | null {
|
|
if (!raw) return null;
|
|
const m = raw.trim().match(CODE_RE);
|
|
if (!m) return null;
|
|
const suffix = (m[3] ?? "").toUpperCase();
|
|
return `${m[1].toUpperCase()}-${m[2].padStart(3, "0")}${suffix}`;
|
|
}
|
|
|
|
export function extractCode(filename: string): string | null {
|
|
const base = filename.replace(/\.[^.]+$/, "");
|
|
// Walk left-to-right, skipping quality prefixes that look like codes (e.g. "FHD-").
|
|
let cursor = 0;
|
|
while (cursor < base.length) {
|
|
const m = base.slice(cursor).match(CODE_RE);
|
|
if (!m) return null;
|
|
const prefix = m[1];
|
|
const num = m[2];
|
|
const suffix = (m[3] ?? "").toUpperCase();
|
|
if (QUALITY_PREFIXES.has(prefix.toLowerCase())) {
|
|
cursor += (m.index ?? 0) + m[0].length;
|
|
continue;
|
|
}
|
|
return `${prefix.toUpperCase()}-${num.padStart(3, "0")}${suffix}`;
|
|
}
|
|
return null;
|
|
}
|