Module:RecursiveSelectiveList: Difference between revisions
EnWikiAdmin (talk | contribs) No edit summary |
EnWikiAdmin (talk | contribs) No edit summary |
||
Line 1: | Line 1: | ||
local | 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 | |||
local | return nil, "HTTP request failed with status: " .. response.status | ||
if | 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 | return | ||
end | 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 | end | ||
-- | continue = data.continue and data.continue.cmcontinue | ||
until not continue | |||
if | -- Fetch pages in the main namespace | ||
continue = nil | |||
repeat | |||
local data, err = fetchCategoryMembers(categoryName, 'page', continue) | |||
if not data then | |||
return nil, err | |||
end | 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 | end | ||
function p.main(frame) | function p.main(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local categoryName = args[ | local categoryName = args['categoryName'] | ||
local limit = tonumber(args[ | local limit = tonumber(args['limit']) | ||
if not categoryName then | if not categoryName then | ||
Line 52: | Line 78: | ||
end | 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 = {} | local output = {} | ||
for _, page in ipairs(pages) do | |||
table.insert(output, "* [[" .. page .. "]]") | |||
end | |||
return table.concat(output, "\n") | |||
end | end | ||
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