Модуль:Вікізьвесткі/P54

Зьвесткі зь Вікіпэдыі — вольнай энцыкляпэдыі
 
Дакумэнтацыя модулю Дакумэнтацыя модулю[прагляд] [рэдагаваць] [гісторыя] [абнавіць]

Модуль для адлюстраваньня ўласьцівасьці Вікізьвестак d:Property:P54 (спартовы клюб).

Функцыя модулю formatPropertyP54 вяртае запоўнены шаблён {{Футбаліст/Кар’ера}}.

Выклік модулю адбываецца праз шаблён {{Вікізьвесткі/p54}}.

Выкарыстоўваецца ў шаблёне {{Футбаліст}} (праз падшаблён {{Футбаліст/Кар’ера}}).
local p = {}
local categoryLinksToEntitiesWithMissingLocalLanguageLabel = '[[Катэгорыя:Вікіпэдыя:Артыкулы з элемэнтамі зь Вікізьвестак, якія патрабуюць перакладу]]';
local categoryLinksToEntitiesWithMissingLabel = '[[Катэгорыя:Вікіпэдыя:Артыкулы з элемэнтамі зь Вікізьвестак, якія патрабуюць подпісу]]';
local contentLanguageCode = mw.getContentLanguage():getCode();

local function min( prev, next )
	if ( prev == nil ) then return next;
	elseif ( prev > next ) then return next;
	else return prev; end
end

local function max( prev, next )
	if ( prev == nil ) then return next;
	elseif ( prev < next ) then return next;
	else return prev; end
end

local function getTimeBoundariesFromQualifiers( context, statement, qualifierId )
	-- only support exact date so far, but need improvment
	local left = nil;
	local right = nil;
	if ( statement.qualifiers and statement.qualifiers[qualifierId] ) then
		for _, qualifier in pairs( statement.qualifiers[qualifierId] ) do
			local boundaries = context.parseTimeBoundariesFromSnak( qualifier );
			if ( not boundaries ) then return nil; end
			left = min( left, boundaries[1] );
			right = max( right, boundaries[2] );
		end
	end

	if ( not left or not right ) then
		return nil;
	end

	return { left, right };
end

local function getParentsInBoundariesSnakImpl( context, entity, boundaries, propertyIds )
    local WDS = require('Модуль:Сьцьверджаньні Вікізьвестак')
	local results = {};
	if entity.claims then
		for _, propertyId in ipairs( propertyIds ) do
			local filteredClaims = WDS.filter( entity.claims, propertyId .. '[rank:preferred, rank:normal]' );
			if filteredClaims then
				for _, claim in pairs( filteredClaims ) do
					local startBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P580' );
					local endBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P582' );
		
					if ( (startBoundaries == nil or ( startBoundaries[2] <= boundaries[1]))
							and (endBoundaries == nil or ( endBoundaries[1] >= boundaries[2]))) then
						table.insert( results, claim.mainsnak );
					end 
				end
			end

			if #results > 0 then
				break;
			end
		end
	end

	return results;
end

local function getParentsInBoundariesSnakImplNotStrong( context, entity, boundaries, propertyIds )
    local WDS = require('Модуль:Сьцьверджаньні Вікізьвестак')
	local results = {};
	if entity.claims then
		for _, propertyId in ipairs( propertyIds ) do
			local filteredClaims = WDS.filter( entity.claims, propertyId .. '[rank:preferred, rank:normal]' );
			if filteredClaims then
				for _, claim in pairs( filteredClaims ) do
					local startBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P580' );
					local endBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P582' );
		
					if ( (startBoundaries == nil or ( startBoundaries[1] <= boundaries[1]))
							and (endBoundaries == nil or ( endBoundaries[2] >= boundaries[2]))) then
						table.insert( results, claim.mainsnak );
					end 
				end
			end

			if #results > 0 then
				break;
			end
		end
	end

	return results;
end

-- get current of historic name of place
function getLabel2( context, entity, boundaries)
	if not entity then
		return nil;
	end
	local lang = mw.language.getContentLanguage();
	local langCode = lang:getCode();
	local returnLangCode = langCode;

	-- name from label
	-- TODO: lang:getFallbackLanguages()
	local label = nil;
	label, returnLangCode = mw.wikibase.getLabelWithLang( entity.id );

	-- name from properties
	local results = getParentsInBoundariesSnakImpl( context, entity, boundaries, {
		'P1813[language:' .. langCode .. ']',
		'P1448[language:' .. langCode .. ']',
		'P1705[language:' .. langCode .. ']'
	} );
        if #results == 0 then
     	  results = getParentsInBoundariesSnakImplNotStrong( context, entity, boundaries, {
		'P1813[language:' .. langCode .. ']',
		'P1448[language:' .. langCode .. ']',
  		'P1705[language:' .. langCode .. ']'
	  } );
        end

	for r, result in pairs( results ) do
		if result.datavalue
				and result.datavalue.value
				and result.datavalue.value.text then
			label = result.datavalue.value.text;
			returnLangCode = langCode;
			break;
		end
	end

	return label, returnLangCode;
end

local function formatEntityId( context, entityId, options )
	-- атрыманьне лакалізаванай назвы
    local entity = mw.wikibase.getEntity(entityId);
    local label = nil;
    local labelLanguageCode = nil;
    local boundaries = { os.time() * 1000, os.time() * 1000 + 999 };
    if options.teamDate then
		local boundaries = context.parseTimeBoundariesFromSnak(options.teamDate)
    end
    label, labelLanguageCode = getLabel2( context, entity, boundaries)
    if label == nil then
      if ( options.text and options.text ~= '' ) then
          label = options.text
      else 
		  label, labelLanguageCode = mw.wikibase.getLabelWithLang( entityId ); 
      end
    end
    
	-- вызначэньне адпаведнай паказванаму элемэнту катэгорыі
	local category = ''
	options['category'] = 'P6112'
	if ( options['category'] ) then
		local WDS = require('Модуль:Сьцьверджаньні Вікізьвестак');
		local claims = WDS.filter( entity.claims, options['category'] );
		if ( claims ) then
			for _, claim in pairs( claims ) do
				if ( claim.mainsnak
						and claim.mainsnak
						and claim.mainsnak.datavalue
						and claim.mainsnak.datavalue.type == "wikibase-entityid" ) then
					local catEntityId =  'Q' .. claim.mainsnak.datavalue.value["numeric-id"];
					local catEntity = mw.wikibase.getEntity( catEntityId );
					if ( catEntity and catEntity:getSitelink() ) then
						category = '[[' .. catEntity:getSitelink() .. ']]';
					end
				end
			end
		end
	end

	-- атрыманьне спасылкі па ідэнтыфікатары
    local link = mw.wikibase.sitelink( entityId )
    if link then
        if label then
			if ( contentLanguageCode ~= labelLanguageCode ) then
            	return '[[' .. link .. '|' .. label .. ']]' .. categoryLinksToEntitiesWithMissingLocalLanguageLabel .. category;
            else
            	return '[[' .. link .. '|' .. label .. ']]' .. category;
            end
        else
            return '[[' .. link .. ']]' .. category;
        end
    end

    if label then
	    if ( contentLanguageCode ~= labelLanguageCode ) then
	      category = category .. categoryLinksToEntitiesWithMissingLocalLanguageLabel
	    end
        -- чырвоная спасылка
        -- TODO: разабрацца, чаму не заўсёды ёсьць options.frame
        if not mw.title.new( label ).exists and options.frame then
            return '[[' .. label .. ']]<sup>[[:d:' .. entityId .. '|[d]]]</sup>' .. category;
        end
    
		-- TODO: перанесьці да праверкі на існаваньне артыкула
		local sup = '';
		if ( not options.format or options.format ~= 'text' )
				and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: перапісаць на format=text
				then
			sup = '<sup>[[:d:' .. entityId .. '|[d]]]</sup>'
		end

        -- аднайменны артыкул ужо існуе — выводзіцца тэкст і спасылка на Вікізьвесткі
        return label .. sup .. category
    end
    -- паведамленьне аб адсутнасьці лякалізаванай назвы
    -- not good, but better than nothing
    return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style{{=}}"border-bottom: 1px dotted; cursor: help; white-space: nowrap">?</span>' .. categoryLinksToEntitiesWithMissingLabel .. category;
end

local function orderByDate( teamClaims )
   local orderedTeams = {}
   while (#teamClaims > 0) do
     local j = 1
     local firstClaim = teamClaims[1]
     for i=2,#teamClaims,1 do
       if (teamClaims[i].qualifiers and teamClaims[i].qualifiers.P580 and firstClaim.qualifiers and firstClaim.qualifiers.P580) then
         if (teamClaims[i].qualifiers.P580[1].datavalue.value.time < firstClaim.qualifiers.P580[1].datavalue.value.time) then
           firstClaim = teamClaims[i]
           j = i
         else 
           if (teamClaims[i].qualifiers.P580[1].datavalue.value.time == firstClaim.qualifiers.P580[1].datavalue.value.time and 
teamClaims[i].qualifiers and teamClaims[i].qualifiers.P582 and firstClaim.qualifiers and firstClaim.qualifiers.P582) then
             if (firstClaim.qualifiers.P1642 or teamClaims[i].qualifiers.P1642) then
               if (teamClaims[i].qualifiers.P582[1].datavalue.value.time > firstClaim.qualifiers.P582[1].datavalue.value.time) then
                 firstClaim = teamClaims[i]
                 j = i
               end
             else
               if (teamClaims[i].qualifiers.P582[1].datavalue.value.time < firstClaim.qualifiers.P582[1].datavalue.value.time) then
                 firstClaim = teamClaims[i]
                 j = i
               end
             end
           end
         end
       else
         if (teamClaims[i].qualifiers and teamClaims[i].qualifiers.P582 and firstClaim.qualifiers and firstClaim.qualifiers.P580) then
           if (teamClaims[i].qualifiers.P582[1].datavalue.value.time <= firstClaim.qualifiers.P580[1].datavalue.value.time) then
             firstClaim = teamClaims[i]
             j = i
           end
         else
           if (teamClaims[i].qualifiers and teamClaims[i].qualifiers.P582 and firstClaim.qualifiers and firstClaim.qualifiers.P582) then
             if (teamClaims[i].qualifiers.P582[1].datavalue.value.time < firstClaim.qualifiers.P582[1].datavalue.value.time) then
               firstClaim = teamClaims[i]
               j = i
             end
           else
             if (teamClaims[i].qualifiers and teamClaims[i].qualifiers.P580 and firstClaim.qualifiers and firstClaim.qualifiers.P582) then
               if (teamClaims[i].qualifiers.P580[1].datavalue.value.time < firstClaim.qualifiers.P582[1].datavalue.value.time) then
                 firstClaim = teamClaims[i]
                 j = i
               end
             end
           end
         end
       end
     end
     table.insert(orderedTeams, firstClaim)
     table.remove(teamClaims, j)
  end
  return orderedTeams
end

local function parseISO8601Year(str)
	local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
	local Y, M, D = mw.ustring.match( str, pattern )
	return tonumber(Y)
end

local function formatFootballCareer( context, options, statement )
     local snak = '|'

     if (statement.qualifiers and statement.qualifiers.P580 and statement.qualifiers.P582) then
        if (statement.qualifiers.P580[1].datavalue and statement.qualifiers.P582[1].datavalue and  parseISO8601Year(statement.qualifiers.P580[1].datavalue.value.time) == parseISO8601Year(statement.qualifiers.P582[1].datavalue.value.time)) then
          snak  = snak ..  parseISO8601Year(statement.qualifiers.P580[1].datavalue.value.time)
       else
       	  if (statement.qualifiers.P580[1].datavalue) then
        	snak  = snak ..  parseISO8601Year(statement.qualifiers.P580[1].datavalue.value.time)
          end
       	  if (statement.qualifiers.P580[1].datavalue or statement.qualifiers.P582[1].datavalue) then
        	snak = snak .. '—'
          end
       	  if (statement.qualifiers.P582[1].datavalue) then
	          snak  = snak ..  parseISO8601Year(statement.qualifiers.P582[1].datavalue.value.time)
          end
       end
     else
       if (statement.qualifiers and statement.qualifiers.P580) then
          snak  = snak ..  parseISO8601Year(statement.qualifiers.P580[1].datavalue.value.time) .. '—{{0|4}}'
       else
         if (statement.qualifiers and statement.qualifiers.P582) then
            snak  = snak ..  '{{0|4}}—' .. parseISO8601Year(statement.qualifiers.P582[1].datavalue.value.time)
         end
       end
     end
     snak = snak .. ' | '

     if (statement.qualifiers 
        and statement.qualifiers.P1642 )
        and ('Q' .. statement.qualifiers.P1642[1].datavalue.value["numeric-id"] == 'Q2914547') then
       snak = snak .. '{{Арэнда}} '
     end

      if (statement.qualifiers and statement.qualifiers.P582) then
        options.teamDate = statement.qualifiers.P582[1]
      end

     snak = snak .. formatEntityId( context, "Q" .. statement.mainsnak.datavalue.value['numeric-id'], options ) .. ' | ' 

     if (statement.qualifiers 
        and statement.qualifiers.P1350) then
        snak  = snak ..  string.gsub(statement.qualifiers.P1350[1].datavalue.value['amount'], '^%+', '')
     end 
     if (statement.qualifiers 
        and statement.qualifiers.P1351) then
        snak  = snak ..  ' (' ..  string.gsub(statement.qualifiers.P1351[1].datavalue.value['amount'], '^%+', '') ..  ')'
     end
    return snak
end

function p.formatPropertyP54( context, options, statement )
	if ( not context ) then error( 'context not specified' ); end;
	if ( not options ) then error( 'options not specified' ); end;
	if ( not options.entity ) then error( 'options.entity missing' ); end;

    -- Абыход усіх заяваў сьцьвярджэньня і з накапленьнем аформленых пераважных 
    -- заяваў у табліцы
    local out = '{{Футбаліст/Кар’ера'
    local clubs = '|кар’ера_клюбы = {{Спартовая кар’ера'
    local natteams = '|кар’ера_зборныя = {{Спартовая кар’ера'
    local clubsUpdate = ''
    local natteamsUpdate = ''
    local currentTeam = ''
    local currentTeamNumericId = ''
    local loanFrom = ''
    local loan = false
    local partOf = ''
    local manager = '|кар’ера_трэнэр = {{Вікізьвесткі/p6087|teamEntity=Q476028,Q28140340,Q51481377,Q94579592,Q6979593}}'

    local claims = context.selectClaims( options, options.property .. '[rank:preferred, rank:normal]' );
    if (claims == nil) then
    	out = out .. manager .. '}}'
    	return options.frame:preprocess(out)
    end

    for i, claim in ipairs(orderByDate(claims)) do
      local team = mw.wikibase.getEntityObject( "Q" .. claim.mainsnak.datavalue.value['numeric-id'] )
      local WDS = require('Модуль:Сьцьверджаньні Вікізьвестак')
      local teamClaims = team.claims
      if ( options.clubEntity ) then 
        teamClaims = WDS.filter(team.claims, 'P31[' .. options.clubEntity .. ']')
      end

      local partOfClaim = WDS.filter(team.claims, 'P361')
      if (partOfClaim ~= nil and partOfClaim[1] ~= nil) then
    	partOf = partOfClaim[1].mainsnak.datavalue.value['numeric-id']
      end

      if (teamClaims[1]) then
        local formattedStatement = formatFootballCareer( context, options, claim )
        clubs = clubs .. formattedStatement 
	    if (claim.qualifiers and claim.qualifiers.P585) then
	    	if (clubsUpdate == '') then
				clubsUpdate = claim.qualifiers.P585[1].datavalue.value.time
			else
				if (claim.qualifiers.P585[1].datavalue.value.time > clubsUpdate) then
					clubsUpdate = claim.qualifiers.P585[1].datavalue.value.time
				end
			end
	    end
		if (claim.qualifiers and not claim.qualifiers.P582) then
			if (claim.qualifiers.P1642 
        			and ('Q' .. claim.qualifiers.P1642[1].datavalue.value["numeric-id"] == 'Q2914547')) then
        		if (partOf ~= '' and currentTeamNumericId == partOf) then
        			mw.log('фарм-клюб')
        		else
					loanFrom = currentTeam
					loan = true
					currentTeam = formatEntityId( context, "Q" .. claim.mainsnak.datavalue.value['numeric-id'], options )
					currentTeamNumericId = claim.mainsnak.datavalue.value['numeric-id']
				end
			else
				if (loan) then
					loanFrom = formatEntityId( context, "Q" .. claim.mainsnak.datavalue.value['numeric-id'], options )
				else
					currentTeam = formatEntityId( context, "Q" .. claim.mainsnak.datavalue.value['numeric-id'], options )
					currentTeamNumericId = claim.mainsnak.datavalue.value['numeric-id']
				end
        	end
		end
      end
      if ( options.natEntity ) then 
        teamClaims = WDS.filter(team.claims, 'P31[' .. options.natEntity .. ']')
      end
      if (teamClaims[1]) then
        local formattedStatement = formatFootballCareer( context, options, claim )
        natteams = natteams .. formattedStatement 
	    if (claim.qualifiers and claim.qualifiers.P585) then
	    	if (natteamsUpdate == '') then
				natteamsUpdate = claim.qualifiers.P585[1].datavalue.value.time
			else
				if (claim.qualifiers.P585[1].datavalue.value.time > natteamsUpdate) then
					natteamsUpdate = claim.qualifiers.P585[1].datavalue.value.time
				end
			end
		end
      end
    end
    if (clubsUpdate ~= '') then
    	clubsUpdate = '|абнаўленьне(клюб) = ' .. mw.getContentLanguage():formatDate( 'j xg Y', clubsUpdate );
    end
    if (natteamsUpdate ~= '') then
	    natteamsUpdate = '|абнаўленьне(зборная) = ' .. mw.getContentLanguage():formatDate( 'j xg Y', natteamsUpdate );
    end
    if (currentTeam ~= '') then
	    currentTeam = '|клюб = ' .. currentTeam;
	    if (loanFrom ~= '') then
	    	currentTeam = currentTeam .. ' (у арэндзе з клюбу «' .. loanFrom .. '»)'
	    end
    end
    if (currentTeamNumericId ~= '') then
	    currentTeamNumericId = '|клюб_ід = ' .. currentTeamNumericId
    end
    
    out = out .. clubs ..  '}}' .. natteams ..  '}}' .. manager .. currentTeam .. currentTeamNumericId .. clubsUpdate .. natteamsUpdate .. '}}'

    return options.frame:preprocess(out)
end

return p