Module:Release: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
mNo edit summary
No edit summary
Line 2: Line 2:
local h = {}
local h = {}


local Franchise = require("Module:Franchise")
local utilsArg = require("Module:UtilsArg")
local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsCargo = require("Module:UtilsCargo")
Line 10: Line 11:


local data = mw.loadData("Module:Releases/Data")
local data = mw.loadData("Module:Releases/Data")
local regionsByParam = utilsTable.keyBy(data.regions, "param")
 
local systemsByCode = utilsTable.keyBy(data.Games.systems, "code")
local systemCodes = utilsTable.map(data.Games.systems, "code")
local TABLES = {
local TABLES = {
Games = "GameReleases"
Games = "GameReleases"
Line 35: Line 34:
function p.CargoStore(frame)
function p.CargoStore(frame)
local medium = frame.args[1]
local medium = frame.args[1]
local args, err = h.evaluateArgs(medium, frame:getParent().args)
local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Game Releases/Store"])
if err then
if err then
return utilsMarkup.categories(err)
return utilsMarkup.categories(err.categories)
end
end
local rows = {}
local rows = {}
for _, regionDate in ipairs(args.regionDates) do
for _, region in ipairs(data.regions) do
local row = utilsTable.merge({}, args, regionDate)
if args[region.param] then
row.regionDates = nil
local row = utilsTable.merge({}, args, {
row.regions = nil
region = region.code,
utilsCargo.store(TABLES[medium], row)
date = args[region.param],
table.insert(rows, row)
reference = args[region.param .. "R"],
})
utilsCargo.store(TABLES[medium], row)
table.insert(rows, row)
end
end
end
return h.printReleases(medium, rows)
return h.printReleases(medium, rows)
Line 58: Line 61:
local result = h.printReleases(medium, releases)
local result = h.printReleases(medium, releases)
return result
return result
end
function h.evaluateArgs(medium, frameArgs)
frameArgs = utilsTable.mapValues(frameArgs, utilsString.trim)
frameArgs = utilsTable.mapValues(frameArgs, utilsString.nilIfEmpty)
local regions = utilsTable.filter(utilsTable.stringKeys(frameArgs), function(arg)
return not utilsString.endsWith(arg, "R")
end)
local regionDates = utilsTable.map(regions, function(region)
return {
region = regionsByParam[region].code,
date = frameArgs[region],
reference= frameArgs[region .. "R"],
}
end)
local mediumArgs, mediumValidators = h.argEvaluators[medium](frameArgs)
local args = utilsTable.merge(mediumArgs, {
regions = regions,
regionDates = regionDates
})
local validators = utilsTable.merge(mediumValidators, {
regions = {
enum = utilsTable.map(data.regions, "param")
}
})
local err = utilsArg.validate(args, validators)
return args, err
end
end


Line 117: Line 92:
local regionDates = utilsTable.keyBy(release.regionDates, "region")
local regionDates = utilsTable.keyBy(release.regionDates, "region")
for _, region in ipairs(data.regions) do
for _, region in ipairs(data.regions) do
local regionCode = regionsByParam[region.param].code
local regionCode = data.regionsByParam[region.param].code
local regionDate = regionDates[regionCode]
local regionDate = regionDates[regionCode]
if regionDate then
if regionDate then
Line 136: Line 111:


-- GAMES
-- GAMES
function h.gameArgs(frameArgs)
local args = {
title = frameArgs[1],
system = frameArgs[2],
service = frameArgs[3],
program = frameArgs[4],
}
local validators = {
title = {
nonEmpty = true,
},
system = {
enum = systemCodes
},
service = {
enum = utilsTable.keys(data.Games.services[args.system] or {})
},
program = {
enum = utilsTable.keys(data.Games.programs[args.system] or {})
},
}
return args, validators
end


function h.labelGameRelease(release)
function h.labelGameRelease(release)
Line 166: Line 117:
label = data.Games.services[release.system][release.service].displayName
label = data.Games.services[release.system][release.service].displayName
else
else
label = systemsByCode[release.system].name
label = data.Games.systemsByCode[release.system].name
end
end
if not utilsString.isEmpty(release.program) then
if not utilsString.isEmpty(release.program) then
Line 175: Line 126:


function h.sortGameRelease(release)
function h.sortGameRelease(release)
return utilsTable.keyOf(systemCodes, release.system)
return utilsTable.keyOf(data.Games.systemCodes, release.system)
end
end


h.argEvaluators = {
Games = h.gameArgs,
}
h.labelers = {
h.labelers = {
Games = h.labelGameRelease,
Games = h.labelGameRelease,
Line 187: Line 135:
Games = h.sortGameRelease,
Games = h.sortGameRelease,
}
}
local regionParams = {}
local regionParamsOrder = {}
for _, region in ipairs(data.regions) do
regionParams[region.param] = {
type = "string",
desc = "Release date in " .. utilsRegion.region(region.code),
trim = true,
}
regionParams[region.param .. "R"] = {
type = "string",
desc = "Source reference for release date.",
inline = true,
trim = true,
}
table.insert(regionParamsOrder, region.param)
table.insert(regionParamsOrder, region.param .. "R")
end
p.Templates = {
["Game Releases/Store"] = {
wip = true,
purpose = "Store information about game releases.",
storesData = "Data:Releases/Games",
format = "block",
paramOrder = utilsTable.concat({1, 2, 3, 4}, regionParamsOrder),
params = {
[1] = {
name = "game",
type = "string",
required = true,
enum = Franchise.enum(),
desc = "Game identifier.",
inline = true,
trim = true,
},
[2] = {
name = "system",
type = "string",
required = true,
enum = data.Games.systemCodes,
desc = "Console or handheld that the game was released for.",
inline = true,
trim = true,
},
[3] = {
name = "service",
type = "string",
enumDependsOn = "system",
enum = function(system)
return utilsTable.keys(data.Games.services[system] or {})
end,
desc = "Software through which this game release is offered (e.g. Virtual Console).",
inline = true,
canOmit = true,
trim = true,
},
[4] = {
name = "program",
type = "string",
enumDependsOn = "system",
enum = function(system)
return utilsTable.keys(data.Games.programs[system] or {})
end,
desc = "Loyalty program through which this release is offered (e.g. Nintendo 3DS Ambassador Program).",
inline = true,
canOmit = true,
trim = true,
}
}
}
}
utilsTable.merge(p.Templates["Game Releases/Store"].params, regionParams)


return p
return p

Revision as of 18:51, 13 June 2020

Lua error in package.lua at line 80: module 'Module:UtilsRegion' not found.


local p = {}
local h = {}

local Franchise = require("Module:Franchise")
local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsRegion = require("Module:UtilsRegion")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

local data = mw.loadData("Module:Releases/Data")

local TABLES = {
	Games = "GameReleases"
}
local FIELDS = {
	Games = {
		title = "String",
		system = "String",
		service = "String",
		program = "String",
		region = "String",
		date = "Date",
		reference = "Wikitext",
	}
}

function p.CargoDeclare(frame)
	local medium = frame.args[1]
	return utilsCargo.declare(TABLES[medium], FIELDS[medium])
end

function p.CargoStore(frame)
	local medium = frame.args[1]
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Game Releases/Store"])
	if err then
		return utilsMarkup.categories(err.categories)
	end
	local rows = {}
	for _, region in ipairs(data.regions) do
		if args[region.param] then
			local row = utilsTable.merge({}, args, {
				region = region.code,
				date = args[region.param],
				reference = args[region.param .. "R"],
			})
			utilsCargo.store(TABLES[medium], row)
			table.insert(rows, row)
		end
	end
	return h.printReleases(medium, rows)
end

function p.Releases(frame)
	return p.printReleases(frame.args[1], frame:getParent().args[1])
end

function p.printReleases(medium, title)
	local releases = h.fetchReleases(medium, title)
	local result = h.printReleases(medium, releases)
	return result
end

function h.fetchReleases(medium, title)
	local tbl = TABLES[medium]
	local fields = utilsTable.keys(FIELDS[medium])
	local query = {
		where = utilsCargo.allOf({ title = title })
	}
	local queryResults = utilsCargo.query(tbl, table.concat(fields, ","), query)
	return queryResults
end

function h.evaluateReleases(medium, releases)
	local releasesByName = utilsTable.groupBy(releases, h.labelers[medium])
	local sortedReleasesByName = {}
	for k, v in pairs(releasesByName) do
		local sortedIndex = h.sorters[medium](v[1])
		sortedReleasesByName[sortedIndex] = {
			name = k,
			regionDates = v
		}
	end
	return utilsTable.compact(sortedReleasesByName)
end

function h.printReleases(medium, releases)
	releases = h.evaluateReleases(medium, releases)
	for i, release in ipairs(releases) do
		local dates = {}
		local regionDates = utilsTable.keyBy(release.regionDates, "region")
		for _, region in ipairs(data.regions) do
			local regionCode = data.regionsByParam[region.param].code
			local regionDate = regionDates[regionCode]
			if regionDate then
				local formattedDate = mw.language.getContentLanguage():formatDate("M d, Y", regionDate.date)
				local date = utilsRegion.flag(regionCode) .. " " .. formattedDate
				if not utilsString.isEmpty(regionDate.reference) then
					date = date .. mw.getCurrentFrame():extensionTag("ref", regionDate.reference)
				end
				table.insert(dates, date)
			end
		end
		releases[i] = utilsTable.concat({release.name}, dates)
	end
	return utilsMarkup.definitionList(releases, {
		class = "releases"
	})
end

-- GAMES

function h.labelGameRelease(release)
	local label
	if not utilsString.isEmpty(release.service) then
		label = data.Games.services[release.system][release.service].displayName
	else
		label = data.Games.systemsByCode[release.system].name
	end
	if not utilsString.isEmpty(release.program) then
		label = label .. (" (%s)"):format(data.Games.programs[release.system][release.program])
	end
	return label
end

function h.sortGameRelease(release)
	return utilsTable.keyOf(data.Games.systemCodes, release.system)
end

h.labelers = {
	Games = h.labelGameRelease,
}
h.sorters = {
	Games = h.sortGameRelease,
}

local regionParams = {}
local regionParamsOrder = {}
for _, region in ipairs(data.regions) do
	regionParams[region.param] = {
		type = "string",
		desc = "Release date in " .. utilsRegion.region(region.code),
		trim = true,
	}
	regionParams[region.param .. "R"] = {
		type = "string",
		desc = "Source reference for release date.",
		inline = true,
		trim = true,
	}
	table.insert(regionParamsOrder, region.param)
	table.insert(regionParamsOrder, region.param .. "R")
end

p.Templates = {
	["Game Releases/Store"] = {
		wip = true,
		purpose = "Store information about game releases.",
		storesData = "Data:Releases/Games",
		format = "block",
		paramOrder = utilsTable.concat({1, 2, 3, 4}, regionParamsOrder),
		params = {
			[1] = {
				name = "game",
				type = "string",
				required = true,
				enum = Franchise.enum(),
				desc = "Game identifier.",
				inline = true,
				trim = true,
			},
			[2] = {
				name = "system",
				type = "string",
				required = true,
				enum = data.Games.systemCodes,
				desc = "Console or handheld that the game was released for.",
				inline = true,
				trim = true,
			},
			[3] = {
				name = "service",
				type = "string",
				enumDependsOn = "system",
				enum = function(system)
					return utilsTable.keys(data.Games.services[system] or {})
				end,
				desc = "Software through which this game release is offered (e.g. Virtual Console).",
				inline = true,
				canOmit = true,
				trim = true,
			},
			[4] = {
				name = "program",
				type = "string",
				enumDependsOn = "system",
				enum = function(system)
					return utilsTable.keys(data.Games.programs[system] or {})
				end,
				desc = "Loyalty program through which this release is offered (e.g. Nintendo 3DS Ambassador Program).",
				inline = true,
				canOmit = true,
				trim = true,
			}
		}
	}
}

utilsTable.merge(p.Templates["Game Releases/Store"].params, regionParams)

return p