Aller au contenu

Module:Infobox/Cycliste

Cette page fait l’objet d’une mesure de semi-protection étendue.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 1 août 2019 à 13:04 et modifiée en dernier par Od1n (discuter | contributions) (variables locales au module, au lieu de "globales de chez globales" ; j'ai un peu lutté pour comprendre l'histoire : on a un traitement coûteux qui produit "amateur" et "pro" à la fois, et on veut l'exécuter une seule fois, pas une fois quand on demande "amateur" et encore une fois (redondante) quand on demande ensuite "pro"). 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 Cycliste.


local person = require "Module:Infobox/Fonctions/Personne"
local Wikidata = require "Module:Wikidata"
local wikibase = mw.wikibase
local Complexedate = require "Module:Date complexe"
local wikidataON=1 
local finalyear=2030
local initialyear=1900

-- lazy-filled by listofTeamTable(), on first call of AmateurTeamTable() or ProTeamTable()
local teamamateur
local teampro

-- ##### Functions from Cycling race module copied #####
--[[ Iterator to get all statements for an entity and property which are not deprecated and have a value]]
local function nextStatement(state, i)
	local s
	repeat
		i = i + 1
		local s = state[i]
		if s and s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then
			return i, s
		end
	until s == nil
end
local function statements(QID, PID)
	return nextStatement, wikibase.getAllStatements(QID, PID), 0
end

--[[ Get any value for a property which is not deprecated ]]
local function firstValue(QID, PID, field)
	local ss = wikibase.getAllStatements(QID, PID)
	for _, s in pairs(ss) do
		if s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then
			return field and s.mainsnak.datavalue.value[field] or s.mainsnak.datavalue.value
		end
	end
end

--[[ Go from season of a team to the team ]]
local function getParentID(teamID)
	return firstValue(teamID, 'P361', 'id') -- P361 is 'part of'
		or firstValue(teamID, 'P5138', 'id') -- P5138 is 'season of club or team'
end

--[[ Get sitelink with no wiki no formating ]]
local function getRawTeamLink(teamID)
	local sitelink
	local parentID = getParentID(teamID)
	if parentID then -- try parent team first
		sitelink = mw.wikibase.getSitelink(parentID)
	end
	if not sitelink then
		sitelink = mw.wikibase.getSitelink(teamID)
	end
	return sitelink
end

--[[ Get a Wikidata statement for an entity and property valid at the given timevalue ]]
local function getStatementForTime(ID, property, time)
	for _, s in statements(ID, property) do
		local start, startPrecision, END, endPrecision
		local q = s.qualifiers
		if q then
			if q.P580 and q.P580[1] and	q.P580[1].snaktype == 'value' then -- P580 is start time
				start = q.P580[1].datavalue.value.time
				startPrecision = q.P580[1].datavalue.value.precision
				if startPrecision == 9 then -- precision is years
					start = string.sub(start, 1, 5) -- Cut of everything after year
				elseif startPrecision == 10 then -- precision is months
					start = string.sub(start, 1, 8) -- Cut of everything after month
				end
			end
			if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end time
				END = q.P582[1].datavalue.value.time
				endPrecision = q.P582[1].datavalue.value.precision
			end
		end
		if not start or start <= time then
			if not END then
				return s
			end
			if endPrecision == 9 then -- precision 9 is 'years'
				END = string.sub(END, 1, 6) .. '13' -- Set month to 13
			elseif endPrecision == 10 then -- precision 10 is 'months'
				END = string.sub(END, 1, 9) .. '32' -- Set day to 32
			end
			if END > time then
				return s
			end
		end
	end
end

local function getOfficialName(teamID, timeOfRace)
	local p1448 = getStatementForTime(teamID, 'P1448', timeOfRace) -- P1448 is official name
	if p1448 then
		if available_lang_priority and p1448.qualifiers and p1448.qualifiers.P1448 then
			local q = p1448.qualifiers.P1448
			local wantedLanguages = {}
			local best = 999
			local name
			for i, lang in ipairs(translations.lang_priority) do
				wantedLanguages[lang] = i
			end
			for _, l in pairs(q) do
				if l.snaktype == 'value' then
					local lang = l.datavalue.value.language
					if wantedLanguages[lang] and wantedLanguages[lang] < best then
						best = wantedLanguages[lang]
						name = l.datavalue.value.text
					end
				end
			end
			if name	then return name, true end
		end
		return p1448.mainsnak.datavalue.value.text, false
	end
	return wikibase.getLabel(teamID) -- No official name, try label
end

--[[ Get sitelink, categoryID and maybe country for a team.
	Returns sitelink, team category ID, countryID (only countryID if country arg is true ]]
local function getTeamLinkCat(teamID, timeOfRace, country) --we expect here directly the team, not team season
	local name, sitelink, parentID, catID
	-- Find team category
	local teamCats = {"Q6154783","Q20638319","Q382927","Q1756006","Q23726798","Q20738667","Q28492441","Q20639848",
	"Q20639847","Q20652655","Q20653563","Q20653564","Q20653566","Q2466826","Q26849121"}

	if not catID then
		p31 =getStatementForTime(teamID, 'P31',timeOfRace) 
		if p31 then	catID  = p31.mainsnak.datavalue.value.id end
	end
	if not catID then catID ='Q53534649' end
	-- Find country if needed
	local countryID
	if country or catID == 'Q23726798' or catID == 'Q20738667' then
		countryID = firstValue(teamID, 'P17', 'id') -- P17 is country
	end
	if countryID and (catID == 'Q23726798' or catID == 'Q20738667') then
		-- It is a national cycling team
		name = getCountryName(countryID)
		if catID == 'Q20738667' then -- national cycling team U23
			local s
			if wiki == 'fr' then s = ' espoirs'
			elseif wiki == 'mk' then s = ' под 23 години'
			elseif wiki == 'ar' then s = ' تحت 23'
			elseif wiki == 'es' then s = ' sub-23'
			else s = ' U23'
			end
			name = name .. s
		end
		sitelink = getRawTeamLink(teamID)
	else
		-- It is not a national cycling team
		local isLocal
		parentID = getParentID(teamID)
		if parentID then -- try parent team first
			sitelink = wikibase.getSitelink(parentID)
			name, isLocal = getOfficialName(parentID, timeOfRace)
		end
		if not sitelink then
			sitelink = wikibase.getSitelink(teamID)
		end

		if not name or (not isLocal and available_lang_priority) then
			local partName, partIsLocal = getOfficialName(teamID, timeOfRace)
			if partName and (not name or partIsLocal) then
				name = partName
			end
		end
	end
	if sitelink then
		if name then
			sitelink = '[[' .. sitelink .. '|' .. name .. ']]'
		else
			sitelink = '[[' .. sitelink .. ']]'
		end
	else
		if name then
			sitelink = name
		else
			sitelink = (ParentID and wikibase.getLabel(ParentID)) or
				wikibase.getLabel(TeamID) or 'No name'
		end
	end
	return sitelink, catID, countryID
end

-- ##### Functions for the Infobox #####
--For the case with direct input of the parameters
local function teamValue( teamParam, dateParam )
	return function( localdata )
		local names, periods = localdata[ teamParam ], localdata[ dateParam ]
		if not names then
			return nil
		end
		if names then
			names =  mw.text.split(names, '<br />')
			periods = mw.text.split(periods or '', '<br />')
		end
		local tab =  mw.html.create('table')
		for i, name in pairs(names) do
			local row = mw.html.create('tr')
				:tag('td'):wikitext(periods[i] or ''):done()
				:tag('td'):wikitext(name):done()
			tab:node(row):done()
		end
		tab:done()
		return tostring(tab)
	end
end

local function presentTeam(item)
	local todaytable=os.date("*t")  
	local teamId, result
	if mw.ustring.len(todaytable["month"])==1 then todaytable["month"]='0'..todaytable["month"] end
	if mw.ustring.len(todaytable["day"])==1 then todaytable["day"]='0'..todaytable["day"] end	
	local today='+'..todaytable["year"].."-"..todaytable["month"].."-"..todaytable["day"].."T00:00:00Z"
	finalyear=tonumber(todaytable["year"])+1 --global
		
	itemID=item:getId()
	local temp=firstValue(itemID, 'P569','time') 
	if temp then
		_, _, initialyear,_,_ = string.find(temp, "(%d+)-(%d+)-(%d+)")
	end
	local p54=getStatementForTime(itemID, 'P54', today) 
	if p54  then
		teamId= p54.mainsnak.datavalue.value.id
		result=getTeamLinkCat(teamId, today)
		return  result 
	else 
		return nil
	end
end

local function convertdate(date1, beginorend1)
	if date1==0 then
		if beginorend1==0 then --begin
			year1=tostring(initialyear)
			m1="01"
			d1="01"
		else
			year1=tostring(finalyear)
			m1="12"
			d1="31"
		end
	else
		_, _, year1,m1,d1 = string.find(date1, "(%d+)-(%d+)-(%d+)")
		if m1 ==nil or m1=="00" then
			if beginorend1==0 then --begin
				m1="01"
				d1="01"
			else--end
				m1="12"
				d1="31"
			end
		end
	end
	return '+'..year1.."-"..m1.."-"..d1.."T00:00:00Z"
end

local function getstartendtime(q)
	-- look for start and end time of team by the riders
	local starttime, endtime, stagiaire
	local outputtable={}
	
	if q then
		if q.P580 and q.P580[1] and	q.P580[1].snaktype == 'value' then -- P580 is start time
			starttime =q.P580[1].datavalue.value.time
		elseif q.P585 and q.P585[1] and	q.P585[1].snaktype == 'value' then
			starttime =q.P585[1].datavalue.value.time
		else
			starttime =0
		end
		starttime=convertdate(starttime, 0)
		
		if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then
			endtime =q.P582[1].datavalue.value.time
		elseif q.P585 and q.P585[1] and	q.P585[1].snaktype == 'value' then
			endtime =q.P585[1].datavalue.value.time
		else
			endtime=0
		end
		endtime=convertdate(endtime, 1)
		
		if q.P39 and q.P39[1] and	q.P39[1].snaktype == 'value' then
			stagiaire = q.P39[1].datavalue.value
		else
			stagiaire = 0
		end
	end
	outputtable[1]=starttime
	outputtable[2]=endtime
	outputtable[3]=stagiaire
	return outputtable
end

local function listofTeam(item)
	--first we have to read P54 of the rider
	local starttime, endtime, teamId
	local riderteam, timetable={},{}
	if not itemID then itemID=item:getId() end
	
	for ii, p54 in statements(itemID, 'P54') do --itemID loaded in presentTeam
		if p54 then
			teamId=p54.mainsnak.datavalue.value.id
		else
			teamId=nil
		end
		local q = p54.qualifiers
		if q then
			timetable=getstartendtime(q)
			table.insert(riderteam,{teamId, timetable[1],  timetable[2], timetable[3]})
		end
	end
	return  riderteam
end

local function formatdate(mm,yy)
	local month=math.ceil(mm/2)
	if month==12 or month==1 then
		return yy
	else
		local date1='+'..yy.."-"..month.."-".."01".."T00:00:00Z"
		local newobj = Complexedate.splitDate(date1)  
		local temp
		if newobj.month == 0 or newobj.month==nil then
			temp=newobj.year
		else
			temp=newobj.month..'.'..newobj.year
		end
		return temp 
	end
end

local function getteaminfo(teamId,mm,yy,dd)
	--get the nature and name of the team for the date mm,yy
	local outputtable={}
	mm=tostring(mm)
	yy=tostring(yy)
	dd=tostring(dd)
	if mw.ustring.len(mm)==1 then mm='0'..mm end
	
	thistime='+'..yy.."-"..mm.."-"..dd.."T00:00:00Z"
	local sitelink, teamnature=getTeamLinkCat(teamId, thistime, false) 

	if teamnature=='Q20639848' or teamnature=='Q20652655' or teamnature=='Q26849121'  then --club
		teamnature=1--amateur
	elseif teamnature=='Q2466826' or teamnature=='Q20639847' or teamnature=='Q1756006' or teamnature=='Q20653566' then
		teamnature=2--pro
	else
		teamnature=2--pro
	end
	outputtable[1]=teamnature
	outputtable[2]=sitelink
	return outputtable
end

local function analyzeteam(teamrider)
	local teamoutput,teaminfo={}, {}	
	for i=1,24 do
		teamoutput[i]={}
		for j=initialyear,finalyear do
			teamoutput[i][j]={}
			for k=1,3 do
				teamoutput[i][j][k]=0
			end
		end
	end

	local teamId, starttime, endtime,getinfo
	local startyear, startmonth,endyear, endmonth, startday, endday

	if teamrider==nil then return nil end
	
	for ii, v in pairs(teamrider) do --for each team where was the rider
		--reload
		teamId=	teamrider[ii][1]
		starttime=teamrider[ii][2]
		endtime=teamrider[ii][3]
		stagiaire=teamrider[ii][4]
		--exception managed at the reading
		_, _, startyear,startmonth,startday = string.find(starttime, "(%d+)-(%d+)-(%d+)")
		_, _, endyear,endmonth,endday = string.find(endtime, "(%d+)-(%d+)-(%d+)")

		startyear=tonumber(startyear)
		startmonth=tonumber(startmonth)
		endyear=tonumber(endyear)
		endmonth=tonumber(endmonth)

		if startyear<=endyear then --test of congruence
			for yy=startyear,endyear do 
				for mm=1,12 do
					getinfo=0
					if yy==startyear and yy==endyear then
						if mm>=startmonth and mm<=endmonth then getinfo=1 end
					elseif yy==startyear then
						if mm>=startmonth then getinfo=1 end
					elseif yy==endyear then
						if mm<=endmonth then getinfo=1 end
					else
						getinfo=1
					end
					if getinfo==1 then	
						local mmindex=(mm-1)*2+1
						if (yy==startyear) and (mm==startmonth) and (startday~='01' and startday~='00' and startday~=nil)then 
							teaminfo=getteaminfo(teamId,mm,yy,startday)
							teamoutput[mmindex+1][yy][1]=teaminfo[1] 
							teamoutput[mmindex+1][yy][2]=teaminfo[2] 
							teamoutput[mmindex+1][yy][3]=stagiaire	
						else
							teaminfo=getteaminfo(teamId,mm,yy,1)
							teamoutput[mmindex][yy][1]=teaminfo[1] 
							teamoutput[mmindex][yy][2]=teaminfo[2] 
							teamoutput[mmindex][yy][3]=stagiaire
							if teamoutput[mmindex+1][yy][1]==0 or stagiaire~=0 then --too avoid problem with team name change during the month
								teaminfo=getteaminfo(teamId,mm,yy,30)
								teamoutput[mmindex+1][yy][1]=teaminfo[1] 
								teamoutput[mmindex+1][yy][2]=teaminfo[2] 
								teamoutput[mmindex+1][yy][3]=stagiaire
							end
						end
					end
				end
			end
		end
	end
	return teamoutput --a filled matrix with the link and nature of the teams
end

local function synthetizetable(teamtablecomplete)
	local teampro={} 
	local teamamateur={}
	local empty=1
	local active=0
	local templink, tempstartmonth,tempstartyear, tempendmonth,tempendyear,pointer, tempstagiaire
	local startdate, enddate
	
	for yy=initialyear,finalyear do
		for mm=1,24 do
			mmindex=mm
			if teamtablecomplete[mmindex][yy][1]==2 or teamtablecomplete[mmindex][yy][1]==1 then
				if empty==1 then --first line
					active=1
					empty=0
					if teamtablecomplete[mmindex][yy][1]==1 then
						pointer=1
					else
						pointer=2
					end
					templink=teamtablecomplete[mmindex][yy][2]
					tempstagiaire=teamtablecomplete[mmindex][yy][3]
					tempstartmonth=mmindex
					tempstartyear=yy
				else
					temp1=teamtablecomplete[mmindex][yy][1]
					temp2=teamtablecomplete[mmindex][yy][2]				
					if pointer==temp1 and templink==temp2 then --no change
						if yy==finalyear and mm==24 then--present team
							startdate=formatdate(tempstartmonth,tempstartyear)
							enddate=''
							if pointer==1 then
								table.insert(teamamateur,{templink, startdate,enddate,tempstagiaire})
							else
								table.insert(teampro,{templink, startdate,enddate,tempstagiaire})
							end
						end
					else--change
						--save the old
						if active==1 then --if active==0 then it was already saved
							if mmindex==1 then
								tempendyear=yy-1
								tempendmonth=24
							else
								tempendyear=yy
								tempendmonth=mmindex-1
							end
							startdate=formatdate(tempstartmonth,tempstartyear)
							enddate=formatdate(tempendmonth,tempendyear)
							if pointer==1 then
								table.insert(teamamateur,{templink, startdate,enddate,tempstagiaire})
							else
								table.insert(teampro,{templink, startdate,enddate,tempstagiaire})
							end
						end
						--save the new
						active=1
						if teamtablecomplete[mmindex][yy][1]==1 then
							pointer=1
						else
							pointer=2
						end
						templink=teamtablecomplete[mmindex][yy][2]
						tempstagiaire=teamtablecomplete[mmindex][yy][3]
						tempstartmonth=mmindex
						tempstartyear=yy
					end --change
				end--first line
			elseif active==1 then --teamtablecomplete[mmindex][yy][1]==2 or teamtablecomplete[mmindex][yy][1]==1
				active=0
				--save the old
				if mmindex==1 then
					tempendyear=yy-1
					tempendmonth=24
				else
					tempendyear=yy
					tempendmonth=mmindex-1
				end
				startdate=formatdate(tempstartmonth,tempstartyear)
				enddate=formatdate(tempendmonth,tempendyear)
				if pointer==1 then
					table.insert(teamamateur,{templink, startdate,enddate,tempstagiaire})
				else
					table.insert(teampro,{templink, startdate,enddate,tempstagiaire})
				end
			end  --teamtablecomplete[mmindex][yy][1]==2 or teamtablecomplete[mmindex][yy][1]==1
		end-- for mm
	end--for yy
	return teamamateur,teampro
end

local function listofTeamTable(item)
	local teamrider = listofTeam(item)--raw list of team
	if not teamrider then
		return nil
	end
	local teamtablecomplete=analyzeteam(teamrider) --table with links and nature of teams
	teamamateur,teampro=synthetizetable(teamtablecomplete) --table formated, global
end	

local function TeamTable(teamrider, titlesing, titleplural)
local rows =  mw.html.create('table')
	if teamrider ~=nil then
		for i, period in pairs(teamrider) do 
			if teamrider[i][2]==teamrider[i][3] then
				if teamrider[i][4]==0 then
					periodtemp=teamrider[i][2]
					nametemp=teamrider[i][1]
				else
					periodtemp=teamrider[i][2]
					nametemp=teamrider[i][1]..' (stagiaire)'
				end
			else
				if teamrider[i][4]==0 then  
					periodtemp=teamrider[i][2]..'-'..teamrider[i][3]
					nametemp=teamrider[i][1]
				else
					periodtemp=teamrider[i][2]..'-'..teamrider[i][3]
					nametemp=teamrider[i][1]..' (stagiaire)'
				end
			end
			local row = mw.html.create('tr')
			:tag('td'):wikitext(periodtemp or ''):done()
			:tag('td'):wikitext(nametemp):done()
			rows:node(row):done()
		end
	end
	
	local title = titleplural

	local temprows=tostring(rows)
	if teamrider ==nil or #teamrider==0 then
		temprows=nil
	else
		if #teamrider == 1 then
			title = titlesing
		end
	end
	return {type = 'table', title = title, rows = {{type = 'row', value = function () return temprows end}}}
end

local function AmateurTeamTable(localdata)
	-- teamamateur called before
	local NotUCInames = localdata['équipes non-UCI']
    local Amateurnames = localdata['équipes amateur']

	if NotUCInames or Amateurnames or localdata['équipes UCI'] or localdata['équipes pro'] then
	   wikidataON=0
	end

	if wikidataON==1 then
		if teamamateur==nil then
			listofTeamTable(localdata.item)
		end
		return TeamTable(teamamateur, 'Équipe non-UCI','Équipes non-UCI')
	else
		if NotUCInames then
		    return {type = 'table', title = 'Équipes non-UCI', rows = {{type = 'row', value = teamValue( 'équipes non-UCI', 'années non-UCI' )}}}
		else
			return {type = 'table', title = 'Équipes amateurs', rows = {{type = 'row', value = teamValue( 'équipes amateur', 'années amateur' )}}}
		end
	end
end		

local function ProTeamTable(localdata)
    local UCInames = localdata['équipes UCI']
    local Pronames = localdata['équipes pro']
	
	if wikidataON==1 then
		if teampro==nil then
			listofTeamTable(localdata.item)
		end
		return TeamTable(teampro, 'Équipe UCI','Équipes UCI')
	else
		if UCInames then
		    return {type = 'table', title = 'Équipes UCI', rows = {{type = 'row', value = teamValue( 'équipes UCI', 'années UCI' )}}}
		else
			return {type = 'table', title = 'Équipes professionnelles', rows = {{type = 'row', value = teamValue( 'équipes pro', 'années pro' )}}}
		end
	end
end

return 
	{
		maincolor = '#FFDF80',
		parts = {
			person.title('cyclisme'),
			person.mainimage('Article à illustrer Cycliste'),
			{type = 'table', title = 'Informations', rows = {
				person.othernames(),
				person.birth(),
				person.death(),
				person.placeofburial(),
				person.nationality(),
				{type = 'row', label = 'Équipe actuelle', value = 'équipe',
				wikidata = function ( item )
					return presentTeam(item)
					end,
				},
				{
					type = 'row',
					label = 'Spécialité',
					singularlabel = 'Spécialité',
					plurallabel = 'Spécialités',
					value = 'type coureur',
					property = 'P413'
				},
				{type = 'row', label = 'Latéralisation', property = 'P552'},
				--person.appearance(),
				{type = 'row', label = 'Groupe sanguin', property = 'P1853'},
				--person.family(),
				person.awards(),
				},
			},
			AmateurTeamTable,
			ProTeamTable,
			{type = 'table', title = 'Équipes dirigées', rows = {
				{type = 'row', value = teamValue( 'équipes dirigées', 'années direction' )}
			}},
			{type = 'table', title = 'Principales victoires', rows = {
				{type = 'row', value = 'victoires principales'},
			}},
		person.plaque(),
        person.tombe(),
		}
	}