Moduł:Information

Z Nonsensopedii, polskiej encyklopedii humoru

Moduł generujący tabelkę w szablonie {{Information}} i ustawiający odpowiednie własności semantyczne. Instrukcję korzystania znajdziesz na stronie Nonsensopedia:Opisywanie grafik.

Zobacz też: Moduł:InformationProvider, który pobiera informacje o plikach.


local autor = require('Moduł:Autor')
local tools = require('Moduł:Narzędzia')
local linki = require('Moduł:Linki')
local data
local props = {}
local rows = {}

-- funkcje lokalne

-- funkcja pomocnicza do scalania tabel atrybutów
local function appendProps(key, value)
	props[key] = props[key] or {}
	table.insert(props[key], value)
end

-- Scala inną tablicę atrybutów SMW do tej "głównej"
-- używane przy wciąganiu danych o autorze
local function mergePropTable(other)
	for k, vals in pairs(other) do
		for _, v in ipairs(vals) do
			appendProps(k, v)
		end
	end
end

local function addRow(id, name, content, trid, tdstyle)
	local row = '<tr style="vertical-align: top"'
	if not content then content = '' end
	
	if trid then
		row = row .. '; id="' .. trid .. '">'
	else
		row = row .. '>'
	end
	
	row = row .. '<td id="' .. id .. '" style="background: #ccf; text-align: right; padding-right: 0.4em; width: 15%; font-weight:bold">'
	row = row .. name .. '</td>'
	
	if tdstyle then
		row = row .. '<td style="' .. tdstyle .. '">' .. content .. '</td></tr>'
	else
		row = row .. '<td>' .. content .. '</td></tr>'
	end
	
	table.insert(rows, row)
end

-- Generuje finalny HTML tabelki
local function getTable()
	local elem = mw.html.create('table')
	elem
		:css('width', '100%')
		:attr('cellpadding', '4')
		:addClass('information-template')
		:addClass('toccolours')
		:node(table.concat(rows))
	
	if props['Importuje informacje o pliku z Commons'] or props['Importuje informacje o autorze'] then
		-- rzeczy dla [[MediaWiki:Gadget-PurgeCommonsMetadata.js]]
		elem:addClass('importing-data')
		elem:attr('data-imported', mw.text.jsonEncode( {
			files = props['Importuje informacje o pliku z Commons'],
			authors = props['Importuje informacje o autorze']
		} ) )
	end

	return tostring(elem)
end

------------------------------------------------------------------------

-- Ogarnia składowe
local function processParts(frame, args)
	local prows = {}
	
	-- generowanie wiersza tabelki
	local function pRow(psource, pauthor, plic)
		local row = '<tr><td>' .. psource .. '</td>'
			.. '<td>' .. pauthor .. '</td>'
			.. '<td style="padding: 0;">' .. plic .. '</td></tr>'
		table.insert(prows, row)
	end
	
	-- zawija minilicboxa w dodatkową tabelkę z bąbelkiem ostrzeżenia
	local function miniLicboxWithBubble(licbox, bubble)
		return '<table style="border-spacing: 0; margin: 0;"><tr><td style="width: 100%; padding: 0;">' 
			.. licbox .. '</td><td>' .. bubble .. '</td></tr></table>'
	end
	
	-- robimy listę plików do ogarnięcia
	local partNums, partNames, partNumsToNames = {}, {}, {}
	local function indexPart(num)
		table.insert(partNums, num)
		local links = linki.wLink(args['psource' .. num])
		for k, _ in pairs(links) do
			local targetName = mw.ustring.gsub(mw.text.trim(k), '^:?[Cc]ommons:', '')
			local target = mw.title.new(targetName)
			
			if target.namespace == 6 then
				table.insert(partNames, target.text)
				partNumsToNames[num] = target.text
				break
			end
		end
	end
	
	if args['psource'] then indexPart('') end
	for i = 1, 50 do
		if args['psource' .. i] then indexPart(i)
		else break end
	end
	
	-- pobieramy informacje z Commons i Nonsy
	local fileInfos = {}
	if #partNames > 0 then
		local infop = require('Moduł:InformationProvider')
		fileInfos = infop.getData(partNames)
	end
	
	-- wypełniamy wiesze tabeli
	for _, num in ipairs(partNums) do
		local name = partNumsToNames[num]
		if name then
			local metadata = fileInfos[name]
			if metadata == nil then
				-- fallback: nie znaleziono pliku, wracamy do specyfikacji explicite
				appendProps('Ma ostrzeżenie składowej', 'Nie znaleziono powiązanego pliku')
				pRow(
					args['psource' .. num] .. ' ' .. mw.smw.info('Podany plik nie został odnaleziony ani na Nonsensopedii, ani w Wikimedia Commons. Niedobrze.', 'error'),
					(args['pauthor' .. num] or ''),
					frame:expandTemplate{ title=(args['plic' .. num] or 'nolic'), args={ mini=1 } }
				)
			else
				-- korzystamy z metadanych pobranych automatycznie
				local psource = args['psource' .. num]
				local pauthor = args['pauthor' .. num]
				if pauthor and metadata.author then
					appendProps('Ma ostrzeżenie składowej', 'Nadpisane pole autorstwa')
					-- przetwarzamy surowy tekst
					local _, pauthor2 = autor.process(pauthor)
					-- i jeszcze warning
					pauthor = pauthor2 .. ' ' .. mw.smw.info('Podany argument nadpisuje wartość pobraną z repozytorium: ' .. metadata.repo, 'warning')
				elseif metadata.author then
					pauthor = metadata.author .. ' ' .. mw.smw.info('Pobrano automatycznie z repozytorium: ' .. metadata.repo)
				else
					appendProps('Ma ostrzeżenie składowej', 'Nie podano autora')
					pauthor = mw.smw.info('Nie udało się pobrać informacji o autorze. Najprawdopodobniej w pliku źródłowym nie ma szablonu Information, to dobra okazja żeby go wstawić i wypełnić.', 'error')
				end
				local plic = args['plic' .. num]
				if plic and metadata.licenseShort then
					appendProps('Ma ostrzeżenie składowej', 'Nadpisane pole licencji')
					plic = miniLicboxWithBubble(
						frame:expandTemplate{ title=plic, args={ mini=1 } },
						mw.smw.info('Podany argument nadpisuje wartość pobraną z repozytorium: ' .. metadata.repo, 'warning')
					)
				elseif metadata.licenseShort then
					plic = frame:expandTemplate{ title='licbox', args={ 
						metadata.licenseShort,
						'',
						metadata.licenseLong or '',
						typ=metadata.licenseType or 'gnu',
						mini=1
					} }
					plic = miniLicboxWithBubble(plic, mw.smw.info('Pobrano automatycznie z repozytorium: ' .. metadata.repo))
				else
					local severity = 'warning'
					if plic == nil then
						appendProps('Ma ostrzeżenie składowej', 'Nie podano licencji')
						severity = 'error'
					end
					plic = miniLicboxWithBubble(
						frame:expandTemplate{ title=plic or 'nolic', args={ mini=1 } },
						mw.smw.info('Nie udało się pobrać informacji o licencji. Póki co działa to tylko dla plików z Commons, te nonsowe musisz przeklepać ręcznie.', severity)
					)
				end
				
				-- Zapisujemy sobie, że informacje o tym pliku zostały pobrane z zewnętrznego repo
				if metadata.repo == 'Wikimedia Commons' then
					appendProps('Importuje informacje o pliku z Commons', name)
				end
				
				pRow(psource, pauthor, plic)
			end
			
		-- składowa podana explicite
		else
			local pauthor = ''
			-- przetwarzamy surowy tekst autorstwa
			if args['pauthor' .. num] then
				local aprops, pauthor2 = autor.process(args['pauthor' .. num])
				pauthor = pauthor2
				
				-- oznaczamy że importujemy zewnętrzne info
				if aprops['Importuje informacje o autorze'] then
					appendProps('Importuje informacje o autorze', aprops['Importuje informacje o autorze'][1])
				end
			end
			
			pRow(
				args['psource' .. num],
				pauthor,
				frame:expandTemplate{ title=(args['plic' .. num] or 'nolic'), args={ mini=1 } }
			)
		end
	end
	
	if #prows == 0 then return end
	
	local s = [[<table class="info-inner"><tr>
<td style="background: #ccf; font-weight:bold">Źródło</td>
<td style="background: #ccf; font-weight:bold">Autor</td>
<td style="background: #ccf; font-weight:bold">Licencja</td>
</tr>]]
	s = s .. table.concat(prows) .. '</table>'
	addRow('fileinfotpl_parts', 'Składowe', s, 'fileinforow_parts', 'padding: 0')
end

local function processCaption(args, required)
	-- caption
	local captionLinksCount = 0
	-- stosujemy podpis jako domyślny opis dla MMV, a w razie jego braku bierzemy pole description
	local descriptionTag = 'fileinfotpl_desc'
	if args['caption'] or demo then
		appendProps('Ma podpis pliku', args['caption'])
		local captionDisplay = args['caption']
		descriptionTag = 'fileinfotpl_full_desc'
		
		local captionLinks = linki.wLink(args['caption'] or '')
		for k, v in pairs(captionLinks) do
			appendProps('Linkuje w podpisie', k)
			captionLinksCount = captionLinksCount + 1
		end
		
		if captionLinksCount == 0 and captionDisplay ~= nil then
			captionDisplay = captionDisplay .. ' ' .. 
				mw.smw.info('W podpisie nie ma żadnego linku do artykułu. Rozważ wstawienie jakiegoś, by odnieść czytelnika do powiązanego artykułu.', 'warning')
		end
		
		addRow('fileinfotpl_desc', 'Podpis', captionDisplay)
	else
		appendProps('Nie ma podpisu pliku', true)
		if required then
			-- inne ID bo nie chcemy żeby pokazywało nam ten error w podglądach
			addRow('fileinfotpl_desc_error', 'Podpis', "''Brak''")
		end
	end
	appendProps('Liczba linków w podpisie', captionLinksCount)
	
	return descriptionTag
end

-- zbuduj tabelkę dla plików z lokalnego repo
local function doLocal(frame, args)
	appendProps('Pochodzi z repozytorium', 'Nonsensopedia')
	local demo = args['demo'] ~= nil
	
	-- caption
	local descriptionTag = processCaption(args)
	
	-- description
	if args['description'] then
		appendProps('Ma opis', args['description'])
		addRow(descriptionTag, 'Opis', args['description'])
	else
		appendProps('Nie ma opisu', true)
		addRow(descriptionTag, 'Opis', "''Brak''")
	end
	
	-- składowe
	processParts(frame, args)
	
	-- data
	if args['date'] or demo then
		if not data then data = require('Module:Data') end		-- lazy
		local dSMW, dClean = data.processToSMW(args['date'])
		appendProps('Ma opis daty', dClean)
		addRow('fileinfotpl_date', 'Data', dSMW)
	else
		appendProps('Nie ma daty', true)
	end
	
	-- źródło
	if args['source'] then
		local source = require('Module:Źródło')
		local aprops, s = source.process(args['source'])
		if not demo then mw.smw.set(aprops) end
		addRow('fileinfotpl_src', 'Źródło', args['source'])
	else
		addRow('fileinfotpl_src', 'Źródło',
			"'''Nie podano źródła.''' Uzupełnij <code>Source=</code> (''Praca własna'', adres URL strony lub pliku)")
		if not demo then appendProps('Nie ma podanego źródła', true) end
	end
	
	-- author
	if args['author'] or demo then
		local aprops, s = autor.process(args['author'])
		-- scalamy tablice atrybutów
		mergePropTable(aprops)
		addRow('fileinfotpl_aut', 'Autor', s)
	end
	
	-- permission
	if args['permission'] or demo then
		-- TODO: smw i te sprawy
		addRow('fileinfotpl_perm', 'Licencja', args['permission'])
	end
	
	-- confirmation
	if args['confirmation'] or demo then
		appendProps('Ma potwierdzenie licencji', args['confirmation'])
		addRow('fileinfotpl_confirmation', 'Potwierdzenie licencji', args['confirmation'])
	end
	
	-- other versions
	local ov = args['other_versions']
	if (ov and ov ~= '' and ov ~= '-' and ov ~= 'none') or demo then
		local ovs = linki.wLink(ov or '')
		for l, v in pairs(ovs) do
			if mw.ustring.find(l, ':') == 1 then
				appendProps('Ma inną wersję', mw.ustring.gsub(l, ';', '\\;') .. ';' .. mw.ustring.gsub(v, ';', '\\;'))
			elseif #l > 0 then
				appendProps('Ma inną wersję', mw.ustring.gsub(l, ';', '\\;'))
			end
		end
		
		addRow('fileinfotpl_ver', 'Inne wersje', ov)
	end
	
	-- location
	local loc = args['location']
	if loc then
		local locModule = require('Moduł:Lokalizacja')
		local _, text, geoprops = locModule.parseLocation(frame, loc, true)
		
		for key, val in pairs(geoprops) do
			appendProps(key, val)
		end
		
		addRow('fileinfotpl_loc', 'Lokalizacja', text)
	end
	
	if not demo then mw.smw.set(props) end
	return getTable()
end

-- zbuduj tabelkę dla pliku z Commons
local function doRemote(frame, args, title)
	local scc = mw.ext.commonsClient.getData(title)
	local remoteData = nil
	for k, v in pairs(scc) do remoteData = v end
	if remoteData == nil or not remoteData.found then
		return doNoSuchFile(args, title)
	end
	
	local demo = args['demo'] ~= nil
	appendProps('Pochodzi z repozytorium', 'Wikimedia Commons')
	appendProps('Ma identyfikator Wikimedia Commons', remoteData.entityId)
	processCaption(args, true)
	
	local importInfo = {}
	-- lokalizacja
	if remoteData.location then
		table.insert(importInfo, 'lokalizacja')
		appendProps('Ma lokalizację', 
			remoteData.location.latitude .. ', ' .. remoteData.location.longitude)
	end
	
	-- data
	if remoteData.dateTime and mw.ustring.find(mw.ustring.lower(remoteData.dateTime), 'nieznan', 1, true) == nil then
		appendProps('Ma datę', remoteData.dateTime)
		appendProps('Ma opis daty', remoteData.dateTime)
		table.insert(importInfo, 'data')
	else
		appendProps('Nie ma daty', true)
	end
	
	-- autor
	local aprops, _, aType = autor.getAuthorFromCommonsData(remoteData.author)
	mergePropTable(aprops)
	if aType ~= '' then
		table.insert(importInfo, 'autor (' .. aType .. ')')
	end
	
	addRow('fileinfotpl_import_info', 'Importowane dane', table.concat(importInfo, ', '))
	
	-- importuje informacje o sobie
	appendProps('Importuje informacje o pliku z Commons', title)
	
	if not demo then mw.smw.set(props) end
	return getTable()
end

-- zbuduj tabelkę dla nieistniejącego pliku
local function doNoSuchFile(args, title)
	local demo = args['demo'] ~= nil
	
	addRow('fileinfotpl_error', 'Błąd', 'Nie odnaleziono pliku "' .. title .. '" ani na Nonsensopedii, ani w Wikimedia Commons.')
	appendProps('Pochodzi z repozytorium', 'nieznane')
	
	if not demo then mw.smw.set(props) end
	return getTable()
end

-- funkcje eksportowane
local p = {}

-- zrób cuda
function p.information(frame)
	local args = tools.getArgs(frame)
	
	local title = args['title'] or mw.title.getCurrentTitle().text
	local repos = mw.ext.commonsClient.getFileRepo(title)
	for k, v in pairs(repos) do
		if v == 'wikimediacommons' then return doRemote(frame, args, title)
		else return doLocal(frame, args) end
	end
	
	return doNoSuchFile(args, title)
end

return p