Vai al contenuto

Modulo:Software

Questa pagina è semiprotetta. Può essere modificata solo da utenti registrati
Da Wikipedia, l'enciclopedia libera.

Modulo Lua per integrare le informazioni espresse nel Template:Software con le informazioni provenienti da Wikidata.

Se alcuni linguaggi sono assenti è un problema di configurazione.

In seguito l'uso di alcune sotto-funzioni.

Uso

isFreeSoftware

{{#invoke:Software|isFreeSoftware}}

Valori di ritorno:

  1. : è software libero
  2. no: è software proprietario
  3. nil: nessuna informazione per determinarlo

isFreeSoftware e Wikidata

A livello implementativo questa funzione cerca di uniformare alcune delle molte modalità con cui si può esprimere questa informazione in Wikidata.

Per quanto riguarda essere software libero:

  1. Il template {{Software}} ha SoftwareLibero=?
  2. La voce è istanza di (P31) software libero (Q341) / software open-source (Q1130645)?
  3. Fra le licenze di questa voce espresse in licenza (P275) ce n'è una istanza di (P31) di licenza di software libero (Q3943414)? (funzione parser dispendiosa, vedi #Albero licenze Wikidata)

Per quanto riguarda essere software proprietario:

  1. Il template {{Software}} ha SoftwareLibero=no?
  2. La voce è istanza di (P31) software proprietario (Q218616) / freeware (Q178285)?
  3. Fra le licenze di questa voce espresse in licenza (P275) ce n'è una sottoclasse di (P279) di licenza proprietaria (Q3238057)? (funzione parser dispendiosa, vedi #Albero licenze Wikidata)

specifiesALanguage

{{#invoke:Software|specifiesALanguage}}
  1. : vi sono linguaggi espressi da Wikidata o specificati da {{Software|Linguaggio}}
  2. no: in caso contrario

shouldHaveALanguage

{{#invoke:Software|shouldHaveALanguage}}

Valori di ritorno:

  1. : questa voce dovrebbe (o potrebbe) mostrare l'etichetta dei linguaggi di programmazione. Vale per i software liberi o se vi sono linguaggi specificati.
  2. no: la voce non dovrebbe (o non potrebbe) mostrare l'etichetta dei linguaggi di programmazione. Capita per software proprietario senza linguaggi noti.
TODO
Da novembre 2018 questa funzione è inutilizzata e potrebbe essere rimossa.

languages

{{#invoke:Software|languages}}

Stampa i linguaggi di programmazione unendo i valori dal template con i valori da Wikidata dalla proprietà linguaggio di programmazione (P277) e categorizzando:

Categoria:Software libero senza linguaggio
La voce dovrebbe mostrare linguaggi perché è un software libero, ma non lo fa.
Categoria:P277 uguale su Wikidata
I linguaggi specificati nel template sono presenti identici in Wikidata.
Categoria:P277 letta da Wikidata
Il template mostra linguaggi esclusivamente grazie a Wikidata.
Categoria:P277 differente su Wikidata
Il template ha linguaggi che Wikidata non ha (o viceversa).
Categoria:P277 assente su Wikidata
Il template ha linguaggi, Wikidata no.
Categoria:Linguaggio di programmazione da Wikidata non previsto
Capita quando in Wikidata c'è un linguaggio assente nella configurazione.

languageCategories

{{#invoke:Software|languageCategories}}

Categorizza la voce in base ai suoi linguaggi di programmazione espressi in Wikidata (usata internamente in #languages).

licenseCategories

{{#invoke:Software|licenseCategories}}

Categorizza la voce in base alle licenze con cui è distribuito il software.

Considerazioni implementative

Albero licenze Wikidata

Ricostruzione dell'albero inverso delle licenze presenti in Wikidata:

Albero delle licenze

Albero GNU GPL

Notare che GNU General Public License (Q7603) è reputato con i medesimi valori sia per istanza di (P31) che per sottoclasse di (P279), in quanto per alcuni è considerata una vera e propria licenza, mentre per altri una sottoclasse di licenze. d:Talk:Q308915.

Albero BSD

Albero caso peggiore

Attualmente il "caso peggiore" per identificare un'istanza di (P31) licenza di software libero (Q3943414) sembra essere il seguente (albero in cascata):

GNU Affero General Public License, versione 3 (o successive) (Q27020062) :

È perciò possibile limitare un massimo livello di ricorsione a 3 fintanto che questa struttura rimane invariata.

Configurazione

Lo stesso argomento in dettaglio: Modulo:Software/Configurazione.

Per cambiare il modo in cui è mostrato un linguaggio o una licenza, prova a guardare in Wikidata tale linguaggio o tale licenza. Considera anche che se il nome in Wikidata è troppo lungo, è scelto il nome in breve (P1813).

Per aggiungere una categoria di un linguaggio, o una licenza, vedi Modulo:Software/Configurazione.

Note storiche

Fino a marzo 2017 per cambiare il wikilink alla voce del linguaggio o mostrare banalmente "C" al posto di "C (linguaggio)" occorreva modificare il Template:Software/Linguaggio considerando complesse sotto-inclusioni del Template:Software/L. Inoltre ora non occorre più mantenere parallelamente la documentazione in Template:Software#Linguaggi perchè è generata. Prima era Template:Software/Linguaggio/man.

Risoluzione dei problemi

Se il template {{Software}} ha l'errore «non in lista» significa che:

  • Potrebbe essere un errore di battitura, si veda quella lista.
  • Se non è un errore di battitura ma manca un linguaggio rilevante, vedere Modulo:Software/Configurazione.

Pagine correlate


local mWikidata = require('Modulo:Wikidata')
local getArgs = require('Modulo:Arguments').getArgs
local conf = mw.loadData('Modulo:Software/Configurazione')

local p = {}

-- TODO Implementare in Modulo:Wikidata
function p._subclassOf(args)
	local statements = mWikidata._getProperty({'P279', from = args.from, formatting = 'raw'}, true)
	if statements then
		for _, statement in ipairs(statements) do
			for _, entityId in ipairs(args) do
				if statement == entityId then
					return true
				end
			end
		end
	end
	return false
end

function p._isFreeSoftwareByTemplate(frame)
	local is = nil
	local args = frame and getArgs(frame)
	local v = args['SoftwareLibero']
	if v then
		local yep = {['sì'] = true, ['si'] = true, ['no'] = false}
		v = yep[ mw.ustring.lower(v) ]
	end
	return v
end

function p._isFreeSoftwareByWikidata(frame)
	-- Q341 free software
	-- Q1130645 open-source software
	return mWikidata._instanceOf({'Q341', 'Q1130645'}) or p._hasAFreeLicense(frame)
end

function p._isProprietarySoftwareByWikidata(frame)
	-- Q218616 proprietary software
	-- Q178285 freeware TODO: impropria, subclass of precedente
	return mWikidata._instanceOf({'Q218616', 'Q178285'}) or p._hasAProprietaryLicense(frame)
end

--[[
* La voce è software libero?
*
* @return true|false|nil
]]
function p._isFreeSoftware(frame)
	local is_wd   = p._isFreeSoftwareByWikidata()
	local isnt_wd = p._isProprietarySoftwareByWikidata()
	local is_tp   = p._isFreeSoftwareByTemplate(frame)
	local is = nil
	if is_wd then
		is = true
	end
	if isnt_wd then
		is = false
	end
	if is_tp ~= nil then
		is = is_tp
	end

	--if is_wd == true and isnt_wd == true then
		-- Wikidata nonsense
	--end

	--if is_wd == true and is_tp == true then
		-- Local same as Wikidata
	--

	--if (is_wd == true and is_tp == false) or (isnt_wd == true and is_tp == false) then
		-- Free different from Wikidata
	--

	--if (is_wd ~= nil or isnt_wd ~= nil) and is_tp == false then
		-- Free/proprietary read from Wikidata
	--
	return is
end

--[[
* @param v bool
* @return string
]]
local function yesNo(v)
	return v and 'sì' or 'no'
end

--[[
* @param v bool
* @return string|nil
]]
local function yesNoNil(v)
	if v == nil then
		return nil
	end
	return yesNo(v)
end

function p.isFreeSoftware(frame)
	return yesNoNil( p._isFreeSoftware(frame) )
end

--[[
* Il template ha linguaggi?
*
* @return truly|nil
]]
function p._templateHasLanguages(frame)
	local args = frame and getArgs(frame)
	return args['Linguaggio'] or args['NotaLinguaggio'] or args['LinguaggioAltri']
end

function p._templateHasExtraInformations(frame)
	local args = frame and getArgs(frame)
	return args['LinguaggioAltri'] or args['NotaLinguaggio'] or args['NotaLinguaggio2'] or args['NotaLinguaggio3']
end

--[[
* La voce specifica un linguaggio di programmazione?
*
* @return true|nil
]]
function p._specifiesALanguage(frame)
	local args = frame and getArgs(frame)
	return p._templateHasLanguages(frame) or mWikidata._getClaims('P277')
end

function p.specifiesALanguage(frame)
	return yesNo( p._specifiesALanguage(frame) )
end

--[[
* La voce dovrebbe specificare un linguaggio?
*
* @return true|nil
]]
function p._shouldHaveALanguage(frame)
	return p._isFreeSoftware(frame) or p._specifiesALanguage(frame)
end

function p.shouldHaveALanguage(frame)
	return yesNo( p._shouldHaveALanguage(frame) )
end

--[[
* 'cpp' → 'c++'
* 'c++' → 'c++'
]]
function p._preferredLanguageSlug(slug)
	if slug then
		slug = string.lower(slug)
	end
	return conf.languageSlugAlias[slug] or slug
end

--[[
* Reverse tree di Modulo:Software/Configurazione
*
* 'cpp' → 'Q2407'
]]
local _languageSlugToWikidata = {}
function p._languageSlugToWikidata(slug)
	if next(_languageSlugToWikidata) == nil then
		for q,l in pairs(conf.wikidataToLanguageSlug) do
			_languageSlugToWikidata[l] = q
		end
	end
	return _languageSlugToWikidata[ p._preferredLanguageSlug(slug) ]
end

function p.languageSlugToWikidata(frame)
	return p._languageSlugToWikidata( getArgs(frame)[1] )
end

--[[
* @return string[] = 'c' => 'nota linguaggio c', 'c++' = '', ..
]]
function p._getTemplateLanguages(frame)
	local languages = {}
	local args = frame and getArgs(frame)
	local v = args['Linguaggio']
	if v then
		languages[ p._preferredLanguageSlug(v) ] = args['NotaLinguaggio'] or ''
	end
	for i=1,3 do
		v = args['Linguaggio' .. i]
		if v then
			languages[ p._preferredLanguageSlug(v) ] = args['NotaLinguaggio' .. i] or ''
		end
	end
	return languages
end

--[[
* Poi non ditemi che PHP fa schifo. asd.
* 00:28, 28 feb 2017‎ Valerio Bozzolan
]]
local function count(t)
	local i = 0
	for _,__ in pairs(t) do
		i = i + 1
	end
	return i
end

--[[
* Le licenze della voce.
*
* @return pairs( {} )
]]
local _licenses_cache = false
function p._licenses(frame)
	if _licenses_cache == false then
		_licenses_cache = mWikidata._getClaims('P275') or {}
	end
	return _licenses_cache
end

function p.licenses(frame)
	local s = ''
	for i, l in pairs( p._licenses(frame) ) do
		local space = i == 1 and '' or '<br />'
		s = s .. space .. mWikidata._formatStatement(l, {formatting = 'raw'})
	end
	return s
end

-- Cache
local licenseIsFree_ = {}
function p._licenseIsFree(license)
	if licenseIsFree_[license] == nil then
		licenseIsFree_[license] =
			-- Q3943414 free software license
			-- | Q7603  GNU General Public License (to get Q27016754 GPL-3.0+)
			-- | Q616526 Apache License (to get Q13785927 Apache-2.0)
			mWikidata._instanceOf({'Q3943414', 'Q7603', 'Q616526', from = license})
			or
			-- Q1437937 permissive free software licence (to get Q616526 Apache License, Q191307 BSD license)
			p._subclassOf({'Q1437937', from = license})
			or
			false
	end
	return licenseIsFree_[license]
end

-- Cache
local licenseIsProprietary_ = {}
function p._licenseIsProprietary(license)
	-- Q14624820 non-free software license
	-- Q218616 proprietary software
	if license == 'Q14624820' or license == 'Q218616' then
		return true
	end
	if licenseIsProprietary_[license] == nil then
		-- Q14624820 non-free software license
		-- Q218616 proprietary software
		-- Q178285 freeware (to get Q193345 adware)
		licenseIsProprietary_[license] = p._subclassOf({'Q14624820', 'Q218616', 'Q178285', from = license}) or false
	end
	return licenseIsProprietary_[license]
end

--[[
* La voce ha almeno una licenza di software libero?
]]
function p._hasAFreeLicense(frame)
	for _, l in pairs( p._licenses(frame) ) do
		l = mWikidata._formatStatement(l, {formatting = 'raw'})
		if p._licenseIsFree(l) then
			return true
		end
	end
	return false
end

--[[
* La voce ha almeno una licenza di software proprietario?
]]
function p._hasAProprietaryLicense(frame)
	for _, l in pairs( p._licenses(frame) ) do
		l = mWikidata._formatStatement(l, {formatting = 'raw'})
		if p._licenseIsProprietary(l) then
			return true
		end
	end
	return false
end

function p.hasAFreeLicense(frame)
	return yesNoNil( p._hasAFreeLicense(frame) )
end

function p.hasAProprietaryLicense(frame)
	return yesNoNil( p._hasAProprietaryLicense(frame) )
end

function p.languages(frame)
	local s = ''

	--[[
	* Argomenti ereditati dal Template:Software e da Wikidata
	]]
	local args = frame and getArgs(frame)
	local categorizza = args['Categorie']
	local libero = p.isFreeSoftware(frame)

	--[[
	* Linguaggi dal Template:Software e da Wikidata
	]]
	local tl_has        = p._templateHasLanguages(frame) and true or false
	local tl_languages  = p._getTemplateLanguages(frame)
	local wd_languages  = mWikidata._getClaims('P277')
	local altri = args['LinguaggioAltri']

	-- È il namespace principale?
	local nszero = mw.title.getCurrentTitle().namespace == 0

	-- Tutti i linguaggi sono identificati?
	local allFound = true

	-- Il template si è arricchito grazie a Wikidata?
	local improved = false

	-- Il template non mostra alcun linguaggio?
	local noLanguages = not tl_has

	if wd_languages then
		for i, language in pairs(wd_languages) do
			local wikidataID = mWikidata._formatStatement(language, {formatting = 'raw'})
			language = conf.wikidataToLanguageSlug[wikidataID]
			if language then
				if tl_languages[language] == nil then
					-- 'c' = 'nota linguaggio c'
					tl_languages[language] = ''
					noLanguages = false
					improved = true
				end
			else
				allFound = false
			end
		end

		if nszero then
			if improved then
				if tl_has then
					-- Wikidata ha migliorato il template e il template aveva già altri valori
					s = s .. '[[Categoria:Linguaggio di programmazione differente da Wikidata]]'
				else
					-- Wikidata ha migliorato il template che era vuoto
					s = s .. '[[Categoria:Linguaggio di programmazione letto da Wikidata]]'
				end
			else
				-- No, `#var` non fa quello che uno si aspetterebbe
				if p._templateHasExtraInformations(frame) or count(tl_languages) > count(wd_languages) then
					-- Nel template c'è qualcosa in più rispetto a Wikidata
					s = s .. '[[Categoria:Linguaggio di programmazione differente da Wikidata]]'
				else
					-- Non ha migliorato niente perchè sono gli stessi valori
					s = s .. '[[Categoria:Linguaggio di programmazione uguale a Wikidata]]'
				end
			end
		end
	else
		if tl_has and nszero then
			-- solo se il template specifica linguaggi ma Wikidata no
			s = s .. '[[Categoria:Linguaggio di programmazione assente su Wikidata]]'
		end
	end

	if noLanguages and nszero then
		if p._isFreeSoftware(frame) then
			s = s .. '[[Categoria:Software libero senza linguaggio]]'
		else
			s = s .. '[[Categoria:Software senza linguaggio]]'
		end
	end

	if not allFound and nszero then
		s = s .. '[[Categoria:Linguaggio di programmazione da Wikidata non previsto]]'
	end

	local i = 0
	for language, note in pairs(tl_languages) do
		local glue = i > 0 and '<br />' or ''
		s = s .. glue .. frame:expandTemplate{
			title = 'Software/Linguaggio',
			args = {language, categorizza, libero}
		} .. note
		i = i + 1
	end

	if altri then
		s = s .. altri
	end

	return s
end

return p