Module:TwitterSnowflake/sandbox: Difference between revisions
m sync |
sync |
||
Line 1: | Line 1: | ||
local p = {} |
local p = {} |
||
local TwitterSnowflake = require('Module:TwitterSnowflake') |
|||
local CiteWeb = require('Module:Cite web')[''] |
|||
local function _if(arg) |
|||
local Date = require('Module:Date')._Date |
|||
return arg and arg ~= '' or nil |
|||
function p.snowflakeToDate(frame) |
|||
local format = frame.args.format or "%B %e, %Y" |
|||
local epoch = tonumber(frame.args.epoch) or 1288834974 |
|||
local id_str = frame.args.id_str |
|||
if type(id_str) ~= "string" then error("bad argument #1 (expected string, got " .. type(id_str) .. ")", 2) end |
|||
if type(format) ~= "string" then error("bad argument #2 (expected string, got " .. type(format) .. ")", 2) end |
|||
if type(epoch) ~= "number" then error("bad argument #3 (expected number, got " .. type(epoch) .. ")", 2) end |
|||
local hi, lo = 0, 0 |
|||
local hiexp = 1 |
|||
local two32 = 2^32 |
|||
for c in id_str:gmatch(".") do |
|||
lo = lo * 10 + c |
|||
if lo >= two32 then |
|||
hi, lo = hi * 10^hiexp + math.floor(lo / two32), lo % two32 |
|||
hiexp = 1 |
|||
else hiexp = hiexp + 1 end |
|||
end |
|||
hi = hi * 10^(hiexp-1) |
|||
local timestamp = math.floor((hi * 1024 + math.floor(lo / 4194304)) / 1000) + epoch |
|||
return os.date(format, timestamp) |
|||
end |
end |
||
p.main = function(frame) |
|||
frame.args = frame:getParent().args |
|||
-- just pass frame directly to snowflakeToDate, this wraps it but the args are the same plus |
|||
return p[''](frame) |
|||
if (frame.args.id_str):match("%D") then -- not a number, so return -2 |
|||
return -2 |
|||
end |
|||
frame.args.format = "%B %e, %Y" |
|||
frame.args.epoch = tonumber(frame.args.epoch) or 1288834974 |
|||
local epochdate = Date(os.date("%B %e, %Y", frame.args.epoch)) |
|||
local twitterdate = Date(p.snowflakeToDate(frame)) |
|||
if twitterdate == epochdate then -- created before epoch, so can't determine the date |
|||
return -1 |
|||
end |
|||
local date = Date(frame.args.date) or 0 -- if we error here, then an input of no date causes an error, which is contrary to the entire way {{TwitterSnowflake/datecheck}} works |
|||
return date - twitterdate |
|||
end |
end |
||
p[''] = function(frame) |
|||
local function abs_datediff(x) |
|||
if type(x) == 'number' then return math.abs(x) end |
|||
return math.abs(x.age_days) |
|||
end |
|||
function p.datecheck(frame) |
|||
local args = frame.args |
local args = frame.args |
||
local cite_args = { |
|||
if not (args.date and args.id_str) then |
|||
url = 'https://twitter.com/' .. ((args.user and args.number) and (args.user .. '/status/' .. args.number) or ''), |
|||
error('Must define date and id_str, even if they are blank.') |
|||
title = (args.title or ''):gsub('https*://', ''), |
|||
['script-title'] = args['script-title'], |
|||
['trans-title'] = args['trans-title'], |
|||
language = args.language, |
|||
['author-link'] = args['author-link'] or args.authorlink, |
|||
others = _if(args.retweet) and ('Retweeted by ' .. args.retweet), |
|||
via = args.link == 'no' and 'Twitter' or '[[Twitter]]', |
|||
type = 'Tweet', |
|||
location = args.location, |
|||
['access-date'] = args['access-date'] or args.accessdate, |
|||
['archive-date'] = args['archive-date'] or args.archivedate, |
|||
['archive-url'] = args['archive-url'] or args.archiveurl, |
|||
['url-status'] = args['url-status'] or args['dead-url'] or args.deadurl, |
|||
quote = args.quote, |
|||
ref = args.ref, |
|||
df = args.df |
|||
} |
|||
if _if(args.last1 or args.last) then |
|||
cite_args.author = (args.last1 or args.last) .. |
|||
(_if(args.first1 or args.first) and (', ' .. (args.first1 or args.first)) or '') .. |
|||
' [@' .. (args.user or '') .. ']' |
|||
elseif _if(args.author1 or args.author) then |
|||
cite_args.author = (args.author1 or args.author) .. ' [@' .. (args.user or '') .. ']' |
|||
elseif _if(args['author-link']) then |
|||
cite_args.author = args['author-link'] .. ' [@' .. (args.user or '') .. ']' |
|||
else |
|||
cite_args.author = '@' .. (args.user or '') |
|||
end |
end |
||
if cite_args.author:find ('[Tt]witter') then |
|||
local errors = { |
|||
cite_args.author = '((' .. cite_args.author .. '))' |
|||
args.error1 or 'Date mismatch of two or more days', |
|||
end |
|||
args.error2 or 'No date, and posted before November 4, 2010', |
|||
if _if(tonumber(args.number)) then |
|||
args.error3 or 'Invalid id_str' |
|||
cite_args.date = args.date or (_if(args.number) and TwitterSnowflake.snowflakeToDate{ args = {id_str = args.number} }) |
|||
} |
|||
else |
|||
if mw.title.getCurrentTitle():inNamespace(0) and args.error_cat then |
|||
cite_args.date = args.date |
|||
for i = 1, 3 do errors[i] = errors[i] .. '[[' .. args.error_cat .. ']]' end |
|||
end |
|||
frame.args = cite_args |
|||
local output = CiteWeb(frame) |
|||
frame.args = args |
|||
-- Error checking |
|||
local error_template = '<span class="cs1-visible-error citation-comment">%s</span>' |
|||
local errors = {} |
|||
if not (_if(args.title) or _if(args['script-title']) or args.user or args.number or args.date) then |
|||
-- No title; error message is provided by CS1 module. |
|||
errors[1] = ';' |
|||
end |
|||
if not _if(args.user) then |
|||
errors[1 + #errors] = ' Missing or empty <kbd>|user=</kbd>;' |
|||
end |
|||
if not _if(args.number) then |
|||
errors[1 + #errors] = ' Missing or empty <kbd>|number=</kbd>;' |
|||
end |
end |
||
errors[1 + #errors] = TwitterSnowflake.datecheck{ args = { |
|||
if not args.date:match('^%s*$') then -- #if:{{{date|}}} |
|||
id_str = args.number or '', |
|||
local testResult = p.getDate{ args = { date = args.date, id_str = args.id_str }} |
|||
date = args.date or '', |
|||
if testResult == -2 then return errors[3] end |
|||
error1 = ' <kbd>|date=</kbd> mismatches calculated date from <kbd>|number=</kbd> by two or more days;', |
|||
if abs_datediff(testResult) > 1 then return errors[1] end |
|||
error2 = ' Missing or empty <kbd>|date=</kbd>, and posted before November 4, 2010;', |
|||
elseif not args.id_str:match('^%s*$') then |
|||
error3 = ' Invalid <kbd>|number=</kbd> parameter;' |
|||
local testResult = p.getDate{ args = { id_str = args.id_str }} |
|||
}} |
|||
if testResult == -1 then return errors[2] end |
|||
if errors[1] then |
|||
local last = errors[#errors] |
|||
errors[#errors] = last:sub(1, #last - 1) .. ' ([[Template:Cite_tweet#Error_detection|help]])' |
|||
local error_out = error_template:rep(#errors):format(unpack(errors)) |
|||
if mw.title.getCurrentTitle():inNamespace(0) then |
|||
error_out = error_out .. '[[Category:Cite tweet templates with errors]]' |
|||
end |
|||
output = output .. error_out |
|||
end |
end |
||
return output |
|||
end |
end |
||
Latest revision as of 02:12, 18 July 2022
![]() | This is the module sandbox page for Module:TwitterSnowflake (diff). See also the companion subpage for test cases (run). |
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This Lua module is used on approximately 44,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
Related pages |
---|
![]() | This module depends on the following other modules: |
This is a Lua module to translate snowflakes from platforms such as Twitter and Discord to timestamps. This can be used for automatically generating dates for templates like {{cite tweet}}.
Usage
[edit]There is one required parameter: |id_str=
, which must be the snowflake ID of the tweet. For example, 1345021162959503360
.
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=1345021162959503360}}
returns January 1, 2021.
To specify the date format, use |format=
.
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=1345021162959503360|format=%e %B %Y}}
returns 1 January 2021 — useful to specify, especially for use in CS1 citations, in case the default date format would change in the future (though unlikely).
Custom epoch
[edit]By default, the epoch used is that of Twitter. To specify a different epoch, such as that of Twitter, use |epoch=
. The epoch of Discord is 1420070400
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=797545051047460888|epoch=1420070400}}
returns January 9, 2021.
See also
[edit]local p = {}
local TwitterSnowflake = require('Module:TwitterSnowflake')
local CiteWeb = require('Module:Cite web')['']
local function _if(arg)
return arg and arg ~= '' or nil
end
p.main = function(frame)
frame.args = frame:getParent().args
return p[''](frame)
end
p[''] = function(frame)
local args = frame.args
local cite_args = {
url = 'https://twitter.com/' .. ((args.user and args.number) and (args.user .. '/status/' .. args.number) or ''),
title = (args.title or ''):gsub('https*://', ''),
['script-title'] = args['script-title'],
['trans-title'] = args['trans-title'],
language = args.language,
['author-link'] = args['author-link'] or args.authorlink,
others = _if(args.retweet) and ('Retweeted by ' .. args.retweet),
via = args.link == 'no' and 'Twitter' or '[[Twitter]]',
type = 'Tweet',
location = args.location,
['access-date'] = args['access-date'] or args.accessdate,
['archive-date'] = args['archive-date'] or args.archivedate,
['archive-url'] = args['archive-url'] or args.archiveurl,
['url-status'] = args['url-status'] or args['dead-url'] or args.deadurl,
quote = args.quote,
ref = args.ref,
df = args.df
}
if _if(args.last1 or args.last) then
cite_args.author = (args.last1 or args.last) ..
(_if(args.first1 or args.first) and (', ' .. (args.first1 or args.first)) or '') ..
' [@' .. (args.user or '') .. ']'
elseif _if(args.author1 or args.author) then
cite_args.author = (args.author1 or args.author) .. ' [@' .. (args.user or '') .. ']'
elseif _if(args['author-link']) then
cite_args.author = args['author-link'] .. ' [@' .. (args.user or '') .. ']'
else
cite_args.author = '@' .. (args.user or '')
end
if cite_args.author:find ('[Tt]witter') then
cite_args.author = '((' .. cite_args.author .. '))'
end
if _if(tonumber(args.number)) then
cite_args.date = args.date or (_if(args.number) and TwitterSnowflake.snowflakeToDate{ args = {id_str = args.number} })
else
cite_args.date = args.date
end
frame.args = cite_args
local output = CiteWeb(frame)
frame.args = args
-- Error checking
local error_template = '<span class="cs1-visible-error citation-comment">%s</span>'
local errors = {}
if not (_if(args.title) or _if(args['script-title']) or args.user or args.number or args.date) then
-- No title; error message is provided by CS1 module.
errors[1] = ';'
end
if not _if(args.user) then
errors[1 + #errors] = ' Missing or empty <kbd>|user=</kbd>;'
end
if not _if(args.number) then
errors[1 + #errors] = ' Missing or empty <kbd>|number=</kbd>;'
end
errors[1 + #errors] = TwitterSnowflake.datecheck{ args = {
id_str = args.number or '',
date = args.date or '',
error1 = ' <kbd>|date=</kbd> mismatches calculated date from <kbd>|number=</kbd> by two or more days;',
error2 = ' Missing or empty <kbd>|date=</kbd>, and posted before November 4, 2010;',
error3 = ' Invalid <kbd>|number=</kbd> parameter;'
}}
if errors[1] then
local last = errors[#errors]
errors[#errors] = last:sub(1, #last - 1) .. ' ([[Template:Cite_tweet#Error_detection|help]])'
local error_out = error_template:rep(#errors):format(unpack(errors))
if mw.title.getCurrentTitle():inNamespace(0) then
error_out = error_out .. '[[Category:Cite tweet templates with errors]]'
end
output = output .. error_out
end
return output
end
return p