Модуль:Сущность/data: различия между версиями

Нет описания правки
Метка: ручная отмена
Отмена версии 315901, сделанной Pok (обсуждение)
Метка: отмена
 
(не показано 7 промежуточных версий этого же участника)
Строка 3: Строка 3:
local JsonPaths = require('Module:JsonPaths')
local JsonPaths = require('Module:JsonPaths')


local moduleDataCache = {}
local dpOk, dpModule = pcall(require, "Module:GetField")
local templateContentCache = {}
local dp = dpOk and dpModule or nil
local templateMetaCache = {}
 
local templateArgCache = {}
local flattenExtraCache = {}
local switchModeRegistry = {}
local switchModeRegistry = {}
local switchModeOrder = {}
local switchModeOrder = {}
Строка 30: Строка 28:
local function load_module_data(page)
local function load_module_data(page)
     local moduleName = JsonPaths.get(page)
     local moduleName = JsonPaths.get(page)
    if moduleDataCache[moduleName] ~= nil then
        return moduleDataCache[moduleName]
    end
     local ok, data = pcall(mw.loadData, moduleName)
     local ok, data = pcall(mw.loadData, moduleName)
     if not ok then
     if not ok then
        moduleDataCache[moduleName] = nil
         return nil
         return nil
     end
     end
    moduleDataCache[moduleName] = data
     return data
     return data
end
end


local function load_template_content(path)
local function load_template_content(path)
    if templateContentCache[path] ~= nil then
        return templateContentCache[path] or nil
    end
     local title = mw.title.new("Template:" .. path)
     local title = mw.title.new("Template:" .. path)
     if not title then
     if not title then
        templateContentCache[path] = false
         return nil
         return nil
     end
     end
     local ok, content = pcall(function() return title:getContent() end)
     local ok, content = pcall(title.getContent, title)
     if not ok then
     if not ok then
        templateContentCache[path] = false
         return nil
         return nil
     end
     end
    templateContentCache[path] = content or false
     return content
     return content
end
end
Строка 108: Строка 90:


local function get_template_params(tplPath, content)
local function get_template_params(tplPath, content)
     local cached = templateArgCache[tplPath]
     return collect_template_params(content)
    if cached ~= nil then
        return cached
    end
 
    local params = collect_template_params(content)
    templateArgCache[tplPath] = params
    return params
end
end


Строка 148: Строка 123:
     if not byKey[key] then
     if not byKey[key] then
         byKey[key] = {}
         byKey[key] = {}
         table.insert(state.keyOrder[sw], key)
         state.keyOrder[sw][#state.keyOrder[sw] + 1] = key
     end
     end
     return byKey[key]
     return byKey[key]
Строка 196: Строка 171:
                     line = line .. '<div class="ts-Сущность-field">' .. makeSourceLink(src) .. '</div>'
                     line = line .. '<div class="ts-Сущность-field">' .. makeSourceLink(src) .. '</div>'
                 end
                 end
                 table.insert(parts, '<div class="ts-Сущность">' .. line .. '</div>')
                 parts[#parts + 1] = '<div class="ts-Сущность">' .. line .. '</div>'
             end
             end
         end
         end
Строка 264: Строка 239:


     return table.concat(out, "\n")
     return table.concat(out, "\n")
end
local function normalizeFilterKey(s)
    s = trim(s or "")
    s = s:gsub("%s*_%s*", "_")
    return s
end
end


Строка 270: Строка 251:
         return false
         return false
     end
     end
    callKey = normalizeFilterKey(callKey)
    compositeKey = normalizeFilterKey(compositeKey)
     return list[callKey] or list[compositeKey] or false
     return list[callKey] or list[compositeKey] or false
end
end
Строка 363: Строка 346:
                     if not merged.sectionsMap[section] then
                     if not merged.sectionsMap[section] then
                         merged.sectionsMap[section] = true
                         merged.sectionsMap[section] = true
                         table.insert(merged.sections, section)
                         merged.sections[#merged.sections + 1] = section
                     end
                     end
                     if displayLabel ~= "" and (not merged.labelOverrides[compositeKey] or merged.labelOverrides[compositeKey] == "") then
                     if displayLabel ~= "" and (not merged.labelOverrides[compositeKey] or merged.labelOverrides[compositeKey] == "") then
Строка 381: Строка 364:
                         merged.labelSets[section][compositeKey] = true
                         merged.labelSets[section][compositeKey] = true
                         local cur = merged.labelLists[section] or {}
                         local cur = merged.labelLists[section] or {}
                         table.insert(cur, compositeKey)
                         cur[#cur + 1] = compositeKey
                         merged.labelLists[section] = cur
                         merged.labelLists[section] = cur
                     end
                     end
Строка 389: Строка 372:
                     if not merged.tagSet[tagText] then
                     if not merged.tagSet[tagText] then
                         merged.tagSet[tagText] = true
                         merged.tagSet[tagText] = true
                         table.insert(merged.tags, tagText)
                         merged.tags[#merged.tags + 1] = tagText
                     end
                     end
                 end
                 end
Строка 399: Строка 382:
         if not merged.tagSet[extraTag] then
         if not merged.tagSet[extraTag] then
             merged.tagSet[extraTag] = true
             merged.tagSet[extraTag] = true
             table.insert(merged.tags, extraTag)
             merged.tags[#merged.tags + 1] = extraTag
         end
         end
     end)
     end)
Строка 504: Строка 487:


local function getTemplateMeta(frame, tplPath)
local function getTemplateMeta(frame, tplPath)
    if templateMetaCache[tplPath] ~= nil then
        return templateMetaCache[tplPath] or ""
    end
     local expanded = frame:expandTemplate {
     local expanded = frame:expandTemplate {
         title = tplPath,
         title = tplPath,
Строка 515: Строка 494:
     local ok, data = pcall(mw.text.jsonDecode, expanded)
     local ok, data = pcall(mw.text.jsonDecode, expanded)
     if not ok or type(data) ~= "table" then
     if not ok or type(data) ~= "table" then
        templateMetaCache[tplPath] = false
         return ""
         return ""
     end
     end
Строка 527: Строка 505:
                     if not seen[lab] then
                     if not seen[lab] then
                         seen[lab] = true
                         seen[lab] = true
                         table.insert(cardKeys, lab)
                         cardKeys[#cardKeys + 1] = lab
                     end
                     end
                 end
                 end
Строка 535: Строка 513:
     end
     end


    templateMetaCache[tplPath] = data
     return data
     return data
end
end
Строка 543: Строка 520:
     if not str or str == "" then return res end
     if not str or str == "" then return res end
     for item in string.gmatch(str, "[^,]+") do
     for item in string.gmatch(str, "[^,]+") do
         local s = trim(item)
         local s = normalizeFilterKey(item)
         if s ~= "" then
         if s ~= "" then
             local a, b = s:match("^([^_]+)_(.+)$")
             local a, b = s:match("^([^_]+)_(.+)$")
Строка 665: Строка 642:
end
end


local function get_selective_extra(dp, id, dataPage, paramNames)
local function get_selective_extra(id, dataPage, paramNames)
     if not dp or type(dp.flattenFieldSelective) ~= "function" then
     if not dp or type(dp.flattenFieldSelectiveDirect) ~= "function" then
         return ""
         return ""
     end
     end
Строка 673: Строка 650:
     end
     end


     local okJson, keysJson = pcall(mw.text.jsonEncode, paramNames)
     return dp.flattenFieldSelectiveDirect(id, dataPage, paramNames) or ""
    if not okJson or not keysJson or keysJson == "" then
        return ""
    end
 
    local cacheKey = dataPage .. "\31" .. id .. "\31" .. keysJson
    if flattenExtraCache[cacheKey] ~= nil then
        return flattenExtraCache[cacheKey]
    end
 
    local extra = dp.flattenFieldSelective({ args = { id, dataPage, keysJson } }) or ""
    flattenExtraCache[cacheKey] = extra
    return extra
end
end


Строка 740: Строка 705:
end
end


local function each_entity_data(frame, id, onEntity, onMissing)
local function extract_whitelist_search_strings(keyFilter)
    if not keyFilter or not keyFilter.hasWhitelist then
        return nil
    end
 
    local strings = {}
    for sw, keys in pairs(keyFilter.whitelist) do
        if type(keys) == "table" then
            for key in pairs(keys) do
                strings[#strings + 1] = key
            end
        end
    end
 
    if #strings == 0 then
        return nil
    end
 
    return strings
end
 
local function content_matches_whitelist(content, searchStrings)
    if not searchStrings then
        return true
    end
    if not content then
        return false
    end
 
    for _, s in ipairs(searchStrings) do
        if string.find(content, s, 1, true) then
            return true
        end
    end
 
    return false
end
 
local function each_entity_data(frame, id, onEntity, onMissing, keyFilter)
     local componentWhitelist = frame.args.componentWhitelist or frame.args.componentwhitelist or ""
     local componentWhitelist = frame.args.componentWhitelist or frame.args.componentwhitelist or ""
     local componentBlacklist = frame.args.componentBlacklist or frame.args.componentblacklist or ""
     local componentBlacklist = frame.args.componentBlacklist or frame.args.componentblacklist or ""
Строка 755: Строка 758:
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)


     local ok, dp = pcall(require, "Module:GetField")
     local compWhitelistSet = parse_csv_set(componentWhitelist)
    local compBlacklistSet = parse_csv_set(componentBlacklist)
    local protoWhitelistSet = parse_csv_set(prototypeWhitelist)
    local protoBlacklistSet = parse_csv_set(prototypeBlacklist)
 
    local compHasWhitelist = next(compWhitelistSet) ~= nil
    local protoHasWhitelist = next(protoWhitelistSet) ~= nil
    local anyEntityWhitelist = compHasWhitelist or protoHasWhitelist
 
    local whitelistSearchStrings = extract_whitelist_search_strings(keyFilter)


     local function processEntity(kind, name, isStore)
     local function processEntity(kind, name, isStore)
Строка 769: Строка 781:
                 onMissing(kind, name, isStore, tplPath)
                 onMissing(kind, name, isStore, tplPath)
             end
             end
            return
        end
        if not content_matches_whitelist(content, whitelistSearchStrings) then
             return
             return
         end
         end
Строка 779: Строка 795:
         local extra = ""
         local extra = ""
         local paramNames = get_template_params(tplPath, content)
         local paramNames = get_template_params(tplPath, content)
         if ok and dp then
         if dp then
             local dataPage = tplPath .. ".json"
             local dataPage = tplPath .. ".json"
             extra = get_selective_extra(dp, id, dataPage, paramNames)
             extra = get_selective_extra(id, dataPage, paramNames)
         end
         end


Строка 794: Строка 810:


     for compName in pairs(foundComponents) do
     for compName in pairs(foundComponents) do
         processEntity("component", compName, false)
         if not anyEntityWhitelist or compHasWhitelist then
            processEntity("component", compName, false)
        end
     end
     end
     for protoName in pairs(foundPrototypes) do
     for protoName in pairs(foundPrototypes) do
         processEntity("prototype", protoName, false)
         if not anyEntityWhitelist or protoHasWhitelist then
            processEntity("prototype", protoName, false)
        end
     end
     end


     local componentStoreDefs = load_module_data("component_store.json")
     local componentStoreDefs = load_module_data("component_store.json")
     if type(componentStoreDefs) == "table" then
     if type(componentStoreDefs) == "table" and (not anyEntityWhitelist or compHasWhitelist) then
         local compStore = componentStoreDefs[id]
         local compStore = componentStoreDefs[id]
         if type(compStore) == "table" then
         if type(compStore) == "table" then
             for compName in pairs(compStore) do
             for compName in pairs(compStore) do
                 processEntity("component", compName, true)
                 local allowed = true
                if compBlacklistSet[compName] then
                    allowed = false
                elseif compHasWhitelist and not compWhitelistSet[compName] then
                    allowed = false
                end
                if allowed then
                    processEntity("component", compName, true)
                end
             end
             end
         end
         end
     end
     end


     if type(prototypeStoreDefs) == "table" then
     if type(prototypeStoreDefs) == "table" and (not anyEntityWhitelist or protoHasWhitelist) then
         local protoStore = prototypeStoreDefs[id]
         local protoStore = prototypeStoreDefs[id]
         if type(protoStore) == "table" then
         if type(protoStore) == "table" then
             for protoName in pairs(protoStore) do
             for protoName in pairs(protoStore) do
                 processEntity("prototype", protoName, true)
                 local allowed = true
                if protoBlacklistSet[protoName] then
                    allowed = false
                elseif protoHasWhitelist and not protoWhitelistSet[protoName] then
                    allowed = false
                end
                if allowed then
                    processEntity("prototype", protoName, true)
                end
             end
             end
         end
         end
Строка 899: Строка 935:
                     entityId, noHeaders, showSource, cardFilter)
                     entityId, noHeaders, showSource, cardFilter)
             end
             end
             if outStr and outStr ~= "" then table.insert(outLocal, outStr) end
             if outStr and outStr ~= "" then outLocal[#outLocal + 1] = outStr end
         else
         else
             for _, key in ipairs(state.keyOrder[sw] or {}) do
             for _, key in ipairs(state.keyOrder[sw] or {}) do
Строка 905: Строка 941:
                 if type(mode.render_key) == "function" then
                 if type(mode.render_key) == "function" then
                     local outStr = mode.render_key(frame, key, entries, noHeaders, showSource)
                     local outStr = mode.render_key(frame, key, entries, noHeaders, showSource)
                     if outStr and outStr ~= "" then table.insert(outLocal, outStr) end
                     if outStr and outStr ~= "" then outLocal[#outLocal + 1] = outStr end
                 end
                 end
             end
             end
Строка 931: Строка 967:
             errors[#errors + 1] = build_missing_template_error(kind, name, isStore, tplPath)
             errors[#errors + 1] = build_missing_template_error(kind, name, isStore, tplPath)
         end
         end
     end)
     end, filter)
     if not ok then return "" end
     if not ok then return "" end


Строка 937: Строка 973:


     if #errors > 0 then
     if #errors > 0 then
         table.insert(out, '{{сущность/infobox|' .. table.concat(errors, "\n") .. '}}')
         out[#out + 1] = '{{сущность/infobox|' .. table.concat(errors, "\n") .. '}}'
     end
     end


Строка 944: Строка 980:
     local blocks = renderBlocks(frame, state, renderOptions, id, showSource)
     local blocks = renderBlocks(frame, state, renderOptions, id, showSource)
     for _, b in ipairs(blocks) do
     for _, b in ipairs(blocks) do
         table.insert(out, b)
         out[#out + 1] = b
     end
     end


Строка 978: Строка 1014:
     }, nil, true)
     }, nil, true)


    local whitelist = previewFilter.whitelist
     local hasWhitelist = previewFilter.hasWhitelist
     local hasWhitelist = previewFilter.hasWhitelist
     renderOptions.noHeaders = hasWhitelist
     renderOptions.noHeaders = hasWhitelist
Строка 985: Строка 1020:
     local blocks = renderBlocks(frame, state, renderOptions, "", showSource)
     local blocks = renderBlocks(frame, state, renderOptions, "", showSource)
     for _, b in ipairs(blocks) do
     for _, b in ipairs(blocks) do
         table.insert(out, b)
         out[#out + 1] = b
     end
     end