Module:Rotations
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Rotations/doc
--[[ <nowiki> Various functions for activities that have time based rotations --]] local p = {} local seconds_in_day = 24 * 60 * 60 local seconds_in_minute = 60 local _on_ = 'table-bg-green' local _off_ = 'table-bg-grey' local yesno = { [true] = _on_, [false] = _off_ } local unit_seconds_from_name = { minute = seconds_in_minute, day = seconds_in_day } local lang = mw.language.new('en') --[[ Returns the plural of the word --]] function p.plural(word, n, plural) if n == 1 then return word else return plural or (word .. 's') end end --[[ --]] function p.on_off(on_time, total_time, offset, unit_seconds) local units_after_utc = math.floor(os.time() / unit_seconds) local units_into_start = (units_after_utc + offset) % total_time local on = units_into_start < on_time local units_until_change if on then units_until_change = on_time - units_into_start else units_until_change = total_time - units_into_start end return on, units_until_change end --[[ Returns a number that can be used to identify the rotation based on: * The number of days per rotation * The number of rotations available * The offset of days such that Tuesday 1 January 1970 - offset would be the starting day for rotation 1 (the absolute value of this should be less than interval * rotation_count) Also returns a second value that determines how many days until the next rotation --]] function p.rotation_days(interval, rotation_count, offset) local days_after_utc = math.floor(os.time() / seconds_in_day) local days_into_period = (days_after_utc + offset) % (interval * rotation_count) local rotation = math.floor(days_into_period / interval) + 1 local days_until_next_rotation = interval - days_into_period % interval return rotation, days_until_next_rotation end --[[ Returns a number that can be used to identify the rotation based on: * The number of minutes per rotation * The number of rotations available * The offset of minutes such that Tuesday 1 January 1970 - offset would be the starting time for rotation 1 Also returns a second value that determines how many minutes until the next rotation --]] function p.rotation_minutes(interval, rotation_count, offset) local minutes_after_utc = math.floor(os.time() / seconds_in_minute) local minutes_into_period = (minutes_after_utc + offset) % (interval * rotation_count) local rotation = math.floor(minutes_into_period / interval) + 1 local minutes_until_next_rotation = interval - minutes_into_period % interval return rotation, minutes_until_next_rotation end --[[ --]] function p.simple_on_off(on_time, total_time, offset, unit_name) local unit_seconds = unit_seconds_from_name[unit_name] local on, change_time = p.on_off(on_time, total_time, offset, unit_seconds) local ret_table = mw.html.create('table') :addClass('wikitable') :css({ ['text-align'] = 'center', float = 'right' }) :tag('tr') :tag('td') :wikitext('Time until ' .. (on and 'end' or 'start') .. ': ' .. change_time .. ' ' .. p.plural(unit_name, change_time)) :addClass(yesno[on]) :done() :done() return ret_table end local function date_of(i_rot, interval, curr_rot, next_in, total_rots) local s = os.time() + seconds_in_day * (next_in + interval * ((i_rot - curr_rot - 1) % total_rots) ) if i_rot==curr_rot then return 'Now!' else return lang:formatDate('j M', '@' .. s, nil) end end local function date_of_full(i_rot, interval, curr_rot, next_in, total_rots) local s = os.time() + seconds_in_day * (next_in + interval * ((i_rot - curr_rot - 1)) ) return lang:formatDate('j F Y', '@' .. s, nil) end --[[ --]] function p.simple_table(rotation_names, interval, offset, dated) local rotation, next = p.rotation_days(interval, #rotation_names, offset) local align = 'center' if dated then align = 'left' pad = '0.5em' end local ret_table = mw.html.create('table') :addClass('wikitable') :css({ ['text-align'] = align, margin = '3px', float = 'right' }) :tag('caption') :wikitext('Current rotation') :done() local td for i, v in ipairs(rotation_names) do td = ret_table:tag('tr'):tag('td') td :addClass(yesno[i==rotation]) :wikitext(v) :done() :done() :done() if dated then td:css('padding-left', '0.5em') :tag('span') :css({ ['float'] = 'right', ['text-align'] = 'right', ['font-size'] = '80%', ['margin-left'] = '5px' }) :wikitext(date_of(i, interval, rotation, next, #rotation_names)) end end td = ret_table:tag('tr'):tag('td') td :css('text-align', 'center') :wikitext("'''Next: "..next..' '..p.plural('day', next).."'''") :done() :done() return ret_table end --[[ --]] function p.simple_table_minutes(rotation_names, interval, offset) local rotation, next = p.rotation_minutes(interval, #rotation_names, offset) local align = 'center' local ret_table = mw.html.create('table') :addClass('wikitable') :css({ ['text-align'] = align, margin = '3px', float = 'right' }) :tag('caption') :wikitext('Current rotation') :done() local td for i, v in ipairs(rotation_names) do td = ret_table:tag('tr'):tag('td') td :addClass(yesno[i==rotation]) :wikitext(v) :done() :done() :done() end td = ret_table:tag('tr'):tag('td') td :css('text-align', 'center') :wikitext("'''Next: "..next..' '..p.plural('minute', next).."'''") :done() :done() return ret_table end function p.resourcecount() return p.simple_on_off(15, 60, 30, 'minute') end return p