Module:Sandbox/Vergir: Difference between revisionsGive feedback
Jump to navigation
Jump to search
Audit script: handle nil section type (with help from vergir-bot LLM) |
Audit script v2: normalize underscores, check target existence, group by change (with help from vergir-bot LLM) |
||
| Line 25: | Line 25: | ||
end | end | ||
local function | local function norm(s) | ||
if s == nil or s == "" then return | if s == nil or s == "" then return nil end | ||
return " | return (tostring(s):gsub("_", " ")) | ||
end | |||
local exists_cache = {} | |||
local function page_status(t) | |||
if t == nil then return "" end | |||
if exists_cache[t] == nil then | |||
local title = mw.title.new(t) | |||
if not title or not title.exists then | |||
exists_cache[t] = "'''MISSING'''" | |||
elseif title.isRedirect then | |||
local target = title.redirectTarget | |||
exists_cache[t] = "redirect → " .. (target and target.prefixedText or "?") | |||
else | |||
exists_cache[t] = "ok" | |||
end | |||
end | |||
return exists_cache[t] | |||
end | end | ||
| Line 35: | Line 52: | ||
local names = {} | local names = {} | ||
for key, item in pairs(data) do | for key, item in pairs(data) do | ||
if not item.IsDisabled then | if not item.IsDisabled then table.insert(names, key) end | ||
end | end | ||
table.sort(names, function(a, b) | table.sort(names, function(a, b) | ||
| Line 43: | Line 58: | ||
end) | end) | ||
local n_items, n_stats, n_diff = 0, 0, 0 | local n_items, n_stats, n_same, n_diff = 0, 0, 0, 0 | ||
local by_change = {} -- "cur → new" -> list of "Item (Label)" | |||
for _, key in ipairs(names) do | for _, key in ipairs(names) do | ||
local item = data[key] | local item = data[key] | ||
| Line 61: | Line 77: | ||
n_stats = n_stats + 1 | n_stats = n_stats + 1 | ||
local attr = obj.Type and ATTR[obj.Type] or nil | local attr = obj.Type and ATTR[obj.Type] or nil | ||
local attr_link = attr and attr.link | local attr_link = norm(attr and attr.link) | ||
local sl = norm(stat_links[label_key]) | |||
local sl = stat_links[label_key] | |||
local cur = attr_link or sl | local cur = attr_link or sl | ||
local new = sl or attr_link | local new = sl or attr_link | ||
local differs = (cur or "") ~= (new or "") | local differs = (cur or "") ~= (new or "") | ||
if differs then n_diff = n_diff + 1 end | if differs then | ||
n_diff = n_diff + 1 | |||
local k = (cur or "(none)") .. " → " .. (new or "(none)") | |||
by_change[k] = by_change[k] or { cur = cur, new = new, list = {} } | |||
table.insert(by_change[k].list, | |||
string.format("[[%s]] (%s)", item.Name or key, label)) | |||
else | |||
n_same = n_same + 1 | |||
end | |||
if mode == "all" or differs then | if mode == "all" or differs then | ||
table.insert(rows, string.format( | table.insert(rows, string.format( | ||
"|-%s\n| [[%s]] || %s || %s || | "|-%s\n| [[%s]] || %s || %s || %s || %s || %s || %s", | ||
differs and ' style="background:#4a3a1a"' or "", | differs and ' style="background:#4a3a1a"' or "", | ||
item.Name or key, tostring(sec.Type), | item.Name or key, tostring(sec.Type), label_key, tostring(obj.Type), | ||
label, cur or "''(none)''", new or "''(none)''")) | |||
end | end | ||
end | end | ||
| Line 85: | Line 107: | ||
local out = {} | local out = {} | ||
table.insert(out, string.format("Items scanned: %d. Passive/Active main stats with a label: %d. | table.insert(out, string.format( | ||
n_items, n_stats, n_diff)) | "Items scanned: %d. Passive/Active main stats with a label: %d. Unchanged: %d. Link changes: %d.\n", | ||
n_items, n_stats, n_same, n_diff)) | |||
-- Grouped summary | |||
table.insert(out, "== Grouped by change ==") | |||
local keys = {} | |||
for k in pairs(by_change) do table.insert(keys, k) end | |||
table.sort(keys) | |||
table.insert(out, '{| class="wikitable sortable"\n! Current link !! Status !! Proposed link !! Status !! # !! Items (label)') | |||
for _, k in ipairs(keys) do | |||
local g = by_change[k] | |||
table.insert(out, string.format("|-\n| [[%s]] || %s || [[%s]] || %s || %d || %s", | |||
g.cur or "", page_status(g.cur), g.new or "", page_status(g.new), | |||
#g.list, table.concat(g.list, ", "))) | |||
end | |||
table.insert(out, "|}") | |||
-- Full row table | |||
table.insert(out, "== Per stat ==") | |||
table.insert(out, '{| class="wikitable sortable"\n! Item !! Section !! Stat key !! Type !! Label !! Current link !! Proposed link') | table.insert(out, '{| class="wikitable sortable"\n! Item !! Section !! Stat key !! Type !! Label !! Current link !! Proposed link') | ||
for _, r in ipairs(rows) do table.insert(out, r) end | for _, r in ipairs(rows) do table.insert(out, r) end | ||
Revision as of 23:03, 6 September 2026
Documentation for this module may be created at Module:Sandbox/Vergir/doc
-- Audit: for every item stat that goes through Infobox item's append_label
-- with attribute styling enabled (Passive/Active Main stats), compute the
-- label link target under the CURRENT priority (attr link > StatLinks)
-- and the PROPOSED priority (StatLinks > attr link) and list the results.
local p = {}
local lang = require "Module:Lang"
local data = mw.loadJsonData("Data:ItemCards.json")
local stat_links = mw.loadJsonData("Data:StatLinks.json")
local ATTR = require("Module:Icon/attr")
local LABEL_KEY_REMAP = { DotDuration = "DOTDuration" }
local IGNORED = { BuildUpPerShot = true }
local function get_pair(base, s1, s2)
local v = lang.get_string(base .. s1)
if v and v ~= "" then return v end
v = lang.get_string(base .. s2)
if v and v ~= "" then return v end
return ""
end
local function resolve_label_key(prop_key, loc_override)
local base = (loc_override or prop_key):gsub("^#", "")
return LABEL_KEY_REMAP[base] or base
end
local function norm(s)
if s == nil or s == "" then return nil end
return (tostring(s):gsub("_", " "))
end
local exists_cache = {}
local function page_status(t)
if t == nil then return "" end
if exists_cache[t] == nil then
local title = mw.title.new(t)
if not title or not title.exists then
exists_cache[t] = "'''MISSING'''"
elseif title.isRedirect then
local target = title.redirectTarget
exists_cache[t] = "redirect → " .. (target and target.prefixedText or "?")
else
exists_cache[t] = "ok"
end
end
return exists_cache[t]
end
function p.audit(frame)
local mode = frame.args[1] or "diff" -- "diff" | "all"
local rows = {}
local names = {}
for key, item in pairs(data) do
if not item.IsDisabled then table.insert(names, key) end
end
table.sort(names, function(a, b)
return (data[a].Name or a) < (data[b].Name or b)
end)
local n_items, n_stats, n_same, n_diff = 0, 0, 0, 0
local by_change = {} -- "cur → new" -> list of "Item (Label)"
for _, key in ipairs(names) do
local item = data[key]
n_items = n_items + 1
local i = 1
while item["Info" .. i] do
local sec = item["Info" .. i]
if sec.Type ~= "Innate" then
local seen = {}
for _, obj in ipairs(sec.Main or {}) do
local pk = obj.Key
if not seen[pk] and not IGNORED[pk] and not pk:match("^StatusEffect") then
seen[pk] = true
local label_key = resolve_label_key(pk, obj.LocTokenOverride)
local label = get_pair(label_key, "_label", "_Label")
if label ~= "" then
n_stats = n_stats + 1
local attr = obj.Type and ATTR[obj.Type] or nil
local attr_link = norm(attr and attr.link)
local sl = norm(stat_links[label_key])
local cur = attr_link or sl
local new = sl or attr_link
local differs = (cur or "") ~= (new or "")
if differs then
n_diff = n_diff + 1
local k = (cur or "(none)") .. " → " .. (new or "(none)")
by_change[k] = by_change[k] or { cur = cur, new = new, list = {} }
table.insert(by_change[k].list,
string.format("[[%s]] (%s)", item.Name or key, label))
else
n_same = n_same + 1
end
if mode == "all" or differs then
table.insert(rows, string.format(
"|-%s\n| [[%s]] || %s || %s || %s || %s || %s || %s",
differs and ' style="background:#4a3a1a"' or "",
item.Name or key, tostring(sec.Type), label_key, tostring(obj.Type),
label, cur or "''(none)''", new or "''(none)''"))
end
end
end
end
end
i = i + 1
end
end
local out = {}
table.insert(out, string.format(
"Items scanned: %d. Passive/Active main stats with a label: %d. Unchanged: %d. Link changes: %d.\n",
n_items, n_stats, n_same, n_diff))
-- Grouped summary
table.insert(out, "== Grouped by change ==")
local keys = {}
for k in pairs(by_change) do table.insert(keys, k) end
table.sort(keys)
table.insert(out, '{| class="wikitable sortable"\n! Current link !! Status !! Proposed link !! Status !! # !! Items (label)')
for _, k in ipairs(keys) do
local g = by_change[k]
table.insert(out, string.format("|-\n| [[%s]] || %s || [[%s]] || %s || %d || %s",
g.cur or "", page_status(g.cur), g.new or "", page_status(g.new),
#g.list, table.concat(g.list, ", ")))
end
table.insert(out, "|}")
-- Full row table
table.insert(out, "== Per stat ==")
table.insert(out, '{| class="wikitable sortable"\n! Item !! Section !! Stat key !! Type !! Label !! Current link !! Proposed link')
for _, r in ipairs(rows) do table.insert(out, r) end
table.insert(out, "|}")
return table.concat(out, "\n")
end
return p