Module:ElectoralCalendarMap: Difference between revisions

From Elections Wiki
Jump to navigation Jump to search
Created page with "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..."
 
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 4: Line 4:
     -- i understand chocolateman now, we can't fetch data from an outside source due to mediawiki's stupid restrictions
     -- 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 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 26:
         Referendum = "#ffa500" -- orange
         Referendum = "#ffa500" -- orange
     }
     }
    local currentDate = os.date("!%Y-%m-%dT%H:%M:%S")
      
      
    -- get date
     local function isUpcoming(electionDate)
    local currentDate = os.date("!%Y-%m-%dT%H:%M:%S")
         local formattedElectionDate = mw.ustring.gsub(electionDate, "[-:T]", ""):sub(1, 14)
    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)
         local formattedCurrentDate = mw.ustring.gsub(currentDate, "[-:T]", ""):sub(1, 14)
         return formattedDate > formattedCurrentDate
         return formattedElectionDate > formattedCurrentDate
     end
     end
   
 
     local function generateDescription(elections)
     local upcomingElections = {}
    local descriptionBits = {}
    for region, elections in pairs(APIData) do
    for _, election in ipairs(elections) do
        for _, election in ipairs(elections) do
    table.insert(descriptionBits, string.format(
            if isUpcoming(election.date) then
    "<b>%s</b><br>%s<br>%s",
                table.insert(upcomingElections, {
    election.election_name,
                    region = region,
    election.date,
                    election = election
    election.description
                })
    ))
            end
    end
        end
    return table.concat(descriptionBits, "<br><br>")
    end
 
    table.sort(upcomingElections, function(a, b)
        return a.election.date < b.election.date
    end)
 
    local limitedElections = {}
    for i = 1, math.min(7, #upcomingElections) do
        table.insert(limitedElections, upcomingElections[i])
     end
     end
      
 
     for region, elections in pairs(APIData) do
     local combinedJSON = {}
     for _, entry in ipairs(limitedElections) 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 63: Line 68:
                 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
                         local validElections = {}
                         feature.properties.title = string.gsub(region, "_", " ")
                        for _, election in ipairs(elections) do
                        feature.properties.description = string.format(
                            if isNewElection(election.date) then
                             "<b>%s</b><br>%s<br>%s",
table.insert(validElections, election)
                            election.election_name,
                            end
                            election.date,
                        end
                             election.description
                       
                        )
                        if #validElections > 0 then
 
                        feature.properties.title = string.gsub(region, "_", " ")
                        local fillColor = electionColors[election.election_type] or "#404040"
                            feature.properties.description = generateDescription(validElections)
                        feature.properties.fill = fillColor
                              
                        feature.properties["fill-opacity"] = 0.8
                             local fillColor = electionColors[validElections[1].election_type] or "#404040"
 
                            feature.properties.fill = fillColor
                        table.insert(combinedJSON, feature)
                            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 96: Line 92:
         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

Latest revision as of 21:14, 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

    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
    }

    local currentDate = os.date("!%Y-%m-%dT%H:%M:%S")
    
    local function isUpcoming(electionDate)
        local formattedElectionDate = mw.ustring.gsub(electionDate, "[-:T]", ""):sub(1, 14)
        local formattedCurrentDate = mw.ustring.gsub(currentDate, "[-:T]", ""):sub(1, 14)
        return formattedElectionDate > formattedCurrentDate
    end

    local upcomingElections = {}
    for region, elections in pairs(APIData) do
        for _, election in ipairs(elections) do
            if isUpcoming(election.date) then
                table.insert(upcomingElections, {
                    region = region,
                    election = election
                })
            end
        end
    end

    table.sort(upcomingElections, function(a, b)
        return a.election.date < b.election.date
    end)

    local limitedElections = {}
    for i = 1, math.min(7, #upcomingElections) do
        table.insert(limitedElections, upcomingElections[i])
    end

    local combinedJSON = {}
    for _, entry in ipairs(limitedElections) do
        local region = entry.region
        local election = entry.election
        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
                        feature.properties.title = string.gsub(region, "_", " ")
                        feature.properties.description = string.format(
                            "<b>%s</b><br>%s<br>%s",
                            election.election_name,
                            election.date,
                            election.description
                        )

                        local fillColor = electionColors[election.election_type] or "#404040"
                        feature.properties.fill = fillColor
                        feature.properties["fill-opacity"] = 0.8

                        table.insert(combinedJSON, feature)
                    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>'
    return frame:preprocess(mapFrame)
end

return p