Module:Deployment schedule/Sandbox

From Wikitech
Jump to: navigation, search

Documentation for this module may be created at Module:Deployment schedule/Sandbox/doc (Test casesTest results)

local p = {}

local timezones = {
    -- Add timezone offsets here!
    Z = 0,
    UTC = 0,
    PST = -8,
    PDT = -7,
}

function us_in_dst( time )
    -- Determine if the United States is in Daylight Savings Time (as of 2013)
    month = tonumber( os.date( "!%m", time ) )
    day = tonumber( os.date( "!%d", time ) )
    
    if ( month == 3 and day >= 10 ) then
        return true
    elseif ( month == 11 and day <= 3 ) then
        return true
    elseif ( month > 3 and month < 11 ) then
        return true
    else
        return false
    end
end

function trim( str )
    -- Trims a string because wikitech apparently doesn't have this library...
    str = string.gsub( str, "%s+$", "" )
    str = string.gsub( str, "^%s+", "" )
    return str
end

function p.header( frame )
    -- Creates the header of the deployments table
    return [[
    {| class='wikitable'
    	!Day PST
        !Day UTC
        !UTC
        !SF Local Time
        !Responsible Party
        !Description
    ]]
end

function p.footer( frame )
    -- Creates the footer of the deployments table
    return "\n|}"
end

function p.row( frame )
    -- Produces a raw row to be reconsumed by this script for sorting
    -- Expects:
    --- when, string, like YYYY-MM-DD HH:mm XXX where XXX is a valid timezone listed in timezones
    --- length, number, of hours the deploy will take
    --- who, string, who is performing the deploy
    --- what, string, what will be deployed
    -- 
    -- Outputs: UTC Timestamp,Length,Who,What
    --- commas in strings are replaced with &#44;
    
    local when = frame.args['when']
    local length = ( tonumber( frame.args['length'] ) or 2 ) * 60 * 60
    local who = frame.args['who'] or "Anonymous Cowards (must provide 'who=')"
    local what = frame.args['what'] or "Nothing? Then why is this an entry!? (must provide 'what=')"
    
    who = string.gsub( who, ",", "&#44;" )
    what = string.gsub( what, ",", "&#44;" )
    
    if when == nil then
        utc_time = 0
        what = "No time given (must provide 'when' and 'tz', e.g.: 'when=YYYY-MM-DD HH:mm XXX'"
    else
        year, month, day, hour, minute, tz = string.match( when, '^(%d+)-(%d+)-(%d+) (%d+):(%d+) ([A-Z]+)$' )
        ts = os.time({
            year = year or 1980,
            month = month or 1,
            day = day or 1,
            hour = hour or 1,
            min = minute or 1
        })
        tz = timezones[tz]
        
        if tz == nil then
            utc_time = 0
            what = "Unknown timezone in 'when' string! -- add it to the module :)"
        else
            utc_time = ts - ( tz * 60 * 60 )
        end
    end
    
    return string.format( "%s,%s,%s,%s", utc_time, length, who, what )
end

function p.formatTable( frame )
    -- Formats a bunch of rows from p.row()
    local rows = {}
    local row
    local count = 1
    local retval = {}
    local sflocal
    local sfdatestr
    local sfdaystr
    local showdate = not ( frame.args['hidedate'] == 'true' )
    local tzoffset = 0
    
    -- Load and sort the arguments
    row = frame.args[count]
    while not ( row == nil ) do
        utc, length, who, what = string.match( row, '^(.*),(.*),(.*),(.*)$' )
        utc = tonumber( trim ( utc ) )
        length = tonumber( trim( length ) )
        who = trim( who )
        what = trim( what )
        
        table.insert( rows, { utc=utc, length=length, who=who, what=what } )
        count = count + 1
        row = frame.args[count]
    end
    table.sort( rows, function( a, b ) return a.utc < b.utc end )
    
    -- For each entry create the final row
    for count = 1, #rows do
        local datestr
        
        utc = rows[count].utc
        length = rows[count].length
        who = rows[count].who
        what = rows[count].what
        
        if us_in_dst( utc ) then
            tzoffset = timezones['PDT']
        else
            tzoffset = timezones['PST']
        end
        sflocal = utc + ( tzoffset * 60 * 60 )
		if os.date( "!%A", utc ) ~= os.date( "!%A", sflocal ) then
			sfdaystr = os.date( "!<small>(%a)</small> ", sflocal )
		else
			sfdaystr = ""
		end
        
        if showdate then
        	sfdatestr = "<time class='deploycal-date' datetime=\"" .. os.date( "!%Y-%m-%dT%H:%M+0", sflocal ) .. "\">" .. os.date( "!%A,&nbsp;%B&nbsp;%d", sflocal ) .. "</time>"
            datestr = "<time class='deploycal-date' datetime=\"" .. os.date( "!%Y-%m-%dT%H:%M+0", utc ) .. "\">" .. os.date( "!%A,&nbsp;%B&nbsp;%d", utc ) .. "</time>"
        else
        	sfdatestr = os.date( "!%A", sflocal )
            datestr = os.date( "!%A", utc )
        end
        
        table.insert( retval, string.format( "|-\n|%s\n|%s\n|'''%s'''&ndash;%s\n|%s'''%s'''&ndash;%s\n|%s\n|%s",
        	sfdatestr,
            datestr,
            "<time datetime=\"" .. os.date( "!%H:%M+0", utc ) .. "\">" .. os.date( "!%H:%M", utc ) .. "</time>",
            "<time datetime=\"" .. os.date( "!%H:%M+0", utc + length ) .. "\">" .. os.date( "!%H:%M", utc + length ) .. "</time>",
            sfdaystr,
            "<time datetime=\"" .. os.date( "!%H:%M+" .. tzoffset, sflocal ) .. "\">" .. os.date( "!%H:%M", sflocal ) .. "</time>",
            "<time datetime=\"" .. os.date( "!%H:%M+" .. tzoffset, sflocal + length ) .. "\">" .. os.date( "!%H:%M", sflocal + length ) .. "</time>",
            who,
            what
        ))
    end
    
    return table.concat( retval, "\n" )
end

function p.dateOf( frame )
    local requestedday = frame.args[1] or 'Sun'
    local tdelta = 0
    local weekstart = 0
    local adddays = 0
    
    day, hour, minute, sec = string.match( os.date('!%w %H %m %S'), '^(%d+) (%d+) (%d+) (%d+)$' )
    tdelta = ( tonumber( day ) * 24 * 60 * 60 ) + ( tonumber( hour) * 60 * 60 ) + ( tonumber( minute ) * 60 ) + tonumber( sec )
    weekstart = os.time() - tdelta
    
    if ( requestedday == 'Mon' ) then
        adddays = 1
    elseif ( requestedday == 'Tue' ) then
        adddays = 2
    elseif ( requestedday == 'Wed' ) then
        adddays = 3
    elseif ( requestedday == 'Thu' ) then
        adddays = 4
    elseif ( requestedday == 'Fri' ) then
        adddays = 5
    end
    
    return os.date( '%Y-%m-%d', weekstart + ( adddays * 24*60*60 ) )
end

return p