MCDM Wiki
Advertisement
MCDM Wiki

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

local episode = {}

local getArgs -- lazily initialised
local yesno -- lazily initialised

local episodeData = mw.loadData( 'Module:EpisodeData' )

--[[
-----------------------------------------------------------------------------
-- getframeargs

This function returns the "show" "number" and "field" arguments, which 
are standard across the episode fuctions
-----------------------------------------------------------------------------
--]]
local function getframeargs(frame)
    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    local args = getArgs(frame)
    
    return 
        args['show'] or args[1], 
        args['number'] or args[2], 
        args['field'] or args[3]
    
end

--[[
-----------------------------------------------------------------------------
-- formatDateString

Formats a date string with the given format, but applies a default if
none is specified
-----------------------------------------------------------------------------
--]]
local function formatDateString(d, formatstring)
    return os.date(formatstring or "%Y-%m-%d %H:%M PT", d) 
end

--[[
-----------------------------------------------------------------------------
-- formatEpisodeNameString

Given an episode name and an episode number, returns them nicely formatted.
-----------------------------------------------------------------------------
--]]
function formatEpisodeNameString(name, number)
    local suffix = mw.html.create('small')
    suffix:wikitext("(Episode " .. number .. ")")

    return "\“'''[[" .. name .. "]]'''\”" .. " " .. tostring(suffix)
end

--[[
-----------------------------------------------------------------------------
-- formatVodLink
arguments: link and s

If link is not specified, returns s as a placeholder text
If link is specified, returns a wikitext link with s as the display text,
if s is present, or with no display text if s is not specified or empty.
-----------------------------------------------------------------------------
--]]
local function formatVodLink(link, s)
    if link == nil or link == "" then return s end
    
    if s == nil or s == "" then
        return "[" .. link .. "]"
    else
        return "[" .. link .. " " .. s .. "]"
    end
end

--[[
-----------------------------------------------------------------------------
-- episode_lookup
arguments: show, number, and field

Returns episode metadata from Module:EpisodeData for the specified show,
number and field. If the data is not found, returns false as its first 
return and an error string reminding the user to fill out Module:EpisodeData
as its second return
-----------------------------------------------------------------------------
--]]
local function episode_lookup(show, number, field)

    local e = false
    local result = nil
    -- Look up the result in the episode data, catching errors
    e, result = pcall(function () return episodeData[show]["episodes"][tonumber(number)][field] end)
    if e and result then
        return result
    else
        return e, string.format("Something went wrong looking up episode metadata for %s %s %s. Check [[Module:EpisodeData]] to make sure that the data you asked for is defined.", tostring(show), tostring(number), tostring(field))
    end
end

--[[
-----------------------------------------------------------------------------
-- episode_metadata
arguments: a frame containing arguments show, number, and field or 1, 2, 3

Returns episode metadata from Module:EpisodeData for the specified show,
number and field. If the data is not found, returns an error string 
reminding the user to fill out Module:EpisodeData
-----------------------------------------------------------------------------
--]]
function episode.episode_metadata (frame)

    local show, number, field = getframeargs(frame)
    
    local result, e = episode_lookup(show, number, field)
    
    if not result and e then
        return e
    else
        return result
    end

end

--[[
-----------------------------------------------------------------------------
-- episode_name
arguments: a frame containing arguments show and number or 1 and 2

Returns a nicely-formatted episode name using episode metadata from 
Module:EpisodeData for the specified show and episode number. If the data 
is not found, returns an error string reminding the user to fill out 
Module:EpisodeData
-----------------------------------------------------------------------------
--]]
function episode.episode_name (frame)
    
    local show, number = getframeargs(frame)

    local name, e = episode_lookup(show, number, "name")

    if not name and e then
        return e
    else 
        return formatEpisodeNameString(name, number)
    end
    
end

--[[
-----------------------------------------------------------------------------
-- episode_airdate
arguments: a frame containing arguments show and number or 1 and 2

Returns a nicely-formatted episode airdate using episode metadata from 
Module:EpisodeData for the specified show and episode number. If the data 
is not found, returns an error string reminding the user to fill out 
Module:EpisodeData
-----------------------------------------------------------------------------
--]]
function episode.episode_airdate (frame)
    
    local show, number = getframeargs(frame)

    local airdate, e = episode_lookup(show, number, "airdate")
    
    if not airdate and e then
        return e
    else
        return formatDateString(airdate)
    end
    
end

--[[
-----------------------------------------------------------------------------
-- episode_pretty_airdate
arguments: a frame containing arguments show and number or 1 and 2

Returns a nicely-formatted episode airdate using episode metadata from 
Module:EpisodeData for the specified show and episode number. If the data 
is not found, returns an error string reminding the user to fill out 
Module:EpisodeData
-----------------------------------------------------------------------------
--]]
function episode.episode_pretty_airdate (frame)
    
    local show, number = getframeargs(frame)

    local airdate, e = episode_lookup(show, number, "airdate")
    
    if not airdate and e then
        return e
    else
        return formatDateString(airdate, "%B %d, %Y")
    end
    
end

--[[
-----------------------------------------------------------------------------
-- episode_vodlinks
arguments: a frame containing arguments show and number or 1 and 2

Returns available vod links for the specified show and episode number.
If no data is found, returns the string "T, Y"
If a twitch_vod or youtube_vod link is found in Module:EpisodeData, T and Y
in the string become links to the videos.
-----------------------------------------------------------------------------
--]]
function episode.episode_vodlinks (frame)
    
    local show, number = getframeargs(frame)

    local twitch_vod, t_e = episode_lookup(show, number, "twitch_vod")
    local youtube_vod, y_e = episode_lookup(show, number, "youtube_vod")
    
    local twitch_string = "T"
    if not (not twitch_vod and t_e) then 
        twitch_string = formatVodLink(twitch_vod, "T")
    end
    
    local yt_string = "Y"
    if not (not youtube_vod and y_e) then 
        yt_string = formatVodLink(youtube_vod, "Y")
    end

    return twitch_string .. ", " .. yt_string
    
end

--[[
-----------------------------------------------------------------------------
-- episode_verbose_vodlinks
arguments: a frame containing arguments show and number or 1 and 2

Returns available vod links for the specified show and episode number.
Returns a HTML object consisting of a list that will be empty if none of
twitch_vod, youtube_vod and campaign_diary are found.
If any of those are found, returns the HTML list with items consisting of
each VOD link found.
-----------------------------------------------------------------------------
--]]
function episode.episode_verbose_vodlinks (frame)
    local show, number = getframeargs(frame)
    
    local twitch_vod, t_e = episode_lookup(show, number, "twitch_vod")
    local youtube_vod, y_e = episode_lookup(show, number, "youtube_vod")
    local tactical_vod, ta_e = episode_lookup(show, number, "tactical_vod")
    local campaign_diary, c_e = episode_lookup(show, number, "campaign_diary")

    local list = mw.html.create("ul")
    
    if twitch_vod and not t_e then 
        list:tag('li'):wikitext(formatVodLink(twitch_vod, "Twitch VOD"))
    end
    if youtube_vod and not y_e then 
        list:tag('li'):wikitext(formatVodLink(youtube_vod, "Youtube VOD"))
    end
    if tactical_vod and not ta_e then 
        list:tag('li'):wikitext(formatVodLink(tactical_vod, "Tactical VOD"))
    end
    if campaign_diary and not c_e then 
        list:tag('li'):wikitext(formatVodLink(campaign_diary, "Campaign Diary"))
    end
    
    return list
    
end

--[[
-----------------------------------------------------------------------------
-- episode_list
arguments: a frame containing argument show or 1

Returns a nicely-formatted episode list for the specified show
-----------------------------------------------------------------------------
--]]
function episode.episode_list (frame)
    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    local args = getArgs(frame)
    
    local show = args['show'] or args[1] or "chain"
    local airdate_option = args['airdate'] or args[2] or "yes"
    local tactical_option = args['tactical'] or args[3] or "yes"
    local diary_option = args['diary'] or args[4] or "yes"
    
    if not yesno then
        yesno = require('Module:Yesno')
    end
    
    airdate_option = yesno(airdate_option)
    tactical_option = yesno(tactical_option)
    diary_option = yesno(diary_option)
    
    local e, show_object = pcall(function () return episodeData[show] end)
    if (not e and show_object) or not show_object.episodes then
        return string.format("Something went wrong looking up episode metadata for show %s. Check [[Module:EpisodeData]] to make sure that the show you asked for is defined and has a .episodes table.", tostring(show))
    end
    
    local headings = {
        "No. in series",
        "Title",
        "VOD links"
    }
    
    if airdate_option then
        table.insert(headings, 3, "Airdate")
    end
    if tactical_option then
        table.insert(headings, "Tactical Stream")
    end
    if diary_option then
        table.insert(headings, "Campaign Diary")
    end
    
    local root = mw.html.create('table')
    root:addClass('article-table')
            
    local head = root:tag('tr')
    for _,heading_text in ipairs(headings) do
        head:tag('th'):wikitext(heading_text)
    end
    
    for n,episode_object in ipairs(show_object.episodes) do
        local row = root:tag('tr')
        row:tag('td'):wikitext(n)
        row:tag('td'):wikitext(formatEpisodeNameString(episode_object.name, n))
        if airdate_option then
            row:tag('td'):wikitext(formatDateString(episode_object.airdate, "%b %d, %Y"))
        end
        row:tag('td'):wikitext(
            formatVodLink(episode_object.twitch_vod, "T")
            .. ", " ..
            formatVodLink(episode_object.youtube_vod, "Y")
        )
        if tactical_option then
            if episode_object.tactical_vod then
                row:tag('td'):wikitext(formatVodLink(episode_object.tactical_vod, "YouTube"))
            else
                row:tag('td'):wikitext("")
            end
        end
        if diary_option then
            if episode_object.campaign_diary then
                row:tag('td'):wikitext(formatVodLink(episode_object.campaign_diary, "YouTube"))
            else
                row:tag('td'):wikitext("")
            end
        end
    end

    return tostring(root)
end

--[[
-----------------------------------------------------------------------------
-- cite_vod
arguments: a frame containing arguments show, number, vod (optional) and timestamp

Returns a citation (reference) for a vod as listed in Module:EpisodeData, 
optionally with a timestamp
-----------------------------------------------------------------------------
--]]
function episode.cite_vod (frame)
    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    local args = getArgs(frame)
    local show = args['show'] or args[1]
    local number = args['number'] or args[2]
    local vod = args['vod'] or args[3]
    local timestamp = args['timestamp'] or args[4] or nil
    
    local vodlink, e = episode_lookup(show, number, vod)
    if not vodlink and e then return e end

    local sep = "#"
    if vod == "twitch_vod" then sep = "?" end

    local episodename = episode.episode_name(frame)
    
    local reference
    if timestamp and timestamp ~= "" then
        reference = vodlink .. sep .. "t=" .. timestamp .. " " .. episodename .. " at " .. timestamp
    else 
        reference = vodlink .. " " .. episodename
    end
    return(frame:preprocess("<ref>" .. reference .. "</ref>"))
end

local function wrap_string(s)
    if s == "" or s == nil then 
        return ""
    else
        return "<default>" .. s .. "</default>" 
    end
end

local function sidebar_vod_link(vod_link, wrapper)
    if vod_link then
        return formatVodLink(vod_link, wrapper)
    else
        return ""
    end
end

--[[
-----------------------------------------------------------------------------
-- episode_sidebar
arguments: a frame containing arguments show and number

Returns an infobox for the episode in question
-----------------------------------------------------------------------------
--]]
function episode.episode_sidebar(frame)
   local infobox = [[<infobox>
  <title>
    <default>%s</default>
  </title>
  <data>
    <label>Airdate</label>
    %s
  </data>
  <data>
    <label>Run Time</label>
    %s
  </data>
  <group>
    <header>Episode Links</header>
    <data>
      <label>YouTube VOD</label>
      %s
    </data>
    <data>
      <label>Twitch VOD</label>
      %s
    </data>
    <data>
      <label>Tactical Stream</label>
      %s
    </data>
    <data>
      <label>Campaign Diary</label>
      %s
    </data>
  </group>
  <group>
    <header>Episode Order</header>
    <data>
      <label>Previous</label>
      %s
    </data>
    <data>
      <label>Next</label>
      %s
    </data>
  </group>
</infobox>]]

    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    local args = getArgs(frame)
    
    local show = args['show'] or args[1] or "chain"
    local number = args['number'] or args[2] or 1
    
    local e, episode_object = pcall(function () return episodeData[show]["episodes"][tonumber(number)] end)

    if not (e and episode_object) then
        return string.format("Something went wrong looking up episode metadata for %s %s. Check [[Module:EpisodeData]] to make sure that the data you asked for is defined. %s : %s", tostring(show), tostring(number), tostring(e), tostring(result))
    end
    
    local previous_ep_name, e = episode_lookup(show, tonumber(number)-1, "name")
    if not previous_ep_name and e then
        previous_ep_name = ""
    else
        previous_ep_name = "[[" .. previous_ep_name .. "]]"
    end
    
    local next_ep_name, e = episode_lookup(show, tonumber(number)+1, "name")
    if not next_ep_name and e then
        next_ep_name = ""
    else
        next_ep_name = "[[" .. next_ep_name .. "]]"
    end

    return frame:preprocess(string.format(
        infobox,
        episode_object.name or "",
        wrap_string(formatDateString(episode_object.airdate)),
        wrap_string(episode_object.runtime),
        wrap_string(sidebar_vod_link(episode_object.youtube_vod, "Youtube VOD")),
        wrap_string(sidebar_vod_link(episode_object.twitch_vod, "Twitch VOD")),
        wrap_string(sidebar_vod_link(episode_object.tactical_vod, "Tactical Stream")),
        wrap_string(sidebar_vod_link(episode_object.campaign_diary, "Campaign Diary")),
        wrap_string(previous_ep_name),
        wrap_string(next_ep_name)
        ))

end

return episode
Advertisement