Module:Version Info

From Ylvapedia

Documentation for this module may be created at Module:Version Info/doc

local utils = require('Module:Utils')
local i18n = mw.loadData('Module:Version Info/i18n')
local title = mw.title.getCurrentTitle()
local namespaceName = title.nsText
local p = {}

local function parse_date(date_str, lang_str)
	local year, month, day = nil, nil, nil
	year, month, day = date_str:match("(%d+).(%d+).(%d+)")
	--month, day, year = date_str:match("(%d+)/(%d+) (%d+)")
	if year and month and day then
		local timestamp = os.time({year = tonumber(year), month = tonumber(month), day = tonumber(day), hour = 0, min = 0, sec = 0})
		return timestamp
	else
		return nil
	end
end

--タイムスタンプ処理
local function processAndSortTable(input_table, lang_code)
	local processed_table = {}
	for _, row in ipairs(input_table) do
		if row and row.ReleaseData then
			local timestamp = parse_date(row.ReleaseData, lang_code)
			if timestamp then
				table.insert(processed_table, { data = row, timestamp = timestamp })
			else
				table.insert(processed_table, { data = row, timestamp = 0 })
			end
		else
			table.insert(processed_table, { data = row, timestamp = nil })
		end
	end

	table.sort(processed_table, function(a, b)
		if a.timestamp == nil and b.timestamp == nil then
			return false
		elseif a.timestamp == nil then
			return false
		elseif b.timestamp == nil then
			return true
		else
			return a.timestamp > b.timestamp
		end
	end)

	return processed_table
end

local function generatePrefixedLinks(prefix, dataTable, lang)
	local wikitextParts = {}
	for i, value in ipairs(dataTable) do
		local full_version_string = value.data['Version']
		local stableMarker = (value.data['VarsionType'] == i18n[lang]['stable']) and '★' or ''

		local display_version_string = full_version_string
		display_version_string = display_version_string:gsub('^EA%s*', '')
		display_version_string = display_version_string:gsub('^Alpha%s*', '')
		display_version_string = display_version_string:gsub('^α%s*', '')
		display_version_string = display_version_string:gsub('^Beta%s*', '')
		display_version_string = display_version_string:gsub('^β%s*', '')

		local link = '[[Elin meta:'..full_version_string..' ('..string.lower(lang)..')|'..stableMarker..display_version_string..']]'
		table.insert(wikitextParts, link)
	end
	return table.concat(wikitextParts, '・')
end

local function generatePrefixedTh(lang, type)
	local wikitextParts = {}
	local rowParts = {
		'<table class="wikitable sortable"><tr><th style="width: 6em;">'..i18n[lang]['navtitleVersions']..'</th>'
	}
	if type == 'true' then table.insert(rowParts, '<th>'..(i18n[lang]['titleVtype'] or '-')..'</th>') end
	table.insert(rowParts, '<th>'..(i18n[lang]['titleReleaseData'] or '-')..'</th>')
	table.insert(rowParts, '<th>'..(i18n[lang]['tabletitleNotes'] or '')..'</th></tr>')
	return table.concat(rowParts)
end

local function generatePrefixedTr(prefix, dataTable, lang, type)
	local wikitextParts = {}
	for i, value in ipairs(dataTable) do
		local rowParts = {
			'<tr><td>[[Elin meta:', value.data['Version'], ' (', string.lower(lang), ')|', value.data['Version'], ']]</td>'
		}
		if type == 'true' then table.insert(rowParts, '<td>'..(value.data['VarsionType'] or '-')..'</td>') end
		table.insert(rowParts, '<td>'..(value.data['ReleaseData'] or '-')..'</td>')
		table.insert(rowParts, '<td>'..(value.data['Notes'] or '')..'</td></tr>')
		local row = table.concat(rowParts)
		table.insert(wikitextParts, row)
	end
	return table.concat(wikitextParts, '\n')
end

function p.main(f)
	local args = f:getParent().args
	local lang = f.args['lang'] or utils.getDefaultIfEmpty(args['lang'], 'JA')
	local version = utils.getDefaultIfEmpty(args['version'],mw.ustring.gsub(mw.ustring.gsub(title.prefixedText, '^[^:]+:', ''), '/[^/]*$', ''))
	local image = utils.nilCheck(args['image'])
	local caption = utils.nilCheck(args['caption'])
	local varsionType = utils.nilCheck(args['varsion type'])
	local releaseData = utils.nilCheck(args['release data'])
	local steamlink = utils.nilCheck(args['steamlink'])
	local previous = utils.nilCheck(args['previous'])
	local next = utils.nilCheck(args['next'])
	local notes = utils.nilCheck(args['notes'])
	
	utils.setPropertyData('Version',version)

	local html = mw.html.create('div'):addClass('elin-infobox elin-parchment')
	html:tag('div'):addClass('ei-title'):cssText('padding: 0.2em 0.2em 0.4em 0.2em;'):wikitext(version):done()
	html:wikitext('<hr class="ei-hr">')
	html:tag('div'):addClass('ei-image')
	if image then
		html:wikitext(string.format('[[File:%s|alt=%s]]',image,version))
		if namespaceName == 'Elin_meta' then utils.setPropertyData('image',image) end
	end
	if caption then
		html:tag('div'):addClass('ei-caption'):wikitext(caption):done()
		if namespaceName == 'Elin_meta' then utils.setPropertyData('caption',caption) end
	end
	html:done()
	if image or caption then
		html:wikitext('<hr class="ei-hr">')
	end

	--コンテンツタイプの表示
	htmlchild = html:tag('div'):addClass('vi-prev-next')
	htmlchild:tag('div'):addClass('vi-grid-L'):cssText('font-weight: bold;'):wikitext(i18n[lang]['titleVtype'])
	if varsionType then
		htmlchild:tag('div'):wikitext(varsionType):done()
		if namespaceName == 'Elin_meta' then
			utils.setPropertyData('VarsionType',varsionType)
			htmlchild:wikitext('[[Category:Elin '..varsionType..']]')
		end
	else
		htmlchild:tag('div'):wikitext(i18n[lang]['BlankValue']):done()
	end

	--リリース日の表示
	htmlchild = html:tag('div'):addClass('vi-prev-next')
	htmlchild:tag('div'):addClass('vi-grid-L'):cssText('font-weight: bold;'):wikitext(i18n[lang]['titleReleaseData'])
	if releaseData then
		local string = ''
		if steamlink then string = f:callParserFunction{ name = '#tag', args = { 'ref', steamlink } } end
		htmlchild:tag('div'):wikitext(releaseData..string):done()
		if namespaceName == 'Elin_meta' then
			utils.setPropertyData('releaseData',releaseData)
		end
	else
		htmlchild:tag('div'):wikitext(i18n[lang]['BlankValue']):done()
	end

	html:wikitext('<hr class="ei-hr">')

	htmlchild = html:tag('div'):addClass('vi-prev-next')
	--前のバージョン
		local string = ''
	if previous then
		string = '[[Elin meta:'..previous..' ('..string.lower(lang)..')|'..previous..']]'
		if namespaceName == 'Elin_meta' then
			utils.setPropertyData('Previous',previous)
		end
	else
		string = '-'
	end
	htmlchild:tag('div'):addClass('vi-grid-L'):wikitext('<b>&larr; '..i18n[lang]['previous']..'</b><br />'..string):done()

	--次のバージョン
		local string = ''
	if next then
		string = '[[Elin meta:'..next..' ('..string.lower(lang)..')|'..next..']]'
		if namespaceName == 'Elin_meta' then
			utils.setPropertyData('Next',next)
		end
	else
		string = '-'
	end
	htmlchild:tag('div'):addClass('vi-grid-R'):wikitext('<b>'..i18n[lang]['next']..' &rarr;</b><br />'..string):done()

	html:wikitext('<hr class="ei-hr">')

	--更新履歴や全てのバージョンへのリンク
	html:tag('div'):wikitext(i18n[lang]['linkChangelog']..' • '..i18n[lang]['linkAllVersions']):done()
	if namespaceName == 'Elin_meta' then
		html:wikitext(i18n[lang]['category'])
	end

	if namespaceName == 'Elin_meta' and notes then
		utils.setPropertyData('Notes',notes)
	end

	return tostring(html)
end

	--navbox
function p.navbox(f)
	local args = f:getParent().args
	local lang = f.args['lang'] or utils.getDefaultIfEmpty(args['lang'], 'JA')
	local result = mw.smw.ask{
		i18n[lang]['category'],
		'?Version',
		'?VarsionType',
		'?ReleaseData',
		limit = 1000,
		mainlabel = '-'
	} or {}

	local EAtable_raw = {}
	local EApretable_raw = {}
	local Alphatable_raw = {}
	local Betatable_raw = {}

	for _, innerTable in ipairs(result) do
		if type(innerTable) == 'table' and innerTable['Version'] then
			local version = innerTable['Version']
			if string.find(version,'EA') then
				local major, minorStr = version:match('^EA (%d+).(%d+)$')
				local minor = tonumber(minorStr)
				if minor and minor >= 1 and minor <= 9 then
					table.insert(EApretable_raw, innerTable)
				else
					table.insert(EAtable_raw, innerTable)
				end
			elseif string.find(version,'α') or string.find(version,'Alpha') then
				table.insert(Alphatable_raw, innerTable)
			elseif string.find(version,'β') or string.find(version,'Beta') then
				table.insert(Betatable_raw, innerTable)
			end
		end
	end

	local sorted_EAtable = processAndSortTable(EAtable_raw, lang)
	local sorted_EApretable = processAndSortTable(EApretable_raw, lang)
	local sorted_Alphatable = processAndSortTable(Alphatable_raw, lang)
	local sorted_Betatable = processAndSortTable(Betatable_raw, lang)

	local EAwikitext = generatePrefixedLinks('EA', sorted_EAtable, lang)
	local EAprewikitext = generatePrefixedLinks('EA', sorted_EApretable, lang)
	local Alphawikitext = generatePrefixedLinks('Alpha', sorted_Alphatable, lang)
	local Betawikitext = generatePrefixedLinks('Beta', sorted_Betatable, lang)

	local html = mw.html.create('div'):addClass('navbox')
	:tag('div'):addClass('navbox-title'):wikitext(i18n[lang]['navtitleVersions']):done()

	:tag('div'):attr('id','mw-customcollapsible-section1'):addClass('mw-collapsible')
	:attr('data-expandtext','+'):attr('data-collapsetext','-')
	:tag('div'):addClass('navbox-title navbox-titlechild'):wikitext(i18n[lang]['navtitleEA']):done()
	:tag('div'):addClass('mw-collapsible-content'):addClass('navbox-contents'):wikitext(EAwikitext):done()
	:done()

	:tag('div'):attr('id','mw-customcollapsible-section2'):addClass('mw-collapsible mw-collapsed')
	:attr('data-expandtext','+'):attr('data-collapsetext','-')
	:tag('div'):addClass('navbox-title navbox-titlechild'):wikitext(i18n[lang]['navtitleEApre']):done()
	:tag('div'):addClass('mw-collapsible-content'):addClass('navbox-contents'):wikitext(EAprewikitext):done()
	:done()

	:tag('div'):attr('id','mw-customcollapsible-section3'):addClass('mw-collapsible mw-collapsed')
	:attr('data-expandtext','+'):attr('data-collapsetext','-')
	:tag('div'):addClass('navbox-title navbox-titlechild'):wikitext(i18n[lang]['navtitleAlpha']):done()
	:tag('div'):addClass('mw-collapsible-content'):addClass('navbox-contents'):wikitext(Alphawikitext):done()
	:done()

	:tag('div'):attr('id','mw-customcollapsible-section4'):addClass('mw-collapsible mw-collapsed')
	:attr('data-expandtext','+'):attr('data-collapsetext','-')
	:tag('div'):addClass('navbox-title navbox-titlechild'):wikitext(i18n[lang]['navtitleBeta']):done()
	:tag('div'):addClass('mw-collapsible-content'):addClass('navbox-contents'):wikitext(Betawikitext):done()
	:done()

	return tostring(html)
end

--バージョン一覧表
function p.table(f)
	local args = f:getParent().args
	local lang = f.args['lang'] or utils.getDefaultIfEmpty(args['lang'], 'JA')
	local result = mw.smw.ask{
		i18n[lang]['category'],
		'?Version',
		'?VarsionType',
		'?ReleaseData',
		'?Notes',
		limit = 1000,
		mainlabel = '-'
	} or {}

	local EAtable = {}
	local EApretable = {}
	local Alphatable = {}
	local Betatable = {}
	for _, innerTable in ipairs(result) do
		if type(innerTable) == 'table' and innerTable['Version'] then
			local version = innerTable['Version']
			if string.find(version,'EA') then
				local major, minorStr = version:match('^EA (%d+).(%d+)$')
				local minor = tonumber(minorStr)
				if minor >= 1 and minor <= 9 then
					table.insert(EApretable, innerTable)
				else
					table.insert(EAtable, innerTable)
				end
			elseif string.find(version,'α') or string.find(version,'Alpha') then
				table.insert(Alphatable, innerTable)
			elseif string.find(version,'β') or string.find(version,'Beta') then
				table.insert(Betatable, innerTable)
			end
		end
	end

	local sorted_EAtable = processAndSortTable(EAtable, lang)
	local sorted_EApretable = processAndSortTable(EApretable, lang)
	local sorted_Alphatable = processAndSortTable(Alphatable, lang)
	local sorted_Betatable = processAndSortTable(Betatable, lang)

	local EAwikitext = generatePrefixedTr('EA', sorted_EAtable, lang, 'true')
	local EAprewikitext = generatePrefixedTr('EA', sorted_EApretable, lang, '')
	local Alphawikitext = generatePrefixedTr('Alpha', sorted_Alphatable, lang, '')
	local Betawikitext = generatePrefixedTr('Beta', sorted_Betatable, lang, '')

	local html = mw.html.create('div')
	html:tag('h2'):wikitext(i18n[lang]['navtitleEA']):done()
	:wikitext(generatePrefixedTh(lang, 'true')):wikitext(EAwikitext..'</table>')

	html:tag('h2'):wikitext(i18n[lang]['navtitleEApre']):done()
	:wikitext(generatePrefixedTh(lang, '')):wikitext(EAprewikitext..'</table>')

	html:tag('h2'):wikitext(i18n[lang]['navtitleAlpha']):done()
	:wikitext(generatePrefixedTh(lang, '')):wikitext(Alphawikitext..'</table>')

	html:tag('h2'):wikitext(i18n[lang]['navtitleBeta']):done()
	:wikitext(generatePrefixedTh(lang, '')):wikitext(Betawikitext..'</table>')

	return tostring(html)
end




--新しいバージョンを取得する(メインページ用)
function p.newVersion(f)
	local args = f:getParent().args
	local lang = f.args['lang'] or utils.getDefaultIfEmpty(args['lang'], 'JA')
	local result = mw.smw.ask{
		i18n[lang]['category'],
		'?Version',
		'?VarsionType',
		'?ReleaseData',
		limit = 1000,
		mainlabel = '-'
	} or {}
	--ReleaseDateをtimestampにして新しいsortable_resultsテーブルにする
	local sortable_results = {}
	for _, row in ipairs(result) do
		if row.ReleaseData then
			local timestamp = parse_date(row.ReleaseData, lang)
			table.insert(sortable_results, { data = row, timestamp = timestamp })
		end
	end
	--timestamp順
	table.sort(sortable_results, function(a, b) return a.timestamp > b.timestamp end)
	--sortable_resultsテーブルの上位5を選出
	local latest_versions = {}
	local n = math.min(#sortable_results, 5)
	for i = 1, n do
		str = string.format('<li><b>[[Elin meta:%s (%s)|%s]]</b> (%s, %s)</li>',sortable_results[i].data['Version'], string.lower(lang), sortable_results[i].data['Version'], sortable_results[i].data['VarsionType'], sortable_results[i].data['ReleaseData'])
		table.insert(latest_versions, str)
	end
	--
	local var = table.concat(latest_versions,'\n')
	local html = mw.html.create('div'):addClass('main-page-content-box elin-parchment'):attr('id','main-page-recent-update')
	html:tag('h2'):addClass('ru-title'):wikitext(i18n[lang]['titleRecentupdates']):done()
	html:tag('div'):addClass('ru-contents'):wikitext(var):done()
	html:tag('div'):addClass('ru-andmore'):wikitext(i18n[lang]['linkChangelog2']):done()
	return tostring(html)
end




--更新履歴
function p.versionHistory(f)
	local args = f:getParent().args
	local lang = f.args['lang'] or utils.getDefaultIfEmpty(args['lang'], 'JA')
	local contents = args[2] or ''
	local link
	local matched_version, matched_subtitle = args[1]:match("^(.*%s%d+%.%d+)%s?(.*)$")
	local versionNumber = matched_version
	local subTitle = utils.nilCheck(matched_subtitle)
	if subTitle then
		link = string.format('[[Elin meta:%s (%s)#%s|%s %s]]',versionNumber, string.lower(lang), subTitle, versionNumber, subTitle)
	else
		link = string.format('[[Elin meta:%s (%s)|%s]]',versionNumber, string.lower(lang), versionNumber)
	end

	local category
	if args[i18n[lang]['Introduced']] then
		if namespaceName == 'Elin_meta' then
			category = '[[Category:'..versionNumber..' '..i18n[lang]['Introduced']..']]'
		end
		if contents == '' then
			contents = i18n[lang]['Introduced2']
		else
			contents = contents..'<ul><li>'..i18n[lang]['Introduced2']..'</li></ul>'
		end
	elseif namespaceName == 'Elin_meta' then
		category = '[[Category:'..versionNumber..' '..i18n[lang]['Revision']..']]'
	end
	local html = mw.html.create('ul')
	if string.find(contents, "<li") then
		html:wikitext(string.format('<li><b>%s : </b></li>%s',link, contents))
	else
		html:wikitext(string.format('<li><b>%s : </b>%s</li>',link, contents))
	end
	
	return tostring(html), category
end

return p