Module:Infobox/Cycliste/forTest

Une page de Wikipédia, l'encyclopédie libre.

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

Cette page définit un module d'infobox.


--copy of Infobox/Cyclist to allow unittesting, as Unittesting requires a table of functions p.

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

local p={}

-- lazy-filled by listofTeamTable(), on first call of AmateurTeamTable() or ProTeamTable()
local teamamateur, 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 checkTime(s, time)
	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
	return nil
end

local function getStatementForTime(ID, property, time)
	local temp
	for _, s in statements(ID, property) do
		temp =checkTime(s, time)
		if temp then return temp end
	end
	return nil
end

local function getOfficialName(teamID, timeOfRace) -- for team
	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
	local label=wikibase.getLabel(teamID)
	return label -- 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)
	--countryID is not used in this module
	local name, sitelink, parentID, catID
	-- Find team category
	local teamCats = {
		Q6154783 = true, Q20638319 = true, Q382927 = true, Q1756006 = true, Q23726798 = true,
		Q20738667 = true, Q28492441 = true, Q20639848 = true, Q20639847 = true, Q20652655 = true,
		Q20653563 = true, Q20653564 = true, Q20653566 = true, Q2466826 = true, Q26849121 = true,
		Q78464255 = true, Q80425135=true
	}
	for _, p31 in statements(teamID, 'P31') do
		if checkTime(p31, timeOfRace) then
			local natureID = p31.mainsnak.datavalue.value.id
			if teamCats[natureID] then
				catID = natureID
				break
			end
		end
	end
	--main team
	-- Find country if needed
	local countryID
	if country or catID == 'Q23726798' or catID == 'Q20738667' then
		countryID = firstValue(teamID, 'P1532', 'id') -- P17 is country for sport
		if countryID == nil then
			countryID = firstValue(teamID, 'P17', 'id') -- P17 is country
		end
	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'	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
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

	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 = nil
		end
	end
	return starttime, endtime, stagiaire
end

local function listofTeam(item)
	--first we have to read P54 of the rider
	local riderteam={}
	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
			local starttime, endtime, stagiaire=getstartendtime(q)
			table.insert(riderteam,{teamId=teamId, starttime=starttime, endtime=endtime, stagiaire=stagiaire})
		end
	end
	return riderteam
end

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

local function getteaminfo(teamId,mm,yy,dd)
	--get the nature and name of the team for the date mm,yy
	local amateurteam
	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) 
	local amateurcat={Q20639848=true,Q20652655=true,Q26849121=true}

	if amateurcat[teamnature] then --club
		amateurteam=true--amateur
	else
		amateurteam=false--pro
	end
	return amateurteam, sitelink
end

local function analyzeteam(teamrider)
	local teamoutput={}
	for i=1,24 do --init table
		teamoutput[i]={}
		for j=initialyear,finalyear do
			teamoutput[i][j]={}
			teamoutput[i][j]['amateurteam']=nil
			teamoutput[i][j]['link']=nil
			teamoutput[i][j]['stagiaire']=nil
		end
	end

	local teamId, amateurteam, sitelink
	local startyear, startmonth,endyear, endmonth, startday, endday

	if teamrider==nil then return nil end
	
	for _, v in pairs(teamrider) do --for each team where was the rider
		--exception managed at the reading
		_, _, startyear,startmonth,startday = string.find(v['starttime'], "(%d+)-(%d+)-(%d+)")
		_, _, endyear,endmonth,endday = string.find(v['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
					local mmindex=(mm-1)*2+1
					--avoid reading info where the team is not the one of the rider
					getinfo=true
					if (yy==startyear and mm<startmonth) or (yy==endyear and mm>endmonth) then
						getinfo=false
					end

					if getinfo then
						if (yy==startyear) and (mm==startmonth) and (startday~='01' and startday~='00' and startday~=nil)then 
							amateurteam, sitelink=getteaminfo(v['teamId'],mm,yy,startday)
							teamoutput[mmindex+1][yy]['amateurteam']=amateurteam
							teamoutput[mmindex+1][yy]['link']=sitelink
							teamoutput[mmindex+1][yy]['stagiaire']=v['stagiaire']
						else
							amateurteam, sitelink=getteaminfo(v['teamId'],mm,yy,1)
							teamoutput[mmindex][yy]['amateurteam']=amateurteam
							teamoutput[mmindex][yy]['link']=sitelink
							teamoutput[mmindex][yy]['stagiaire']=v['stagiaire']
							if teamoutput[mmindex+1][yy]['amateurteam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month
								amateurteam, sitelink=getteaminfo(v['teamId'],mm,yy,30)
								teamoutput[mmindex+1][yy]['amateurteam']=amateurteam
								teamoutput[mmindex+1][yy]['link']=sitelink
								teamoutput[mmindex+1][yy]['stagiaire']=v['stagiaire']
							end
						end
					end
				end
			end
		end
	end
	return teamoutput --a filled matrix with the link and nature of the teams
end

local function insertteam(teamamateur,teampro,startdate,enddate,v)
	local startdate2=formatdate(startdate)
	local enddate2=formatdate(enddate)

	if v['amateurteam'] then
		table.insert(teamamateur,{link=v['link'], startdate=startdate2,enddate=enddate2,stagiaire=v['stagiaire']})
	else
		table.insert(teampro,{link=v['link'], startdate=startdate2,enddate=enddate2,stagiaire=v['stagiaire']})
	end
	return teamamateur,teampro
end

local function synthetizetable(analyzedteam)
	local teampro, teamamateur, tempteam, tempstartdate, tempenddate={}, {},{},{},{}
	local empty=true
	local active=false

	for yy=initialyear,finalyear do
		for mm=1,24 do
			local v=analyzedteam[mm][yy]
			if v['amateurteam']~=nil then
				if empty then --first line
					active=true
					empty=false
					tempteam=v
					tempstartdate['month']=mm
					tempstartdate['year']=yy
				else
					if tempteam['amateurteam']==v['amateurteam'] and tempteam['link']==v['link']
					and tempteam['stagiaire']==v['stagiaire'] then --no change
						if yy==finalyear and mm==24 then--present team
							teamamateur,teampro=insertteam(teamamateur,teampro,tempstartdate,'',tempteam)
						end
					else--change
						--save the old
						if active then --if active false then it was already saved
							if mm==1 then
								tempenddate['year']=yy-1
								tempenddate['month']=24
							else
								tempenddate['year']=yy
								tempenddate['month']=mm-1
							end
							teamamateur,teampro=insertteam(teamamateur,teampro,tempstartdate,tempenddate,tempteam)
						end
						--save the new
						active=true
						tempteam=v
						tempstartdate['month']=mm
						tempstartdate['year']=yy
					end --change
				end--first line
			elseif active then --there was a team and now there is an empty period
				active=false
				--save the old
				if mm==1 then
					tempenddate['year']=yy-1
					tempenddate['month']=24
				else
					tempenddate['year']=yy
					tempenddate['month']=mm-1
				end
				teamamateur,teampro=insertteam(teamamateur,teampro,tempstartdate,tempenddate,tempteam)
			end  
		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 analyzedteam=analyzeteam(teamrider) --table with links and nature of teams
	teamamateur,teampro=synthetizetable(analyzedteam) --table formated, global
end	

local function TeamTable(teamrider, titlesing, titleplural)
	local temprows=nil
	local title = titleplural
	if teamrider and #teamrider~=0 then
		local nametemp, periodtemp
		local rows =  mw.html.create('table')
		for _, v in pairs(teamrider) do 
			nametemp=v['link']
			if v['startdate']==v['enddate'] then
				periodtemp=v['startdate']
			else
				periodtemp=v['startdate']..'-'..v['enddate']
			end
			if v['stagiaire'] then
				nametemp=nametemp..' (stagiaire)'
			end
			local row = rows:tag('tr')
			row:tag('td'):wikitext(periodtemp or '')
			row:tag('td'):wikitext(nametemp)
		end
		temprows=tostring(rows)
		if #teamrider == 1 then
			title = titlesing
		end
	else
		temprows=nil
	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=false
	end

	if wikidataON then
		if teamamateur==nil and localdata.item 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 then
		if teampro==nil and localdata.item 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

local function toboolean(str)
	if str=="true" then
		return true
	elseif str=="false" then
		return false
	else
		return str
	end
end

function p.testlocal(frame) --function to test local functions
	local function_name=frame.args[1]
	local argu=frame.args
	local temp, temp2

	if function_name=='firstValue' then
		return firstValue(argu[2],argu[3],argu[4])
	elseif function_name=='getStatementForTime' then
		temp=getStatementForTime(argu[2],argu[3],argu[4])	
		if temp then
			return temp.mainsnak.datavalue.value.id
		else
			return 'nil'
		end
	elseif function_name=='getTeamLinkCat' then
		temp, _=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]),toboolean(argu[5]))	
		if temp then return temp else return 'nil' end
	elseif function_name=='getTeamLinkCat2' then
		temp, temp2 =getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]),toboolean(argu[5]))	
		if temp2 then return temp2 else return 'nil' end		
	elseif function_name=='convertdate' then
		if argu[2]=='0' then argu[2]=0 end
		return convertdate(argu[2],tonumber(argu[3]))
	end
end

return p