Módulo:Rotten Tomatoes data

Revisão em 01h22min de 14 de maio de 2024 por Jaewoo (discussão | contribs) (Criou a página com "local Error = require('Module:Erro') local getArgs = require('Module:Arguments').getArgs local p = {} local months = {'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'} local aliasesQ = { RottenTomatoes = "Q105584", RottenTomatoesScore = "Q108403393", RottenTomatoesAverage = "Q108403540", Fandango = "Q5433722", } local aliasesP = { RottenToma...")
(dif) ← Revisão anterior | Revisão atual (dif) | Revisão seguinte → (dif)

A documentação para este módulo pode ser criada na página Módulo:Rotten Tomatoes data/doc

local Error = require('Module:Erro')
local getArgs = require('Module:Arguments').getArgs
local p = {}
local months = {'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
				'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'}
local aliasesQ = {
				RottenTomatoes          = "Q105584",
				RottenTomatoesScore     = "Q108403393",
				RottenTomatoesAverage   = "Q108403540",
				Fandango                = "Q5433722",
}
local aliasesP = {
				RottenTomatoesId        = "P1258",
				reviewScore             = "P444",
				reviewScoreBy           = "P447",
				numberOfReviews         = "P7887",
				pointInTime             = "P585",
				determinationMethod     = "P459",
				author                  = "P50",
				publisher               = "P123",
				statedIn                = "P248",
				language                = "P407",
				retrieved               = "P813",
				referenceURL            = "P854",
				archiveURL              = "P1065",
				title                   = "P1476",
				formatterURL            = "P1630",
				archiveDate             = "P2960",
}
-- Helper functions ------------------------------------------------------------
local function falsy(x)
				return x == false or x == nil or x == '' or x == 0 or type(x) == 'table' and next(x) == nil
end
-- copied from Module:wd
local function parseDate(dateStr, precision)
				precision = precision or "d"
				local i, j, index, ptr
				local parts = {nil, nil, nil}
				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, day
end
-- nil dates precede all reasonable dates since year becomes 1
local 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 false
end
-- format options: 'dmy', 'mdy', 'ymd', 'iso'
local function format_date(Y, M, D, format)
				format = format or 'MDY'
				local s = (D or '') .. (months[M] or '') .. (Y or '')
				return mw.getCurrentFrame():expandTemplate{title='Date', args={s, format}}
end
--------------------------------------------------------------------------------
-- Returns either QID, true, or ErrorString, false
local function getentityID(args)
				local entityID = args.qid
				if falsy(entityID) then
								local title = args.title
								if falsy(title) then
												local currentID = mw.wikibase.getEntityIdForCurrentPage()
												if currentID then
																return currentID, true
												end
												return Error.error({'No Wikidata item connected to current page. Need qid or title argument.'}), false
								else
												-- if not mw.title.makeTitle(0, title).exists then
												--     return Error.error({'Article ' .. title .. ' does not exist.'}), false
												-- end
												entityID = mw.wikibase.getEntityIdForTitle(title)
												if not entityID then
																return Error.error({'Article "' .. title .. '" does not exist or has no Wikidata item.'}), 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({'Invalid Q-identifier.'}), false
				end
				if not mw.wikibase.entityExists(entityID) then
								return Error.error({'Wikidata item ' .. entityID .. ' does not exist.'}), false
				end
				return entityID, true
end
local function point_in_time(statement)
				if not statement.qualifiers then
								return nil, nil, nil
				end
				local pointintime = statement.qualifiers[aliasesP.pointInTime]
				if pointintime then
								return parseDate(pointintime[1].datavalue.value.time)
				end
				return nil, nil, nil
end
local function access_date(statement)
				if statement.references then
								local accessdate = statement.references[1].snaks[aliasesP.retrieved]
								if accessdate then
												return parseDate(accessdate[1].datavalue.value.time)
								end
				end
				return nil, nil, nil
end
local function date_from_statement(statement)
				local Y, M, D = point_in_time(statement)
				if Y then
								return Y, M, D
				end
				Y, M, D = access_date(statement)
				if Y then
								return Y, M, D
				end
				if statement.rank == 'preferred' then
								return 1, 1, 3
				elseif statement.rank == 'normal' then
								return 1, 1, 2
				end
				return 1, 1, 1
end
local function reviewedby_RT(statement)
				if not statement.qualifiers then return false end
				local x = statement.qualifiers[aliasesP.reviewScoreBy]
				return x and x[1].datavalue.value.id == aliasesQ.RottenTomatoes
end
local function score_type(statement)
				local x = nil
				if statement.qualifiers then
								x = statement.qualifiers[aliasesP.determinationMethod]
				end
				if x then
								x = x[1].datavalue.value.id
				end
				local y = ''
				if statement.mainsnak.snaktype == 'value' then
								y = statement.mainsnak.datavalue.value
				end
				if x == aliasesQ.RottenTomatoesScore then
								return 'percent'
				elseif x == aliasesQ.RottenTomatoesAverage then
								return 'average'
				elseif string.match(y, '^[0-9]%%$') or string.match(y, '^[1-9][0-9]%%$') or string.match(y, '^100%%$') then
								return 'percent'
				elseif string.match(y, '^[0-9] percent$') or string.match(y, '^[1-9][0-9] percent$') or string.match(y, '^100 percent$') then
								return 'percent'
				elseif string.match(y, '^%d/10$') or string.match(y, '^%d%.%d%d?/10$') then
								return 'average'
				elseif string.match(y, '^%d out of 10$') or string.match(y, '^%d%.%d%d? out of 10$') then
								return 'average'
				end
				return nil
end
local function most_recent_score_statement(entityID, scoretype)
				scoretype = scoretype or 'percent'
				local score_statements = mw.wikibase.getAllStatements(entityID, aliasesP.reviewScore)
				local newest, nY, nM, nD
				for i, v in ipairs(score_statements) do
								local Y, M, D = date_from_statement(v)
								if v.rank ~= 'deprecated' and v.mainsnak.snaktype == 'value'
																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 newest
end
local function get_score(entityID, scoretype)
				scoretype = scoretype or 'percent'
				local x = most_recent_score_statement(entityID, scoretype)
				if x == nil then
								return nil
				end
				return x.mainsnak.datavalue.value
end
local function get_count(entityID, args)
				local x = most_recent_score_statement(entityID)
				if x == nil then
								return nil
				end
				local y = x.qualifiers[aliasesP.numberOfReviews]
				if y == nil then
								return nil
				end
				local retval = string.match(y[1].datavalue.value.amount, '%d+') -- dont get sign
				if args ~= nil and args.spell then
								local s = {[1]=retval}
								for key, val in pairs(args) do
												if key == 1 or key == 'qid' or key == 'title' then
												elseif type(key) == 'number' then
															
												else
																s[key] = val
												end
								end
								return mw.getCurrentFrame():expandTemplate{title='Spellnum per MOS', args=s}
				end
				return retval
end
local function get_rtid(entityID, noprefix)
				local rtid_statements = mw.wikibase.getBestStatements(entityID, aliasesP.RottenTomatoesId)
				local newest, nY, nM, nD
				for i, v in ipairs(rtid_statements) do
								local Y, M, D = date_from_statement(v)
								if not datePrecedesDate(Y, M, D, nY, nM, nD) then
												nY, nM, nD = Y, M, D
												newest = v
								end
				end
				if newest == nil then
								return nil
				end
				newest = newest.mainsnak.datavalue.value
				if noprefix then
								newest = string.sub(newest, string.find(newest, '/') + 1)
				end
				return newest
end
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)
				return (string.gsub(x[1].mainsnak.datavalue.value, '$1', rtid))
end
local function get_date(entityID, part, format)
				local z = most_recent_score_statement(entityID)
				if z == nil then
								return nil
				end
				local Y, M, D = date_from_statement(z)
				if     part == 'year' then
								return Y or ''
				elseif part == 'month' then
								return months[M] or ''
				elseif part == 'day' then
								return D or ''
				end
				return format_date(Y, M, D, format)
end
local function get_access_date(entityID, format)
				local z = most_recent_score_statement(entityID)
				if z == nil then
								return nil
				end
				local Y, M, D = access_date(z)
				if not Y then
								Y, M, D = point_in_time(z)
				end
				return format_date(Y, M, D, format)
end
local function get_asof(entityID, args)
				local s = {}
				for key, val in pairs(args) do
								if key == 1 or key == 'qid' or key == 'title' then
											
								elseif key == 2 then
												s[1] = get_date(entityID, 'year')
								elseif key == 3 then
												s[2] = get_date(entityID, 'month')
								elseif key == 4 then
												s[3] = get_date(entityID, 'day')
								elseif type(key) == 'number' then
												s[key-1] = val
								else
												s[key] = val
								end
				end
				return mw.getCurrentFrame():expandTemplate{title='As of', args=s}
end
local function get_rtprose(entityID, args)
				local s = {get_score(entityID), get_score(entityID, 'average'), get_count(entityID)}
				s[1] = string.match(s[1], '%d+')
				s[2] = string.match(s[2], '%d%.%d%d?') or string.match(s[2], '%d')
				s["access-date"] = get_access_date(entityID, args.df)
				for key, val in pairs(args) do
								if key == 1 or key == 'qid' or key == 'title' then
											
								elseif type(key) == 'number' then
												s[key + 2] = val
								else
												s[key] = val
								end
				end
				return mw.getCurrentFrame():expandTemplate{title='Rotten Tomatoes prose', args=s}
end
local function get_edit_icon(entityID)
				return mw.getCurrentFrame():expandTemplate{title='EditAtWikidata', args={qid=entityID, pid='P444'}}
end
local function get_table(entityID)
				return get_score(entityID) .. ' (' .. get_count(entityID) .. ' reviews)'
end
function p.main(frame)
				local args = getArgs(frame, {
								wrappers = 'Template:Rotten Tomatoes data',
								removeBlanks = false,
				})
				return p._main(args)
end
function p._main(args)
				local entityID, is_good = getentityID(args)
				if not is_good then
								return entityID -- which is the error message in this case
				end
				local command = args[1]
				if falsy(command) then
								return Error.error({'Missing command.'})
				end
				command = string.lower(command)
				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, args)
				elseif command == 'rtid' then
								retval = get_rtid(entityID, args.noprefix)
				elseif command == 'url' then
								retval = get_url(entityID)
				elseif command == 'date' then
								retval = get_date(entityID, 'date', args.df)
				elseif command == 'year' then
								retval = get_date(entityID, command)
				elseif command == 'month' then
								retval = get_date(entityID, command)
				elseif command == 'day' then
								retval = get_date(entityID, command)
				elseif command == 'access date' or command == 'accessdate' or command == 'access-date' then
								retval = get_access_date(entityID, args.df)
				elseif command == 'as of' or command == 'asof' then
								retval = get_asof(entityID, args)
				elseif command == 'prose' then
								retval = get_rtprose(entityID, args)
				elseif command == 'edit' then
								retval = get_edit_icon(entityID)
				elseif command == 'table' then
								retval = get_table(entityID)
				else
								return Error.error({'Invalid command.'})
				end
				if falsy(retval) then
								return Error.error({'RT data for "' .. command .. '" unavailable.'})
				end
				return retval
end
return p