Module:Video game series reviews

local getArgs = require('Module:Arguments').getArgs

local yesno = require('Module:Yesno')

local Vgwd = require('Module:Video game wikidata')

local p = {}

local columns = {

['mc'] = nil,

['gr'] = nil,

['oc'] = nil,

['fam'] = nil,

['sales'] = nil,

['year'] = nil,

}

local function sortByNumber(a,b)

return a['num'] < b['num']

end;

local function sortByPublicationDate(a,b)

local aP = a['pubDate'];

local bP = b['pubDate'];

if(aP ~= nil and bP ~= nil) then

return aP < bP;

end;

-- fallback sorting, let's assume the oldest wikidata entity is the oldest game

local aQ = a['qid'];

local bQ = b['qid'];

if(aQ ~= nil and bQ ~= nil) then

return aQ < bQ;

end;

-- still nothing? okay, let's just use the initial order

return a['num'] < b['num'];

end;

local function getVGWD(frame, reviewer)

-- Obey local override on displaying this reviewer, don't bother trying to get Wikidata.

if(columns[reviewer] == false) then

return nil;

end;

local vgwdScore = Vgwd.setReviewer(reviewer);

if(vgwdScore ~= nil) then

return vgwdScore;

end;

-- Because a game with no platforms may disable show system, we have to reenable for each game.

Vgwd.setShowSystem(true);

return Vgwd.printReviewScores(frame);

end;

local function checkColumn(game, column)

if(game[column] ~= nil and game[column] ~= "" and columns[column] ~= false) then

columns[column] = true;

end;

end;

local function buildGameEntry(args, num, qid)

local game = {}

game['num'] = num;

game['name'] = args["game"..num];

game['mc'] = args["mc"..num];

game['gr'] = args["gr"..num];

game['oc'] = args["oc"..num];

game['fam'] = args["fam"..num];

game['sales'] = args["sales"..num];

game['year'] = args["year"..num];

if(qid ~= nil) then

-- If a qid was supplied, we are doing a series pull and won't check columns here.

game['qid'] = qid;

else

-- Pulling game data purely from arguments, so check columns.

game['qid'] = args["qid"..num];

checkColumn(game, 'mc');

checkColumn(game, 'gr');

checkColumn(game, 'oc');

checkColumn(game, 'fam');

checkColumn(game, 'year');

checkColumn(game, 'sales');

end;

return game;

end;

local function buildGameWikidata(frame, game)

if(game['qid'] ~= nil) then

local vgwdScore = Vgwd.setGame(game["qid"]);

if(vgwdScore == nil) then

game['updateLink'] = Vgwd.getUpdateLink();

if(game['mc'] == nil) then

game['mc'] = getVGWD(frame, 'mc')

end;

if(game['gr'] == nil and columns['gr']) then

game['gr'] = getVGWD(frame, 'gr')

end;

if(game['oc'] == nil and columns['oc']) then

game['oc'] = getVGWD(frame, 'oc')

end;

if(game['fam'] == nil and columns['fam']) then

game['fam'] = getVGWD(frame, 'fam')

end;

if(game['name'] == nil) then

local sitelink = Vgwd.getSitelink();

local label = Vgwd.getLabel();

if(sitelink ~= nil) then

if(sitelink ~= label) then

game['name'] = "" .. label .. "";

else

game['name'] = "" .. sitelink .. "";

end;

else

game['name'] = label;

end;

end;

if(game['year'] == nil) then

local pubDate = Vgwd.getEarliestPublicationDate();

game['pubDate'] = pubDate;

if(pubDate ~= nil) then

game['year'] = pubDate.year;

end;

end;

else

-- Entity wasn't found... How to represent? TODO.

end;

end;

-- We don't check GR and FAM because they must be explicitly enabled by arguments.

checkColumn(game, 'mc');

checkColumn(game, 'oc');

checkColumn(game, 'year');

checkColumn(game, 'sales');

return game;

end;

function p.main(frame)

local args = getArgs(frame)

return p._main(frame, args)

end

function p._main(frame, args)

-- Get specified values of column display parameters. Nil = Unspecified.

if(args["mc"]) then

columns['mc'] = yesno(args.mc);

end

if(args["gr"]) then

columns['gr'] = yesno(args.gr);

end

if(args["oc"]) then

columns['oc'] = yesno(args.oc);

end

if(args["fam"]) then

columns['fam'] = yesno(args.fam);

end

if(args["sales"]) then

columns['sales'] = yesno(args.sales);

end

if(args["years"]) then

columns['year'] = yesno(args.years);

end

local seriesQid = args["seriesQid"]; -- Should be nil, but for testing we have to be able to supply one.

Vgwd.setDateFormat(args["df"]);

Vgwd.setSystem(nil);

Vgwd.setGenerateReferences(true);

Vgwd.setShowUpdateLink(false);

Vgwd.setUpdateLinkStyle("pen");

local games = {};

local gameRead = {};

-- Look for locally provided gameN and qidN parameters first. Build a table containing all the arguments.

for k, v in pairs(args) do

if(string.find(k, "game%d+") or string.find(k, "qid%d+")) then

local num = tonumber(string.match(k, "%d+"))

if(num ~= nil) then

if(gameRead[num] == nil) then

gameRead[num] = true;

table.insert(games, buildGameEntry(args,num));

end;

end;

end;

end;

-- Did we find any games specified on the arguments?

if(#games > 0) then

-- Sort by entry.

table.sort(games, sortByNumber);

-- Retrieve missing data with Wikidata if possible, for each entry.

for i, game in ipairs(games) do

games[i] = buildGameWikidata(frame,game);

end;

else

-- If we didn't get any games from the arguments, try to pull the parts of the series from Wikidata.

-- Reset vgwd to current page, presumably a series.

local vgwdScore = Vgwd.setGame(seriesQid);

if(vgwdScore == nil) then

local parts = Vgwd.getParts();

for i, qid in ipairs(parts) do

-- Build an entry.

local game = buildGameEntry({},i,qid)

-- Retrieve the data from Wikidata and store in the table.

table.insert(games, buildGameWikidata(frame,game));

end;

table.sort(games, sortByPublicationDate);

else

-- Entity wasn't found... How to represent? TODO.

end;

end;

local ret = "

class=\"wikitable plainrowheaders\" style=\"font-size: 90%; float: right; clear: right; margin:0.5em 0 0.5em 1em;\"\n"

ret = ret .."|+ style=\"font-size: 111.11%;\" | "

if args.title then

ret = ret .. args.title

elseif columns['sales'] then

if columns['fam'] then

ret = ret .. "Sales and review scores"

elseif columns['gr'] or columns['mc'] or columns['oc'] then

ret = ret .. "Sales and aggregate review scores"

else

ret = ret .. "Sales"

end

elseif columns['fam'] then

if columns['gr'] or columns['mc'] or columns['oc'] then

ret = ret .. "Japanese and Western review scores"

else

ret = ret .. "Famitsu review scores"

end

else

ret = ret .. "Aggregate review scores"

end

if args.updated then

ret = ret .. "
As of " .. args.updated .."."

end

ret = ret .. " \n"

ret = ret .. "! scope=\"col\" | Game \n"

if columns['year'] then

ret = ret .. "! scope=\"col\" | Year\n"

end

if columns['sales'] then

ret = ret .. "! scope=\"col\" | " .. (args.sales_title or "Units sold") .. " \n"

end

if columns['fam'] then

ret = ret .. "! scope=\"col\" | " .. (args.fam_title or "Famitsu") .. " \n"

end

if columns['gr'] then

ret = ret .. "! scope=\"col\" | " .. (args.gr_title or "GameRankings") .. " \n"

end

if columns['mc'] then

ret = ret .. "! scope=\"col\" | " .. (args.mc_title or "Metacritic") .. " \n"

end

if columns['oc'] then

ret = ret .. "! scope=\"col\" | " .. (args.oc_title or "OpenCritic") .. " \n"

end

-- Print the reviews

for i,game in ipairs(games) do

ret = ret .. "

\n"

ret = ret .. "! scope=\"row\" | " .. game['name'] .. " "

if(game['updateLink']) then

ret = ret .. " " .. game['updateLink'];

end;

ret = ret .. "\n"

if columns['year'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['year'] or '') .. " \n"

end

if columns['sales'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['sales'] or '') .. " \n"

end

if columns['fam'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['fam'] or '') .. " \n"

end

if columns['gr'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['gr'] or '') .. " \n"

end

if columns['mc'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['mc'] or '') .. " \n"

end

if columns['oc'] then

ret = ret .. "| style=\"text-align: center;\" | " .. (game['oc'] or '') .. " \n"

end

end;

ret = ret .. "

"

return ret

end

return p