Module:RecursiveSelectiveList: Difference between revisions

From Ikwipedia
No edit summary
No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 1: Line 1:
local p = {}
local p = {}
local mw = require('mw')


-- Main function: Entry point for the module
-- Helper function to format numbers with commas
function p.main(frame)
local function formatNumber(num)
     -- Retrieve the template arguments
    if not num then return "0" end
     local args = frame.args
    local formatted = tostring(num)
    local k
    while true do 
        formatted, k = formatted:gsub("^(-?%d+)(%d%d%d)", '%1,%2')
        if k == 0 then break end
    end
    return formatted
end
 
-- Helper function to format dates
local function formatDate(timestamp)
     -- Convert ISO 8601 to a more readable format
     return mw.language.formatDate(timestamp, '%Y-%m-%d %H:%M:%S')
end


    -- Get the 'categoryName' parameter from the template
-- Function to retrieve category statistics
     local categoryName = args.categoryName
function p.getCategoryStats(frame)
     local categoryName = frame.args.categoryName -- Pass the category name as an argument


    -- Check if 'categoryName' is provided
     if not categoryName or categoryName == "" then
     if not categoryName or categoryName == "" then
         return "Error: 'categoryName' parameter is missing or empty."
         return "'''Error:''' No category name provided."
     end
     end


     -- Ensure the category name starts with "Category:"
     local stats = mw.site.stats.pagesInCategory(categoryName, "*")
    -- If the user provides "Books" instead of "Category:Books", fix it here
     if not stats then
     if not categoryName:match("^Category:") then
         return "'''Error:''' Unable to retrieve statistics for the category."
         categoryName = "Category:" .. categoryName
     end
     end


     -- Debugging: Display the final category name being used
     -- Calculate percentages
     local debugInfo = "Debug: Fetching members for '" .. categoryName .. "'\n"
     local total = stats.all
    local pagesPercent = total > 0 and string.format("%.2f%%", (stats.pages / total) * 100) or "0%"
    local subcatsPercent = total > 0 and string.format("%.2f%%", (stats.subcats / total) * 100) or "0%"
    local filesPercent = total > 0 and string.format("%.2f%%", (stats.files / total) * 100) or "0%"


     -- Fetch category members using the API
     -- Create a link to the category
     local members = p.getCategoryMembers(categoryName)
     local categoryLink = "[[Category:" .. mw.text.encode(categoryName) .. "|" .. mw.text.encode(categoryName) .. "]]"


     -- Check if the category has members
     -- Build the wikitext table for category stats
     if not members or #members == 0 then
     local result = {}
        -- Add debug information about failure
    table.insert(result, '{| class="wikitable sortable" style="width:50%; margin:auto;"')
        debugInfo = debugInfo .. "No members found for '" .. categoryName .. "'.\n"
    table.insert(result, '! colspan="3" style="text-align:center; font-size:150%;" ' .. categoryLink)
        return debugInfo .. "The category '" .. categoryName .. "' has no members."
    table.insert(result, '|-')
     end
    table.insert(result, '! Statistic !! Count !! Percentage')
    table.insert(result, '|-')
    table.insert(result, '| Total items || ' .. formatNumber(stats.all) .. ' || 100%')
    table.insert(result, '|-')
    table.insert(result, '| Pages || ' .. formatNumber(stats.pages) .. ' || ' .. pagesPercent)
    table.insert(result, '|-')
    table.insert(result, '| Subcategories || ' .. formatNumber(stats.subcats) .. ' || ' .. subcatsPercent)
    table.insert(result, '|-')
    table.insert(result, '| Files || ' .. formatNumber(stats.files) .. ' || ' .. filesPercent)
     table.insert(result, '|}')


    -- Return the list of category members as a comma-separated string
     return table.concat(result, "\n")
     return debugInfo .. "Members: " .. table.concat(members, ", ")
end
end


-- Function to fetch category members using the MediaWiki API
-- Function to list revision dates for pages in the category
function p.getCategoryMembers(categoryName)
function p.listRevisionDates(frame)
     -- Table to store the member titles
     local categoryName = frame.args.categoryName -- Pass the category name as an argument
    local members = {}


     -- Debug: Log the API parameters
     if not categoryName or categoryName == "" then
    local params = {
         return "'''Error:''' No category name provided."
        action = "query", -- Query action for fetching data
     end
         list = "categorymembers", -- Specify that we want category members
        cmtitle = categoryName, -- The full title of the category
        cmlimit = "max", -- Fetch the maximum number of members allowed (500 or server limit)
        format = "json" -- Specify that the API response should be in JSON format
     }


     -- Debugging: Log the parameters being sent to the API
     local stats = mw.site.stats.pagesInCategory(categoryName, "*")
     mw.logObject(params)
    if not stats then
        return "'''Error:''' Unable to retrieve statistics for the category."
     end


     -- Call the MediaWiki API
     -- For demonstration purposes, we'll assume 'stats.pages' gives us the number of pages.
     local success, result = p.callAPI(params)
    -- However, to list individual pages and their revisions, we need to fetch them.
    -- Since 'mw.site.stats.pagesInCategory' provides counts, not individual titles,
    -- we need an alternative approach. Unfortunately, without 'getCategoryMembers',
    -- it's challenging to list individual pages. If your environment has another
     -- way to retrieve page titles, please let me know. Otherwise, we'll proceed
    -- by limiting the functionality to category statistics.


     -- Check if the API call succeeded
     -- Placeholder message indicating the limitation
     if not success then
     local result = {}
        -- Log the failure to retrieve data
    table.insert(result, "<h2>Latest Revisions for Pages in [[" .. mw.text.encode(categoryName) .. "]]</h2>")
        mw.log("API call failed for category: " .. categoryName)
    table.insert(result, "'''Note:''' Listing individual page revisions requires access to page titles, which is not available using `mw.site.stats.pagesInCategory`. To enable this functionality, consider using `mw.site.getCategoryMembers` or another method that provides page titles.")
        return members -- Return an empty table on failure
 
    return table.concat(result, "\n")
end
 
-- Function to get the latest revision date of a single page (optional)
function p.getLatestEditDate(frame)
    local pageName = frame.args.pageName
    if not pageName or pageName == "" then
        return "'''Error:''' No page name provided."
     end
     end


     -- Debugging: Log the raw API result
     local title = mw.title.new(pageName)
    mw.logObject(result)
    if not title or not title.exists then
        return "'''Error:''' Invalid or non-existent page title."
    end


     -- Check if the API result contains the 'query' and 'categorymembers' data
     local revision = title:getLatestRevision()
     if not result.query or not result.query.categorymembers then
     if not revision then
         mw.log("Invalid API response structure for category: " .. categoryName)
         return "'''Error:''' Unable to retrieve the latest revision."
        return members -- Return an empty table if the response is invalid
     end
     end


     -- Extract member titles from the API result
     local timestamp = revision:getTimestamp()
     for _, member in ipairs(result.query.categorymembers) do
     local formattedTime = formatDate(timestamp)
        table.insert(members, member.title) -- Add the title of each member to the list
    local user = revision:getUser()
    end


     return members
     return string.format("**Latest Edit Date for [[%s]]:** %s UTC by [[User:%s|%s]]",
        mw.text.encode(pageName),
        formattedTime,
        mw.text.encode(user),
        mw.text.encode(user)
    )
end
end


-- Function to call the MediaWiki API
-- Main function to orchestrate the output
-- Function to call the MediaWiki API
function p.main(frame)
function p.callAPI(params)
     local categoryStats = p.getCategoryStats(frame)
     -- Use pcall to safely call the API and handle any errors
     local revisionData = p.listRevisionDates(frame)
     local success, result = pcall(function()
    local singlePageRevision = p.getLatestEditDate(frame) -- Example of single page revision
        -- Call the MediaWiki API and return the JSON-decoded result
 
        local response = mw.site.api(params)
    -- You can control the inclusion of the single page revision by checking for 'pageName'
        mw.log("Raw API response: " .. tostring(response))
    -- If 'pageName' is not provided, you can skip this part
        return mw.text.jsonDecode(response)
    local includeSinglePageRevision = frame.args.pageName and frame.args.pageName ~= ""
     end)
 
     -- Add a separator between sections
    local separator = "\n\n"


     -- Return whether the call succeeded and the result (or nil on failure)
     -- Combine all parts
     if success then
     local outputParts = {categoryStats, revisionData}
        return true, result
     if includeSinglePageRevision then
     else
         table.insert(outputParts, separator .. singlePageRevision)
         mw.log("Error in API call: " .. tostring(result)) -- Log the error message
        return false, nil
     end
     end
    -- Combine with separators
    local output = table.concat(outputParts, separator)
    -- Optionally, add a timestamp of when the data was retrieved
    local timestamp = os.date("Retrieved on %Y-%m-%d at %H:%M:%S UTC")
    output = output .. '\n<div style="text-align:center; font-size:small; color:gray;">' .. timestamp .. '</div>'
    return output
end
end


return p
return p

Latest revision as of 18:05, 22 December 2024

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

local p = {}

-- Helper function to format numbers with commas
local function formatNumber(num)
    if not num then return "0" end
    local formatted = tostring(num)
    local k
    while true do  
        formatted, k = formatted:gsub("^(-?%d+)(%d%d%d)", '%1,%2')
        if k == 0 then break end
    end
    return formatted
end

-- Helper function to format dates
local function formatDate(timestamp)
    -- Convert ISO 8601 to a more readable format
    return mw.language.formatDate(timestamp, '%Y-%m-%d %H:%M:%S')
end

-- Function to retrieve category statistics
function p.getCategoryStats(frame)
    local categoryName = frame.args.categoryName -- Pass the category name as an argument

    if not categoryName or categoryName == "" then
        return "'''Error:''' No category name provided."
    end

    local stats = mw.site.stats.pagesInCategory(categoryName, "*")
    if not stats then
        return "'''Error:''' Unable to retrieve statistics for the category."
    end

    -- Calculate percentages
    local total = stats.all
    local pagesPercent = total > 0 and string.format("%.2f%%", (stats.pages / total) * 100) or "0%"
    local subcatsPercent = total > 0 and string.format("%.2f%%", (stats.subcats / total) * 100) or "0%"
    local filesPercent = total > 0 and string.format("%.2f%%", (stats.files / total) * 100) or "0%"

    -- Create a link to the category
    local categoryLink = "[[Category:" .. mw.text.encode(categoryName) .. "|" .. mw.text.encode(categoryName) .. "]]"

    -- Build the wikitext table for category stats
    local result = {}
    table.insert(result, '{| class="wikitable sortable" style="width:50%; margin:auto;"')
    table.insert(result, '! colspan="3" style="text-align:center; font-size:150%;" ' .. categoryLink)
    table.insert(result, '|-')
    table.insert(result, '! Statistic !! Count !! Percentage')
    table.insert(result, '|-')
    table.insert(result, '| Total items || ' .. formatNumber(stats.all) .. ' || 100%')
    table.insert(result, '|-')
    table.insert(result, '| Pages || ' .. formatNumber(stats.pages) .. ' || ' .. pagesPercent)
    table.insert(result, '|-')
    table.insert(result, '| Subcategories || ' .. formatNumber(stats.subcats) .. ' || ' .. subcatsPercent)
    table.insert(result, '|-')
    table.insert(result, '| Files || ' .. formatNumber(stats.files) .. ' || ' .. filesPercent)
    table.insert(result, '|}')

    return table.concat(result, "\n")
end

-- Function to list revision dates for pages in the category
function p.listRevisionDates(frame)
    local categoryName = frame.args.categoryName -- Pass the category name as an argument

    if not categoryName or categoryName == "" then
        return "'''Error:''' No category name provided."
    end

    local stats = mw.site.stats.pagesInCategory(categoryName, "*")
    if not stats then
        return "'''Error:''' Unable to retrieve statistics for the category."
    end

    -- For demonstration purposes, we'll assume 'stats.pages' gives us the number of pages.
    -- However, to list individual pages and their revisions, we need to fetch them.
    -- Since 'mw.site.stats.pagesInCategory' provides counts, not individual titles,
    -- we need an alternative approach. Unfortunately, without 'getCategoryMembers',
    -- it's challenging to list individual pages. If your environment has another
    -- way to retrieve page titles, please let me know. Otherwise, we'll proceed
    -- by limiting the functionality to category statistics.

    -- Placeholder message indicating the limitation
    local result = {}
    table.insert(result, "<h2>Latest Revisions for Pages in [[" .. mw.text.encode(categoryName) .. "]]</h2>")
    table.insert(result, "'''Note:''' Listing individual page revisions requires access to page titles, which is not available using `mw.site.stats.pagesInCategory`. To enable this functionality, consider using `mw.site.getCategoryMembers` or another method that provides page titles.")

    return table.concat(result, "\n")
end

-- Function to get the latest revision date of a single page (optional)
function p.getLatestEditDate(frame)
    local pageName = frame.args.pageName
    if not pageName or pageName == "" then
        return "'''Error:''' No page name provided."
    end

    local title = mw.title.new(pageName)
    if not title or not title.exists then
        return "'''Error:''' Invalid or non-existent page title."
    end

    local revision = title:getLatestRevision()
    if not revision then
        return "'''Error:''' Unable to retrieve the latest revision."
    end

    local timestamp = revision:getTimestamp()
    local formattedTime = formatDate(timestamp)
    local user = revision:getUser()

    return string.format("**Latest Edit Date for [[%s]]:** %s UTC by [[User:%s|%s]]", 
        mw.text.encode(pageName), 
        formattedTime, 
        mw.text.encode(user), 
        mw.text.encode(user)
    )
end

-- Main function to orchestrate the output
function p.main(frame)
    local categoryStats = p.getCategoryStats(frame)
    local revisionData = p.listRevisionDates(frame)
    local singlePageRevision = p.getLatestEditDate(frame) -- Example of single page revision

    -- You can control the inclusion of the single page revision by checking for 'pageName'
    -- If 'pageName' is not provided, you can skip this part
    local includeSinglePageRevision = frame.args.pageName and frame.args.pageName ~= ""

    -- Add a separator between sections
    local separator = "\n\n"

    -- Combine all parts
    local outputParts = {categoryStats, revisionData}
    if includeSinglePageRevision then
        table.insert(outputParts, separator .. singlePageRevision)
    end

    -- Combine with separators
    local output = table.concat(outputParts, separator)

    -- Optionally, add a timestamp of when the data was retrieved
    local timestamp = os.date("Retrieved on %Y-%m-%d at %H:%M:%S UTC")
    output = output .. '\n<div style="text-align:center; font-size:small; color:gray;">' .. timestamp .. '</div>'

    return output
end

return p