Module:ElectoralCalendarMap: Difference between revisions

From Elections Wiki
Jump to navigation Jump to search
No edit summary
Tag: Reverted
No edit summary
Tag: Manual revert
Line 2: Line 2:


function p.load(frame)
function p.load(frame)
    -- i understand chocolateman now, we can't fetch data from an outside source due to mediawiki's stupid restrictions
     local dataPage = "Data:Election_Data.json"
     local dataPage = "Data:Election_Data.json"
     local rowsPerPage = 7
      
    local currentPage = tonumber(frame.args.page) or 1
 
     local dataTitle = mw.title.new(dataPage)
     local dataTitle = mw.title.new(dataPage)
     if not dataTitle then
     if not dataTitle then
         return "could not find data page '" .. dataPage .. "'!"
         return "could not find data page '" .. dataPage .. "'!"
     end
     end
 
   
     local dataContent = dataTitle:getContent()
     local dataContent = dataTitle:getContent()
     if not dataContent then
     if not dataContent then
         return "could not retrieve content from '" .. dataPage .. "'!"
         return "could not retrieve content from '" .. dataPage .. "'!"
     end
     end
 
   
    -- Parse the JSON data
     local APIData = mw.text.jsonDecode(dataContent)
     local APIData = mw.text.jsonDecode(dataContent)
     if not APIData then
     if not APIData then
         return "invalid JSON content in '" .. dataPage .. "'!"
         return "invalid JSON content in '" .. dataPage .. "'!"
     end
     end
 
   
     local electionColors = {
     local electionColors = {
         General = "#4682b4", -- blue
         General = "#4682b4", -- blue
Line 27: Line 27:
         Referendum = "#ffa500" -- orange
         Referendum = "#ffa500" -- orange
     }
     }
 
   
     local allElections = {}
    -- get date
 
     local currentDate = os.date("!%Y-%m-%dT%H:%M:%S")
     for region, elections in pairs(APIData) do
    local combinedJSON = {}
         for _, election in ipairs(elections) do
   
            table.insert(allElections, {
     -- i'll try to clean up older elections of course,
                region = region,
    -- but a function to remove old ones is a good idea.
                election = election
    local function isNewElection(electionDate)
            })
         -- make it consistent with our format
         end
        local formattedDate = mw.ustring.gsub(electionDate, "[-:T]", ""):sub(1, 14)  
        local formattedCurrentDate = mw.ustring.gsub(currentDate, "[-:T]", ""):sub(1, 14)
         return formattedDate > formattedCurrentDate
     end
     end
    table.sort(allElections, function(a, b)
        return a.election.date > b.election.date
    end)
      
      
     local totalRows = #allElections
     local function generateDescription(elections)
    local totalPages = math.ceil(totalRows / rowsPerPage)
    local descriptionBits = {}
    if currentPage > totalPages then currentPage = totalPages end
    for _, election in ipairs(elections) do
    if currentPage < 1 then currentPage = 1 end
    table.insert(descriptionBits, string.format(
 
    "<b>%s</b><br>%s<br>%s",
    local startRow = (currentPage - 1) * rowsPerPage + 1
    election.election_name,
    local endRow = math.min(startRow + rowsPerPage - 1, totalRows)
    election.date,
 
    election.description
    local paginatedElections = {}
    ))
    for i = startRow, endRow do
    end
        table.insert(paginatedElections, allElections[i])
    return table.concat(descriptionBits, "<br><br>")
     end
     end
 
      
     local combinedJSON = {}
     for region, elections in pairs(APIData) do
     for _, entry in ipairs(paginatedElections) do
        local region = entry.region
        local election = entry.election
         local mapDataTitle = mw.title.new("MapData:" .. region .. ".map")
         local mapDataTitle = mw.title.new("MapData:" .. region .. ".map")
 
       
         if mapDataTitle then
         if mapDataTitle then
             local content = mapDataTitle:getContent()
             local content = mapDataTitle:getContent()
Line 68: Line 63:
                 if parsedContent and type(parsedContent.features) == "table" then
                 if parsedContent and type(parsedContent.features) == "table" then
                     for _, feature in ipairs(parsedContent.features) do
                     for _, feature in ipairs(parsedContent.features) do
                         feature.properties.title = string.gsub(region, "_", " ")
                         local validElections = {}
                        feature.properties.description = string.format(
                        for _, election in ipairs(elections) do
                             "<b>%s</b><br>%s<br>%s",
                            if isNewElection(election.date) then
                            election.election_name,
table.insert(validElections, election)
                            election.date,
                            end
                             election.description
                        end
                        )
                       
 
                        if #validElections > 0 then
                        local fillColor = electionColors[election.election_type] or "#404040"
                        feature.properties.title = string.gsub(region, "_", " ")
                        feature.properties.fill = fillColor
                            feature.properties.description = generateDescription(validElections)
                        feature.properties["fill-opacity"] = 0.8
                              
 
                             local fillColor = electionColors[validElections[1].election_type] or "#404040"
                        table.insert(combinedJSON, feature)
                            feature.properties.fill = fillColor
                            feature.properties["fill-opacity"] = 0.8
                         
                            -- filter out "invalid" elections for now
                            if feature.properties.fill ~= "#555555" then
                                table.insert(combinedJSON, feature)
                            end
                        else
                        mw.log("election date passed for '" .. region .. "'!")
                        end
                     end
                     end
                 else
                 else
Line 92: Line 96:
         end
         end
     end
     end
 
   
     local combinedMapData = mw.text.jsonEncode({
     local combinedMapData = mw.text.jsonEncode({
         type = "FeatureCollection",
         type = "FeatureCollection",
         features = combinedJSON
         features = combinedJSON
     })
     })
 
   
     local mapFrame = '<mapframe width="100%" height="400" zoom="3" longitude="0" latitude="0">' .. combinedMapData .. '</mapframe>'
     local mapFrame = '<mapframe width="100%" height="400" zoom="3" longitude="0" latitude="0">' .. combinedMapData .. '</mapframe>'
 
    --local mapFrame = '' .. combinedMapData .. ''
   
     return frame:preprocess(mapFrame)
     return frame:preprocess(mapFrame)
end
end


return p
return p

Revision as of 21:13, 26 January 2025

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

local p = {}

function p.load(frame)
    -- i understand chocolateman now, we can't fetch data from an outside source due to mediawiki's stupid restrictions
    local dataPage = "Data:Election_Data.json"
    
    local dataTitle = mw.title.new(dataPage)
    if not dataTitle then
        return "could not find data page '" .. dataPage .. "'!"
    end
    
    local dataContent = dataTitle:getContent()
    if not dataContent then
        return "could not retrieve content from '" .. dataPage .. "'!"
    end
    
    -- Parse the JSON data
    local APIData = mw.text.jsonDecode(dataContent)
    if not APIData then
        return "invalid JSON content in '" .. dataPage .. "'!"
    end
    
    local electionColors = {
        General = "#4682b4", -- blue
        Local = "#8a2be2", -- purple
        Statewide = "#008000", -- green
        Referendum = "#ffa500" -- orange
    }
    
    -- get date
    local currentDate = os.date("!%Y-%m-%dT%H:%M:%S") 
    local combinedJSON = {}
    
    -- i'll try to clean up older elections of course,
    -- but a function to remove old ones is a good idea.
    local function isNewElection(electionDate)
        -- make it consistent with our format
        local formattedDate = mw.ustring.gsub(electionDate, "[-:T]", ""):sub(1, 14) 
        local formattedCurrentDate = mw.ustring.gsub(currentDate, "[-:T]", ""):sub(1, 14)
        return formattedDate > formattedCurrentDate
    end
    
    local function generateDescription(elections)
    	local descriptionBits = {}
    	for _, election in ipairs(elections) do
    		table.insert(descriptionBits, string.format(
    			"<b>%s</b><br>%s<br>%s",
    			election.election_name,
    			election.date,
    			election.description
    		))
    	end
    	return table.concat(descriptionBits, "<br><br>")
    end
    
    for region, elections in pairs(APIData) do
        local mapDataTitle = mw.title.new("MapData:" .. region .. ".map")
        
        if mapDataTitle then
            local content = mapDataTitle:getContent()
            if content then
                local parsedContent = mw.text.jsonDecode(content)
                if parsedContent and type(parsedContent.features) == "table" then
                    for _, feature in ipairs(parsedContent.features) do
                        local validElections = {}
                        for _, election in ipairs(elections) do
                            if isNewElection(election.date) then
								table.insert(validElections, election)
                            end
                        end
                        
                        if #validElections > 0 then 
                        	feature.properties.title = string.gsub(region, "_", " ")
                            feature.properties.description = generateDescription(validElections)
                            
                            local fillColor = electionColors[validElections[1].election_type] or "#404040"
                            feature.properties.fill = fillColor
                            feature.properties["fill-opacity"] = 0.8
                           
                            -- filter out "invalid" elections for now
                            if feature.properties.fill ~= "#555555" then
                                table.insert(combinedJSON, feature)
                            end
                        else
                        	mw.log("election date passed for '" .. region .. "'!")
                        end
                    end
                else
                    mw.log("invalid or missing features in mapdata for region '" .. region .. "'!")
                end
            else
                mw.log("warning: couldn't fetch mapdata for region '" .. region .. "'!")
            end
        else
            mw.log("warning: couldn't create title object for region '" .. region .. "'!")
        end
    end
    
    local combinedMapData = mw.text.jsonEncode({
        type = "FeatureCollection",
        features = combinedJSON
    })
    
    local mapFrame = '<mapframe width="100%" height="400" zoom="3" longitude="0" latitude="0">' .. combinedMapData .. '</mapframe>'
    --local mapFrame = '' .. combinedMapData .. ''
    
    return frame:preprocess(mapFrame)
end

return p