Module:Availability: Difference between revisions

From SPCodex, The Smashing Pumpkins wiki
(fix issue with grouping by date)
No edit summary
Line 1: Line 1:
local p = {}
local p = {}
local cargo = mw.ext.cargo


local function pairsByKeys (t, f)
local function pairsByKeys (t, f)
Line 17: Line 18:
local function dateFormat(str, precision)
local function dateFormat(str, precision)
if precision == '2' then
if precision == '2' then
return string.sub(str, 0, -3) .. 'xx'
return string.sub(str, 0, -3) .. 'XX'
elseif precision == '3' then
elseif precision == '3' then
return string.sub(str, 0, -6) .. 'xx-xx'
return string.sub(str, 0, -6) .. 'XX-XX'
else
else
return str
return str
Line 46: Line 47:


function p._main(song)
function p._main(song)
local cargo = mw.ext.cargo
local albums = cargo.query(
local albums = cargo.query(
'track_listings, albums, releases',
'track_listings, albums, releases',
Line 87: Line 87:
local root = mw.html.create()
local root = mw.html.create()
local tableRoot = root:tag('table')
local tableRoot = root:tag('table')
tableRoot:addClass('mw-datatable sortable jquery-tablesorter')
tableRoot:addClass('wikitable sortable')
local headerRow = tableRoot:tag('tr')
local headerRow = tableRoot:tag('tr')
headerRow:tag('th')
headerRow:tag('th')
Line 127: Line 127:
local song = frame.args[1]
local song = frame.args[1]
return p._main(song)
return p._main(song)
end
function p._tour_history(song)
local root = mw.html.create()
local counts = cargo.query(
'live_songs, shows',
"COUNT(DISTINCT live_songs._pageName)=Count, shows.artist=Artist",
{
where = 'live_songs.name = "' .. song .. '"',
join = 'live_songs._pageName = shows._pageName',
groupBy = 'shows.artist',
orderBy = 'Count DESC'
}
)
if next(counts) == nil then
return ''
end
local statsRoot = root:tag('table')
statsRoot:addClass('wikitable')
local totalsRow = statsRoot:tag('tr')
totalsRow:tag('th'):wikitext('Total plays')
local total_plays = 0
local total_plays_artists = {}
if #counts == 1 then
total_plays = counts[1]['Count']
else
total_plays_str = '('
for r = 1, #counts do
total_plays = total_plays + counts[r]['Count']
table.insert(total_plays_artists, '[[' .. counts[r]['Artist'] .. ']]: ' .. counts[r]['Count'])
end
end
local totalsTd = totalsRow:tag('td')
totalsTd:tag('b'):wikitext(total_plays)
if next(totalsTd) ~= nil then
totalsTd:wikitext(' (' .. table.concat(total_plays_artists, ', ') .. ')')
end
local firstShow = cargo.query(
'live_songs, shows',
'shows._pageName, shows.artist, shows.featuring_artist, shows.date, shows.venue, shows.location, live_songs.tease, live_songs.abandoned',
{
where = 'name = "' .. song .. '" AND soundcheck = 0',
join = 'live_songs._pageName = shows._pageName',
groupBy = '_pageName',
orderBy = 'date ASC',
limit = 1
}
)[1]
local lastShow = cargo.query(
'live_songs, shows',
'shows._pageName, shows.artist, shows.featuring_artist, shows.date, shows.venue, shows.location, live_songs.tease, live_songs.abandoned',
{
where = 'name = "' .. song .. '" AND soundcheck = 0',
join = 'live_songs._pageName = shows._pageName',
groupBy = '_pageName',
orderBy = 'date DESC',
limit = 1
}
)[1]
local firstShowRow = statsRoot:tag('tr')
firstShowRow:tag('th'):wikitext('First performance')
mw.logObject(firstShow)
local firstShowStr = '[[' .. firstShow['shows._pageName'] .. ']]'
if firstShow['featuring_artist'] then
firstShowStr = firstShowStr .. '(featuring [[' .. firstShow['featuring_artist'] .. ']]) '
end
if firstShow['tease'] == '1' then
firstShowStr = firstShowStr .. '(tease) '
end
if firstShow['abandoned'] == '1' then
firstShowStr = firstShowStr .. '(abandoned) '
end
firstShowRow:tag('td'):wikitext(firstShowStr)
--- [[[First full performance (if it was teased or abandoned, e.g. [[Sunshine of Your Love"]]) ---
return '== Tour stats ==\n' .. tostring(root)
end
end


return p
return p

Revision as of 19:12, 13 October 2020

This module implements the {{availability}} template, which is placed on every song page. This generates the "Availability" and "Tour stats" sections, as applicable.


local p = {}
local cargo = mw.ext.cargo

local function pairsByKeys (t, f)
	local a = {}
	for n in pairs(t) do table.insert(a, n) end
	table.sort(a, f)
	local i = 0      -- iterator variable
	local iter = function ()   -- iterator function
		i = i + 1
		if a[i] == nil then return nil
		else return a[i], t[a[i]]
		end
	end
	return iter
end

local function dateFormat(str, precision)
	if precision == '2' then
		return string.sub(str, 0, -3) .. 'XX'
	elseif precision == '3' then
		return string.sub(str, 0, -6) .. 'XX-XX'
	else
		return str
	end
end

local function typeFormat(str)
	local ret = ''

	for t in string.gmatch(str, "[^,]+") do
		if t == 'ep' then
			t = 'EP'
		else
			t = t:gsub("^%l", string.upper)
		end

		ret = ret .. t .. ' • '
	end
	
	if string.sub(ret, -8) == ' • ' then
		ret = string.sub(ret, 0, -9)
	end

	return ret
end

function p._main(song)
	local albums = cargo.query(
		'track_listings, albums, releases',
		"track_listings._pageName=title, releases.release_date=date, release_date__precision=precision, albums.type=type, track_listings.listing_id=listing_id, headline",
		{
			where = "releases.release_date != '' AND song_page_title = \"" .. song .. '"',
			join = 'track_listings._pageName=albums._pageName,albums.name=releases._pageName',
			groupBy = 'track_listings.work',
			orderBy = 'releases.release_date ASC'
		}
	)
	local songs = cargo.query(
		'track_listings, songs, releases',
		"track_listings._pageName=title, releases.release_date=date, release_date__precision=precision, songs.type=type, track_listings.listing_id=listing_id, headline",
		{
			where = "releases.release_date != '' AND song_page_title = \"" .. song .. '"',
			join = 'track_listings._pageName=songs._pageName,songs.name=releases.work',
			groupBy = 'track_listings.work',
			orderBy = 'releases.release_date ASC'
		}
	)

	local releasesByDate = {}
	local has_headline = false

	for r = 1, #songs do
		releasesByDate[songs[r]['date'] .. r] = songs[r]
		if songs[r]['headline'] ~= '' then
			has_headline = true
		end
	end
	for r = 1, #albums do
		releasesByDate[albums[r]['date'] .. r] = albums[r]
		if albums[r]['headline'] ~= '' then
			has_headline = true
		end
	end

	local has_result = false
	local root = mw.html.create()
	local tableRoot = root:tag('table')
	tableRoot:addClass('wikitable sortable')
	local headerRow = tableRoot:tag('tr')
	headerRow:tag('th')
		:addClass('headerSort')
		:wikitext('Title')
	
	if has_headline then
		headerRow:tag('th')
			:wikitext('Notes')
	end
	-- headerRow:tag('th')
	-- 	:addClass('headerSort')
	-- 	:wikitext('Release date')
	headerRow:tag('th')
		:addClass('headerSort')
		:wikitext('Type')

	for _date, release in pairsByKeys(releasesByDate) do
		has_result = true
		local row = tableRoot:tag('tr')
		row:tag('td'):wikitext('[[' .. release['title'] .. '#track-listing-' .. release['listing_id'] .. '|' .. release['title'] .. ']]')

		if has_headline then
			row:tag('td'):wikitext(release['headline'])
		end

		-- row:tag('td'):wikitext(dateFormat(release['date'], release['precision']))
		row:tag('td'):wikitext(typeFormat(release['type']))
	end

	if has_result then
		return '== Availability ==\n' .. tostring(root)
	end

	return '[[Category:Songs with no availability]]'
end

function p.main(frame)
	local song = frame.args[1]
	return p._main(song)
end

function p._tour_history(song)
	local root = mw.html.create()

	local counts = cargo.query(
		'live_songs, shows',
		"COUNT(DISTINCT live_songs._pageName)=Count, shows.artist=Artist",
		{
			where = 'live_songs.name = "' .. song .. '"',
			join = 'live_songs._pageName = shows._pageName',
			groupBy = 'shows.artist',
			orderBy = 'Count DESC'
		}
	)

	if next(counts) == nil then
		return ''
	end

	local statsRoot = root:tag('table')
	statsRoot:addClass('wikitable')
	local totalsRow = statsRoot:tag('tr')
	totalsRow:tag('th'):wikitext('Total plays')

	local total_plays = 0
	local total_plays_artists = {}
	if #counts == 1 then
		total_plays = counts[1]['Count']
	else
		total_plays_str = '('
		for r = 1, #counts do
			total_plays = total_plays + counts[r]['Count']
			table.insert(total_plays_artists, '[[' .. counts[r]['Artist'] .. ']]: ' .. counts[r]['Count'])
		end
	end

	local totalsTd = totalsRow:tag('td')
	totalsTd:tag('b'):wikitext(total_plays)
	if next(totalsTd) ~= nil then
		totalsTd:wikitext(' (' .. table.concat(total_plays_artists, ', ') .. ')')
	end

	local firstShow = cargo.query(
		'live_songs, shows',
		'shows._pageName, shows.artist, shows.featuring_artist, shows.date, shows.venue, shows.location, live_songs.tease, live_songs.abandoned',
		{
			where = 'name = "' .. song .. '" AND soundcheck = 0',
			join = 'live_songs._pageName = shows._pageName',
			groupBy = '_pageName',
			orderBy = 'date ASC',
			limit = 1
		}
	)[1]
	local lastShow = cargo.query(
		'live_songs, shows',
		'shows._pageName, shows.artist, shows.featuring_artist, shows.date, shows.venue, shows.location, live_songs.tease, live_songs.abandoned',
		{
			where = 'name = "' .. song .. '" AND soundcheck = 0',
			join = 'live_songs._pageName = shows._pageName',
			groupBy = '_pageName',
			orderBy = 'date DESC',
			limit = 1
		}
	)[1]

	local firstShowRow = statsRoot:tag('tr')
	firstShowRow:tag('th'):wikitext('First performance')
	mw.logObject(firstShow)
	local firstShowStr = '[[' .. firstShow['shows._pageName'] .. ']]'
	if firstShow['featuring_artist'] then
		firstShowStr = firstShowStr .. '(featuring [[' .. firstShow['featuring_artist'] .. ']]) '
	end
	if firstShow['tease'] == '1' then
		firstShowStr = firstShowStr .. '(tease) '
	end
	if firstShow['abandoned'] == '1' then
		firstShowStr = firstShowStr .. '(abandoned) '
	end
	firstShowRow:tag('td'):wikitext(firstShowStr)

	--- [[[First full performance (if it was teased or abandoned, e.g. [[Sunshine of Your Love"]]) ---

	return '== Tour stats ==\n' .. tostring(root)
end

return p