Module:Infobox Media

From the Tesseract Wiki, the wiki for all things Marvel Cinematic Universe
Jump to navigation Jump to search

Documentation for this module may be created at Module:Infobox Media/doc

--------------------------
-- Module for [[Template:Infobox Media]]
--------------------------
local p = {}

-- "imports"
local onmain = require('Module:Mainonly').on_main
local yesno = require('Module:Yesno')
local paramtest = require('Module:Paramtest')
local infobox = require('Module:Infobox')
local cleanimg = require('Module:Clean image').clean

local media_type = {
	video = { text = 'Video', category = 'Videos' },
	stream = { text = 'Livestream', category = 'Livestreams' },
	podcast = { text = 'Podcast', category = 'Podcasts' }
}

function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)

	ret:defineParams{
		{ name = 'name', func = 'name' },
		{ name = 'image', func = imgarg },
		{ name = 'uploader', func = 'has_content' },
		{ name = 'date', func = 'has_content' },
		{ name = 'type', func = 'has_content' },
		{ name = 'type_link',  func = { name = lookuparg, params = { media_type, 'type', 'text' }, flag = { 'r', 'd', 'r' } } },
		{ name = 'participants', func = 'has_content' },
		{ name = 'duration', func = 'has_content' },
		{ name = 'youtube', func = 'has_content' },
		{ name = 'youtube_link', func = { name = youtube, params = { 'youtube' }, flag = 'd' } },
		{ name = 'twitch', func = 'has_content' },
		{ name = 'twitch_link', func = { name = twitch, params = { 'twitch' }, flag = 'd' } },
		{ name = 'file', func = { name = file, params = { 'file' }, flag = 'd' } },
		{ name = 'SMWarg', func = { name = SMWarg, params = {
				'name', 'image', 'date', 'type', 'participants', 'duration', 'twitch', 'youtube', 'file'
			}, flag = 'd' } }
	}

	ret:useSMWOne({
		SMWarg = 'Media JSON',
	})

	ret:setMaxButtons(4)	
	ret:create()
	ret:cleanParams()
	ret:customButtonPlacement(true)
	
	ret:defineLinks({ links = {{ 'Template:%s', 'Infobox' },
		{ 'Template_talk:%s', 'Talk page' }}, colspan = '2' })

	ret:defineName('Infobox Media')
	ret:addClass('tsw-infobox plainlinks')

	ret:addButtonsCaption()
	
	-- PARAMETER: image
	if args['type'] == 'video' or args['type'] == 'stream' then
		ret:addRow{
			{ tag = 'argd', content = 'image', class = 'infobox-image infobox-full-width-content', colspan = '2' }
		}
	end

	-- PARAMETER: name
	ret:addRow{
		{ tag = 'argh', content = 'name', class='infobox-header', colspan = '2' }
	}

	-- PARAMETER: uploader
	ret:addRow{
		{ tag = 'th', content = 'Uploader' },
		{ tag = 'argd', content = 'uploader' }
	}
	
	-- PARAMETER: date
	ret:addRow{
		{ tag = 'th', content = 'Publish date' },
		{ tag = 'argd', content = 'date' }
	}
	
	-- PARAMETER: type
	ret:addRow{
		{ tag = 'th', content = 'Type' },
		{ tag = 'argd', content = 'type_link' }
	}
	
	ret:addRow{
		{ tag = 'th', content = 'Details', class='infobox-subheader', colspan = '2' }
	}
	
	-- PARAMETER: participants
	if ret:paramDefined('participants') then
		ret:addRow{
			{ tag = 'th', content = 'Participants' },
			{ tag = 'argd', content = 'participants' }
		}
	end
	
	-- PARAMETER: duration
	ret:addRow{
		{ tag = 'th', content = 'Duration' },
		{ tag = 'argd', content = 'duration' }
	}
	
	ret:addRow{
		{ tag = 'th', content = 'Media', class='infobox-subheader', colspan = '2' }
	}

	-- PARAMETER: youtube
	if ret:paramDefined('youtube') then
		ret:addRow{
			{ tag = 'argd', content = 'youtube_link', class = 'infobox-image', colspan = '2',
				css = { ['text-align'] = 'center' }
			}
		}
	end
	
	-- PARAMETER: twitch
	if ret:paramDefined('twitch') then
		ret:addRow{
			{ tag = 'argd', content = 'twitch_link', class = 'infobox-image', colspan = '2',
				css = { ['text-align'] = 'center' }
			}
		}
	end
	
	-- PARAMETER: file
	if ret:paramDefined('file') then
		ret:addRow{
			{ tag = 'argd', content = 'file', class = 'infobox-image', colspan = '2',
				css = { ['text-align'] = 'center',
						['padding'] = '3px 0 0.2em 0',
						['border-right'] = '0'
					}
			}
		}
	end

	ret:finish()
	if onmain() then
		local a1 = ret:param('all')
		local a2 = ret:categoryData()
		ret:wikitext(addcategories(a1, a2))
	end
	return ret:tostring()
end

function imgarg(arg)
	if infobox.isDefined(arg) then
		return cleanimg{ file = arg, width = 300, height = 300 }
	end
	return nil
end

function name(arg)
	return string.match(arg or '','%S') and arg or nil
end

function lookuparg(t, c, y)
	local arg = t[string.lower(c or '')]
	if arg then
		if y ~= nil and y ~= '' then
			return arg[y]
		else
			return arg
		end
	end
	return nil
end

function youtube(arg)
	if infobox.isDefined(arg) then
		return '[[File:YouTube small logo.png|15px|link=]] ['..arg..' Watch on YouTube]'
	end
	return nil
end

function twitch(arg)
	if infobox.isDefined(arg) then
		return '[[File:Twitch small logo.png|15px|link=]] ['..arg..' Watch on Twitch]'
	end
	return nil
end

function file(arg)
	if string.match(arg, "%.ogg$") or string.match(arg, "%.mp3$") then
		frame = mw.getCurrentFrame()
		return frame:expandTemplate{ title = 'Listen inline', args = { filename = arg } }
	end
end

-- SMW JSON
function SMWarg(name, image, publish_date, media_type, participants, duration, twitch, youtube, file)
	local toJSON = {
		name = name,
		image = image,
		['date'] = publish_date,
		['type'] = string.lower(tostring(media_type) or ''),
		participants = participants,
		duration = string.lower(tostring(duration) or ''),
		twitch = twitch,
		youtube = youtube,
		file = file
	}

	for k,v in pairs(toJSON) do
		if v == '' or (type(v) == 'string' and string.find(v,'action=edit')) then
			toJSON[k] = nil
		else
			toJSON[k] = mw.text.unstrip(v)
		end
	end

	return mw.text.jsonEncode(toJSON)
end

function addcategories(args, catargs)
	local ret = {}
	
	local cat_map = {
		-- Added if the parameter has content
		defined = {

		},
		-- Added if the parameter has no content
		notdefined = {
			uploader = 'Needs media uploader',
			['date'] = 'Needs media upload date',
			['type'] = 'Needs media type',
			duration = 'Needs media duration'
		},
		podcastnotdefined = {
			file = 'Needs media file',
			participants = 'Needs media participants'
		},
	}
	
	-- Run and add mapped categories
	for n, v in pairs(cat_map.defined) do
		if catargs[n] and catargs[n].one_defined then
			table.insert(ret,v)
		end
	end
	for n, v in pairs(cat_map.notdefined) do
		if catargs[n] and catargs[n].all_defined == false then
			table.insert(ret,v)
		end
	end
	
	-- Add the associated media type if matched
	if args['type'] then
		local category = lookuparg(media_type, args['type'].d, 'category' )
		if category then
			table.insert(ret, category)
		else
			table.insert(ret, 'Needs media type')
		end
	end
	
	-- Podcast specific
	if args['type'].d:lower() == 'podcast' then
		for n, v in pairs(cat_map.podcastnotdefined) do
			if catargs[n] and catargs[n].all_defined == false then
				table.insert(ret,v)
			end
		end
	end
	
	-- combine table and format category wikicode
	for i, v in ipairs(ret) do
		if (v ~= '') then
			ret[i] = string.format('[[Category:%s]]', v)
		end
	end

	return table.concat(ret, '')
end

return p