Модуль:GetField: различия между версиями

Нет описания правки
мНет описания правки
 
(не показано 10 промежуточных версий этого же участника)
Строка 3: Строка 3:
local cache = {}
local cache = {}
local entryCache = {}
local entryCache = {}
local BASE_USER = "IanComradeBot/"
local function get_module_name(pagePath)
    return "Module:" .. BASE_USER .. pagePath .. "/data"
end
local function load_cached_data(moduleName)
    local data = cache[moduleName]
    if data then
        return data
    end
    local ok, loaded = pcall(mw.loadData, moduleName)
    if not ok or not loaded then
        return nil
    end
    cache[moduleName] = loaded
    return loaded
end


local function parse_indexed_part(part)
local function parse_indexed_part(part)
Строка 39: Строка 59:


local function format_value(v)
local function format_value(v)
    local okJson, json = pcall(mw.text.jsonEncode, v)
    if okJson and json == "null" then
        return "null"
    end
     if v == nil then return "" end
     if v == nil then return "" end
     local t = type(v)
     local t = type(v)
     if t == "string" or t == "number" or t == "boolean" then
     if t == "string" or t == "number" or t == "boolean" then
         return tostring(v)
         return tostring(v)
     elseif t == "table" then
     elseif t == "table" then
         local ok, json = pcall(mw.text.jsonEncode, v)
         local ok, json2 = pcall(mw.text.jsonEncode, v)
         if ok and json then
         if ok and json2 then
             return json
             return json2
         end
         end
         return ""
         return ""
Строка 55: Строка 81:


local function to_nowiki(v)
local function to_nowiki(v)
    local s = tostring(v)
     return "<nowiki>" .. v .. "</nowiki>"
     return "<nowiki>" .. s .. "</nowiki>"
end
end


Строка 127: Строка 152:
     end
     end
     return nil
     return nil
end
local function contains_target(v, target)
    if type(v) == "table" then
        if is_array(v) then
            for _, item in ipairs(v) do
                if tostring(item) == target then
                    return true
                end
            end
            return false
        end
        for _, item in pairs(v) do
            if tostring(item) == target then
                return true
            end
        end
        return false
    end
    return tostring(v) == target
end
local function find_matching_ids(idsTable, keyPath, searchValue)
    local target = tostring(searchValue)
    local matches = {}
    for idKey, entry in pairs(idsTable) do
        if type(entry) == "table" then
            local v = get_by_path(entry, keyPath)
            if v ~= nil and contains_target(v, target) then
                matches[#matches + 1] = idKey
            end
        end
    end
    return matches
end
local function preprocess_or_return(frame, text)
    if type(frame.preprocess) == "function" then
        return frame:preprocess(text)
    end
    return text
end
local function get_field_loose(entry, fieldId)
    local value = entry[fieldId]
    if value ~= nil then return value end
    if fieldId == "" then return nil end
    local first = string.sub(fieldId, 1, 1)
    local tail = string.sub(fieldId, 2)
    value = entry[string.lower(first) .. tail]
    if value ~= nil then return value end
    return entry[string.upper(first) .. tail]
end
end


Строка 142: Строка 225:
     end
     end


     local baseUser = "IanComradeBot/"
     local storeName = (kind == "prototype") and "prototype_store.json" or "component_store.json"
    local storeName
     local moduleName = get_module_name(storeName)
    if kind == "prototype" then
     local data = load_cached_data(moduleName)
        storeName = "prototype_store.json"
    else
        storeName = "component_store.json"
    end
     local moduleName = "Module:" .. baseUser .. storeName .. "/data"
 
     local data = cache[moduleName]
     if not data then
     if not data then
         local ok, loaded = pcall(mw.loadData, moduleName)
         return ""
        if not ok or not loaded then
            return ""
        end
        data = loaded
        cache[moduleName] = data
     end
     end


Строка 166: Строка 237:
     end
     end


     local value = entry[fieldId]
     local value = get_field_loose(entry, fieldId)
     if value == nil then
     if value == nil then
         return ""
         return ""
Строка 190: Строка 261:
     if id == "" or pagePath == "" then return "" end
     if id == "" or pagePath == "" then return "" end


    local baseUser = "IanComradeBot/"
     local moduleName = get_module_name(pagePath)
     local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
     local data = load_cached_data(moduleName)
 
     if not data then return "" end
     local data = cache[moduleName]
     if not data then
        local ok, loaded = pcall(mw.loadData, moduleName)
        if not ok or not loaded then return "" end
        data = loaded
        cache[moduleName] = data
    end


     local entry = resolve_entry(data, id) or {}
     local entry = resolve_entry(data, id) or {}
Строка 206: Строка 270:


     local parts = {}
     local parts = {}
    local function append_table_json(key, value)
        local ok, json = pcall(mw.text.jsonEncode, value)
        if ok and json then
            parts[#parts + 1] = key .. "=" .. to_nowiki(json)
        end
    end
     local function walk(tbl, prefix)
     local function walk(tbl, prefix)
         local keys = {}
         local keys = {}
Строка 212: Строка 283:
         for _, k in ipairs(keys) do
         for _, k in ipairs(keys) do
             local v = tbl[k]
             local v = tbl[k]
             local key = (prefix == "" and tostring(k) or prefix .. "." .. tostring(k))
            local kStr = tostring(k)
             local key = (prefix == "" and kStr or prefix .. "." .. kStr)
             if type(v) == "table" then
             if type(v) == "table" then
                 if next(v) == nil then
                 if next(v) == nil then
                elseif is_array(v) then
                    local ok, json = pcall(mw.text.jsonEncode, v)
                    if ok and json then
                        parts[#parts + 1] = key .. "=" .. tostring(json)
                    end
                 else
                 else
                     local ok, json = pcall(mw.text.jsonEncode, v)
                     append_table_json(key, v)
                     if ok and json then
                     if not is_array(v) then
                         parts[#parts + 1] = key .. "=" .. to_nowiki(json)
                         walk(v, key)
                     end
                     end
                    walk(v, key)
                 end
                 end
             else
             else
Строка 246: Строка 312:
     if pagePath == "" then return "" end
     if pagePath == "" then return "" end


    local baseUser = "IanComradeBot/"
     local moduleName = get_module_name(pagePath)
     local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
     local data = load_cached_data(moduleName)
 
     if not data then return "" end
     local data = cache[moduleName]
     if not data then
        local ok, loaded = pcall(mw.loadData, moduleName)
        if not ok or not loaded then return "" end
        data = loaded
        cache[moduleName] = data
    end


     local entryKey = moduleName .. "|" .. (id ~= "" and id or "default")
     local entryKey = moduleName .. "|" .. (id ~= "" and id or "default")
Строка 283: Строка 342:
     end
     end


    local baseUser = "IanComradeBot/"
     local moduleName = get_module_name(pagePath)
     local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
     local data = load_cached_data(moduleName)
 
     if not data then return "[]" end
     local data = cache[moduleName]
     if not data then
        local ok, loaded = pcall(mw.loadData, moduleName)
        if not ok or not loaded then return "" end
        data = loaded
        cache[moduleName] = data
    end


     local idsTable = data.id
     local idsTable = data.id
Строка 299: Строка 351:
     end
     end


     local target = tostring(searchValue)
     local matches = find_matching_ids(idsTable, keyPath, searchValue)
 
    if #matches == 0 then
        return ""
    end


     for idKey, entry in pairs(idsTable) do
     local ok, json = pcall(mw.text.jsonEncode, matches)
        if type(entry) == "table" then
    if ok and json then
            local v = get_by_path(entry, keyPath)
        return json
            if v ~= nil then
                if type(v) == "table" then
                    if is_array(v) then
                        for _, item in ipairs(v) do
                            if tostring(item) == target then
                                return idKey
                            end
                        end
                    else
                        for _, item in pairs(v) do
                            if tostring(item) == target then
                                return idKey
                            end
                        end
                    end
                else
                    if tostring(v) == target then
                        return idKey
                    end
                end
            end
        end
     end
     end


Строка 342: Строка 376:
     end
     end


    local baseUser = "IanComradeBot/"
     local moduleName = get_module_name(pagePath)
     local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
     local data = load_cached_data(moduleName)
 
     if not data then return "" end
     local data = cache[moduleName]
     if not data then
        local ok, loaded = pcall(mw.loadData, moduleName)
        if not ok or not loaded then return "" end
        data = loaded
        cache[moduleName] = data
    end


     local idsTable = data.id
     local idsTable = data.id
Строка 358: Строка 385:
     end
     end


    local target = tostring(searchValue)
     local matches = find_matching_ids(idsTable, keyPath, searchValue)
     local matches = {}
 
    for idKey, entry in pairs(idsTable) do
        if type(entry) == "table" then
            local v = get_by_path(entry, keyPath)
            if v ~= nil then
                if type(v) == "table" then
                    if is_array(v) then
                        for _, item in ipairs(v) do
                            if tostring(item) == target then
                                matches[#matches + 1] = idKey
                                break
                            end
                        end
                    else
                        for _, item in pairs(v) do
                            if tostring(item) == target then
                                matches[#matches + 1] = idKey
                                break
                            end
                        end
                    end
                else
                    if tostring(v) == target then
                        matches[#matches + 1] = idKey
                    end
                end
            end
        end
    end


     if #matches == 0 then
     if #matches == 0 then
Строка 406: Строка 403:
     end
     end


     local result = table.concat(out, "\n")
     local result = table.concat(out, " ")
     if type(frame.preprocess) == "function" then
     return preprocess_or_return(frame, result)
        return frame:preprocess(result)
    end
 
    return result
end
end


Строка 431: Строка 424:
     tplStr = tplStr .. "}}"
     tplStr = tplStr .. "}}"


     if type(frame.preprocess) == "function" then
     return preprocess_or_return(frame, tplStr)
        return frame:preprocess(tplStr)
    end
 
    return tplStr
end
end


Строка 469: Строка 458:
     end
     end


     local result = table.concat(out, "\n")
     local result = table.concat(out, " ")
     if type(frame.preprocess) == "function" then
    return preprocess_or_return(frame, result)
         return frame:preprocess(result)
end
 
function p.getGenerator(frame)
    local args = frame.args or {}
    local searchId = args[1] or ""
    local kind = (args[2] or ""):lower()
    local generatorId = args[3] or ""
 
    if searchId == "" or generatorId == "" then
        return ""
    end
     if kind ~= "prototype" and kind ~= "component" then
        return ""
    end
 
    local idsJson = p.findInGenerator({ args = { searchId, kind, generatorId } })
    local ok, ids = pcall(mw.text.jsonDecode, idsJson or "")
    if not ok or type(ids) ~= "table" or #ids == 0 then
        return ""
    end
 
    local okOut, outJson = pcall(mw.text.jsonEncode, ids)
    if okOut and outJson then
        return outJson
    end
 
    return ""
end
 
function p.hasComp(frame)
    local args = frame.args or {}
    local entityId = args[1] or ""
    local compName = args[2] or ""
 
    if entityId == "" or compName == "" then
        return "false"
    end
 
    local moduleName = get_module_name("component.json")
    local data = load_cached_data(moduleName)
    if not data then
        return "false"
    end
 
    if type(data) ~= "table" then
        return "false"
    end
 
    local entry = data[entityId]
    if type(entry) ~= "table" then
         return "false"
    end
 
    local target = tostring(compName)
    for _, v in ipairs(entry) do
        if tostring(v) == target then
            return "true"
        end
     end
     end


     return result
     return "false"
end
end


return p
return p