Module:Xeno-canto version
Appearance
Documentation for this module may be created at Module:Xeno-canto version/doc
-- Module:Xeno-canto version
--[[
Renders WhiskerWiki's xeno-canto coverage card from JSON:Xeno-canto_provenance,
which the R pipeline writes from scripts/02_species.R (the point where
xeno-canto's species list is matched against WhiskerWiki's species roster).
p.infobox the card (Template:Xeno-canto version box)
p.data the parsed JSON, for other modules
p.field one top-level JSON value, e.g. {{#invoke:Xeno-canto version|field|last_updated}}
"Xeno-canto species/recordings" are xeno-canto's counts for WhiskerWiki's
focal orders worldwide (the JSON's "scope"), not every land mammal.
Ported from HopperWiki's Module:Xeno-canto version. Uses the shared .ib-h card
classes in MediaWiki:Common.css, plus the xc-* rules there.
--]]
local json = require("Module:JSON pipeline")
local p = {}
local PAGE = "JSON:Xeno-canto_provenance"
local function fmt_number(n)
n = tonumber(n)
if not n then return "—" end
local s = tostring(math.floor(n + 0.5)):reverse():gsub("(%d%d%d)", "%1,"):reverse():gsub("^,", "")
return s -- one value only: gsub's second return (the match count) would leak into callers' argument lists
end
local function cell(label, value)
return string.format(
'<div class="ib-h-cell"><div class="ib-h-label">%s</div><div class="ib-h-value">%s</div></div>',
label, value
)
end
function p.infobox(frame)
local data, err = json.load(PAGE)
if not data then
return '<span class="error">Xeno-canto version data unavailable: ' .. tostring(err) .. '</span>'
end
local counts = type(data.record_counts) == "table" and data.record_counts or {}
local source = data.source or "xeno-canto"
local source_url = data.source_url or ""
local updated = data.last_updated or "unknown"
local source_link = source_url ~= ""
and string.format('[%s %s]', source_url, source)
or source
local header = string.format(
'<div class="ib-h-header">' ..
'<span class="ib-h-badge">XC</span>' ..
'<span class="xc-title">WhiskerWiki\'s xeno-canto coverage</span>' ..
'<span class="xc-source">%s</span>' ..
'</div>',
source_link
)
local linked = fmt_number(counts.linked_species)
if counts.total_whiskerwiki_species then
linked = linked .. ' <span class="xc-of">of ' .. fmt_number(counts.total_whiskerwiki_species) .. '</span>'
end
local cells = table.concat({
cell("Last updated", mw.text.encode(updated)),
cell("Species linked", linked),
cell("Xeno-canto species", fmt_number(counts.xc_species_available)),
cell("Xeno-canto recordings", fmt_number(counts.xc_recordings_available)),
})
local scope_html = data.scope
and string.format('<div class="xc-scope">Xeno-canto counts cover %s worldwide.</div>', mw.text.encode(data.scope))
or ""
local html = string.format(
'<div class="ib-h xc-version-box">' ..
'%s' ..
'<div class="ib-h-cells ib-h-cols-4">%s</div>' ..
'%s' ..
'</div>',
header, cells, scope_html
)
return frame:preprocess(html)
end
function p.data()
return json.load(PAGE)
end
function p.field(frame)
local args = frame.args or frame
local key = args[1] or args.key
if not key then return "" end
local data = json.load(PAGE)
if not data then return "" end
return tostring(data[key] or "")
end
return p