Module:Add to Calendar/sandbox
Appearance
| This is the module sandbox page for Module:Add to Calendar (diff). |
Module documentation
[create]
local function get_days_in_month (year, month)
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
year = tonumber(year)
month = tonumber(month)
if (month == 2) then
if (year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)) then
return 29
end
end
return days_in_month[month]
end
local function get_date (date)
local year, month, day, hour, minute, second =
date:match('(%d%d%d%d)%-(%d%d?)%-(%d%d?)T(%d%d?):(%d%d?):(%d%d?)')
if not year then
year, month, day, hour, minute, second =
date:match('^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$')
if not year then
return nil
end
end
local t = {
year = tonumber(year),
month = tonumber(month),
day = tonumber(day),
hour = tonumber(hour),
min = tonumber(minute),
sec = tonumber(second) or 0
}
if t.hour < 0 or t.hour > 23 or t.min < 0 or t.min > 59 or t.sec < 0 or t.sec > 59 then return nil end
if t.month < 1 or t.month > 12 then return nil end
if t.day < 1 or t.day > get_days_in_month(t.year, t.month) then return nil end
return t
end
local function get_utc_offset (utc_offset)
local h, m, sign
local patterns = {
'^([%+%-±−]?)(%d%d?%.%d%d?)$',
'^([%+%-±−]?)(%d%d?):(%d%d)$',
'^([%+%-±−]?)(%d%d?)[%.:]?$',
}
for _, pattern in ipairs(patterns) do
sign, h, m = mw.ustring.match(utc_offset, pattern)
if h then break end
end
if not h then return nil end
if sign == '-' then sign = -1 else sign = 1 end
h = tonumber(h)
m = tonumber(m) or 0
return sign * ((h * 3600) + (m * 60))
end
local function main(frame)
local getArgs = require('Module:Arguments with aliases').getArgs
local arg_aliases = {
text = { 'text', 'title' },
date = { 'date', 'start' },
end_date = { 'end_date', 'end' },
details = { 'details', 'description' },
location = { 'location', 'venue' },
url_title = { 'url_title' },
timezone = { 'timezone', 'tz' }
}
local args = getArgs(frame, { aliases = arg_aliases })
local tz_offest = (args.timezone and get_utc_offset(args.timezone)) or 0
local date_t = args.date and get_date(args.date) or nil
local end_date_t = args.end_date and get_date(args.end_date) or nil
if not date_t then
return error('Invalid date format. Please use YYYY-MM-DDThh:mm:ss or YYYYMMDDhhmmss.')
end
local date_u = os.time(date_t) + tz_offest
local end_date_u = date_u
if end_date_t then
end_date_u = os.time(end_date_t) + tz_offest
if end_date_u < date_u then
return error('End date cannot be before start date.')
end
end
local date_txt = os.date('%Y%m%dT%H%M%SZ', date_u) .. '/' .. os.date('%Y%m%dT%H%M%SZ', end_date_u)
-- Google Calendar
local google_link = '[https://calendar.google.com/calendar/render?action=TEMPLATE' ..
'&text=' .. mw.uri.encode(args.text or '') ..
'&dates=' .. date_txt ..
'&details=' .. mw.uri.encode(args.details or '') ..
'&location=' .. mw.uri.encode(args.location or '') ..
' <span class="google">Google</span>]'
-- Outlook.com / Office 365
local outlook_link = '[https://outlook.live.com/calendar/0/deeplink/compose?path=/calendar/action/compose' ..
'&rru=addevent' ..
'&subject=' .. mw.uri.encode(args.text or '') ..
'&startdt=' .. os.date('!%Y-%m-%dT%H:%M:%SZ', date_u) ..
'&enddt=' .. os.date('!%Y-%m-%dT%H:%M:%SZ', end_date_u) ..
'&body=' .. mw.uri.encode(args.details or '') ..
'&location=' .. mw.uri.encode(args.location or '') ..
' <span class="outlook">Outlook</span>]'
-- Yahoo Calendar
local yahoo_link = '[https://calendar.yahoo.com/?v=60' ..
'&TITLE=' .. mw.uri.encode(args.text or '') ..
'&ST=' .. os.date('!%Y%m%dT%H%M%SZ', date_u) ..
'&ET=' .. os.date('!%Y%m%dT%H%M%SZ', end_date_u) ..
'&DESC=' .. mw.uri.encode(args.details or '') ..
'&in_loc=' .. mw.uri.encode(args.location or '') ..
' <span class="yahoo">Yahoo</span>]'
return '<span class="add-to-calendar">' ..
google_link .. ' | ' ..
outlook_link .. ' | ' ..
yahoo_link ..
'</span>'
end
return { main = main }