MCDM Wiki
Register
No edit summary
No edit summary
Line 447: Line 447:
 
wrap_string(formatVodLink(episode_object.tactical_vod, "Tactical Stream")),
 
wrap_string(formatVodLink(episode_object.tactical_vod, "Tactical Stream")),
 
wrap_string(formatVodLink(episode_object.campaign_diary, "Campaign Diary")),
 
wrap_string(formatVodLink(episode_object.campaign_diary, "Campaign Diary")),
wrap_string(previous_ep_name),
+
wrap_string("previous_ep_name"),
 
wrap_string(next_ep_name)
 
wrap_string(next_ep_name)
 
))
 
))

Revision as of 01:11, 1 June 2019

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

local episode = {}

local getArgs -- 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
-----------------------------------------------------------------------------
--]]
function getframeargs(frame)
    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    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
-----------------------------------------------------------------------------
--]]
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.
-----------------------------------------------------------------------------
--]]
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
-----------------------------------------------------------------------------
--]]
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)
    
    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
    args = getArgs(frame)
    
    show = args['show'] or args[1] or "chain"
    
    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
    
    headings = {
        "No. in series",
        "Title",
        "Airdate",
        "VOD links",
        "Tactical Stream",
        "Campaign Diary"
    }
    
    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))
        row:tag('td'):wikitext(formatDateString(episode_object.airdate))
        row:tag('td'):wikitext(
            formatVodLink(episode_object.twitch_vod, "T")
            .. ", " ..
            formatVodLink(episode_object.youtube_vod, "Y")
        )
        row:tag('td'):wikitext(formatVodLink(episode_object.tactical_vod, "Y"))
        row:tag('td'):wikitext(formatVodLink(episode_object.campaign_diary, "Y"))
    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 episodename = episode.episode_name(frame)
    
    local reference
    if timestamp and timestamp ~= "" then
        reference = vodlink .. "?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

--[[
-----------------------------------------------------------------------------
-- cite_vod
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
    args = getArgs(frame)
    
    show = args['show'] or args[1] or "chain"
    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(episode_lookup(show, tonumber(number)-1, "name"))
    --if not previous_ep_name and e then
    --    previous_ep_name = ""
    --end
    
    local next_ep_name, e = episode_lookup(episode_lookup(show, tonumber(number)+1, "name"))
    --if not next_ep_name and e then
    --    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(formatVodLink(episode_object.youtube_vod, "Youtube VOD")),
        wrap_string(formatVodLink(episode_object.twitch_vod, "Twitch VOD")),
        wrap_string(formatVodLink(episode_object.tactical_vod, "Tactical Stream")),
        wrap_string(formatVodLink(episode_object.campaign_diary, "Campaign Diary")),
        wrap_string("previous_ep_name"),
        wrap_string(next_ep_name)
        ))

end

return episode