Jump to content

Module:Authority control: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Mark Arsten (talk | contribs)
m Protected Module:Authority control: High-risk Lua module ([Edit=Block all non-admin users] (indefinite) [Move=Block all non-admin users] (indefinite))
added Wikidata parsing per lack of objections at Template talk:Authority control/Archive 3#Wikidata support
Line 9: Line 9:
return '[[Category:Miscellaneous pages with ' .. id .. ' identifiers]]'
return '[[Category:Miscellaneous pages with ' .. id .. ' identifiers]]'
end
end
end

function getIdsFromWikidata( item, property )
local ids = {}
if not item.claims[property] then
return ids
end
for _, statement in pairs( item.claims[property] ) do
table.insert( ids, statement.mainsnak.datavalue.value )
end
return ids
end
end


Line 135: Line 146:
return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
end
end
end

function inArray( value, array )
for _, element in pairs( array ) do
if value == element then
return true
end
end
return false
end
end


Line 152: Line 172:
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, ulanLink }
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, ulanLink }
}
}

local p = {}
local p = {}


Line 159: Line 179:
--Create rows
--Create rows
local elements = {}
local elements = {}

--Item
local item = mw.wikibase.getEntity()


--Worldcat
--Worldcat
Line 173: Line 196:
for k, params in pairs( conf ) do
for k, params in pairs( conf ) do
local val = parentArgs[params[1]]
local val = parentArgs[params[1]]
local text = ''

--Wikidata
if item ~= nil and params[3] ~= 0 then
local wikidataIds = getIdsFromWikidata( item, 'p' .. params[3] )
if wikidataIds[1] then
if val and val ~= '' then
--[[TODO Consistency check
if not inArray( val, wikidataIds ) then
text = text .. '[Category:Inconsistent Authority identifier between Wikidata and Wikipedia]'
end]]--
else
--Fallback
val = wikidataIds[1]
end
end
end

if val and val ~= '' then
if val and val ~= '' then
table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )

Revision as of 09:14, 21 August 2013

function getCatForId( id )
    local title = mw.title.getCurrentTitle()
    local namespace = title.namespace
    if namespace == 0 then
        return '[[Category:Wikipedia articles with ' .. id .. ' identifiers]]'
    elseif namespace == 2 and not title.isSubpage then
        return '[[Category:User pages with ' .. id .. ' identifiers]]'
    else
        return '[[Category:Miscellaneous pages with ' .. id .. ' identifiers]]'
    end
end

function getIdsFromWikidata( item, property )
    local ids = {}
    if not item.claims[property] then
        return ids
    end
    for _, statement in pairs( item.claims[property] ) do
        table.insert( ids, statement.mainsnak.datavalue.value )
    end
    return ids
end

function viafLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[http://viaf.org/viaf/' .. id .. ' ' .. id .. ']' .. getCatForId( 'VIAF' )
end

function lccnLink( id )
    local parts = splitLccn( id )
    if not parts then
        return false
    end
    id = parts[1] .. parts[2] .. append( parts[3], '0', 6 )
    return '[http://id.loc.gov/authorities/names/' .. id .. ' ' .. id .. ']' .. getCatForId( 'LCCN' )
end

function splitLccn( id )
    if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
        id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
    end
    if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
         return mw.text.split( id, '/' )
    end
    return false
end

function append(str, c, length)
    while str:len() < length do
        str = c .. str
    end
    return str
end

function isniLink( id )
    id = validateIsni( id )
    if not id then
        return false
    end
    return '[http://isni-url.oclc.nl/isni/' .. id .. ' ' .. id:sub( 1, 4 ) .. ' ' .. id:sub( 5, 8 ) .. ' '  .. id:sub( 9, 12 ) .. ' '  .. id:sub( 13, 16 ) .. ']' .. getCatForId( 'ISNI' )
end

--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function validateIsni( id )
    id = id:gsub( '[ %-]', '' ):upper()
    if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
        return false
    end
    if getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
        return false
    end
    return id
end

--Returns the ISNI check digit isni must be a string where the 15 first elements are digits
function getIsniCheckDigit( isni )
    local total = 0
    for i = 1, 15 do
        local digit = isni:byte( i ) - 48 --Get integer value
        total = (total + digit) * 2
    end
    local remainder = total % 11
    local result = (12 - remainder) % 11
    if result == 10 then
        return "X"
    end
    return tostring( result )
end

function orcidLink( id )
    id = validateIsni( id )
    if not id then
        return false
    end
    id = id:sub( 1, 4 ) .. '-' .. id:sub( 5, 8 ) .. '-'  .. id:sub( 9, 12 ) .. '-'  .. id:sub( 13, 16 )
    return '[http://orcid.org/' .. id .. ' ' .. id .. ']' .. getCatForId( 'ORCID' )
end

function gndLink( id )
    return '[http://d-nb.info/gnd/' .. id .. ' ' .. id .. ']' .. getCatForId( 'GND' )
end

function selibrLink( id )
    return '[http://libris.kb.se/auth/' .. id .. ' ' .. id .. ']' .. getCatForId( 'SELIBR' )
end

function bnfLink( id )
    --Add cb prefix if it has been removed
    if not string.match( id, '^cb.+$' ) then
        id = 'cb' .. id
    end

    return '[http://catalogue.bnf.fr/ark:/12148/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BNF' )
end

function bpnLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[http://www.biografischportaal.nl/persoon/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BPN' )
end

function ridLink( id )
    return '[http://www.researcherid.com/rid/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RID' )
end

function bibsysLink( id )
    return '[http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&cql=bs.autid+%3D+' .. id .. '&feltselect=bs.autid ' .. id .. ']' .. getCatForId( 'BIBSYS' )
end

function ulanLink( id )
    return '[http://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=' .. id .. ' ' .. id .. ']' .. getCatForId( 'ULAN' )
end

function createRow( id, label, rawValue, link, withUid )
    if link then
        if withUid then
            return '* ' .. label .. ' <span class="uid">' .. link .. '</span>\n'
        else
            return '* ' .. label .. ' ' .. link .. '\n'
        end
    else
        return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
    end
end

function inArray( value, array )
    for _, element in pairs( array ) do
        if value == element then
            return true
        end
    end
    return false
end

--In this order: name of the parameter, label, propertyId in Wikidata, formatting function
local conf = {
    { 'VIAF', '[[Virtual International Authority File|VIAF]]', 214, viafLink },
    { 'LCCN', '[[Library of Congress Control Number|LCCN]]', 244, lccnLink },
    { 'ISNI', '[[International Standard Name Identifier|ISNI]]', 213, isniLink },
    { 'ORCID', '[[ORCID]]', 496, orcidLink },
    { 'GND', '[[Integrated Authority File|GND]]', 227, gndLink },
    { 'PND', '[[Integrated Authority File|GND]]', 0, gndLink },
    { 'SELIBR', '[[LIBRIS]]', 0, selibrLink },
    { 'BNF', '[[Bibliothèque nationale de France|BNF]]', 268, bnfLink },
    { 'BPN', '[[Biografisch Portaal|BPN]]', 651, bpnLink },
    { 'RID', '[[ResearcherID]]', 0, ridLink },
    { 'BIBSYS', '[[BIBSYS]]', 0, bibsysLink },
    { 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, ulanLink }
}

local p = {}

function p.authorityControl( frame )
    local parentArgs = frame:getParent().args
    --Create rows
    local elements = {}

    --Item
    local item = mw.wikibase.getEntity()

    --Worldcat
    if parentArgs['WORLDCATID'] and parentArgs['WORLDCATID'] ~= '' then
        table.insert( elements, createRow( 'WORLDCATID', '', parentArgs['WORLDCATID'], '[http://www.worldcat.org/identities/' .. parentArgs['WORLDCATID'] .. ' WorldCat]', false ) ) --Validation?
    elseif parentArgs['LCCN'] and parentArgs['LCCN'] ~= '' then
        local lccnParts = splitLccn( parentArgs['LCCN'] )
        if lccnParts then
            table.insert( elements, createRow( 'LCCN', '', parentArgs['LCCN'], '[http://www.worldcat.org/identities/lccn-' .. lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3] .. ' WorldCat]', false ) )
        end
    end

    --Configured rows
    for k, params in pairs( conf ) do
        local val = parentArgs[params[1]]
        local text = ''

        --Wikidata
        if item ~= nil and params[3] ~= 0 then
            local wikidataIds = getIdsFromWikidata( item, 'p' .. params[3] )
            if wikidataIds[1] then
                if val and val ~= '' then
                    --[[TODO Consistency check
                    if not inArray( val, wikidataIds ) then
                        text = text .. '[Category:Inconsistent Authority identifier between Wikidata and Wikipedia]'
                    end]]--
                else
                    --Fallback
                    val = wikidataIds[1]
                end
            end
        end

        if val and val ~= '' then
            table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
        end
    end
    local Navbox = require('Module:Navbox')
    return Navbox._navbox( {
        name  = 'Authority control',
        bodyclass = 'hlist',
        group1 = '[[Authority control]]',
        list1 = table.concat( elements )
    } )
end

return p