Module:Release

From Zelda Wiki, the Zelda encyclopedia
Revision as of 04:46, 10 May 2020 by PhantomCaleb (talk | contribs)
Jump to navigation Jump to search

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


local p = {}
local h = {}

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 regionsByParam = utilsTable.keyBy(data.regions, "param")
local systemsByCode = utilsTable.keyBy(data.Games.systems, "code")
local systemCodes = utilsTable.map(data.Games.systems, "code")
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 = h.evaluateArgs(medium, frame:getParent().args)
	if err then
		return utilsMarkup.categories(err)
	end
	local rows = {}
	for _, regionDate in ipairs(args.regionDates) do
		local row = utilsTable.merge({}, args, regionDate)
		row.regionDates = nil
		row.regions = nil
		utilsCargo.store(TABLES[medium], row)
		table.insert(rows, row)
	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.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

function h.fetchReleases(medium, title)
	local tbl = TABLES[medium]
	local fields = utilsTable.keys(FIELDS[medium])
	local query = utilsCargo.allOf({title = title})
	local queryResults = utilsCargo.query(tbl, table.concat(fields, ","), game)
	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 = 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.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)
	local label
	if not utilsString.isEmpty(release.service) then
		label = data.Games.services[release.system][release.service].displayName
	else
		label = 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(systemCodes, release.system)
end

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

return p