Module:Screencap
More actions
Overview
Module:Screencap is the Lua backend for Template:Screencap, the unified image tag for BattlestarWiki Media. It replaces the fragmented family of legacy sub-templates (
| <img src="//media.battlestarwiki.org/w/index.php?title=Special:Redirect/file/BSG_WIKI_Screencap.png" alt="Unknown Source" width="30" height="30" style="vertical-align:middle"> screen capture (source unknown) | |
|---|---|
| The an unknown series, Season "Unknown" from an unknown episode. Please help us identify the episode by updating this tag or discussing it on the [[{{TALKPAGENAME}}|talk page]]. | |
| This capture is copyright by the copyright holder. Use of it here is believed to be fair use. | |
| The timestamp for this image is unknown. Please supply the time index for this capture. | |
| Screen capture (source unknown). Native resolution: unknown. | |
,
| <img src="//media.battlestarwiki.org/w/index.php?title=Special:Redirect/file/BSG_WIKI_Bluray.png" alt="Blu-ray" width="30" height="30" style="vertical-align:middle"> Blu-ray screen capture | |
|---|---|
| The original Battlestar Galactica, Season "Unknown" from an unknown episode. Please help us identify the episode by updating this tag or discussing it on the [[{{TALKPAGENAME}}|talk page]]. | |
| This capture is copyright by Universal Studios. Use of it here is believed to be fair use. | |
| The timestamp for this image is unknown. Please supply the time index for this capture. | |
| Blu-ray screen capture. Native resolution: 1920×1080. | |
,
| <img src="//media.battlestarwiki.org/w/index.php?title=Special:Redirect/file/BSG_WIKI_HDTV.png" alt="HDTV" width="30" height="30" style="vertical-align:middle"> HD broadcast screen capture | |
|---|---|
| The Caprica, Season "Unknown" from an unknown episode. Please help us identify the episode by updating this tag or discussing it on the [[{{TALKPAGENAME}}|talk page]]. | |
| This capture is copyright by Universal Studios / Syfy. Use of it here is believed to be fair use. | |
| The timestamp for this image is unknown. Please supply the time index for this capture. | |
| HD broadcast screen capture. Native resolution: 1280×720 or 1920×1080. | |
, etc.) with a single module that auto-detects as much metadata as possible from the file itself, while allowing any detected value to be overridden via named template parameters.
The module does four things:
- Detects the series from filename prefix patterns
- Detects the season and episode from filename patterns (SxxExx, NxNN, or prose title hint)
- Detects the source type / quality tier from the file's pixel dimensions
- Renders a collapsible infobox and applies maintenance categories
Entry Point
The module exposes one public function:
| Function | Called by | Description |
|---|---|---|
p.main(frame) |
{{#invoke:Screencap|main}} in Template:Screencap |
Full pipeline: detect → render infobox → emit categories |
Series Detection
Series is detected by matching the start of the filename against a prefix table. Matching is case-sensitive on the prefix but tolerates spaces or underscores as separators (e.g. RDM -, RDM_).
| Filename starts with | Detected series key
|
|---|---|
RDM -, TRS -, BSG - S##, BSG - #x## |
rdm
|
CAP -, Caprica - |
cap
|
B&C -, BNC - |
bnc
|
TOS - |
tos
|
1980 -, G1980 - |
1980
|
| (no match) | unknown
|
Each series key maps to a SERIES_META entry containing the human-readable name, category abbreviation, wiki article links, and copyright holder used in the infobox.
To add a new series, add a new entry to both SERIES_PREFIXES and SERIES_META in the module.
Episode & Season Detection
The module attempts to extract season and episode numbers from the filename in this priority order:
| Pattern | Example filename | Result |
|---|---|---|
SxxExx (standard) |
RDM - S04E20 - Daybreak.jpg |
Season 4, Episode 20 |
NxNN (alternate) |
BSG - 1x05 - Act of Contrition.jpg |
Season 1, Episode 5 |
| Prose title hint | TOS - The Lost Warrior - Apollo.jpg |
Title hint: "The Lost Warrior - Apollo" |
| (no match) | Adamabed.jpg |
No season, no episode, no hint |
When only a title hint is extracted (no season/episode numbers), the infobox displays the hint with a message asking editors to verify and supply the full episode name. When nothing is extracted at all, the infobox flags the image as unidentified and links to the talk page.
Note: the |episode= parameter is not auto-detected from the filename — it must be explicitly supplied if you want a linked episode name in the infobox. The filename extraction only produces season/episode numbers or a hint string.
Source Type Detection
When no |type= override is supplied, the module reads the file's pixel dimensions via mw.title.getCurrentTitle().file and classifies the source using the longest pixel axis (so portrait-orientation promotional photographs are handled correctly alongside landscape screencaps).
| Longest pixel dimension | Detected type |
Label shown |
|---|---|---|
| ≥ 3840 px | 4k |
4K Ultra HD screen capture |
| ≥ 1920 px | bluray |
Blu-ray screen capture |
| ≥ 1280 px | hdtv |
HD broadcast screen capture |
| ≥ 853 px | ntscdvd |
NTSC DVD screen capture |
| ≥ 720 px | paldvd |
PAL DVD screen capture |
| < 720 px | dvd |
DVD screen capture |
| dimensions unavailable | unknown |
screen capture (source unknown) |
Dimensions are unavailable when the module runs outside a File: page context (e.g. during template sandbox testing), in which case it falls back gracefully to unknown rather than erroring.
All valid type keys that can be used as overrides:
| Key | Description |
|---|---|
4k |
4K UHD Blu-ray (≥ 3840px) |
bluray |
Blu-ray / 1080p stream |
hdtv |
HD broadcast or download |
hddvd |
HD DVD (manual override only — not auto-detected) |
itunes |
iTunes / digital download (manual override only) |
ntscdvd |
NTSC DVD |
ntscb |
NTSC broadcast (manual override only) |
paldvd |
PAL DVD |
palb |
PAL broadcast (manual override only) |
promo |
Promotional photograph (manual override only) |
dvd |
Generic / low-res DVD |
unknown |
Source unknown |
hddvd, itunes, ntscb, palb, and promo cannot be auto-detected from dimensions alone and must always be set via |type=.
Timestamp Handling
The |timestamp= parameter accepts three input formats:
| Input | Interpretation | Displayed as |
|---|---|---|
427 |
Bare integer → total seconds | 00:07:07
|
3662 |
Bare integer → total seconds | 01:01:02
|
00:07:07 |
Already HH:MM:SS | 00:07:07
|
0h20m42s |
Non-numeric string → passed through | 0h20m42s
|
Any input that does not parse as a pure number via tonumber() is passed through as-is, so existing timestamps in any format continue to work without changes.
Infobox Output
The rendered infobox is a standard MediaWiki wikitable with class wikitable mw-collapsible screencap-infobox. Rows are emitted in this order:
- Header — source type icon + label (collapsible toggle)
- Series / episode identification line with language bar links
- Copyright notice (links to Wikipedia)
- Timestamp (or missing-timestamp notice)
- Source description and native resolution
- Detected pixel dimensions (if available)
- Scaling note (if
|scaled=yes) - Cropping note (if
|cropped=yes) - Aspect ratio confirmation (if
|aspect=yes)
Cross-wiki icon rendering
Source type icons are referenced using standard [[File:Name|30px|link=]] wikitext. The language wikis (de., fr., etc.) serve these files via ForeignAPIRepo from media.battlestarwiki.org, so the icons render correctly everywhere without any special URL construction.
Category Output
Categories are appended after the infobox and applied automatically — no manual [[Category:...]] tags are needed on file pages.
For a Blu-ray RDM image of "Daybreak" from Season 4, the following categories would be applied:
[[Category:Screen captures]][[Category:Screen captures (TRS)]][[Category:Blu-ray screen captures (TRS)]][[Category:Screen captures by season 4 (TRS)]][[Category:Screen captures (Daybreak)]][[Category:Blu-ray screen captures (Daybreak)]]
Additional maintenance categories are applied automatically based on conditions:
| Condition | Maintenance category added |
|---|---|
type is unknown |
Screen captures requiring source identification
|
type is ntscdvd, paldvd, ntscb, or palb |
Screen captures requiring upgrade
|
Extending the Module
Adding a new series
Add one or more entries to SERIES_PREFIXES (for filename detection) and a corresponding entry to SERIES_META (for display metadata):
<syntaxhighlight lang="lua"> -- In SERIES_PREFIXES: { pattern = "^BLOOD%s*[-_]%s*", series = "bnc" },
-- In SERIES_META: bnc = {
name = "Battlestar Galactica: Blood & Chrome", abbr = "BNC", enlink = "Battlestar Galactica: Blood & Chrome", copyright = "Universal Studios / Syfy",
}, </syntaxhighlight>
Adding a new source type
Add an entry to TYPE_LABELS and a corresponding entry to the iconMap inside renderInfobox:
<syntaxhighlight lang="lua"> -- In TYPE_LABELS: webdl = { short = "Web DL", long = "web download screen capture", badge = "Web DL", res = "variable" },
-- In iconMap inside renderInfobox: webdl = "File:BSG WIKI WebDL.png", </syntaxhighlight>
See Also
- Template:Screencap — the template that invokes this module
- Template:Screencap/doc — end-user documentation and parameter reference
- Template:Master screencap — legacy parent template (now a wrapper)
- Battlestar Wiki Media:Image tagging policy
-- ============================================================
-- Module:Screencap
-- BattlestarWiki Media — Unified Screen Capture / Image Tag
--
-- Auto-detects series, episode, season, source type and quality
-- from the current file's name and its pixel dimensions, then
-- formats the standard infobox + maintenance categories.
--
-- All auto-detected values are overridable via template params.
-- ============================================================
local p = {}
-- ----------------------------------------------------------------
-- SERIES DETECTION TABLE
-- Maps filename prefix patterns → canonical series keys
-- Extend this table as new series/spin-offs are added.
-- ----------------------------------------------------------------
local SERIES_PREFIXES = {
-- Re-imagined Series (RDM / TRS)
{ pattern = "^RDM%s*[-_]%s*", series = "rdm" },
{ pattern = "^TRS%s*[-_]%s*", series = "rdm" },
{ pattern = "^BSG%s*[-_]%s*S%d", series = "rdm" },
{ pattern = "^BSG%s*[-_]%s*%d+x%d+", series = "rdm" },
-- Caprica
{ pattern = "^CAP%s*[-_]%s*", series = "cap" },
{ pattern = "^Caprica%s*[-_]%s*", series = "cap" },
-- Blood & Chrome
{ pattern = "^B&C%s*[-_]%s*", series = "bnc" },
{ pattern = "^BNC%s*[-_]%s*", series = "bnc" },
-- Original Series (TOS)
{ pattern = "^TOS%s*[-_]%s*", series = "tos" },
-- Galactica 1980
{ pattern = "^1980%s*[-_]%s*", series = "1980" },
{ pattern = "^G1980%s*[-_]%s*", series = "1980" },
}
-- Human-readable series names and wiki links
local SERIES_META = {
rdm = {
name = "Re-imagined ''Battlestar Galactica''",
abbr = "TRS",
enlink = "Battlestar Galactica (RDM)",
delink = "Battlestar Galactica (RDM)",
frlink = "Battlestar Galactica (LSR)",
copyright = "Universal Studios",
},
cap = {
name = "''Caprica''",
abbr = "CAP",
enlink = "Caprica",
delink = "Caprica",
frlink = "Caprica",
copyright = "Universal Studios / Syfy",
},
bnc = {
name = "''Battlestar Galactica: Blood & Chrome''",
abbr = "BNC",
enlink = "Battlestar Galactica: Blood & Chrome",
delink = "Battlestar Galactica: Blood & Chrome",
frlink = "Battlestar Galactica: Blood & Chrome",
copyright = "Universal Studios / Syfy",
},
tos = {
name = "original ''Battlestar Galactica''",
abbr = "TOS",
enlink = "Battlestar Galactica (TOS)",
delink = "Battlestar Galactica (TOS)",
frlink = "Battlestar Galactica (TOS)",
copyright = "Universal Studios",
},
["1980"] = {
name = "''Galactica 1980''",
abbr = "1980",
enlink = "Galactica 1980",
delink = "Galactica 1980",
frlink = "Galactica 1980",
copyright = "Universal Studios",
},
}
-- ----------------------------------------------------------------
-- SOURCE TYPE (quality tier) DETECTION FROM DIMENSIONS
--
-- Thresholds (width-based, landscape assumed):
-- ≥3840 → 4k (UHD Blu-ray)
-- ≥1920 → bluray (1080p Blu-ray / stream)
-- ≥1280 → hdtv (720p HD broadcast / download)
-- ≥853 → dvd (NTSC anamorphic widescreen upscaled)
-- ≥720 → ntscdvd (native NTSC DVD)
-- ≥1024 → paldvd (native PAL DVD upscaled)
-- other → unknown
--
-- Portrait images (height > width) use the longer dimension.
-- ----------------------------------------------------------------
local function detectTypeFromDimensions(width, height)
if not width or not height then return "unknown" end
local w = tonumber(width)
local h = tonumber(height)
if not w or not h then return "unknown" end
-- Use longer axis so portrait promo shots also work
local long = math.max(w, h)
if long >= 3840 then return "4k" end
if long >= 1920 then return "bluray" end
if long >= 1280 then return "hdtv" end
if long >= 853 then return "ntscdvd" end -- NTSC anamorphic ≈ 853×480
if long >= 720 then return "paldvd" end -- PAL 720×576
return "dvd"
end
-- ----------------------------------------------------------------
-- EPISODE / SEASON EXTRACTION FROM FILENAME
--
-- Supported patterns (case-insensitive):
-- SxxExx e.g. S01E05, S04E20 → standard
-- xxXxx e.g. 1x05, 4x20 → alternate
-- BSG-era prefix then episode title → title after prefix
-- ----------------------------------------------------------------
local function extractEpisodeInfo(filename)
if not filename then return nil, nil, nil end
-- Remove file extension
local name = filename:gsub("%.[^%.]+$", "")
-- SxxExx pattern
local s, e = name:match("[Ss](%d+)[Ee](%d+)")
if s and e then
return tonumber(s), tonumber(e), nil
end
-- NxNN or NN×NN pattern
s, e = name:match("(%d+)[xX](%d+)")
if s and e then
return tonumber(s), tonumber(e), nil
end
-- Attempt to extract a prose episode title after known prefixes
-- e.g. "RDM - 33 - Adama helmet.jpg" → episode hint "33"
-- Returns nil for season/ep numbers but a title hint
local titleHint = name:match("^[A-Z0-9&]+%s*[-_]%s*(.+)$")
if titleHint then
-- Strip trailing frame number pattern like "- 042" or "- Frame042"
titleHint = titleHint:gsub("%s*[-_]%s*[Ff]rame%s*%d+$", "")
titleHint = titleHint:gsub("%s*[-_]%s*%d+$", "")
-- Trim
titleHint = titleHint:match("^%s*(.-)%s*$")
end
return nil, nil, titleHint
end
-- ----------------------------------------------------------------
-- SERIES DETECTION FROM FILENAME
-- ----------------------------------------------------------------
local function detectSeriesFromFilename(filename)
if not filename then return nil end
for _, entry in ipairs(SERIES_PREFIXES) do
if filename:match(entry.pattern) then
return entry.series
end
end
return nil
end
-- ----------------------------------------------------------------
-- SOURCE TYPE LABELS
-- ----------------------------------------------------------------
local TYPE_LABELS = {
["4k"] = { short = "4K UHD", long = "4K Ultra HD screen capture", badge = "4K UHD Blu-ray", res = "3840×2160 (or equivalent 4K source)" },
bluray = { short = "Blu-ray", long = "Blu-ray screen capture", badge = "Blu-ray", res = "1920×1080" },
hdtv = { short = "HDTV", long = "HD broadcast screen capture", badge = "HDTV", res = "1280×720 or 1920×1080" },
hddvd = { short = "HD DVD", long = "HD DVD screen capture", badge = "HD DVD", res = "1920×1080" },
itunes = { short = "iTunes/Download", long = "digital download screen capture", badge = "iTunes/Download", res = "variable" },
ntscdvd = { short = "NTSC DVD", long = "NTSC DVD screen capture", badge = "NTSC DVD", res = "720×480 (anamorphic widescreen → 853×480)" },
ntscb = { short = "NTSC Broadcast", long = "NTSC broadcast screen capture", badge = "NTSC Broadcast", res = "720×480 (fullscreen)" },
paldvd = { short = "PAL DVD", long = "PAL DVD screen capture", badge = "PAL DVD", res = "720×576 (anamorphic widescreen → 1024×576)" },
palb = { short = "PAL Broadcast", long = "PAL broadcast screen capture", badge = "PAL Broadcast", res = "720×576" },
promo = { short = "Promotional", long = "promotional photograph", badge = "Promo Photo", res = "variable (original photography)" },
dvd = { short = "DVD", long = "DVD screen capture", badge = "DVD", res = "variable" },
unknown = { short = "Unknown", long = "screen capture (source unknown)", badge = "Unknown Source", res = "unknown" },
}
-- ----------------------------------------------------------------
-- CATEGORY BUILDER
-- ----------------------------------------------------------------
local function buildCategories(series, typeLower, season, episode)
local cats = {}
local seriesMeta = SERIES_META[series]
local abbr = seriesMeta and seriesMeta.abbr or (series and series:upper() or "")
local typeLabel = TYPE_LABELS[typeLower]
local typeShort = typeLabel and typeLabel.short or typeLower
-- Always add base category
table.insert(cats, "[[Category:Screen captures]]")
if abbr ~= "" then
table.insert(cats, string.format("[[Category:Screen captures (%s)]]", abbr))
table.insert(cats, string.format("[[Category:%s screen captures (%s)]]", typeShort, abbr))
end
if season and abbr ~= "" then
table.insert(cats, string.format("[[Category:Screen captures by season %s (%s)]]", season, abbr))
end
if episode then
table.insert(cats, string.format("[[Category:Screen captures (%s)]]", episode))
table.insert(cats, string.format("[[Category:%s screen captures (%s)]]", typeShort, episode))
end
-- Quality maintenance categories
if typeLower == "unknown" then
table.insert(cats, "[[Category:Screen captures requiring source identification]]")
end
if typeLower == "ntscdvd" or typeLower == "paldvd" or typeLower == "ntscb" or typeLower == "palb" then
table.insert(cats, "[[Category:Screen captures requiring upgrade]]")
end
return table.concat(cats, "\n")
end
-- ----------------------------------------------------------------
-- LANGUAGE BAR BUILDER
-- ----------------------------------------------------------------
local function buildLangBar(args, seriesMeta, episode, cepisode)
if not seriesMeta then return "" end
local parts = {}
local function addLang(langCode, wikiBase, epName, cepName, label)
if epName and epName ~= "" then
local displayName = (cepName and cepName ~= "") and cepName or epName
local link = string.format("[%s/%s %s]", wikiBase, epName:gsub(" ", "_"), label)
table.insert(parts, link)
end
end
-- English always present
if episode and episode ~= "" then
local enDisplay = (cepisode and cepisode ~= "") and cepisode or episode
table.insert(parts, string.format("[[%s|en]]", seriesMeta.enlink))
end
local langs = {
{ code = "de", base = "https://de.battlestarwiki.org", label = "de", argEp = args.de, argCep = args.cde },
{ code = "es", base = "https://es.battlestarwiki.org", label = "es", argEp = args.es, argCep = args.ces },
{ code = "fr", base = "https://fr.battlestarwiki.ddns.net/wiki", label = "fr", argEp = args.fr, argCep = args.cfr },
{ code = "tr", base = "https://tr.battlestarwiki.org", label = "tr", argEp = args.tr, argCep = args.ctr },
{ code = "zh", base = "http://zh.battlestarwiki.org/wiki", label = "zh", argEp = args.zh, argCep = args.czh },
}
for _, lang in ipairs(langs) do
if lang.argEp and lang.argEp ~= "" then
local displayName = (lang.argCep and lang.argCep ~= "") and lang.argCep or lang.argEp
table.insert(parts, string.format("[%s/%s %s]",
lang.base, lang.argEp:gsub(" ", "_"), lang.label))
end
end
if #parts == 0 then return "" end
return "(" .. table.concat(parts, ") (") .. ")"
end
-- ----------------------------------------------------------------
-- INFOBOX RENDERER
-- ----------------------------------------------------------------
local function renderInfobox(data)
local rows = {}
local function row(content)
table.insert(rows, string.format("|-\n| %s", content))
end
-- Header row with badge icon and type label
local typeInfo = TYPE_LABELS[data.typeLower] or TYPE_LABELS["unknown"]
-- Map type to full absolute icon URLs using media.battlestarwiki.org's
-- Special:Redirect/file endpoint. This bypasses the MD5-hashed /w/images/
-- directory structure and works correctly when the infobox is transcluded
-- to foreign wikis (de., fr., etc.) — those wikis don't have these files
-- locally so mw.title and relative paths both fail there.
-- Protocol-relative (//) so it works over both http and https.
local BASE = "//media.battlestarwiki.org/w/index.php?title=Special:Redirect/file/"
local iconMap = {
["4k"] = BASE .. "BSG_WIKI_4K.png",
bluray = BASE .. "BSG_WIKI_Bluray.png",
hdtv = BASE .. "BSG_WIKI_HDTV.png",
hddvd = BASE .. "BSG_WIKI_HDDVD.png",
itunes = BASE .. "ITunes_Icon.png",
ntscdvd = BASE .. "BSG_WIKI_Dvd.png",
ntscb = BASE .. "BSG_WIKI_Screencap.png",
paldvd = BASE .. "BSG_WIKI_Dvd.png",
palb = BASE .. "BSG_WIKI_Screencap.png",
promo = BASE .. "BSG_WIKI_Promo.png",
dvd = BASE .. "BSG_WIKI_Dvd.png",
unknown = BASE .. "BSG_WIKI_Screencap.png",
}
local iconUrl = iconMap[data.typeLower] or iconMap["unknown"]
local iconWikitext = string.format(
'<img src="%s" alt="%s" width="30" height="30" style="vertical-align:middle">',
iconUrl, typeInfo.badge
)
-- Main header
local header = string.format(
'{| class="wikitable mw-collapsible screencap-infobox" style="width:100%%;font-size:90%%"\n' ..
'! colspan="2" style="background:#1a1a2e;color:#c8a951;text-align:left" |' ..
' %s \'\'\'%s\'\'\'',
iconWikitext, typeInfo.long
)
table.insert(rows, header)
-- Series / episode identification row
local seriesMeta = SERIES_META[data.series]
local seriesName = seriesMeta and seriesMeta.name or "an unknown series"
local copyright = seriesMeta and seriesMeta.copyright or "the copyright holder"
local langBar = buildLangBar(data.args, seriesMeta, data.episode, data.cepisode)
local episodeText
if data.episode and data.episode ~= "" then
local epDisplay = (data.cepisode and data.cepisode ~= "") and data.cepisode or data.episode
episodeText = string.format(
"The %s %s, Season %s %s episode \"[[%s|%s]]\".",
seriesName,
langBar,
data.season or "''Unknown''",
langBar ~= "" and "" or "",
data.episode,
epDisplay
)
elseif data.episodeTitleHint and data.episodeTitleHint ~= "" then
episodeText = string.format(
"The %s. Episode identified from filename as \"''%s''\" — " ..
"please verify and supply the full episode name.",
seriesName, data.episodeTitleHint
)
else
episodeText = string.format(
"The %s, Season \"''Unknown''\" from an unknown episode. " ..
"Please help us identify the episode by updating this tag or discussing it on the [[{{TALKPAGENAME}}|talk page]].",
seriesName
)
end
row(episodeText)
-- Copyright notice
row(string.format(
"This capture is copyright by [http://www.wikipedia.org/wiki/%s %s]. " ..
"Use of it here is believed to be [http://www.wikipedia.org/wiki/fair_use fair use].",
copyright:gsub(" ", "_"), copyright
))
-- Timestamp row
if data.timestamp and data.timestamp ~= "" then
row(string.format("Timestamp: <code>%s</code> (HH:MM:SS)", data.timestamp))
else
row("The timestamp for this image is unknown. Please supply the time index for this capture.")
end
-- Source/quality description
row(string.format("%s. Native resolution: %s.", typeInfo.long:gsub("^%l", string.upper), typeInfo.res))
-- Dimensions / scaling notes
if data.width and data.height then
local w, h = tonumber(data.width), tonumber(data.height)
if w and h then
row(string.format("Detected image dimensions: %d×%d pixels.", w, h))
end
end
if data.scaled and data.scaled ~= "" then
row("This image has been scaled from its original dimensions.")
end
if data.cropped and data.cropped ~= "" then
row("This image has been cropped from its original dimensions.")
end
if data.aspect and data.aspect == "yes" then
row("Aspect ratio has been confirmed correct.")
end
-- Close table
table.insert(rows, "|}")
return table.concat(rows, "\n")
end
-- ----------------------------------------------------------------
-- MAIN ENTRY POINT
-- ----------------------------------------------------------------
function p.main(frame)
local args = frame:getParent().args
local title = mw.title.getCurrentTitle()
local filename = title.text -- e.g. "RDM - 33 - 042.jpg"
-- --- Series ---
local series = (args.series and args.series ~= "") and args.series:lower()
or detectSeriesFromFilename(filename)
or "unknown"
-- --- Episode/Season ---
local detectedSeason, detectedEp, detectedTitleHint = extractEpisodeInfo(filename)
local season = (args.season and args.season ~= "") and args.season or detectedSeason
local episode = (args.episode and args.episode ~= "") and args.episode or nil
local cepisode = (args.cepisode and args.cepisode ~= "") and args.cepisode or nil
local episodeTitleHint = (episode == nil) and detectedTitleHint or nil
-- --- Image Dimensions (from EXIF via file object) ---
local fileObj = title.file
local width, height
if fileObj then
width = fileObj.width
height = fileObj.height
end
-- --- Source Type ---
local autoType = detectTypeFromDimensions(width, height)
local typeLower = (args.type and args.type ~= "") and args.type:lower() or autoType
-- --- Render ---
local data = {
series = series,
season = season,
episode = episode,
cepisode = cepisode,
episodeTitleHint = episodeTitleHint,
typeLower = typeLower,
timestamp = args.timestamp,
scaled = args.scaled,
cropped = args.cropped,
aspect = args.aspect,
width = width,
height = height,
args = args,
}
local infobox = renderInfobox(data)
local categories = buildCategories(series, typeLower, season, episode or episodeTitleHint)
return infobox .. "\n" .. categories
end
return p