Documentation for this module may be created at Module:Authority control/doc
require('Module:No globals') local p = {} local title = mw.title.getCurrentTitle() local namespace = title.namespace local testcases = (string.sub(title.subpageText,1,9) == 'testcases') --[[==========================================================================]] --[[ Category functions ]] --[[==========================================================================]] function p.getCatForId( id ) local catName = '' if namespace == 0 then catName = 'PBC articles with '..id..' identifiers' elseif namespace == 2 and not title.isSubpage then catName = 'User pages with '..id..' identifiers' else catName = 'Miscellaneous pages with '..id..' identifiers' end return '[[Category:'..catName..']]'..p.redCatLink(catName) end function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]') if catName and catName ~= '' and testcases == false and mw.title.new(catName, 14).exists == false then return '[[Category:Pages with red-linked authority control categories]]' end return '' end function p.createRow( id, label, rawValues, link, links, withUid, specialCat ) local catName = 'PBC articles with faulty '..(specialCat or id)..' identifiers' if links then -- all links[] use withUid = false; no check needed local row = '*<span class="nowrap">'..label for i, l in ipairs( links ) do if i == 1 then row = row..' ' else row = row..', ' end if l then row = row..'<span class="uid">'..l..'</span>' else row = row..'<span class="error">The '..id..' id '..rawValues[i]..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName) end end return row..'</span>\n' elseif link then if withUid then return '*<span class="nowrap">'..label..' <span class="uid">'..link..'</span></span>\n' end return '*<span class="nowrap">'..label..' '..link..'</span>\n' end return '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName)..'\n' end --[[=========================== Helper functions =============================]] function p.append(str, c, length) while str:len() < length do str = c .. str end return str end --Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145 function p.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 --[[==========================================================================]] --[[ PornBaseData & documentation functions ]] --[[==========================================================================]] function p.getIdsFromPornBaseData( itemId, property ) local ids = {} local statements = mw.wikibase.getBestStatements( itemId, property ) if statements then for _, statement in ipairs( statements ) do if statement.mainsnak.datavalue then table.insert( ids, statement.mainsnak.datavalue.value ) end end end return ids end function p.matchesPornBaseDataRequirements( itemId, reqs ) for _, group in ipairs( reqs ) do local property = 'P'..group[1] local qid = group[2] local statements = mw.wikibase.getBestStatements( itemId, property ) if statements then for _, statement in ipairs( statements ) do if statement.mainsnak.datavalue then if statement.mainsnak.datavalue.value['numeric-id'] == qid then return true end end end end end return false end -- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation function p.docConfTable( frame ) local wikiTable = '{| class="wikitable sortable"\n'.. '! rowspan=2 | Parameter\n'.. '! rowspan=2 | Label\n'.. '! rowspan=2; data-sort-type=number | PornBaseData property\n'.. '! colspan=4 | Tracking categories and page counts\n'.. '|-\n'.. '! [[:Category:PBC articles with authority control information|'.. 'Articles]]\n'.. '! [[:Category:User pages with authority control information|'.. 'User pages]]\n'.. '! [[:Category:Miscellaneous pages with authority control information|'.. 'Misc. pages]]\n'.. '! [[:Category:PBC articles with faulty authority control information|'..'Faulty IDs]]\n'.. '|-\n' local lang = mw.getContentLanguage() for _, conf in pairs( p.conf ) do local param, link, pid = conf[1], conf[2], conf[3] local category = conf.category or param local args = { id = 'f', pid } local wpl = frame:expandTemplate{ title = 'PBD property link', args = args } --cats local articleCat = 'PBC articles with '..category..' identifiers' local userCat = 'User pages with '..category..' identifiers' local miscCat = 'Miscellaneous pages with '..category..' identifiers' local faultyCat = 'PBC articles with faulty '..category..' identifiers' --counts local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') ) local userCount = lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') ) local miscCount = lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') ) local faultyCount = lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') ) --concat wikiTable = wikiTable..'\n'.. '|-\n'.. '||'..param.. '||'..link.. '||data-sort-value='..pid..'|'..wpl.. '||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'.. '||style="text-align: right;"|[[:Category:'.. userCat..'|'.. userCount..']]'.. '||style="text-align: right;"|[[:Category:'.. miscCat..'|'.. miscCount..']]'.. '||style="text-align: right;"|[[:Category:'.. faultyCat..'|'.. faultyCount..']]' end --append derivative WorldCat cats local wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' } for _, w in pairs(wcd) do local articleCat = 'PBC articles with '..w..' identifiers' local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') ) wikiTable = wikiTable..'\n'.. '|-\n'.. '||'..'—'.. '||'..w.. '||data-sort-value='..w..'|'..'—'.. '||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'.. '||style="text-align: right;"|—'.. '||style="text-align: right;"|—'.. '||style="text-align: right;"|—' end return wikiTable..'\n|}' end --[[==========================================================================]] --[[ Configuration ]] --[[==========================================================================]] -- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used. -- Check that the PornBaseData item has this property-->value before adding it local reqs = {} --[[==========================================================================]] --[[ Main ]] --[[==========================================================================]] function p.authorityControl( frame ) local resolveEntity = require( "Module:ResolveEntityId" ) local parentArgs = frame:getParent().args local elements = {} --create/insert rows later local worldcatCat = '' local multipleIdCat = '' local suppressedIdCat = '' local deprecatedIdCat = '' --Redirect aliases to proper parameter names for _, a in pairs( p.aliases ) do local alias, param = a[1], a[2] if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then parentArgs[param] = parentArgs[alias] end end --Redirect deprecated parameters to proper parameter names, and assign tracking cat for _, d in pairs( p.deprecated ) do local dep, param = d[1], d[2] if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then parentArgs[param] = parentArgs[dep] if namespace == 0 then deprecatedIdCat = '[[Category:PBC articles with deprecated authority control identifiers|'..dep..']]' end end end --Use QID= parameter for testing/example purposes only local itemId = nil if namespace ~= 0 then local qid = parentArgs['qid'] or parentArgs['QID'] if qid then itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '') itemId = resolveEntity._id(itemId) --nil if unresolvable end else itemId = mw.wikibase.getEntityIdForCurrentPage() end --PornBaseData fallback if requested if itemId then for _, params in ipairs( p.conf ) do if params[3] > 0 then local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]] if val == nil or val == '' then local canUsePornBaseData = nil if reqs[params[1]] then canUsePornBaseData = p.matchesPornBaseDataRequirements( itemId, reqs[params[1]] ) else canUsePornBaseData = true end if canUsePornBaseData then local wikidataIds = p.getIdsFromPornBaseData( itemId, 'P'..params[3] ) if wikidataIds[1] then if val == '' and (namespace == 0 or testcases) then suppressedIdCat = '[[Category:PBC articles with suppressed authority control identifiers|'..params[1]..']]' else parentArgs[params[1]] = wikidataIds[1] end end end end end end end --Configured rows local rct = 0 for _, params in ipairs( p.conf ) do local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]] local tval, tlinks = {}, {} if val and val ~= '' and type(params[4]) == 'function' then table.insert( tval, val ) table.insert( tlinks, params[4]( val ) ) end -- collect other unique vals (IDs) from WD, if present if itemId and tval[1] then local wikidataIds = p.getIdsFromPornBaseData( itemId, 'P'..params[3] ) for _, v in pairs( wikidataIds ) do local bnew = true for _, w in pairs( tval ) do if v == w then bnew = false end end if bnew then table.insert( tval, v ) table.insert( tlinks, params[4]( v ) ) end end end -- assemble if tval[1] then table.insert( elements, p.createRow( params[1], params[2]..':', tval, nil, tlinks, true, params.category ) ) rct = rct + 1 if tval[2] then multipleIdCat = p.getCatForId( 'multiple' ) end end end --WorldCat local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID'] if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat Identities (identifier)|WorldCat Identities]]: [https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' '..worldcatId..']', nil, false ) ) --Validation? worldcatCat = p.getCatForId( 'WORLDCATID' ) elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed local viafId = parentArgs['viaf'] or parentArgs['VIAF'] local lccnId = parentArgs['lccn'] or parentArgs['LCCN'] if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat Identities (identifier)|WorldCat Identities]] (via VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', nil, false ) ) if namespace == 0 then worldcatCat = '[[Category:PBC articles with WorldCat-VIAF identifiers]]' end elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated local lccnParts = p.splitLccn( lccnId ) if lccnParts and lccnParts[1] ~= 'sh' then local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3] table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat Identities (identifier)|WorldCat Identities]] (via LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', nil, false ) ) if namespace == 0 then worldcatCat = '[[Category:PBC articles with WorldCat-LCCN identifiers]]' end end end elseif worldcatId == '' then --if WORLDCATID suppressed suppressedIdCat = '[[Category:PBC articles with suppressed authority control identifiers|WORLDCATID]]' end local Navbox = require('Module:Navbox') local elementsCat = '' if rct == 0 or rct >= 25 then local eCat = 'AC with '..rct..' elements' elementsCat = '[[Category:'..eCat..']]'..p.redCatLink(eCat) end local outString = '' if #elements > 0 then local args = { pid = 'identifiers' } -- #target the list of identifiers if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive local pencil = frame:expandTemplate{ title = 'EditAtPornBaseData', args = args} outString = Navbox._navbox( { name = 'Authority control', navboxclass = 'authority-control', bodyclass = 'hlist', group1 = '[[Help:Authority control|Authority control]]'..pencil, list1 = table.concat( elements ) } ) end local auxCats = worldcatCat .. elementsCat .. multipleIdCat .. suppressedIdCat .. deprecatedIdCat if testcases then auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking end outString = outString .. auxCats if namespace ~= 0 then outString = mw.ustring.gsub(outString, '(%[%[)(Category:PBC articles)', '%1:%2') --by definition end return outString end return p