Module:Film song/sandbox

require('strict')

-- Module:Film_song
local p = {}

local getArgs = require('Module:Arguments').getArgs
local error_message = require('Module:Error')['error']

local function getEditionNumber(QID)
	if not QID then
		return nil
	end
	
	local editionNumber = mw.wikibase.getEntity(QID):getBestStatements('P393')[1]
	if editionNumber then
		return editionNumber.mainsnak.datavalue.value
	else
		return nil
	end
end

local function getWorkItem(QID)
	-- Fetch the entity data for the given QID
	local entity = mw.wikibase.getEntity(QID)
	if not entity then
		return nil, 'No entity found for ' .. QID
	end
	
	-- Access the 'recording or performance of' property (P629) directly
	local recordingOrPerformance = entity.claims['P2550']
	if not recordingOrPerformance or #recordingOrPerformance == 0 then
		recordingOrPerformance = entity.claims['P629']
	end
	if not recordingOrPerformance or #recordingOrPerformance == 0 then
		return nil, 'No "edition or translation of" or "recording or performance of" property found for ' .. QID
	end
	
	-- Extract the QID of the work item
	local workQID = recordingOrPerformance[1].mainsnak.datavalue.value.id
	if not workQID then
		return nil, 'No work QID found for ' .. QID
	end
	
	return workQID
end

local function getVersionItemLabel(args)
	local QID = args[1]
	local template = args[2] or "" -- Added to handle different situations
	
	if not QID then
		return error_message('Error: No Wikidata item specified')
	end
	
	local versionItemLabel = mw.wikibase.getLabel(QID)
	if not versionItemLabel or versionItemLabel == '' then
		versionItemLabel = 'Item ' .. QID -- Fallback text if no label is found
	end
	
	-- Check for edition number and append to the label if necessary
	if template == "anchor" then
		local editionNumber = getEditionNumber(QID)
		if editionNumber then
			versionItemLabel = mw.uri.anchorEncode(versionItemLabel .. "_rendition_" .. editionNumber)
		end
	end
	
	return versionItemLabel
end

local function getLink(args)
	local QID = args[1]
	local template = args[2] or "" -- Assign default value within the function

	if not QID then
		return error_message({'[[Module:Film song]] error: no Wikidata item specified'})
	end
	
	local workQID, err = getWorkItem(QID)
	if err then
		return err
	end
	
	local versionItemLabel = getVersionItemLabel(args)
	local editionNumber = getEditionNumber(QID)
	local versionItemNonTemplateLabel = "" -- for later logic
	
	if editionNumber and not template then
		versionItemLabel = versionItemLabel .. " (rendition " .. editionNumber .. ")"
	end

	if template ~= "" then
		local versionItemAnchor = versionItemLabel:gsub(" ", "_")
		local pageTitle = mw.title.getCurrentTitle().text
		if editionNumber then
			versionItemAnchor = mw.uri.anchorEncode(versionItemAnchor .. "_rendition_" .. editionNumber)
			versionItemLabel = versionItemLabel .. " (rendition " .. editionNumber .. ")"
		end
		return mw.ustring.format('[[%s#%s|%s]]', pageTitle, versionItemAnchor, versionItemLabel)
	-- else
	-- 	if versionItemNonTemplateLabel then
	-- 		versionItemLabel = versionItemNonTemplateLabel
	-- 	end
	end

	local sitelink = mw.wikibase.getSitelink(workQID, 'enwikisource')
	if not sitelink then
		return versionItemLabel
	end
	
	return mw.ustring.format('[[%s|%s]]', sitelink, versionItemLabel)
end

function p._film_song_link(args)
	if not args[1] then
		return error_message({'[[Module:Film song]] error: no Wikidata item specified'})
	end
	
	local link = mw.html.create('div'):addClass('wst-film-song-link')
		:attr('id', getVersionItemLabel({args[1], 'anchor'}))
		:wikitext('Song: "' .. getLink({args[1]}) .. '" ([[File:Wikidata-logo.svg|15px|link=d:' .. args[1] .. ']])')
		:allDone()
	
	return link
end

function p._film_song_link_table(args)
	if not args[1] then
		return error_message({'[[Module:Film song]] error: no Wikidata item specified'})
	end
	return '"' .. getLink({args[1], 'table'}) .. '" ([[File:Wikidata-logo.svg|15px|link=d:' .. args[1] .. ']])'
end

-- Function to check if a page exists
local function pageExists(title)
	return mw.title.new(title).exists
end

-- Function to generate the list of songs
function p._film_song_list(args)
	local currentPageQID = args[1] or mw.wikibase.getEntityIdForCurrentPage()
	-- Get the current page's title and check if the Hour 0 subpage exists
	local currentTitle = mw.title.getCurrentTitle()
	local basePageTitle = currentTitle.baseText -- Extract base page title
	local hour0SubpageTitle = basePageTitle .. '/Hour 0'

	if pageExists(hour0SubpageTitle) then
		-- Do not show the table if the Hour 0 subpage exists
		return ''
	end

	-- Check if entity is nil or if entity does not have claims
	-- (if this is the case this should be fixed on Wikidata, but shouldn't cause a public error on Wikisource)
	if not currentPageQID then
		return ''
	end

	local entity = mw.wikibase.getEntity(currentPageQID)
	-- Check if entity exists and has the 'has part(s)' property (P527)
	if not entity or not entity.claims or not entity.claims['P527'] then
		return ''
	end

	local parts = entity.claims['P527']
	local list = {}

	for _, part in ipairs(parts) do
		local partQID = part.mainsnak.datavalue.value.id
		
		-- Expand the 'film song link table' template for each song part
		local songLinkTable = p._film_song_link_table({partQID})
		
		local performers = {}
		local partEntity = mw.wikibase.getEntity(partQID)
		if partEntity and partEntity.claims['P175'] then
			for _, claim in ipairs(partEntity.claims['P175']) do
				local performerQID = claim.mainsnak.datavalue.value.id
				local performerPage = performerQID and mw.wikibase.getSitelink(performerQID, 'enwikisource') or nil
				local performerName = mw.text.trim(performerPage and mw.ustring.gsub(performerPage, "Author:", "") or "Unknown")
				local performerLink = (performerPage and '[[Author:' .. performerName .. '|' .. performerName .. ']]') or 'Unknown'
				table.insert(performers, performerLink)
			end
		end
		local performerLinks = #performers > 0 and table.concat(performers, ', ') or "Unknown"
		
		-- Construct the table row with the expanded template and performer links
		table.insert(list, mw.html.create('tr')
			:tag('td')
				:wikitext(songLinkTable)
				:done()
			:tag('td')
				:wikitext(performerLinks)
				:allDone()
		)
		
	end
	
	if #list == 0 then
		return nil
	end
	
	local list_table = mw.html.create('table')
		:addClass('wikitable wst-film-song-list')
		:tag('tr')
			:tag('th')
				:wikitext('Song')
				:done()
			:tag('th')
				:wikitext('Performer')
				:wikitext('[[Category:' .. 'Sound films containing lyrical music' .. ']]')
				:allDone()
	
	for i, tr in ipairs(list) do
		list_table:node(tr)
	end
	return list_table
end

-- frame functions

function p.film_song_link(frame)
	return p._film_song_link(getArgs(frame))
end

function p.film_song_link_table(frame)
	return p._film_song_link_table(getArgs(frame))
end

function p.film_song_list(frame)
	return p._film_song_list(getArgs(frame))
end

return p
Category:Module sandboxes