Module:Work license
Appearance
--[=[
A module that can be used to get licensing information about an entity
WORK IN PROGRESS
]=]
local p = {} --p stands for package
-- library util provided by MW
local util = require 'libraryUtil'
local wikibaseUtils = require( 'Module:Wikibase utils' )
-- common constants
local DATA = mw.loadData( 'Module:Work data/properties' )
-- local constants useful mainly for this module
local LDATA = {
props = {
jurisdiction = 'P1001',
determinationMethod = 'P459',
relevantCopyrightDate = 'P9905'
},
items = {
usa = 'Q30',
publicDomain = 'Q19652',
pma50Countries = 'Q59621182',
pma70Countries = 'Q73560261',
pma25orLessCountries = 'Q68543134',
pma60orLessCountries = 'Q105480667',
pma70orLessCountries = 'Q59542795',
pma80orLessCountries = 'Q61830521',
pma100orLessCountries = 'Q60332278',
pma50orMoreCountries = 'Q87048619',
pma70orMoreCountries = 'Q60845045',
countriesWithPDArt = 'Q108574927',
countriesWithoutPDArt = 'Q108574944',
pubOver95YearsAgo = 'Q47246828',
byUsFederalGov = 'Q60671452',
noUsRenweal = 'Q29941035',
noUsNotice = 'Q47012574',
badUsNotice = 'Q61062601',
pma100Determination = 'Q29940705',
}
}
-- "extra" jurisdications that countries belong to and can't be worked out
-- by maths
local JURISDICTIONS = {
[ LDATA.items.usa ] = {
LDATA.items.countriesWithPDArt,
}
}
local PMAS = {
}
local function getJurisdictionsForCountry( countryQid )
-- always contains the country itself
local jurisdictions = {
countryQid
}
-- add "specials"
for _, j in pairs( JURISDICTIONS[ countryQid ] or {} ) do
table.insert( jurisdictions, j )
end
local pma = PMAS[ countryQid ]
if pma ~= nil then
-- work out the membership of the PMA items
-- these are incomplete at WD, so this looks wierd, but it does what it
-- needs to for us
-- XX or less groupins
if pma <= 25 then
table.insert( jurisdictions, LDATA.items.pma25orLessCountries )
end
if pma <= 60 then
table.insert( jurisdictions, LDATA.items.pma60orLessCountries )
end
if pma <= 70 then
table.insert( jurisdictions, LDATA.items.pma70orLessCountries )
end
if pma <= 80 then
table.insert( jurisdictions, LDATA.items.pma80orLessCountries )
end
if pma <= 100 then
table.insert( jurisdictions, LDATA.items.pma100orLessCountries )
end
-- exact PMA groupings
if pma == 50 then
table.insert( jurisdictions, LDATA.items.pma50Countries )
elseif pma == 70 then
table.insert( jurisdictions, LDATA.items.pma70Countries )
end
-- or more groupings
if pma >= 70 then
table.insert( jurisdictions, LDATA.items.pma70orMoreCountries )
end
if pma >= 50 then
table.insert( jurisdictions, LDATA.items.pma50orMoreCountries )
end
else
-- error('Do not know the PMA for the requested country: ' .. countryQid )
end
return jurisdictions
end
--[=[
Get any qualifiers of the given statement with a QID in the given list
Returns a table of snaks, or an empty table
]=]
local function getStatementQualifiersWithValueQids( statement, pid, qids )
if type( qids ) ~= 'table' then
qids = { qids }
end
local matchingQualifiers = {}
-- look in every suitable qualifier of this statement
local qualifiersOfProperty = wikibaseUtils.getQualifiersOfStatementWithPid( statement, pid )
-- for every qualifier, see if it has one of the desired values
for _, qualifierSnak in pairs( qualifiersOfProperty ) do
local snakValue = wikibaseUtils.getSnakValueQid( qualifierSnak )
for _, qid in pairs( qids ) do
if snakValue == qid then
table.insert( matchingQualifiers, qualifierSnak )
end
end
end
return matchingQualifiers
end
--[=[
Get the list of the copyright claims that apply to the given country
]=]
local function getApplicableCopyrightStatusClaims( entity, countryQid )
local copyrightStatusClaims = entity:getAllStatements( DATA.props.copyrightStatus )
-- the list of jurisdictions that this country belongs to
local allowedJurisdictions = getJurisdictionsForCountry( countryQid )
local applicableClaims = {}
for _, statement in pairs( copyrightStatusClaims ) do
local applicableClaimsForStatement = getStatementQualifiersWithValueQids(
statement, LDATA.props.jurisdiction, allowedJurisdictions )
if #applicableClaimsForStatement > 0 then
table.insert( applicableClaims, statement )
end
end
-- did not find any statement indicating PD
return applicableClaims
end
--[=[
Determine if a work is public domain in the given country
]=]
local function isEntityPdInCountry( entity, countryQid )
local applicableClaims = getApplicableCopyrightStatusClaims( entity, countryQid )
for _, claim in pairs( applicableClaims ) do
if wikibaseUtils.getSnakValueQid( claim.mainsnak ) == LDATA.items.publicDomain then
return true
end
end
-- no claim indicates PD in the given country
return false
end
local function getBestRelevantDate( claim )
local dates = wikibaseUtils.getQualifiersOfStatementWithPid(
claim, LDATA.props.relevantCopyrightDate )
local relevantDate
for _, dateQual in pairs( dates ) do
relevantDate = wikibaseUtils.getSnakValueYear( dateQual )
end
return relevantDate
end
local function getUsLicenceFromClaim( claim )
local status = wikibaseUtils.getSnakValueQid( claim.mainsnak )
-- list of determination qualifers on the claim
local determinations = wikibaseUtils.getQualifiersOfStatementWithPid(
claim, LDATA.props.determinationMethod )
local relevantDate = getBestRelevantDate( claim )
-- convert suitable determination qualifers to a simple representation
for _, det in pairs( determinations ) do
-- the Qid of the determination method
local detQid = wikibaseUtils.getSnakValueQid( det )
if status == LDATA.items.publicDomain then
if detQid == LDATA.items.pubOver95YearsAgo then
lic = {
nature = 'pub-date',
date = relevantDate
}
elseif detQid == LDATA.items.byUsFederalGov then
lic = {
nature = 'us-gov',
date = nil -- date doesn't matter
}
elseif detQid == LDATA.items.noUsRenweal then
lic = {
nature = 'not-renewed',
date = relevantDate
}
elseif detQid == LDATA.items.noUsNotice then
lic = {
nature = 'no-notice',
date = relevantDate
}
elseif detQid == LDATA.items.badUsNotices then
lic = {
nature = 'no-notice',
date = relevantDate
}
end
end
if lic ~= nil then
return lic
end
end
return nil
end
--[=[
Get the US and non-US license data
]=]
local function getEntityLicenseData( entity )
local usLicenses
local otherLicenses
-- get all the US-applicable copyright statements
local usClaims = getApplicableCopyrightStatusClaims( entity, LDATA.items.usa )
for _, claim in pairs( usClaims ) do
local usLic = getUsLicenceFromClaim( claim)
-- probably just need one(?)
if usLic ~= nil then
usLicenses = usLic
break
end
end
return {
us = usLicenses,
other = otherLicenses
}
end
--[=[
This is the main entry point to get a new workLicense object
This function is public, and is designed to be called by other modules
]=]
function p.newWorkLicense( titleOrQid )
-- the object we will eventually return
local obj = {}
-- the function that checks if a call to a method is using . instead of :
local checkSelfFunc = util.makeCheckSelfFunction( 'Module:Work license',
'aWorkLicense', obj, 'work license object' );
local entity = wikibaseUtils.getEntity( titleOrQid )
-- bail out if we don't find a WB entity
if entity == nil then
return nil
end
-- data object of this object
-- this is private, and access is granted though the returned meta-table
local data = {
entity = entity,
}
return setmetatable( obj, {
__eq = entity.id.equals,
__lt = entity.id.__lt,
__tostring = function ( t )
return t.entity
end,
-- return specific fields
__index = function ( t, key )
-- figure out if a work is PD at Wikisource (i.e. in the US specifically)
-- returns true, false or nil (meaning cannot be determined)
if key == 'isPublicDomain' then
if data.isPublicDomain == nil then
data.isPublicDomain = isEntityPdInCountry( entity, LDATA.items.usa )
end
return data.isPublicDomain
end
if key == 'licenseData' then
if data.licenseData == nil then
data.licenseData = getEntityLicenseData( entity )
end
return data.licenseData
end
-- otherwise, just return the member of data
return data[ key ]
end,
-- workLicense objects are always read-only
__newindex = function ( t, k, v )
error( "index '" .. k .. "' is read only", 2 )
end
} )
end
return p