Модуль:Wikidata/Medals

З Вікіпедыі, свабоднай энцыклапедыі

Дакументацыю да гэтага модуля можна стварыць у Модуль:Wikidata/Medals/Дакументацыя

local WDS = require( 'Module:WikidataSelectors' )
local moduleDate = require( 'Module:Wikidata/date' )
local awardsOrder = mw.ext.data.get( "Wikidata/awards order.tab" )
local p = {}

function getElementByDate( context, statements, actualDate )
	local elements = {};
	for _, statement in pairs( statements ) do
		if ( statement.rank ~= 'deprecated' ) then
			local element;
			if ( statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value ) then
				element = statement.mainsnak.datavalue.value;
			end
			local startTime = -9223372036854775808;
			if ( statement.qualifiers
					and statement.qualifiers.P580
					and statement.qualifiers.P580[1] ) then
				 local parsedStartTime = context.parseTimeFromSnak( statement.qualifiers.P580[1] );
				 if ( parsedStartTime ) then
				 	startTime = parsedStartTime;
				 end
			end
			if ( element ) then
				elements[ startTime ] = element;
			end
		end
	end

	local goodElement = nil;
	if ( elements ) then
		local ordered_dates = {}
		for beginDate in pairs(elements) do
			table.insert(ordered_dates, beginDate)
		end
		table.sort(ordered_dates)

		for i = 1, #ordered_dates do
			local beginDate, element = ordered_dates[i], elements[ ordered_dates[i] ];
			if ( actualDate >= beginDate ) then
				goodElement = element;
			end
		end
	end
	if ( goodElement ) then
		return goodElement;
	end
	return nil;
end

-- атрыманне радка з датамі з табліцы кваліфікатараў
function datesFromQualifier( context, options, qualifierId )
	local dates = {}
	local qualifiers = options.qualifiers[ qualifierId ]

	if qualifiers then
		for _, qualifier in pairs( qualifiers ) do
			if (qualifier and qualifier.datavalue and qualifier.datavalue.value) then
			    local dateValue = moduleDate.formatDate( context, options, qualifier.datavalue.value )
			    if dateValue then
			    	table.insert( dates, dateValue )
			    end
			end
		end
	end

	return table.concat( dates, ', ' )
end

--[[ 
  Функцыя для атрымання ідэнтыфікатара сутнасцяў 

  Прымае: аб’ект табліцу сутнасці
  Вяртае: радковы ідэнтыфікатар (тыпу P18, Q42)
]]
local function getEntityIdFromValue( value )
	local prefix = ''
	if value['entity-type'] == 'item' then
		prefix = 'Q'
	elseif value['entity-type'] == 'property' then
		prefix = 'P'
	else
		return nil
	end
	return prefix .. value['numeric-id']
end

--Property function for [[d:Property:P166]]
function p.formatProperty( context, options )
	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 claims;
	if options.property then -- TODO: Почему тут может не быть property?
		claims = context.selectClaims( options, options.property );
	end
	if claims == nil then
		return '' --TODO error?
	end

	-- Обход всех заявлений утверждения и с накоплением оформленых
	-- предпочтительных заявлений в таблице.
	local formattedData = {}

	for i, claim in ipairs( claims ) do
		if ( claim.mainsnak and
			claim.mainsnak and
			claim.mainsnak.datavalue and
			claim.mainsnak.datavalue.type == 'wikibase-entityid'
		) then
			local valueId = claim.mainsnak.datavalue.value.id
			local formattedStatement = context.formatStatement( options, claim )
			-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
			if ( formattedStatement and formattedStatement ~= '' ) then
				formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
				table.insert( formattedData, {
					id = valueId,
					html = formattedStatement,
				} )
			end
		end
	end
	
	-- Сортировка медалей по старшинству
	local orderedData = {}
	local lastValue;

    if awardsOrder then
	for i, awardFields in ipairs( awardsOrder.data ) do
		local awardOrder = awardFields[ 1 ]
		if awardOrder == '-' then
			-- separator
			if lastValue ~= '-' then
				table.insert( orderedData, '<br>' )
				lastHeight = nil
			end
		else
			for k, awardData in ipairs( formattedData ) do
				if awardOrder == awardData.id and not awardData.used then
					table.insert( orderedData, awardData.html )
					formattedData[ k ].used = true
				end
			end
		end
	end
	end

	for i, awardData in ipairs( formattedData ) do
		if not awardData.used then
			table.insert( orderedData, awardData.html )
		end
	end

	local lastHeight
	for i, awardHtml in ipairs( orderedData ) do
		local height = mw.ustring.match( awardHtml, 'x%d+px' )
		if height and lastHeight and height ~= lastHeight then
			table.insert( orderedData, i, '<br>' )
		end
		lastHeight = height
	end

	-- создание текстовой строки со списком оформленых заявлений из таблицы
	local out = mw.text.listToText( orderedData, options.separator, options.conjunction )
	if out ~= '' then
		if options.before then
			out = options.before .. out
		end
		if options.after then
			out = out .. options.after
		end
	end

	return out
end

--Property:P166
function p.formatMedalValue( context, options, statement )
	local entityId = statement.id
	if not entityId then
		return statement
	end
	local label = mw.wikibase.label( entityId )
	local image = nil
	local entity = mw.wikibase.getEntity( entityId )
	local size = 'x17px'
	local medalDate = nil

	local dates = ''
	if options.qualifiers then
		mw.logObject( options.qualifiers )
		local startDates = {}
		dates = datesFromQualifier( context, options, 'P580' )
		if dates ~= '' then
			local endDates = datesFromQualifier( context, options, 'P582' )
			if endDates and endDates ~= '' then
				dates = dates .. ' — ' .. endDates
			end
		else
			dates = datesFromQualifier( context, options, 'P585' )
		end
		if (options.qualifiers.P580) then
		  medalDate = context.parseTimeFromSnak(options.qualifiers.P580[1])
	    elseif (options.qualifiers.P585) then
		  medalDate = context.parseTimeFromSnak(options.qualifiers.P585[1])
	    end
	end

	-- атрыманне выявы планкі з элемента
	local ribbonImageClaims = WDS.filter( entity.claims, 'p2425' )
	if ribbonImageClaims and #ribbonImageClaims then
		if medalDate then
	    	image = getElementByDate( context, ribbonImageClaims, medalDate )
	    else
		  for i, claim in pairs( ribbonImageClaims ) do
		  	if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
				image = claim.mainsnak.datavalue.value
				break
			end
		  end
     	end
	end
	
	-- атрыманне абразка з элемента
	if not image then
		local imageClaims = WDS.filter( entity.claims, 'p2910' )
		if imageClaims and #imageClaims then
	    	if medalDate then
	        	image = getElementByDate( context, imageClaims, medalDate )
			    size = '40x40px'
	        else
			    for i, claim in pairs( imageClaims ) do
			    	if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
			    		image = claim.mainsnak.datavalue.value
			    		size = '40x40px'
			    		break
			    	end
		    	end
		     end
		end
	end

	-- атрыманне катэгорыі
	local recipientCategoryClaims = WDS.filter( entity.claims, 'p2517' )
	local recipientCategory = ''
	if recipientCategoryClaims and #recipientCategoryClaims then
		for i, claim in pairs( recipientCategoryClaims ) do
			if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
				local categoryLink = mw.wikibase.sitelink( claim.mainsnak.datavalue.value.id )
				if categoryLink then
					recipientCategory = recipientCategory .. '[[' .. categoryLink .. ']]'
				end
			end
		end
	end

	-- атрыманне спасылкі па ідэнтыфікатары і выснова планкі
	if image then
		local link = mw.wikibase.sitelink( entityId )
		local out = '[[File:' .. image .. '|border|' .. size .. '|link='
		
		-- атрыманне спасылкі з бацькоўскага элемента
		-- для ступеняў звычайна толькі адзін агульны артыкул
		if not link then
			local partOfClaims = WDS.filter( entity.claims, 'p361' ) -- частка ад
			if not partOfClaims or #partOfClaims == 0 then
				partOfClaims = WDS.filter( entity.claims, 'p279' ) -- падклас ад
			end
			if partOfClaims and #partOfClaims then
				for i, claim in pairs( partOfClaims ) do
					if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
						link = mw.wikibase.sitelink( claim.mainsnak.datavalue.value.id )
						if link then
							break;
						end
					end
				end
			end
		end
		
		if link then
			out = out .. link
		else
			out = out .. 'd:' .. entityId
		end
		if label then
			out = out .. '|' .. label
		end
		out = out .. ']]'
		out = out .. recipientCategory

		return out
	end

	local out = context.formatValueDefault( context, options, statement )
	if out and out ~= '' then
		if dates ~= '' then
			out = out .. ' (' .. dates .. ')'
		end
		return '<p style="text-align:left>' .. out .. recipientCategory .. '</p>'
	end
	
	return ''
end

return p;