Hopp til innhold

Modul:Valuta

Fra Wikipedia, den frie encyklopedi
--- Class for handling valuta entries

local mt = {}
local Valuta = setmetatable( {}, mt )

--- Fast lookup of all entities known to the lib
local entitiesById = {}
local idByCode = mw.loadData( 'Module:Valuta/data' )

--- The local language
local contentLanguage = mw.getContentLanguage()

--- Lookup of missing class members
function Valuta:__index( key ) -- luacheck: no self
	return Valuta[key]
end

local validEntityTypes = {}
validEntityTypes['item'] = true

local validSchemaVersion = {}
validSchemaVersion[2] = true

function assertEntity( entity )
	assert( entity )
	assert( entity.id)
	assert( entity.type)
	assert( entity.schemaVersion )
	assert( validSchemaVersion[entity.schemaVersion] )
	assert( validEntityTypes[entity.type] )
end

function assertEntityId( id )
	assert( string.match( id, '^[qQ]%d+$') )
end

--- Create a new instance
function Valuta.create( ... )
	local self = setmetatable( {}, Valuta )
	self:_init( ... )
	return self
end

--- Initialize a new instance
function Valuta:_init( ... )
	self._items = {}
	for _,arg in ipairs( {...} ) do
		local tpe = type( arg )
		local value = arg
		if tpe == 'function' then
			value = arg()
			tpe = type( value )
		end
		if tpe == 'string' then
			local id = idByCode[value]
			assertEntityId( id )
			local entity = Valuta.loadEntity( id )
			assertEntity( entity )
			self.entity = entity
		elseif tpe == 'table' then
			assertEntity( value )
			local entity = value
			Valuta.registerEntity( entity, true )
			self.entity = entity
		elseif tpe == 'number' then
			self.value = value
		else
			error()
		end
	end
	return self
end

function mt.__call( tbl, ... )
	return tbl.create( ... )
end

function Valuta.registerEntity( entity, noAssert )
	assertEntity( entity, noAssert )
	local ucEntityId = string.upper( entity.id )
	entitiesById[ucEntityId] = entity
end

function Valuta.loadEntity( entityId, noAssert )
	assertEntityId( entityId, noAssert )
	local ucEntityId = string.upper( entityId )
	local entity = entitiesById[ucEntityId]
	if not entity then
		entity = mw.wikibase.getEntity( ucEntityId )
		if not entity then
			return nil
		end
		Valuta.registerEntity( entity, true )
	end
	return entity
end

function Valuta:getValue()
	return self.value
end

function Valuta:getBestStatements( propertyId )
	return self.entity:getBestStatements( propertyId )
end

function Valuta:getSymbolStatements()
	local claims = self:getBestStatements( 'P5061' )
	if #claims == 0 then
		claims = self:getBestStatements( 'P558' )
	end
	return claims
end

function Valuta:getSymbols()
	local rendered = {}
	for i,v in ipairs( self:getSymbolStatements() ) do
		rendered[i] = mw.wikibase.renderSnak( v.mainsnak )
	end
	return rendered
end

function Valuta:getCodeStatements()
	return self:getBestStatements( 'P498' )
end

function Valuta:getCodes()
	local rendered = {}
	for i,v in ipairs( self:getCodeStatements() ) do
		rendered[i] = mw.wikibase.renderSnak( v.mainsnak )
	end
	return rendered
end

function Valuta:getLabel( lang )
	return lang and self.entity:getLabel( lang ) or self.entity:getLabel()
end

function Valuta:getPriceStatements()
	local claims = self:getBestStatements( 'P2284' )
	return claims
end

function Valuta:getSitelink( site )
	return site and self.entity:getSitelink( site ) or self.entity:getSitelink()
end

function Valuta:formatTitlestring( lang )
	local items = {}
	local label = self:getLabel( lang )
	local symbol = unpack( self:getSymbols() )
	if label and symbol then
		local formatted = string.format( '%s (%s)', label, symbol )
		table.insert( items, formatted )
	elseif label and not symbol then
		local formatted = string.format( '%s', label )
		table.insert( items, formatted )
	elseif not label and symbol then
		local formatted = string.format( '%s', symbol )
		table.insert( items, formatted )
	end
	local value = self:getValue()
	if value then
		--local formatted = string.format( '%g', value )
		local formatted = contentLanguage:formatNum( value )
		if #items > 0 then
			table.insert( items, ': ' )
		end
		table.insert( items, formatted )
	end
	return table.concat( items, '' )
end

function Valuta:formatWikitext( site )
	local items = {}
	local sitelink = self:getSitelink( site )
	local code = unpack( self:getCodes() )
	if sitelink and code then
		local formatted = string.format( '[[%s|%s]]', sitelink, code )
		table.insert( items, formatted )
	elseif sitelink and not code then
		local formatted = string.format( '[[%s]]', sitelink )
		table.insert( items, formatted )
	elseif not sitelink and code then
		local formatted = string.format( '[[%s]]', code )
		table.insert( items, formatted )
	end
	local value = self:getValue()
	if value then
		local formatted = contentLanguage:formatNum( value )
		if #items > 0 then
			table.insert( items, ' ' )
		end
		table.insert( items, formatted )
	end
	return table.concat( items, '' )
end

function Valuta:format( site, lang )
	local html = mw.html.create( 'span' )
		:addClass( 'note' )
		:addClass( 'nowrap' )
		:attr( 'title', self:formatTitlestring( lang ) )
		:wikitext( self:formatWikitext( site ) )
	return html
end

function Valuta.isValidCode( code )
	return not not idByCode[code]
end

function Valuta.parse( str )
	local items = {}
	local len = string.len( str )
	local index = 1
	local first = nil
	local last = nil
	local step = 10
	local keep = index
	repeat
		local valuta = nil
		keep = index
		step = step - 1
		first, last = string.find( str, '^%s+', index)
		if first then
			index = last+1
		end
		first, last = string.find( str, '^[A-Z][A-Z][A-Z] *[0-9%.,]+[0-9]', index)
		if first then
			if string.find( string.sub( str, -1 ), '[%.,]' ) then
				last = last - 1
			end
			local code = string.sub( str, first, first+2 )
			local value = contentLanguage:parseFormattedNumber( string.sub( str, first+3, last ) )
			if value and Valuta.isValidCode( code ) then
				valuta = Valuta.create( code, value )
			end
		end
		if valuta then
			table.insert( items, string.sub( str, keep, first-1 ) )
			table.insert( items, tostring( valuta:format() ) )
		else
			table.insert( items, string.sub( str, keep, keep ) )
		end
		index = (last or keep)+1
	until (index > len)
		
	return table.concat( items, '' )
end

function Valuta.query( frame )
	local valutas = {}
	if not frame.args[1] then
		frame = frame:getParent()
	end
	for _,v in ipairs( frame.args ) do
		table.insert( valutas, Valuta.parse( v ) )
	end
	return table.concat( valutas, ', ' )
end

return Valuta