Module:Card datatable: Difference between revisions

From Sekaipedia
Content added Content deleted
mNo edit summary
mNo edit summary
Line 611: Line 611:
if args['test'] then
if args['test'] then
ab:setPlainlistOptions('Card datatable header', 'Card datatable row', nil)
ab:setPlainlistOptions('Card datatable header', 'Card datatable row', nil)
return '<table class="wikitable">' .. ab:ask(frame) .. '</table>'
else
else
ab:setPlainlistOptions(nil, 'Card datatable row', nil)
ab:setPlainlistOptions(nil, 'Card datatable row', nil)
return '<table class="wikitable">' .. p.header(frame) .. ab:ask(frame) .. '</table>'
end
end
return '<table class="wikitable">' .. p.header(frame) .. ab:ask(frame) .. '</table>'
end
end



Revision as of 18:36, 16 April 2023

local getArgs          = require('Module:Arguments').getArgs
local AskBuilder       = require('Module:AskBuilder')
local DatatableBuilder = require('Module:DatatableBuilder')
local QueryBuilder     = require('Module:QueryBuilder')
local Yesno            = require('Module:Yesno')

local DisplayFns    = require('Module:DisplayFunctions')
local ProcessingFns = require('Module:ProcessingFunctions')

local aicon = require('Module:Attribute icon')._main
local cicon = require('Module:Character icon')._main
local ricon = require('Module:Rarity icon')._main
local uicon = require('Module:Unit icon')._main

local p = {}

local DisplayType = {
	text = 'TEXT',
	icon = 'ICON',
	both = 'BOTH'
}

local function formatName(cardPage, cardName)
	return string.format('[[%s|%s]]', cardPage, cardName)
end

local function formatAttribute(attribute)
	if attribute == nil or attribute == '' then return nil end
	
	return string.format(
		'%s %s',
		aicon({ attribute, size = '25px' }),
		attribute
	)
end

local function formatCharacter(character)
	if character == nil or character == '' then return nil end
	
	return string.format(
		'%s %s',
		cicon({ character, size = '25px' }),
		character
	)
end

local function formatUnit(unit)
	if unit == nil or unit == '' then return nil end
		
	return string.format(
		'%s %s',
		uicon({ unit, size = '25px' }),
		unit
	)
end

local function formatRarity(rarity)
	if rarity == nil or rarity == '' then return nil end 
	
	return ricon({ rarity, size='25px' })
end

local function formatAcquire(acquire)
	local acquireArr = ProcessingFns.stringToArray(',')(acquire)
	return DisplayFns.list('unbulleted')(acquireArr)
end

local function formatLink(page, name)
	if page and name then
		return string.format('[[%s|%s]]', page, name)
	end
	
	return nil
end

local function formatIfPretty(pretty, fn)
	if pretty == true then
		return fn
	end
	
	return nil
end

local function columnToProperty(column)
	local map = {
		['id'] = 'Card ID',
		['character'] = 'Character',
		['unit'] = 'Unit',
		['support unit'] = 'Support unit',
		['attribute'] = 'Attribute',
		['rarity'] = 'Rarity',
		['date'] = 'Release date',
		['status'] = 'Card status'
	}
	
	return map[column]
end

local function isColumn(arg)
	local columns = {
		'__page',
		'id',
		'character',
		'unit',
		'support unit',
		'attribute',
		'rarity',
		'date',
		'status'
	}
	
	for _,column in ipairs(columns) do
		if column == arg then
			return true
		end	
	end
	
	return false
end


function p.main(frame)
	local args = getArgs(frame)
	
	local columns = args['columns']	
	local isPretty = Yesno(args['pretty'])
	local displayType = DisplayType[args['display type']] or DisplayType.text
	
	local qb = QueryBuilder.new()
	qb
		:setTables('Cards, card_skills, gachas, Costumes')
		:setFields([[
			Cards._pageName = cardPageName,
			Cards.card_id,
			Cards.card_name,
			Cards.thumbnail,
			Cards.card_character,
			Cards.unit,
			Cards.support_unit,
			Cards.attribute,
			Cards.rarity,
			Cards.date,
			Cards.status,
			Cards.obtain,
			Cards.event,
			Cards.banner,
			card_skills.skill_type,
			gachas._pageName = gachaPageName,
			gachas.gacha_id,
			gachas.gacha_name,
			Costumes._pageName = costumePageName,
			Costumes.costume_name,
		]])
		:setJoinOn([[
			Cards._pageID = card_skills._pageID,
			Cards.banner = gachas._pageName,
			Cards._pageName = Costumes.card
		]])
		:addWhere('card_id', '>', 0)
		:setOrderBy('Cards.card_id ASC')
		:setGroupBy('Cards._pageID, Costumes._pageID')
		:setLimit(args['limit'] or 500)
		:setOffset(args['offset'])
	qb
		:addWhereList(
			'Cards.card_id',
			'=',
			args['card ids'],
			',',
			'OR'
		)
		:addWhereList(
			'Cards.card_character',
			'=',
			args['characters'],
			',',
			'OR'
		)
		:addWhereList(
			'Cards.unit',
			'=',
			args['units'],
			';',
			'OR'
		)
		:addWhereList(
			'Cards.support_unit',
			'=',
			args['support units'],
			';',
			'OR'
		)
		:addWhereList(
			'Cards.attribute',
			'=',
			args['attributes'],
			',',
			'OR'
		)
		:addWhereList(
			'Cards.rarity',
			'=',
			args['rarities'],
			',',
			'OR'
		)
		:addWhere('Cards.date', '>=', args['released after'])
		:addWhere('Cards.date', '<=', args['released before'])
		:addWhereList(
			'Cards.status',
			'=',
			args['statuses'],
			',',
			'OR'
		)
		:addWhereList(
			'Cards.obtain',
			'HOLDS',
			args['acquire'],
			',',
			'OR'
		)
		:addWhereList(
			'card_skills.skill_type',
			'=',
			args['skills'],
			';',
			'OR'
		)
		:addWhereList(
			'Cards.event',
			'=',
			args['events'],
			';',
			'OR'
		)

	local datatable = DatatableBuilder.new()
	datatable
		:setColumns{
			{
				name = 'id',
				header = 'ID',
				dataFields = { 'Cards.card_id' },
				visible = false
			},
			{
				name = 'thumbnail',
				header = 'Thumbnail',
				dataFields = { 'Cards.thumbnail' },
				fn = DisplayFns.image('64px'),
				sortable = false
			},
			{
				name = 'name',
				header = 'Card name',
				dataFields = { 'cardPageName', 'Cards.card_name' },
				css = { ['width'] = '30em' },
				fn = formatName
			},
			{
				name = 'character',
				header = 'Character',
				dataFields = { 'Cards.card_character' },
				fn = formatIfPretty(isPretty, formatCharacter),
				visible = false
			},
			{
				name = 'unit',
				header = 'Unit',
				dataFields = { 'Cards.unit' },
				fn = formatIfPretty(isPretty, formatUnit),
				visible = false
			},
			{
				name = 'support unit',
				header = 'Support unit',
				dataFields = { 'Cards.support_unit' },
				fn = formatIfPretty(isPretty, formatUnit),
				default = '',
				visible = false
			},
			{
				name = 'attribute',
				header = 'Attribute',
				dataFields = { 'Cards.attribute' },
				fn = formatIfPretty(isPretty, formatAttribute),
				css = { ['min-width'] = 'calc(25px + 6em)' },
				visible = false
			},
			{
				name = 'rarity',
				header = 'Rarity',
				dataFields = { 'Cards.rarity' },
				fn = formatIfPretty(isPretty, formatRarity),
				visible = false
			},
			{
				name = 'date',
				header = 'Release date',
				dataFields = { 'Cards.date' },
				visible = false
			},
			{
				name = 'status',
				header = 'Status',
				dataFields = { 'Cards.status' },
				visible = false
			},
			{
				name = 'skill',
				header = 'Skill',
				dataFields = { 'card_skills.skill_type' },
				css = { ['min-width'] = '5em' },
				visible = false
			},
			{
				name = 'acquire',
				header = 'Acquisition method(s)',
				dataFields = { 'Cards.obtain' },
				fn = formatAcquire,
				visible = false
			},
			{
				name = 'event',
				header = 'Associated event',
				dataFields = { 'Cards.event' },
				default = '',
				visible = false
			},
			{
				name = 'gacha',
				header = 'Debut gacha',
				dataFields = { 'gachaPageName', 'gachas.gacha_name' },
				fn = formatLink,
				default = '',
				visible = false
			},
			{
				name = 'costume',
				header = 'Costume',
				dataFields = { 'costumePageName', 'Costumes.costume_name' },
				fn = formatLink,
				default = '',
				visible = false
			}
		}
		:setData({})
	
	columns = ProcessingFns.stringToArray(',')(columns)
	if columns and #columns > 0 then
		for _, column in ipairs(columns) do
			datatable:setColumnVisibility(column, true)
		end
	end
	
	return datatable:tostring() .. 
	'<p>Data table has been disabled, see our [https://blog.sekaipedia.org/2023/04/unexpected-disruption-due-to-extension.html first] and [https://blog.sekaipedia.org/2023/04/acknowledgements-on-continued-wiki.html second] blog posts for more details.</p>'
	..
	'<p>Consider using [[:Category:Cards]] instead.</p>'
end

local function defineDatatable(columns, isPretty)
	local datatable = DatatableBuilder.new()
	datatable
		:setColumns{
			{
				name = 'id',
				header = 'ID',
				dataFields = { 'id' },
				visible = false
			},
			{
				name = 'thumbnail',
				header = 'Thumbnail',
				dataFields = { 'thumbnail' },
				fn = DisplayFns.image('64px'),
				sortable = false
			},
			{
				name = '__page',
				header = 'Card name',
				dataFields = { '__page', 'card name' },
				css = { ['width'] = '30em' },
				fn = formatName
			},
			{
				name = 'character',
				header = 'Character',
				dataFields = { 'character' },
				fn = formatIfPretty(isPretty, formatCharacter),
				visible = false
			},
			{
				name = 'unit',
				header = 'Unit',
				dataFields = { 'unit' },
				fn = formatIfPretty(isPretty, formatUnit),
				visible = false
			},
			{
				name = 'support unit',
				header = 'Support unit',
				dataFields = { 'support unit' },
				fn = formatIfPretty(isPretty, formatUnit),
				default = '',
				visible = false
			},
			{
				name = 'attribute',
				header = 'Attribute',
				dataFields = { 'attribute' },
				fn = formatIfPretty(isPretty, formatAttribute),
				css = { ['min-width'] = 'calc(25px + 6em)' },
				visible = false
			},
			{
				name = 'rarity',
				header = 'Rarity',
				dataFields = { 'rarity' },
				fn = formatIfPretty(isPretty, formatRarity),
				visible = false
			},
			{
				name = 'date',
				header = 'Release date',
				dataFields = { 'date' },
				visible = false
			},
			{
				name = 'status',
				header = 'Status',
				dataFields = { 'status' },
				visible = false
			},
			{
				name = 'skill',
				header = 'Skill',
				dataFields = { 'skill' },
				css = { ['min-width'] = '5em' },
				visible = false
			},
			{
				name = 'Acquisition method',
				header = 'Acquisition method(s)',
				dataFields = { 'Acquisition method' },
				fn = formatAcquire,
				visible = false
			},
			-- {
			-- 	name = 'event',
			-- 	header = 'Associated event',
			-- 	dataFields = { 'Cards.event' },
			-- 	default = '',
			-- 	visible = false
			-- },
			-- {
			-- 	name = 'gacha',
			-- 	header = 'Debut gacha',
			-- 	dataFields = { 'gachaPageName', 'gachas.gacha_name' },
			-- 	fn = formatLink,
			-- 	default = '',
			-- 	visible = false
			-- },
			-- {
			-- 	name = 'costume',
			-- 	header = 'Costume',
			-- 	dataFields = { 'costumePageName', 'Costumes.costume_name' },
			-- 	fn = formatLink,
			-- 	default = '',
			-- 	visible = false
			-- }
		}
	
	if columns and #columns > 0 then
		for _, column in ipairs(columns) do
			datatable:setColumnVisibility(column, true)
		end
	end
	
	return datatable
end

function p.header(frame)
	local args = getArgs(frame)
	
	local columns = args['columns']
	
	columns = ProcessingFns.stringToArray(',')(columns)
	for column,_ in pairs(args) do
		if isColumn(column) then
			table.insert(columns, column)
		end
	end
	
	local datatable = defineDatatable(columns, true)
	
	return mw.text.jsonEncode(args) .. tostring(datatable:renderHeader())
end

function p.row(frame)
	local args = getArgs(frame)
	
	local columns = {}
	
	for column,_ in pairs(args) do
		if isColumn(column) then
			table.insert(columns, column)
		end
	end
	
	local datatable = defineDatatable(columns, true)
	return tostring(datatable:renderRow(args))
end


function p.smw(frame)
	local args = getArgs(frame)
	local columns = args['columns']
	columns = ProcessingFns.stringToArray(',')(columns)
	local properties = {
		'=__page',
		'Display name=card name',
		'Card thumbnail=thumbnail'
	}
	for _,column in ipairs(columns) do
		local property = columnToProperty(column)
		if property then
			table.insert(
				properties,
				string.format('%s=%s', property, column)
			)
		end
	end
	
	local ab = AskBuilder.new()
	ab
		:setCategory('Cards')
		:setProperties(table.concat(properties, ','))
		:addWhere('Card ID', '>', 0)
		:setOrderBy('Card ID', 'ASC')
		:setLimit(args['limit'] or 700)
		:setOffset(args['offset'])
	ab
		:addWhereList(
			'Card ID',
			'=',
			args['card ids'],
			',',
			'OR'
		)
		:addWhereList(
			'Character',
			'=',
			args['characters'],
			',',
			'OR'
		)
		:addWhereList(
			'Unit',
			'=',
			args['units'],
			';',
			'OR'
		)
		:addWhereList(
			'Support unit',
			'=',
			args['support units'],
			';',
			'OR'
		)
		:addWhereList(
			'Attribute',
			'=',
			args['attributes'],
			',',
			'OR'
		)
		:addWhereList(
			'Rarity',
			'=',
			args['rarities'],
			',',
			'OR'
		)
		:addWhere('Release date', '>=', args['released after'])
		:addWhere('Release date', '<=', args['released before'])
		:addWhereList(
			'Card status',
			'=',
			args['statuses'],
			',',
			'OR'
		)
		:addWhereList(
			'Acquisition method',
			'HOLDS',
			args['acquire'],
			',',
			'OR'
		)
		:addWhereList(
			'Skill',
			'=',
			args['skills'],
			';',
			'OR'
		)
	
	if args['test'] then
		ab:setPlainlistOptions('Card datatable header', 'Card datatable row', nil)
		return '<table class="wikitable">' .. ab:ask(frame) .. '</table>'
	else
		ab:setPlainlistOptions(nil, 'Card datatable row', nil)
		return '<table class="wikitable">' .. p.header(frame) .. ab:ask(frame) .. '</table>'
	end
	
end

return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.