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 27 janvier 2019 à 23:33 et modifiée en dernier par Psemdel (discuter | contributions) (exception après pause). 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


-- ##### 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"
	todayyear=todaytable["year"] --global
	
	itemID=item:getId()
	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="1900"
			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=1900,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=1900,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(),
		}
	}