Module:WikidataIB/sandbox1: Difference between revisions

Content deleted Content added
sync with sandbox
major update to use getAllStatements instead of getEntity
Line 1:
-- Module to implement use of a blacklist and whitelist for infobox fields
-- Can take a named parameter |qid which is the Wikidata ID for the article
-- if not supplied, it will use the Wikidata ID associated with the current page.
-- (this will not normally be used because it's an expensive call)
-- Fields in blacklist are never to be displayed, i.e. module must return nil in all circumstances
-- Fields in whitelist return local value if it exists or the Wikidata value otherwise
Line 51:
["abbr"] =
{
["Q828224"] = "km",
["Q11573"] = "m",
["Q174728"] = "cm",
["Q174789"] = "mm",
["Q11570"] = "kg",
["Q41803"] = "g",
["Q3241121"] = "mg",
["Q2332346"] = "ml",
["Q7727"] = "min",
},
}
Line 214 ⟶ 215:
-- parseInput processes the Q-id , the blacklist and the whitelist
-- if an input parameter is supplied, it returns that and ends the call.
-- it returns a(1) booleaneither the qid or nil indicating whether or not the call should continue
-- and an(2) objecta table containing all of the Wikidatastatements for the QidpropertyID suppliedand orrelevant the current pageQid
local parseInput = function(frame, input_parm, property_id)
-- There may be a local parameter supplied, if it's blank, set it to nil
local input_parm = mw.text.trim(input_parm or "")
if input_parm == "" then input_parm = nil end
 
Line 224 ⟶ 225:
 
-- can take a named parameter |qid which is the Wikidata ID for the article.
-- Thisif willit's not normallysupplied, beuse usedthe becauseid it'sfor anthe expensivecurrent call.page
local qid = args.qid or ""
if qid == "" then qid = nilmw.wikibase.getEntityIdForCurrentPage() end
 
-- The blacklist is passed in named parameter |suppressfields
Line 240 ⟶ 241:
if blacklist then
-- The name is compulsory when blacklist is used, so return nil if it is not supplied
if not fieldname or fieldname == "" then return false, nil, nil end
-- If this field is on the blacklist, then return nil
if blacklist:find(fieldname) then return false, nil, nil end
end
 
Line 248 ⟶ 249:
-- The blacklist overrides any locally supplied parameter as well
-- If a non-blank input parameter was supplied return it
if input_parm then return false, input_parm, nil end
 
-- Otherwise see if this field is on the whitelist:
Line 256 ⟶ 257:
found = ((found or 0) > 0)
if whitelist ~= 'ALL' and (whitelist:upper() == "NONE" or not found) then
return false, nil, nil
end
 
-- See what's on Wikidata (the call always returns a table, but it may be empty):
local entityprops = mw.wikibase.getEntityObjectgetAllStatements(qid, property_id)
if entity and entity.claimsprops[1] then
return qid, props
local props = entity.claims[property_id]
if props and props[1] then
return true, entity, props
end
end
-- no property on Wikidata
return false, input_parm, nil
end
 
Line 275 ⟶ 273:
-- assembleoutput takes the sequence table containing the property values
-- and formats it according to switches given
-- it needs the entityID and propertyID to link from the pen icon
local function assembleoutput(out, args, entityID, propertyID)
 
Line 553 ⟶ 552:
-- datatypes which are global coordinates:
elseif datatype == "globe-coordinate" then
local-- 'display' =parameter args.displaydefaults orto "inline, title" *** unused for now ***
local formatdisp = args.formatdisplay or ""
if displaydisp == "decimal" then disp = "inline, title" end
 
local latdecimal = 0
-- format parameter switches from deg/min/sec to decimal degrees
local longdecimal = 0
-- default is deg/min/sec -- decimal degrees needs |format = dec
local coords = entity:formatPropertyValues(propertyID).value
local form = (args.format or ""):lower():sub(1,3)
-- the latitude and longitude are returned like this: nn°nn'nn.n"
if form == "" then form = "dms" end
-- using html entities with hex values really screws up parsing the numbers
 
local lat = mw.ustring.match(coords, "^[^,]*") -- everything from the start to before the comma
local lat, long = datavalue.latitude, datavalue.longitude
local long = mw.ustring.match(coords, "[^ ]*$") -- everything from after the space to the end
if form == "dec" then
lat = lat:gsub("&#%d%d;", ":") -- clean out the html entities
lat_long[1] = lat
long = long:gsub("&#%d%d;", ":") -- clean out the html entities
lat_long[2] = long
-- read the latitude numbers into a table
else
local newlat = {}
local ns, ew
for num in mw.ustring.gmatch(lat, "%d+%.?%d*") do
newlat[#newlatif +lat 1]< =0 numthen
end ns = "S"
if lat #newlat==3 then- lat
latdecimal = newlat[1] + newlat[2]/60 + newlat[3]/3600
elseif #newlat==2 then
latdecimal = newlat[1] + newlat[2]/60
else
latdecimalns = newlat[1]"N"
end
local latdeg = math.floor(lat)
if lat:sub(-1)=="S" then
latdecimallocal latms = (lat -latdecimal latdeg) * 60
local latmin = math.floor(latms)
end
local newlonglatsec = {}(latms - latmin) * 60
if long < 0 then
for num in mw.ustring.gmatch(long, "%d+%.?%d*") do
newlong[#newlong + 1]ew = num"W"
end long = - long
if #newlong==3 then
longdecimal = newlong[1] + newlong[2]/60 + newlong[3]/3600
elseif #newlat==2 then
longdecimal = newlong[1] + newlong[2]/60
else
longdecimalew = newlong[1]"E"
end
local longdeg = math.floor(long)
if long:sub(-1)=="W" then
local longms = (long - longdeg) * 60
longdecimal = -longdecimal
local longmin = math.floor(longms)
end
local longsec = (longms - longmin) * 60
if format == "longlat" then
 
out[#out+1] = longdecimal .. ", " .. latdecimal
elseifif formatlatsec == "lat"0 and longsec == 0 then
if latmin == 0 and longmin == 0 then
out[#out+1] = latdecimal
out[#out + 1] = latdeg .. "°" .. ns .. " " .. longdeg .. "°" .. ew
elseif format == "long" then
else
out[#out+1] = longdecimal
out[#out + 1] = latdeg .. "°" .. latmin .. "′" .. ns .. " "
out[#out] = out[#out] .. longdeg .. "°".. longmin .. "′" .. ew
end
else
out[#out + 1] = latdecimallatdeg .. ",°" .. latmin .. "′" .. longdecimallatsec .. "″" .. ns .. " "
out[#out] = out[#out] .. longdeg .. "°" .. longmin .. "′" .. longsec .. "″" .. ew
end
else
out[#out+1] = entity:formatPropertyValues(propertyID).value
end
------------------------------------
else
-- some other data type so write a specific handler
out[#out+1] = "unknown data type"
-- either write a specific handler
-- or we can use formatPropertyValues() as a temporary measure.
-- This won't work with multiple valid values.
out[#out+1] = entity:formatPropertyValues(propertyID).value
break
end -- of datatype/unknown value/sourced check
 
Line 676 ⟶ 667:
 
-------------------------------------------------------------------------------
-- _getvalue is the commonprivate function for getValue, getPreferredValue, and getNormalValue
--
local function _getvalue(frame, entity, props, propertyID, entityid)
 
-- qual is a string containing the property ID of the qualifier(s) to be returned
Line 721 ⟶ 712:
 
-- format the table of values and return it as a string:
return assembleoutput(out, frame.args, entity.identityid, propertyID)
end
 
Line 741 ⟶ 732:
if not frame.args[1] then return i18n.errors["No property supplied"] end
end
 
local propertyID = mw.text.trim(frame.args[1] or "")
 
local success, errorOrEntityentityid, props = parseInput(frame, frame.args[2], propertyID)
if not successentityid then
return props -- either the input parameter or nothing
return errorOrEntity
end
--[[
 
local function filter(claim)
return true
end
--]]
return _getvalue(frame, errorOrEntity, props, propertyID)
return _getvalue(frame, props, propertyID, entityid)
end
 
Line 779 ⟶ 772:
-------------------------------------------------------------------------------
-- getCoords is used to get coordinates for display in an infobox
-- whitelist and blacklist areto be implemented
-- optional 'display' parameter is allowed, defaults to "inline, title"
--
Line 787 ⟶ 780:
-- if there is a 'display' parameter supplied, use it
-- otherwise default to "inline, title"
local disp = frame.args.display or ""
if not disp or disp == "" then
disp = "inline, title"
end
 
-- there may be a format parameter to switch from deg/min/sec to decimal degrees
local success, errorOrEntity = parseInput(frame, frame.args[1], propertyID)
-- default is deg/min/sec
-- decimal degrees needs |format = dec
local form = (frame.args.format or ""):lower():sub(1,3)
if form == "" then
form = "dms"
end
 
local qid, props = parseInput(frame, frame.args[1], propertyID)
if not success then
return props -- either local parameter or nothing
return errorOrEntity
else
local entity = errorOrEntity
local lat_long = {}
dv = props[1].mainsnak.datavalue.value
local coords = entity:formatPropertyValues(propertyID).value
local lat, long, prec = dv.latitude, dv.longitude, dv.precision
-- the latitude and longitude are returned like this: nn°nn&#39;nn.n&#34;
 
-- using html entities with hex values really screws up parsing the numbers - thanks devs
if form == "dec" then
local lat = mw.ustring.match(coords, "^[^,]*") -- everything from start to before comma
lat_long[1] = lat
local long = mw.ustring.match(coords, "[^ ]*$") -- everything from after space to the end
lat_long[2] = long
lat = lat:gsub("&#%d%d;", ":") -- replace the html entities with colon
else
long = long:gsub("&#%d%d;", ":") -- replace the html entities with colon
local ns, ew
-- read the latitude numbers into a table
 
for num in mw.ustring.gmatch(lat, "%d+%.?%d*") do
if lat < 0 then
lat_long[#lat_long + 1] = num
ns = "S"
lat = - lat
else
ns = "N"
end
local latdeg = math.floor(lat)
local latms = (lat - latdeg) * 60
local latmin = math.floor(latms)
local latsec = (latms - latmin) * 60
 
if long < 0 then
ew = "W"
long = - long
else
ew = "E"
end
local longdeg = math.floor(long)
local longms = (long - longdeg) * 60
local longmin = math.floor(longms)
local longsec = (longms - longmin) * 60
 
if latsec == 0 and longsec == 0 then
if latmin == 0 and longmin == 0 then
lat_long = { latdeg, ns, longdeg, ew }
else
lat_long = { latdeg, latmin, ns, longdeg, longmin, ew }
end
else
lat_long = { latdeg, latmin, latsec, ns, longdeg, longmin, longsec, ew }
end
end
 
-- add the N/S
lat_long[#lat_long + 1] = lat:sub(-1)
-- read the longitude numbers into a table
for num in mw.ustring.gmatch(long, "%d+%.?%d*") do
lat_long[#lat_long + 1] = num
end
-- add E/W for long
lat_long[#lat_long + 1] = long:sub(-1)
-- add named parameter for display
lat_long["display"] = disp
-- invoke template Coord with the values stored in the table
Line 856 ⟶ 878:
-- check for locally supplied parameter in second unnamed parameter
-- success means no local parameter and the property exists
local success, errorOrEntity, props = parseInput(frame, frame.args[2], propertyID) --$$$
if success then
local entity = errorOrEntity --$$$
local out = {}
-- Scan through the values of the property