Module:RecursiveSelectiveList: Difference between revisions

From Ikwipedia
No edit summary
No edit summary
Line 1: Line 1:
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
    })


-- Function to get pages recursively
     local response = mw.http.get(url)
local function getPagesFromCategory(categoryName, limit, visited, output)
     if response.status ~= 200 then
     local categoryTitle = mw.title.new("Category:" .. categoryName)
         return nil, "HTTP request failed with status: " .. response.status
     if not categoryTitle or not categoryTitle.exists then
    end
         table.insert(output, "<!-- Debug: Category '" .. categoryName .. "' does not exist -->")
 
    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
         return
     end
     end
    visitedCategories[categoryName] = true


     -- Debug: Add to HTML comments
     -- Fetch subcategories
     table.insert(output, "<!-- Debug: Processing category '" .. categoryName .. "' -->")
     local continue
    repeat
        local data, err = fetchCategoryMembers(categoryName, 'subcat', continue)
        if not data then
            return nil, err
        end


    -- Get pages directly in the category
        for _, member in ipairs(data.query.categorymembers) do
    local members = mw.site.categories[categoryName]
            getPagesRecursively(member.title:match('Category:(.+)'), visitedCategories, pages, limit)
    for _, member in ipairs(members) do
             if limit and #pages >= limit then
        if member.ns == 0 and not visited[member.prefixedText] then
                return
             visited[member.prefixedText] = true
             end
             table.insert(output, "* [[" .. member.prefixedText .. "]]")
         end
         end
    end


     -- Get subcategories and process them recursively
        continue = data.continue and data.continue.cmcontinue
     local subcategories = {}
    until not continue
     for _, member in ipairs(members) do
 
         if member.ns == 14 and not visited[member.prefixedText] then
     -- Fetch pages in the main namespace
             visited[member.prefixedText] = true
     continue = nil
            table.insert(subcategories, member.title)
     repeat
        local data, err = fetchCategoryMembers(categoryName, 'page', continue)
         if not data then
             return nil, err
         end
         end
    end


    -- Debug: Log subcategories being processed
        for _, member in ipairs(data.query.categorymembers) do
    table.insert(output, "<!-- Debug: Found " .. #subcategories .. " subcategories in '" .. categoryName .. "' -->")
            if member.ns == 0 then
                table.insert(pages, member.title)
                if limit and #pages >= limit then
                    return
                end
            end
        end


    for _, subcategory in ipairs(subcategories) do
         continue = data.continue and data.continue.cmcontinue
         if limit and #output >= limit then
     until not continue
            break
        end
        getPagesFromCategory(subcategory, limit, visited, output)
     end
end
end


-- Main function
 
function p.main(frame)
function p.main(frame)
     local args = frame:getParent().args
     local args = frame:getParent().args
     local categoryName = args["categoryName"]
     local categoryName = args['categoryName']
     local limit = tonumber(args["limit"])
     local limit = tonumber(args['limit'])
    local debugOutput = {} -- For storing debug comments


     if not categoryName then
     if not categoryName then
Line 52: Line 78:
     end
     end


     -- Debug: Add initial input validation to comments
     local visitedCategories = {}
     table.insert(debugOutput, "<!-- Debug: Starting with category '" .. categoryName .. "' -->")
    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 = {}
     local output = {}
     getPagesFromCategory(categoryName, limit, {}, output)
     for _, page in ipairs(pages) do
        table.insert(output, "* [[" .. page .. "]]")
    end


     -- Join output and debug comments
     return table.concat(output, "\n")
    local result = table.concat(debugOutput, "\n") .. "\n" .. table.concat(output, "\n")
    return result
end
end
return p

Revision as of 06:44, 22 December 2024

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

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