Module:RecursiveSelectiveList

From Ikwipedia
Revision as of 06:46, 22 December 2024 by EnWikiAdmin (talk | contribs)

Documentation for this module may be created at Module:RecursiveSelectiveList/doc

local p = {}
local function fetchCategoryMembers(categoryName, cmtype, continue)
    local url = mw.uri.fullUrl('api.php', {
        action = 'query',
        list = 'categorymembers',
        cmtitle = 'Category:' .. categoryName,
        cmtype = cmtype,
        cmlimit = 'max',
        format = 'json',
        cmcontinue = continue
    })

    local response = mw.http.get(url)
    if response.status ~= 200 then
        return nil, "HTTP request failed with status: " .. response.status
    end

    local data = mw.json.decode(response.body)
    if not data then
        return nil, "Failed to decode JSON response."
    end

    return data
end

local function getPagesRecursively(categoryName, visitedCategories, pages, limit)
    if visitedCategories[categoryName] then
        return
    end
    visitedCategories[categoryName] = true

    -- Fetch subcategories
    local continue
    repeat
        local data, err = fetchCategoryMembers(categoryName, 'subcat', continue)
        if not data then
            return nil, err
        end

        for _, member in ipairs(data.query.categorymembers) do
            getPagesRecursively(member.title:match('Category:(.+)'), visitedCategories, pages, limit)
            if limit and #pages >= limit then
                return
            end
        end

        continue = data.continue and data.continue.cmcontinue
    until not continue

    -- Fetch pages in the main namespace
    continue = nil
    repeat
        local data, err = fetchCategoryMembers(categoryName, 'page', continue)
        if not data then
            return nil, err
        end

        for _, member in ipairs(data.query.categorymembers) do
            if member.ns == 0 then
                table.insert(pages, member.title)
                if limit and #pages >= limit then
                    return
                end
            end
        end

        continue = data.continue and data.continue.cmcontinue
    until not continue
end


function p.main(frame)
    local args = frame:getParent().args
    local categoryName = args['categoryName']
    local limit = tonumber(args['limit'])

    if not categoryName then
        return "Error: Please provide a category name."
    end

    local visitedCategories = {}
    local pages = {}

    local success, err = pcall(function()
        getPagesRecursively(categoryName, visitedCategories, pages, limit)
    end)

    if not success then
        return "Error: " .. err
    end

    if #pages == 0 then
        return "No pages found."
    end

    -- Generate a bulleted list
    local output = {}
    for _, page in ipairs(pages) do
        table.insert(output, "* [[" .. page .. "]]")
    end

    return table.concat(output, "\n")
end
return p