Aller au contenu

Module:Infobox/Logiciel

Cette page est semi-protégée.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 23 novembre 2022 à 15:25 et modifiée en dernier par Metamorforme42 (discuter | contributions) (corr.). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[voir] [modifier] [historique] [purger]

Cette page définit un module d'infobox. Pour les conseils sur l'usage de ce module, voyez Modèle:Infobox Logiciel.

Ce module est destiné à remplacer l’infobox Logiciel. Il n’est pas encore fonctionnel et il ne faut pas l’utiliser dans l’espace principal.

Prochaines étapes

  1. déplacement des fonctions vers Module:Infobox/Fonctions/Logiciel
  2. documentation du module (cf. Projet:Infobox/Lua/Documentation)
  3. documentation du modèle
  4. tests de quelques semaines avec une deuxième annonce sur discussion projet:Informatique et sur la pdd de l’infobox
  5. demande de SP pour les deux pages de modules concernées
  6. remplacement du modèle, si pas d’opposition ni de bug majeur
  7. suppression de la catégorie de maintenance devenue inutile : Catégorie:Page utilisant l'infobox Logiciel avec une description mais pas d'image
  8. suppressions des sous-cats inutilisées de Catégorie:Logiciel par langage de programmation (toutes celles avec plus qu’un seul langage)

Paramètres pour l’infobox

Le module reprend tous les paramètres de Modèle:Infobox Logiciel. Les changements sont détaillés sur Discussion_modèle:Infobox_Logiciel#Passage_en_lua (en attendant que je fasse la documentation).

local general = require "Module:Infobox/Fonctions"
local wikidata = require "Module:Wikidata"
local date = require "Module:Date"
local localdata = require "Module:Infobox/Localdata"
local page = mw.title.getCurrentTitle()

-- Liste locale de la fin des noms de catégories par langage de programmation
local programmingLanguageCat = {
	Q234657 = 'ActionScript',
	Q154755 = 'Ada',
	Q165436 = 'Assembleur',
	Q15777 = 'C',
	Q2407 = 'C++',
	Q487378 = 'Delphi',
	Q334879 = 'Erlang',
	Q83303 = 'Fortran',
	Q189248 = 'GNU Bash',
	Q37227 = 'Go',
	Q34010 = 'Haskell',
	Q776372 = 'Information Processing Language',
	Q251 = 'Java',
	Q2005 = 'JavaScript',
	Q132874 = 'Lisp',
	Q849146 = 'Common Lisp',
	Q1334586 = 'Emacs Lisp',
	Q633894 = 'Object Pascal',
	Q188531 = 'Objective-C',
	Q212587 = 'OCaml',
	Q81571 = 'Pascal',
	Q42478 = 'Perl',
	Q59 = 'PHP',
	Q28865 = 'Python',
	Q161053 = 'Ruby',
	Q575650 = 'Rust',
	Q460584 = 'Scala',
	Q959549 = 'Script shell',
	Q235086 = 'Smalltalk',
	Q1138939 = 'Vala',
	Q2378 = 'Visual Basic',
}
--[[
-- Catégorise le logiciel en fonction du langage de programmation dans lequel il est écrit
-- (cette fonction était initialement implémentée dans Modèle:Infobox Logiciel en wikicode)
--]]
local function catByProgrammingLanguage()
	-- On vérifie qu’on est dans l’espace principal
	-- À des fins de tests, on peut forcer la catégorisation avec le paramètre "forcer la catégorisation"
	-- qui doit être non-vide
	if page.namespace ~= 0 and not localdata['forcer la catégorisation'] then
		return ''
	end

	-- S’il y a des données locales, on abandonne pour éviter toute confusion,
	-- vu qu’on ne va pas utiliser les données locales (pas structurées, et avec des wikiliens)
	-- et qu’on ne veut pas que la catégorisation diverge de l’affichage dans l’infobox
	if localdata['langage de programmation'] then
		return ''
	end
	local plang, plangnum = wikidata.getIds(localdata.item, {
			property = 'P277',
			atdate= "today",
		})
	if #plangnum == 0 then
		return ''
	end
	local ret = ''
	local isCat = false
	for i=1, #plang  do
		local cat = programmingLanguageCat[plang[i]]
		if cat then
			ret = ret .. '[['..'Category:Logiciel écrit en ' .. cat .. ']]'
			isCat = true
		else
			-- Catégorie de maintenance
			ret = ret .. '[[' .. 'Category:Logiciel écrit en un langage sans catégorie associée' .. ']]'
		end
	end
	if isCat then
		-- Catégorie de maintenance
		ret = ret .. '[[' .. "Category:Logiciel catégorisé automatiquement par langage d'écriture" .. ']]'
	end
	return ret
end


--[[
-- Retourne les langues supportées par le logiciel.
-- Si il y en a au moins autant que "nbmax", affiche « Multilingue ».
-- Dans ce cas, si le français fait parti de ces langues, il est précisé « dont français ».
--]]
local function internationalisation(nbmax)
	return {
		type = 'row',
		label = '[[Internationalisation (informatique)|Langue]]',
		plurallabel = '[[Internationalisation (informatique)|Langues]]',
		value = 'langues',
		wikidata = function()
			local values, num = wikidata.formatAndCat {
				entity = localdata.item,
				conjtype = 'new line',
				property = 'P407',
				atdate = 'today',
				returnnumberofvalues = true,
			}
			if num and (num >= nbmax) then
				local fr = wikidata.getIds(localdata.item, {
					property = 'P407',
					targetvalue = 'Q150', -- français
					atdate = 'today',
					numval = 1,
				})
				values, num = wikidata.addLinkBack('[[Multilinguisme|Multilingue]]' .. (#fr ~= 0 and ' dont [[français]]' or ''), localdata.item, 'P407').. wikidata.addTrackingCat('P407'), 1
			elseif num == 1 then
				local multilingue = wikidata.getIds(localdata.item, {
					property = 'P407',
					targetvalue = 'Q20923490', -- multilingue
					atdate = 'today',
					numval = 1,
				})
				if #multilingue ~= 0 then
					-- on regarde si le français fait parti des langues qui ne sont pas en rang préféré
					local fr = wikidata.getIds(localdata.item, {
						property = 'P407',
						targetvalue = 'Q150', -- français
						atdate = 'today',
						numval = 1,
						rank = 'valid',
					})
					if #fr ~= 0 then
						values, num = wikidata.addLinkBack('[[Multilinguisme|Multilingue]]' .. (#fr ~= 0 and ' dont [[français]]' or ''), localdata.item, 'P407').. wikidata.addTrackingCat('P407'), 1
					end
				end
			end
			return values, num
		end,
	}
end
--[[
-- Retourne la ligne avec la première version connue du logiciel
--]]
local function firstVersion()
	return {
		type = 'row',
		label = 'Première version',
		wikidata = function()
			--[[
			-- On cherche les identifiants de version (P348) avec un qualificatif type de version (P548) égal à
			-- Q56514665 (première version).
			-- On ajoute les qualificatifs:
			-- * P1476 (titre),
			-- * P400 (plateforme),
			-- * P306 (système d’exploitation),
			-- * P577 (date de publication)
			-- Les paramètres locaux sont "date de première version" et "première version".
			--]]
			return wikidata.formatAndCat {
				entity = localdata.item,
				conjtype = 'new line',
				property = 'P348',
				qualifier = 'P548',
				qualifiervalue = 'Q56514665',
				qualifconjtype = 'comma',
				showqualifiers = {'P1476','P400','P306','P577'},
				showsource = true,
				qualiflinktopic = '-',
				rank = 'valid', -- La première version est généralement en rang normal, mais peut également être en rang préféré
				returnnumberofvalues = true,
			}
		end,
		value = function()
			--[[
			-- Si les paramètres "date de première version" ou "première version" sont renseignés,
			-- on ne cherche pas sur Wikidata
			-- (les deux valeurs étant liées, par cohérence il faut qu’elles soient renseignées au même endroit)
			--]]
			-- Désactivation de l’affichage du paramètre en utilisant '-'
			local versionNum = localdata['première version'] or ''
			local versionDate = localdata['date de première version'] or ''
			if (versionNum == '-') or (versionDate == '-') then
				return '-'
			end
			local r = versionNum ..
				((versionNum ~= '' and versionDate ~= '') and ' (' or '') ..
				(date.dateInfobox{args={'date', versionDate, nolinks=true}} or '') ..
				((versionNum ~= '' and versionDate ~= '') and ')' or '')
			if r ~= '' then
				return r
			else
				return nil
			end
		end,
	}
end

-- Types de versions qui sont considérés comme « version avancée » (ou non-stable)
local nonStableVersionTypes = {
	'Q3295609', -- version beta
	'Q2122918', -- version alpha
	'Q1072356', -- version RC
	'Q23356219', -- version pre-alpha
	'Q51930650', -- version pré-release
	'Q21727724', -- version non-stable
	'Q5209391', -- daily build
}

-- Valeur de P31 qui ne doivent pas être affichées dans le champ 'Type'
-- Il faudra envisager d’utiliser une propriété dédiée (à créer) et de faire en sorte que l’unique valeur P31 pour les logiciels soit Q7397.
-- Idem pour 'Politique de prix' (freeware, donationware, logiciel commercial, etc.), qui reste à remplir manuellement,
-- mais qu’il vaudrait mieux remplir par une propriété dédiée (à créer) que par P31.
-- Les valeurs relatives à la propriété intellectuelle du logiciel et la licence ne devraient pas être ajoutées dans P31 idéalement,
-- puisqu’il existe des propriétés qui permettent de préciser la licence exacte et donc de déduire ces informations.
local softwareTypesExcluded = {
	'Q166142', -- application
	'Q341', -- logiciel libre
	'Q7397', -- logiciel
	'Q218616', -- logiciel propriétaire
	'Q506883', -- logiciel libre et open-source
	'Q1130645', -- logiciel open-source
	'Q178285', -- freeware
	'Q10267', -- donationware
	'Q1340793', -- logiciel commercial
}

--[[
-- Retourne la ligne de la dernière version stable
--]]
local function lastStableVersion()
	return {
		type = 'row',
		label = "[[Version d'un logiciel|Dernière version]]",
		wikidata = function()
			--[[
			-- On cherche la valeur de P348 (identifiant de version) la plus récente,
			-- dont la valeur de P548 (type de version) n’est pas une version avancée.
			-- Idéalement, il faudrait juste regarder si c’est une version de type version stable (Q2804309)
			-- ou une version avec support étendu (Q104243413) mais ce n’est souvent pas renseigné.
			-- 
			-- On ajoute les qualificatifs:
			-- * P1476 (titre),
			-- * P400 (plateforme),
			-- * P306 (système d’exploitation),
			-- * P577 (date de publication)
			--
			-- Les paramètres locaux sont "date de dernière version" et "dernière version".
			--
			-- Si les paramètres "date de dernière version","dernière version", "date de version avancée", ou
			-- "version avancée" sont renseignés, on ne cherche pas sur Wikidata
			-- (ces valeurs étant liées, par cohérence il faut qu’elles soient renseignées au même endroit)
			--
			-- Dans cette fonction on suppose que les toutes les versions stables
			-- à ne pas afficher ne feront jamais parti du "best rank",
			-- c’est-à-dire qu’on affiche l’intégralité du "best rank" (à l’exception des versions non-stables)
			-- et on ne filtre pas par date : il peut y avoir différentes valeurs pertinentes pour la version stable (une par plateforme/os),
			-- indépendamment de la date de publication.
			--]]
			if localdata['date de dernière version'] or localdata['dernière version'] then
				-- valeur locale de la date de dernière version
				return nil, 0
			end
			if (localdata['version avancée'] or localdata['date de version avancée']) and (localdata['version avancée'] ~= '-' and localdata['date de version avancée'] ~= '-') then
				-- valeur locale de la date de version avancée
				return nil, 0
			end
			return wikidata.formatAndCat {
				entity = localdata.item,
				conjtype = 'new line',
				property = 'P348',
				excludequalifier = 'P548',
				qualifier = 'P577',
				showqualifiers = {'P1476','P400','P306','P577'},
				excludequalifiervalue = nonStableVersionTypes,
				showsource = true,
				qualiflinktopic = '-',
				qualifconjtype = 'comma',
				returnnumberofvalues = true,
				rank = 'best',
			}
		end,
		value = function()
			-- Désactivation de l’affichage du paramètre en utilisant '-'
			local versionNum = localdata['dernière version'] or ''
			local versionDate = localdata['date de dernière version'] or ''
			if (versionNum == '-') or (versionDate == '-') then
				return '-'
			end
			local r = versionNum ..
				((versionNum ~= '' and versionDate ~= '') and ' (' or '') ..
				(date.dateInfobox{args={'date', versionDate, nolinks=true}} or '') ..
				((versionNum ~= '' and versionDate ~= '') and ')' or '')
			if r ~= '' then
				return r
			else
				return nil
			end
		end,
	}
end

--[[
-- Retourne la ligne de la version avancée.
--]]
local function advancedVersion()
	return {
		type = 'row',
		label = "[[Version d'un logiciel|Version avancée]]",
		wikidata = function()
			--[[
			-- On cherche la valeur de P348 (identifiant de version) la plus récente,
			-- dont la valeur de P548 (type de version) est une version avancée.
			-- 
			-- Si la version avancée est affichée, on affiche le qualificatif date de publication (P548).
			--
			-- On ajoute les qualificatifs:
			-- * P1476 (titre),
			-- * P400 (plateforme),
			-- * P306 (système d’exploitation),
			-- * P577 (date de publication)
			--
			-- Les paramètres locaux sont "date de version avancée" et "version avancée".
			--
			-- Si les paramètres "date de dernière version", "dernière version", "date de version avancée", ou
			-- "version avancée" sont renseignés, on ne cherche pas sur Wikidata
			-- (ces valeurs étant liées, par cohérence il faut qu’elles soient renseignées au même endroit)
			--
			-- Dans cette fonction on suppose que les toutesles versions avancées
			-- à afficher feront toujours parti du "preferred rank",
			-- c’est-à-dire qu’on affiche l’intégralité du "preferred rank" (à l’exception des versions stables)
			-- Justification:
			-- * une version avancée qui est réellement avancée
			--   par rapport à la dernière version stable disponible, et qui est la plus récente disponible
			--   devrait toujours avoir le rang « préféré »
			-- * une version avancée qui n’est pas plus récente que la dernière version stable
			--   devrait toujours avoir le rang « normal »
			-- * une version avancée qui n’est pas la plus récente devrait toujours avoir le rang « normal ».
			-- * baser l’affichage sur les date de publication des différentes versions ne fonctionne pas bien
			--   lorsqu’il y a plusieurs branches qui ont un rythme de
			--   publication indépendants et plusieurs versions d’écart (par exemple pour firefox)
			-- * on ne peut pas se fier aux numéros de versions car ils ne sont pas toujours sémantiques
			-- 
			--]]
			if localdata['date de dernière version'] or localdata['dernière version'] or localdata['version avancée'] or localdata['date de version avancée'] then
				return nil, 0
			end
			return wikidata.formatAndCat {
				entity = localdata.item,
				conjtype = 'new line',
				property = 'P348',
				qualifier = 'P548',
				qualifiervalue = nonStableVersionTypes,
				showqualifiers = {'P1476','P400','P306','P577'},
				showsource = true,
				qualiflinktopic = '-',
				qualifconjtype = 'comma',
				returnnumberofvalues = true,
				rank = 'preferred',
			}
		end,
		value = function()
			-- Désactivation de l’affichage du paramètre en utilisant '-'
			local versionNum = localdata['version avancée'] or ''
			local versionDate = localdata['date de version avancée'] or ''
			if (versionNum == '-') or (versionDate == '-') then
				return '-'
			end
			local r = versionNum ..
				((versionNum ~= '' and versionDate ~= '') and ' (' or '') ..
				(date.dateInfobox{args={'date', versionDate, nolinks=true}} or '') ..
				((versionNum ~= '' and versionDate ~= '') and ')' or '')
			if r ~= '' then
				return r
			else
				return nil
			end
		end,
	} 
end

return {
	maincolor = '#DFEDFF',
	parts = {
		general.title('informatique'),
		-- Illustrations
		general.logo('Article à illustrer Logiciel'),
		general.mainimage('Article à illustrer Logiciel'),
		{
			type = 'table', title = 'Informations', rows = {
				-- Informations sur l’auteur
				{
					type = 'row',
					label = 'Créateur',
					plurallabel  ='Créateurs',
					value = 'créateur',
					wikidata = function()
						-- Si le "développeur" est une donnée locale, on ne cherche pas le créateur sur Wikidata
						-- pour ne pas risquer de faire un doublon avec la ligne "développeur"
						if localdata['développeur'] or localdata['développeurs'] then
							return nil, 0
						end
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = {'P170', 'P112'},
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Développeur|Développé par]]',
					plurallabel  ='[[Développeur|Développé par]]',
					value = {'développeur', 'développeurs'},
					wikidata = function()
						-- Si le "créateur" est une donnée locale, on ne cherche pas les devs sur Wikidata
						-- pour ne pas risquer de faire un doublon avec la ligne "créateur"
						if localdata['créateur'] then
							return nil, 0
						end
						local creators, creatornum = wikidata.formatAndCat {
							entity = localdata.item,
							property = {'P170', 'P112'},
							returnnumberofvalues = true,
						}
						local devs, devnum = wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P178',
							atdate= "today",
							returnnumberofvalues = true,
						}
						-- On affiche cette ligne que si le créateur est différent du développeur
						if (creatornum == devnum) and (creators == devs) then
							return nil, 0
						end
						return devs, devnum
					end,
				},
				{
					type = 'row',
					label = 'Début du [[Développement de logiciel|développement]]',
					value = 'début du développement',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P571',
							linktopic = '-',
							 -- on peut séparer les dates de début du développement par OS/plateforme
							showqualifiers = {'P400','P306'},
							returnnumberofvalues = true,
						}
					end,
				},
				-- Informations de version
				firstVersion(),
				lastStableVersion(),
				advancedVersion(),
				-- informations sur le projet
				{
					type = 'row',
					label = '[[Dépôt (informatique)|Dépôt]]',
					plurallabel = '[[Dépôt (informatique)|Dépôts]]',
					value = 'dépôt',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P1324',
							atdate= "today", -- ça ne sert à rien d’afficher une adresse qui n’est plus la bonne
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Assurance qualité]]',
					value = 'assurance qualité',
					property = 'P2992'
				},
				{
					type = 'row',
					label = 'État du projet',
					value = 'état'
				},
				{
					type = 'row',
					label = '[[Langage de programmation|Écrit en]]',
					value = 'langage de programmation',
					wikidata = function()
						local value, num = wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P277',
							atdate= "today", -- le logiciel peut avoir été ré-écrit en un autre langage
							returnnumberofvalues = true,
						}
						if num then
							value = value .. catByProgrammingLanguage() -- catégorisation
						end
						return value, num
					end,
				},
				{
					type = 'row',
					label = '[[Interface graphique|Interface]]',
					plurallabel = '[[Interface graphique|Interfaces]]',
					value = 'interface',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P1414',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Langage de programmation|Supporte le langage]]',
					plurallabel = '[[Langage de programmation|Supporte les langages]]',
					value = 'langages supportés',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P3985',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = "[[Système d'exploitation|Système d’exploitation]]",
					plurallabel  ="[[Système d'exploitation|Systèmes d’exploitation]]",
					value = {"système d'exploitation","systèmes d'exploitation"},
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P306',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Plate-forme (informatique)|Environnement]]',
					-- Note: la forme au pluriel "Environnements" est trop longue et empiète sur
					-- le contenu de la colonne de droite. Elle a donc été retirée.
					value = {'environnement','environnements'},
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P400',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Taille de fichier|Taille des données]]',
					value = 'taille des données',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P3575',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Format de données|Formats]] lus',
					value = 'importe',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P1072',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Format de données|Formats]] écrits',
					value = 'exporte',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P1073',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				internationalisation(4),
				{
					type = 'row',
					label = '[[Fichier exécutable|Fichier exécutable]]',
					plurallabel  ='[[Fichier exécutable|Fichiers exécutables]]',
					value = {"exécutable","exécutables"}
				},
				{
					type = 'row',
					label = 'Type',
					value = 'type',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							conjtype = 'new line',
							property = 'P31',
							excludevalues = softwareTypesExcluded,
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Politique de distribution]]',
					value = 'politique de prix'
				},
				{
					type = 'row',
					label = '[[Licence de logiciel|Licence]]',
					plurallabel  ='[[Licence de logiciel|Licences]]',
					value = {'licence','licences'},
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							conjtype = 'comma',
							property = 'P275',
							atdate = 'today',
							returnnumberofvalues = true,
							labelformat = function(qid)
								-- affichage de l’identifiant SPDX qui a l’avantage
								-- d’être court et explicite
								local label, isset = wikidata.formatStatements {
									entity = qid,
									numval = 1,
									property = 'P2479',
									returnnumberofvalues = true,
									atdate = 'today', -- les identifiants SPDX ont changé en avril 2015
								}
								-- fallback sur le label de la licence
								if isset == 0 then
									label = nil
								end
								return label
							end,
						}
					end,
				},
				{
					type = 'row',
					label = '[[Documentation logicielle|Documentation]]',
					value = 'documentation',
					wikidata = function()
						return wikidata.formatAndCat {
							entity = localdata.item,
							property = 'P2078',
							atdate= "today",
							returnnumberofvalues = true,
						}
					end,
				},
				general.website() -- site web
			},
		},
		{
			type = 'table',
			title = 'Chronologie des versions',
			rows = {
				{
					type = 'navbox',
					previousLabel = 'Version précédente',
					previousval = 'version précédente',
					previousproperty= 'P155',
					nextLabel = 'Version suivante',
					nextval = 'version suivante',
					nextproperty = 'P156',
					separated = true,
				},
			}
    	},
	}
}