Modulo:Progetti interessati

Versione del 5 feb 2016 alle 00:23 di Rotpunkt (discussione | contributi) (fix preposizione)

Modulo che implementa il template {{Progetti interessati}}.

Ha due sottopagine di configurazione:


--[[
* Modulo che implementa il template Monitoraggio.
]]--

require('Modulo:No globals')

local getArgs = require('Modulo:Arguments').getArgs

-- Configurazione
local cfg = mw.loadData('Modulo:Monitoraggio/Configurazione')

-- Variabili globali
local projParams = { 'progetto', 'progetto2', 'progetto3', 'progetto4' }
local gradeParams = { 'accuratezza', 'scrittura', 'fonti', 'immagini' }
--local importanceParams = { 'importanza', 'importanza2', 'importanza3', 'importanza4' }
local validGrades = { a = true, b = true, c = true, d = true, e = true }
local validImportances = { massima = true, alta = true, media = true, bassa = true }

-------------------------------------------------------------------------------
--                             Funzioni di utilità
-------------------------------------------------------------------------------

-- Wrapper di mw.title.exists, verifica sia che name sia valido, sia che esista
local function titleExists(name)
	local title = mw.title.new(name)
	return title and title.exists
end

local function project(param, args)
	return cfg.alias[args[param] and args[param]:lower()] or mw.language.getContentLanguage():ucfirst(args[param])
end

local function grade(param, args)
	return args[param] or 'nc'
end

-- utilizzata per le icone e per l'etichetta del wikilink del progetto
local function subpage(title)
	return mw.title.new('Progetto:' .. title).subpageText
end

--local function importanceFromProject(projParam, args)
--	local num = mw.ustring.match(projParam, '^progetto(%d)$')
--	local param = num and ('importanza' .. num) or
--				  (projParam == 'progetto' and 'importanza' or nil)
--	return args[param] or 'sconosciuta'
--end

local function lowestGrade(args)
	local t = { args.accuratezza, args.scrittura, args.fonti, args.immagini }
	table.sort(t)
	return t[4]
end

local function parseArgs(args)
	local cat = ''

	-- controllo importanza
	--for _, param in ipairs(importanceParams) do
	--	if args[param] and not validImportances[args[param]] then
	--		args[param] = nil
	--		cat = '[[Categoria:Pagine con template Monitoraggio con importanza invalida]]'
	--	end
	--end

	-- controllo valutazioni
	for _, param in ipairs(gradeParams) do
		if args[param] and not validGrades[args[param]] then
			if args[param] ~= 'nc' then
				cat = cat .. '[[Categoria:Pagine con template Monitoraggio con valutazione invalida]]'
			end
			args[param] = nil
		end
	end
	args.data = args.data and args.data:lower() or nil

	-- controllo progetto
	if args.progetto then
		for _, param in ipairs(projParams) do
			if args[param] and not titleExists('Progetto:' .. project(param, args)) then
				cat = cat .. '[[Categoria:Pagine con template Monitoraggio con progetto non esistente]]'
				break
			end
		end
	else
		cat = cat .. '[[Categoria:Errori di compilazione del template Monitoraggio]]'
	end

	return args, cat
end

-------------------------------------------------------------------------------
--                             Monitoraggio
-------------------------------------------------------------------------------

local function getLivello(args)
	local ret

	-- è presente accuratezza
	if args.accuratezza then
		if not args.scrittura then
			ret = '0.4'
		elseif not args.fonti then
			ret = '0.3'
		elseif not args.immagini then
			ret = '0.2'
		else
			-- sono presenti tutti e quattro i parametri di valutazione
			if args.accuratezza == 'e' then
				ret = 'BOZZA'
			elseif args.scrittura == 'e' then
				ret = 'W'
			elseif args.fonti == 'e' then
				ret = 'F'
			elseif args.immagini == 'e' then
				ret = 'IMMAGINI'
			else
				local values = { a = 4, b = 3, c = 2, d = 1 }
				ret = tostring(values[lowestGrade(args)])
			end
		end
	-- manca accuratezza
	else
		if args.scrittura or args.fonti or args.immagini then
			ret = '0.5'
		else
			ret = nil
		end
	end

	return ret
end

local function getCategories(livello, args)
	local ret = {}
	local cat

	local suffix = livello and cfg.livello[livello].cat or 'non compilate'

	-- per la "Situazione generale" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
	cat = string.format('[[Categoria:Voci monitorate - %s]]', suffix)
	table.insert(ret, cat)

	for _, param in ipairs(projParams) do
		if args[param] then
			cat = string.format('[[Categoria:Voci monitorate Progetto %s]]', project(param, args))
			table.insert(ret, cat)
		end
	end

	for _, gradeParam in ipairs(gradeParams) do
		-- per la "Situazione monitoraggio per parametro" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
		cat = string.format('[[Categoria:Voci monitorate - %s %s]]',
							gradeParam, grade(gradeParam, args):upper())
		table.insert(ret, cat)

		-- categorie per il [[template:Tabella monitoraggio]]
		for _, projParam in ipairs(projParams) do
			if args[projParam] then
				cat = string.format('Categoria:Progetto:%s/Tabella monitoraggio automatico - %s %s',
									project(projParam, args), gradeParam, grade(gradeParam, args))
				if titleExists(cat) then
					table.insert(ret, '[[' .. cat .. ']]')
				end
			end
		end
	end

	-- categorie per il [[template:Tabella monitoraggio]]
	for _, param in ipairs(projParams) do
		if args[param] then
			cat = string.format('Categoria:Voci monitorate Progetto %s - %s',
								project(param, args), suffix)
			if titleExists(cat) then
				table.insert(ret, '[[' .. cat .. ']]')
			end
			--cat = string.format('Categoria:Voci monitorate Progetto %s - importanza %s',
			--					project(param, args), importanceFromProject(param, args))
			--table.insert(ret, '[[' .. cat .. ']]')
		end
	end

	-- per la "Situazione monitoraggio per mese" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
	if args.data then
		cat = string.format('Categoria:Voci monitorate - %s', args.data)
		if titleExists(cat) then
			table.insert(ret, '[[' .. cat .. ']]')
		else
			table.insert(ret, '[[Categoria:Errori di compilazione del template Monitoraggio]]')
		end
	else
		table.insert(ret, '[[Categoria:Voci monitorate - non datate]]')
	end

	return ret
end

-------------------------------------------------------------------------------
--                             Creazione HTML
-------------------------------------------------------------------------------

local function getIconProject(name)
	local icon = mw.getCurrentFrame():expandTemplate {
		title = 'Icona argomento',
		args = { name }
	}
	icon = icon == '' and 'Crystal Clear app ksirtet.png' or icon

	return string.format('[[File:%s|25x40px]]', icon)
end

local function getWlinkProject(param, args)
	local fmt = '<small>([[Discussioni progetto:%s|leggi discussioni]]' ..
			    ' <b>·</b> [%s nuova discussione]' ..
			    ' <b>·</b> [[Progetto:%s/Monitoraggio voci|monitoraggio]])</small>'
	return string.format(fmt,
						 project(param, args),
						 mw.title.new('Discussioni progetto:' ..
							project(param, args)):fullUrl( { action = 'edit', section = 'new' } ),
						 project(param, args))
						 --importanceFromProject(param, args))
end

local function getNodeProjects(args)
	local tableNode = mw.html.create('table')

	tableNode
		:css('border-collapse', 'collapse')
		:css('width', '100%')

	-- progetti
	for _, param in ipairs(projParams) do
		if args[param] then
			tableNode:tag('tr')
				:css('background-color', 'white')
				:css('border', 'thin solid #D8D8D8')
				:tag('td')
					:css('width', '28px')
					:css('text-align', 'center')
					:wikitext(getIconProject(subpage(project(param, args))))
					:done()
				:tag('td')
					:css('width', '1px')
					:css('white-space', 'nowrap')
					:wikitext(string.format("'''[[Progetto:%s|%s]]'''", project(param, args), subpage(project(param, args))))
					:done()
				:tag('td')
					:wikitext('<div class="plainlinks" style="padding-left: 5px">' .. getWlinkProject(param, args) .. '</div>')
					:done()
		end
	end

	return tableNode
end

local function getWlinkLivello(livello)
	local spanStyle = {
		['font-weight'] = 'bold',
		['font-size'] = '125%',
		['border'] = '1px solid lightsteelblue',
		['background'] = (livello and cfg.livello[livello].color) and cfg.livello[livello].color or 'white',
		['color']  = 'blue'
	}
	local spanNode = mw.html.create('span')
	local text
	if livello and cfg.livello[livello].label then
		text = string.format('[[:Categoria:Voci monitorate - %s|%s]]',
							 cfg.livello[livello].cat, cfg.livello[livello].label)
	elseif not livello then
		text = '[[:Categoria:Voci monitorate - non compilate|NC]]'
	end
	if text then
		spanNode:css(spanStyle)
		text = string.format("'''<tt>&nbsp;%s&nbsp;</tt>'''", text)
	else
		text = '[[File:Symbol stub class.svg|25px|center]]'
	end
	spanNode:wikitext(text)

	return spanNode
end

local function getTextData(args)
	local ret

	if args.data then
		local cat = string.format('Categoria:Voci monitorate - %s', args.data)
		if titleExists(cat) then
			ret = '<small>(' .. args.data .. ')</small>'
		end
	end

	return ret or "(<span style=\"color:red;\"><small>'''''mese e anno'''''</small></span>)"
end

local function getNodeLivello(livello, args)
	local url = mw.title.getCurrentTitle():fullUrl( { action = 'edit' } )
	local trNode = mw.html.create('tr')
	trNode
		:tag('td')
			:css('background-color', 'none')
			:css('width', '90px')
			:node(getWlinkLivello(livello))
			:done()
		:tag('td')
			:wikitext(livello and cfg.livello[livello].msg .. ' ' .. getTextData(args) or
				"<div class=\"plainlinks\">La voce non è stata ancora monitorata, [" .. url .. " fallo ora]!</div>")
			:done()
		:tag('td')
			:css('width', '80px')
			:wikitext('')
			:done()

	return trNode
end

local function getSpanGrade(value)
	local spanStyle = {
		['font-weight'] = 'bold',
		['font-size'] = '155%',
		['border'] = '1px solid lightsteelblue',
		background = cfg.colors[value] or 'white'
	}
	local spanNode = mw.html.create('span')
	value = string.format("&thinsp;'''<tt>%s&thinsp;</tt>'''",
						  value and value:upper() or '<small>nc</small>')
	spanNode
		:css(spanStyle)
		:wikitext(value)
	return spanNode
end

local function getNodeGrade(param, args)
	local trNode = mw.html.create('tr')
	local descr = cfg[param][args[param] or 'nc'] .. ' ' .. cfg[param].help
	trNode
		:css('background-color', 'white')
		:css('border', 'thin solid #D8D8D8')
		:tag('td')
			:css('width', '40px')
			:css('padding-left', '5px')
			:node(getSpanGrade(args[param]))
			:done()
		:tag('td')
			:wikitext(descr)
			:done()

	return trNode
end

local function getHTML(livello, args)
	local tableStyle = {
		margin = '5px 10%',
		width = '80%',
		border = '1px solid #a7d7f9',
		['background-color'] = '#EAF7ED'
	}
	local tableNode1 = mw.html.create('table')
	tableNode1
		:css(tableStyle)
		:css('margin-bottom', '0px')

	-- intestazione
	local projects = {}
	for _, param in ipairs(projParams) do
		if args[param] then
			table.insert(projects, args[param])
		end
	end
	local text = 'La voce <b>' .. mw.title.getCurrentTitle().text .. '</b> rientra tra gli argomenti trattati' .. 
				 (#projects > 1 and " dai seguenti [[Wikipedia:Progetto|progetti]]:" or
				 " dal seguente [[Wikipedia:Progetto|progetto]]:")
	tableNode1
		:tag('tr')
			:tag('td')
				:css('padding-left', '.3em')
				:wikitext(text)
				:done()
		:tag('tr')
			:tag('td')
				:node(getNodeProjects(args))
				:done()

	local tableNode2 = mw.html.create('table')
	tableNode2
		:addClass('mw-collapsible mw-collapsed')
		:css(tableStyle)
		:css('border-top', '0px')
		:css('margin-top', '0px')

	-- livello	
	tableNode2
		:node(getNodeLivello(livello, args))
	-- valutazioni
	tableNode2
		:tag('tr')
			:tag('td')
				:attr('colspan', '3')
				:css('background-color', 'none')
				:css('font-size', '95%')
				:tag('table')
					:css('width', '100%')
					:css('border-collapse', 'collapse')
					:node(getNodeGrade('accuratezza', args))
					:node(getNodeGrade('scrittura', args))
					:node(getNodeGrade('fonti', args))
					:node(getNodeGrade('immagini', args))
	-- note
	if args.note then
		tableNode2
			:tag('tr')
				:tag('td')
					:attr('colspan', '3')
					:wikitext(string.format("<ul><li>''note:'' %s</li></ul>", args.note))
	end

	return tostring(tableNode1) .. tostring(tableNode2)
end

-------------------------------------------------------------------------------
--                                    API
-------------------------------------------------------------------------------

local p = {}

-- Per l'utilizzo da un altro modulo
function p._livello(args)
	return getLivello(parseArgs(args))	
end

-- Entry-point per {{#invoke:monitoraggio|livello}}
function p.livello(frame)
	return p._livello(getArgs(frame))
end

-- Entry-point per {{#invoke:monitoraggio|categorie}}
function p.categorie(frame)
	local args = parseArgs(getArgs(frame))
	local livello = getLivello(args)	
	local categories = getCategories(livello, args)
	return args.debug and ( table.concat(categories, '<br />'):gsub('%[%[', '[[:') ) .. '<br />' or
		   table.concat(categories)
end

-- Entry-point per {{Monitoraggio/classe}}
-- per retrocompatibilità con template che lo usavano
function p.classe(frame)
	local value = frame:getParent().args[1]
	return tostring(getSpanGrade(validGrades[value] and value or nil))
end

-- Entry-point per il template {{Monitoraggio}}
function p.main(frame)
	local args, errorCat = parseArgs(getArgs(frame, {parentOnly = true}))
	local livello = getLivello(args)
	local categories = mw.title.getCurrentTitle().namespace == 1 and
					   (table.concat(getCategories(livello, args)) .. errorCat) or ''
	return getHTML(livello, args) .. categories
end

return p