From eccae362ec24b6de711fb29dcb723422cddb18d1 Mon Sep 17 00:00:00 2001 From: Stan Runge Date: Sat, 24 Oct 2026 20:26:13 +0000 Subject: [PATCH] planes: stricter photo matching, skip company articles, payload-not-pax --- scripts/planes-photos.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/planes-photos.ts b/scripts/planes-photos.ts index 702c52e..b00ee37 100644 --- a/scripts/planes-photos.ts +++ b/scripts/planes-photos.ts @@ -70,7 +70,7 @@ type Photo = { // ---------------------------------------------------------------- commons const BAD_FILE = - /\.(svg|gif|tiff?|pdf|djvu|webm|ogv|stl)$|logo|emblem|badge|insignia|roundel|patch\b|wordmark|map\b|karte|locator|diagram|chart|graph|schema|schematic|drawing|sketch|blueprint|patent|3[- ]?view|three[- ]view|icon|flag|coat of arms|wappen|signature|symbol|cutaway|silhouette|commons-|wiki|stub|poster|advert|brochure|stamp|timeline|cockpit|flight deck|instrument|panel|cabin|interior|seats?\b|galley|lavatory|engine\b|nacelle|propeller\b|landing gear|undercarriage|wheel|tyre|tire\b|crash|wreck|accident|debris|incident|fire\b|burnt|scrap|graveyard|boneyard|\btoys?\b|scale model|model aircraft|lego|diecast|plastic model|kit\b|simulator|mock-?up|ticket|menu|uniform|crew\b|pilot\b|portrait|ceremony|memorial|grave|plaque|statue|stamp/i; + /\.(svg|gif|tiff?|pdf|djvu|webm|ogv|stl)$|logo|emblem|badge|insignia|roundel|patch\b|wordmark|map\b|karte|locator|diagram|chart|graph|schema|schematic|drawing|sketch|blueprint|patent|3[- ]?view|three[- ]view|icon|flag|coat of arms|wappen|signature|symbol|cutaway|silhouette|commons-|wiki|stub|poster|advert|brochure|stamp|timeline|cockpit|flight deck|instrument|panel|cabin|interior|seats?\b|galley|lavatory|engine\b|nacelle|propeller\b|landing gear|undercarriage|wheel|tyre|\btire\b|crash|wreck|accident|debris|incident|\bfire\b|burnt|scrap|graveyard|boneyard|\btoys?\b|scale model|model aircraft|lego|diecast|plastic model|kit\b|simulator|mock-?up|ticket|menu|uniform|crew\b|pilot\b|portrait|ceremony|memorial|grave|plaque|statue|stamp|\bvs\b|versus|deliveries|render|cgi\b|\btug\b|tow cart|comparison|3 ?-?seiten|zeichnung|fahrwerk|atterrissage|tail ?gear|tail ?bumper|wn.trze|innenraum|first class|business class|radar\b/i; const infoCache = new Map(); async function imageInfo(files: string[], width = THUMB) { @@ -210,7 +210,12 @@ const GENERIC = new Set( ); const esc = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -type Rule = { test: (f: string) => boolean; designators: string[]; required: string[] }; +type Rule = { + test: (f: string) => boolean; + loose: (f: string) => boolean; + designators: string[]; + required: string[]; +}; /** Name-based tests for one type: designators like AH64 / A320 / 737 (with maker) and rare words. */ function ruleFor(t: Target, wordUse: Map): Rule { const makerWords = tokens(t.maker).filter((w) => w.length >= 3 && !GENERIC.has(w)); @@ -238,9 +243,12 @@ function ruleFor(t: Target, wordUse: Map): Rule { else if (makerWords.length) tests.push(new RegExp(`(?=.* (?:${makerWords.map(esc).join('|')}) ).* ${esc(w)} `)); } + // Inside the type's own article or category, a telling name word alone is enough ("Spitfire"). + const looseRe = words.length ? new RegExp(words.map((w) => ` ${esc(w)} `).join('|')) : null; return { designators, required, + loose: (f) => !!looseRe && looseRe.test(norm(f)), test: (f) => { const F = norm(f); return ( @@ -306,7 +314,11 @@ async function photosFor(targets: Target[], all: Target[]) { o.required.some((r) => !rule.required.includes(r)) || o.designators.some((d) => !rule.designators.includes(d)) ); - const ok = (f: string) => !BAD_FILE.test(f) && rule.test(f) && !siblings.some((s) => s.test(f)); + const ok = (f: string) => + !BAD_FILE.test(f) && + !/\.png$/i.test(f) && + (rule.test(f) || rule.loose(f)) && + !siblings.some((s) => s.test(f)); const own = wd.own.get(t.wikidata); const picks: { file: string; kind: Photo['kind']; caption: string | null }[] = []; if (own?.image && !/\.(svg|gif)$/i.test(own.image))