Module:Commons link

From Zoophilia Wiki
Revision as of 07:19, 17 February 2020 by meta>Hike395 (simplify search logic)
Jump to navigationJump to search

Documentation for this module may be created at Module:Commons link/doc

-- Module to find commons galleries and categories based on wikidata entries
local getArgs = require('Module:Arguments').getArgs
local p = {}

-- Find the Commons gallery page associated with article
function p.getGallery(frame)
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})
	return p._getGallery(args[1],args.linktext,args.search,args.qid)
end

-- Arguments:
--   default = use as Commons link, don't access wikidata
--   linktext = text to display in link
--   search = string to search for
--   qid = QID to lookup in wikidata (for testing only)
function p._getGallery(default,linktext,search,qid)
	if default then
		return "[[Commons:"..default.."|"..(linktext or default).."]]"
	end
	if search then
		return "[[Commons:Special:Search/"..search.."|"..(linktext or search).."]]"
	end
	local titleObject = mw.title.getCurrentTitle()
	local title = titleObject.text
	qid = (qid or ""):upper()
	if qid == "" then
		-- look up qid for current page (if not testing)
		qid = mw.wikibase.getEntityIdForCurrentPage()
	else
		-- if qid specified, look up title from that
	    title = mw.wikibase.sitelink(qid)
	end
	-- construct default result (which searches for title)
	local searchResult = "[[Commons:Special:Search/"..title.."|"..(linktext or title).."]]"
	if qid then
		local galleryLink = nil
		local consistent = true
		-- look up commons sitelink for article, use if not category
		local commonsSitelink = mw.wikibase.getSitelink(qid,"commonswiki")
		if commonsSitelink and mw.ustring.sub(commonsSitelink,1,9) ~= "Category:" then
			galleryLink = commonsSitelink
		end
		-- P935 is the "commons gallery" property for this article
		local P935 = mw.wikibase.getBestStatements(qid, "P935")[1]
		if P935 and P935.mainsnak.datavalue then
			local gallery = P935.mainsnak.datavalue.value
			if galleryLink and galleryLink ~= gallery then
				consistent = false
			else
				galleryLink = gallery
			end
		end
		-- use wikidata if either sitelink or P935 exist, and they both agree
		if galleryLink and consistent then
			return "[[Commons:"..galleryLink.."|"..(linktext or galleryLink).."]]"
		end
		-- if not consistent, fall back to search and add to tracking cat
		if not consistent and titleObject.namespace == 0 then
			searchResult = searchResult.."[[Category:Inconsistent wikidata for Commons gallery]]"
		end
	end
	return searchResult
end

-- Find the Commons category page associated with article
function p.getCategory(frame)
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})
	return p._getCategory(args[1],args.linktext,args.search,args.qid)
end

-- Arguments:
--   default = use as Commons Category link, don't access wikidata
--   linktext = text to display in link
--   search = string to search for
--   qid = QID to lookup in wikidata (for testing only)
function p._getCategory(default,linktext,search,qid)
	if default then
		return "[[Commons:Category:"..default.."|"..(linktext or default).."]]"
	end
	if search then
		return "[[Commons:Special:Search/Category:"..search.."|"..(linktext or search).."]]"
	end
	local titleObject = mw.title.getCurrentTitle()
	local title = titleObject.text
	qid = (qid or ""):upper()
	if qid == "" then
		-- look up qid for current page (if not testing)
		qid = mw.wikibase.getEntityIdForCurrentPage()
	else
		-- if qid specified, look up title from that
	    title = mw.wikibase.sitelink(qid)
	end
	-- construct default result (which searches for title in Category space)
	local searchResult = "[[Commons:Special:Search/Category:"..title.."|"..(linktext or title).."]]"
	if qid then
		local categoryLink = nil
		local consistent = true
		-- look up commons sitelink for article, use if starts with "Category:"
		local commonsSitelink = mw.wikibase.getSitelink(qid,"commonswiki")
		if commonsSitelink and mw.ustring.sub(commonsSitelink,1,9) == "Category:" then
			categoryLink = mw.ustring.sub(commonsSitelink,10)
		end
		-- P935 is the "commons category" property for this article
		local P373 = mw.wikibase.getBestStatements(qid, "P373")[1]
		if P373 and P373.mainsnak.datavalue then
			P373 = P373.mainsnak.datavalue.value
			if categoryLink and categoryLink ~= P373 then
				consistent = false
			else
				categoryLink = P373
			end
		end
		-- P910 is the "topic's main category". Look for commons sitelink there
		local P910 = mw.wikibase.getBestStatements(qid, "P910")[1]
		if P910 and P910.mainsnak.datavalue and P910.mainsnak.datavalue.value.id then
			P910 = P910.mainsnak.datavalue.value.id
			local fallback = mw.wikibase.getSitelink(P910, "commonswiki")
			if fallback and mw.ustring.sub(fallback,1,9) == "Category:" then
				fallback = mw.ustring.sub(fallback,10)
				if categoryLink and categoryLink ~= fallback then
					consistent = false
				else
					categoryLink = fallback
				end
			end
		end
		-- if any of sitelink category, P373, and P910 commons sitelink exist,
		-- use it. But don't use if they don't agree with each other
		if categoryLink and consistent then
			return "[[Commons:Category:"..categoryLink.."|"..(linktext or categoryLink).."]]"
		end
		-- if not consistent, fall back to search, but add tracking category
		if not consistent and titleObject.namespace == 0 then
			searchResult = searchResult.."[[Category:Inconsistent wikidata for Commons category]]"
		end
	end
	return searchResult
end

return p