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

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
 
(не показано 29 промежуточных версий этого же участника)
Строка 1: Строка 1:
local data = mw.loadData("Модуль:IanComradeBot/loc.json/data")
local p = {}
local p = {}


-- Глобальный кэш данных и индекса
local function tolower(s)
local cachedData = nil
    return s and mw.ustring.lower(s) or s
local cachedIndex = nil
end


-- Загрузка данных из JSON
local complexLowerIndex = nil
local function loadData(filePath)
    if not cachedData then
        local page = mw.title.new(filePath)
        local content = page and page:getContent()
        cachedData = content and mw.text.jsonDecode(content) or nil
    end
    return cachedData
end


-- Создание индекса для быстрого поиска по ключам
local function buildComplexIndex()
local function buildIndex(data)
     if complexLowerIndex then return end
     if not cachedIndex then
    complexLowerIndex = {}
        cachedIndex = {}
    for k, v in pairs(data) do
        for categoryName, category in pairs(data) do
        if type(v) == "table" and type(k) == "string" then
             for key, value in pairs(category) do
             local lk = tolower(k)
                 cachedIndex[key] = value
            if not complexLowerIndex[lk] then
                 complexLowerIndex[lk] = v
             end
             end
         end
         end
     end
     end
    return cachedIndex
end
-- Поиск текста по ключу через индекс
local function findTextByKey(index, key)
    return index[key] or nil
end
end


-- Поиск ключа по тексту (всё ещё перебор, но он используется реже)
local function getValueFromEntry(entry, subkey)
local function findKeyByText(data, text)
    if entry == nil then return nil end
     for categoryName, category in pairs(data) do
    local t = type(entry)
         for key, value in pairs(category) do
     if t == "string" then
            if value == text then
         return entry
                return key
    elseif t == "table" then
             end
        if subkey then
            return entry[subkey]
        else
             return entry["_value"]
         end
         end
     end
     end
Строка 45: Строка 37:
end
end


-- Получение всех строк из категории
local function findTextByKeyOptimized(key, subkey)
local function getCategoryStrings(data, categoryName)
    if not key then return nil end
     local category = data[categoryName]
 
     if not category then
     local direct = data[key]
        return nil
    local r = getValueFromEntry(direct, subkey)
    end
     if r then return r end


     local result = {}
    buildComplexIndex()
     for _, value in pairs(category) do
     local lk = tolower(key)
        if type(value) == "string" then
     local complexEntry = complexLowerIndex[lk]
            table.insert(result, value)
    if complexEntry then
         end
        local rr = getValueFromEntry(complexEntry, subkey)
         if rr then return rr end
     end
     end


     return result
     return nil
end
end


-- Основная функция модуля
function p.GetString(frame)
function p.main(frame)
     local key = frame.args[1]
     local mode = frame.args[1]
     local subkey = frame.args[2] or "_value"
     local param = frame.args[2]


     if not mode or not param then
     if not key then
         return "Ошибка: Не указаны все необходимые параметры."
         return "Ошибка: Не указаны все необходимые параметры."
     end
     end


    -- Загрузка данных из JSON
     local result = findTextByKeyOptimized(key, subkey)
     local data = loadData('User:IanComradeBot/ftl/ru-RU.json')
 
     if not data or type(data) ~= 'table' then
     if not result then
         return 'Ошибка: Невозможно загрузить данные из JSON.'
         return key
     end
     end


     -- Построение индекса (если требуется)
     return frame:preprocess("{{#invoke:Loc/Marking|main|<nowiki>".. result .. "</nowiki>}}")
     local index = buildIndex(data)
end
 
function p.GetRawString(frame)
     local key = frame.args[1]
    local subkey = frame.args[2] or "_value"
 
    if not key then
        return "Ошибка: Не указаны все необходимые параметры."
    end


     if mode == "translation" then
     local result = findTextByKeyOptimized(key, subkey)
        local result = findTextByKey(index, param)
        return result or "Ошибка: Ключ не найден."
    elseif mode == "key" then
        local result = findKeyByText(data, param)
        return result or "Ошибка: Текст не найден."
    elseif mode == "categories" then
        local strings = getCategoryStrings(data, param)
        if not strings or #strings == 0 then
            return "Ошибка: Категория не найдена или пуста."
        end


        local output = {}
     if not result then
        for _, value in ipairs(strings) do
         return key
            table.insert(output, "<li>" .. mw.text.encode(value) .. "</li>")
        end
        return table.concat(output)
     else
         return "Ошибка: Неизвестный режим работы."
     end
     end
    return frame:preprocess("<nowiki>".. result .. "</nowiki>")
end
end


return p
return p

Текущая версия от 17:57, 24 февраля 2026

Для документации этого модуля может быть создана страница Модуль:Loc/doc

local data = mw.loadData("Модуль:IanComradeBot/loc.json/data")

local p = {}

local function tolower(s)
    return s and mw.ustring.lower(s) or s
end

local complexLowerIndex = nil

local function buildComplexIndex()
    if complexLowerIndex then return end
    complexLowerIndex = {}
    for k, v in pairs(data) do
        if type(v) == "table" and type(k) == "string" then
            local lk = tolower(k)
            if not complexLowerIndex[lk] then
                complexLowerIndex[lk] = v
            end
        end
    end
end

local function getValueFromEntry(entry, subkey)
    if entry == nil then return nil end
    local t = type(entry)
    if t == "string" then
        return entry
    elseif t == "table" then
        if subkey then
            return entry[subkey]
        else
            return entry["_value"]
        end
    end
    return nil
end

local function findTextByKeyOptimized(key, subkey)
    if not key then return nil end

    local direct = data[key]
    local r = getValueFromEntry(direct, subkey)
    if r then return r end

    buildComplexIndex()
    local lk = tolower(key)
    local complexEntry = complexLowerIndex[lk]
    if complexEntry then
        local rr = getValueFromEntry(complexEntry, subkey)
        if rr then return rr end
    end

    return nil
end

function p.GetString(frame)
    local key = frame.args[1]
    local subkey = frame.args[2] or "_value"

    if not key then
        return "Ошибка: Не указаны все необходимые параметры."
    end

    local result = findTextByKeyOptimized(key, subkey)

    if not result then
        return key
    end

    return frame:preprocess("{{#invoke:Loc/Marking|main|<nowiki>".. result .. "</nowiki>}}")
end

function p.GetRawString(frame)
    local key = frame.args[1]
    local subkey = frame.args[2] or "_value"

    if not key then
        return "Ошибка: Не указаны все необходимые параметры."
    end

    local result = findTextByKeyOptimized(key, subkey)

    if not result then
        return key
    end

    return frame:preprocess("<nowiki>".. result .. "</nowiki>")
end

return p