Module:Sandbox/Notsniwiast/learn explained

local Error = require('Module:Error')

local p =

local aliasesQ =

local aliasesP =

-- Helper functions ------------------------------------------------------------function mw.ustring.startswith(s, pattern, plain) return mw.ustring.find(s, pattern, 1, plain)

1end

-- 0, nil, empty string, or empty tablelocal function falsy(x) if x

nil or x

or x

then return true elseif type(x)

'table' and next(x)

nil then return true end return falseend

-- copied from Module:wdlocal function parseDate(dateStr, precision) precision = precision or "d"

local i, j, index, ptr local parts =

if dateStr

nil then return parts[1], parts[2], parts[3] -- year, month, day end

-- 'T' for snak values, '/' for outputs with '/Julian' attached i, j = dateStr:find("[T/]")

if i then dateStr = dateStr:sub(1, i-1) end

local from = 1

if dateStr:sub(1,1)

"-" then -- this is a negative number, look further ahead from = 2 end

index = 1 ptr = 1

i, j = dateStr:find("-", from)

if i then -- year parts[index] = tonumber(mw.ustring.gsub(dateStr:sub(ptr, i-1), "^\+(.+)$", "%1"), 10) -- remove '+' sign (explicitly give base 10 to prevent error)

if parts[index]

-0 then parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead end

if precision

"y" then -- we're done return parts[1], parts[2], parts[3] -- year, month, day end

index = index + 1 ptr = i + 1

i, j = dateStr:find("-", ptr)

if i then -- month parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)

if precision

"m" then -- we're done return parts[1], parts[2], parts[3] -- year, month, day end

index = index + 1 ptr = i + 1 end end

if dateStr:sub(ptr) ~= "" then -- day if we have month, month if we have year, or year parts[index] = tonumber(dateStr:sub(ptr), 10) end

return parts[1], parts[2], parts[3] -- year, month, dayend

-- nil dates precede all other (reasonable) dates since year becomes 1local function datePrecedesDate(aY, aM, aD, bY, bM, bD) aY, aM, aD = aY or 1, aM or 1, aD or 1 bY, bM, bD = bY or 1, bM or 1, bD or 1 if aY < bY then return true end if aY > bY then return false end if aM < bM then return true end if aM > bM then return false end if aD < bD then return true end return falseend

---------------------------------------------------------------------------------- Returns either QID, true, or ErrorString, falselocal function getEntityId(frame) local entityId = frame.args.qid local title = frame.args.title if falsy(entityId) then if falsy(title) then local currentPageEntityId = mw.wikibase.getEntityIdForCurrentPage if currentPageEntityId then return currentPageEntityId, true end return Error.error, false else if not mw.title.makeTitle(0, title).exists then return Error.error, false end entityId = mw.wikibase.getEntityIdForTitle(title) if not entityId then return Error.error, false end return entityId, true end end --At this point we should have an entityId. Check if valid. if not mw.wikibase.isValidEntityId(entityId) then return Error.error, false end if not mw.wikibase.entityExists(entityId) then return Error.error, false end return entityId, true end

local function date_from_statement(statement) local pointintime = statement.qualifiers[aliasesP.pointInTime] if not falsy(pointintime) then pointintime = pointintime[1].datavalue.value.time return parseDate(pointintime) end if statement.references[1] then local accessdate = statement.references[1].snaks[aliasesP.retrieved] if not falsy(accessdate) then accessdate = accessdate[1].datavalue.value.time return parseDate(accessdate) end end return nil, nil, nilend

local function reviewedby_RT(statement) local x = statement.qualifiers[aliasesP.reviewScoreBy] if falsy(x) then return false end x = x[1].datavalue.value.id if x ~= aliasesQ.RottenTomatoes then return false end return trueend

-- statement should be a review score (P444) statementlocal function score_type(statement) local x = statement.qualifiers[aliasesP.determinationMethod] if falsy(x) then return nil end x = x[1].datavalue.value.id if x

aliasesQ.RottenTomatoesScore then return 'percent' end if x

aliasesQ.RottenTomatoesAverage then return 'average' end local y = statement.mainsnak.datavalue.value if string.match(y, '^0%%$') or string.match(y, '^[1-9][0-9]%%$') or string.match(y, '^100%%$') then return 'percent' end if string.match(y, '^0 percent$') or string.match(y, '^[1-9][0-9] percent$') or string.match(y, '^100 percent$') then return 'percent' end if string.match(y, '^%d/10$') or string.match(y, '^%d.%d%d?/10$') then return 'average' end if string.match(y, '^%d out of 10$') or string.match(y, '^%d.%d%d? out of 10$') then return 'average' end return nilend

local function most_recent_score_statement(entityId, scoretype) scoretype = scoretype or 'percent' local score_statements = mw.wikibase.getAllStatements(entityId, aliasesP.reviewScore) if falsy(score_statements) then return nil end local newest = nil local nY, nM, nD = nil, nil, nil for i, v in ipairs(score_statements) do local Y, M, D = date_from_statement(v) if v.rank ~= 'deprecated' and reviewedby_RT(v) and score_type(v)

scoretype and not datePrecedesDate(Y, M, D, nY, nM, nD) then nY, nM, nD = Y, M, D newest = v end end return newestend

local function get_score(entityId, scoretype) scoretype = scoretype or 'percent' local x = most_recent_score_statement(entityId, scoretype) if x then return x.mainsnak.datavalue.value end return nilend

local function get_count(entityId) local x = most_recent_score_statement(entityId) local y = x.qualifiers[aliasesP.numberOfReviews] if falsy(y) then return nil end return string.match(y[1].datavalue.value.amount, '%d+') -- dont get signend

local function get_rtid(entityId) local x = mw.wikibase.getBestStatements(entityId, aliasesP.RottenTomatoesId) if falsy(x) then return nil end return x[1].mainsnak.datavalue.valueend

local function get_url(entityId) local rtid = get_rtid(entityId) if rtid

nil then return nil end local x = mw.wikibase.getBestStatements(aliasesP.RottenTomatoesId, aliasesP.formatterURL) subbed, k = string.gsub(x[1].mainsnak.datavalue.value, '$1', rtid) return subbedend

local function get_date(entityId, part) local Y, M, D = date_from_statement(most_recent_score_statement(entityId)) local months = if part

'year' then if Y then return Y else return end end if part

'month' then if M then return months[M] else return end end if part

'day' then if D then return D else return end end local s = if Y then s = Y if M then s = M .. ' ' .. s if D then s = D .. ' ' .. s end end end return send

function p.test(frame) mw.log('starting') local entityId, is_good = getEntityId(frame) if not is_good then return entityId -- which is the error message end local command = frame.args[1] if falsy(command) then return Error.error end local retval = if command

'score' then retval = get_score(entityId, 'percent') elseif command

'average' then retval = get_score(entityId, 'average') elseif command

'count' then retval = get_count(entityId) elseif command

'rtid' then retval = get_rtid(entityId) elseif command

'url' then retval = get_url(entityId) elseif command

'date' or command

'year' or command

'month' or command

'day' then retval = get_date(entityId, command) else return Error.error end if falsy(retval) then return Error.error end return retvalend

function p.test2(frame)end

return p