Bước tới nội dung

Mô đun:Commons link

Bách khoa toàn thư mở Wikipedia
require('strict')-- Module to find commons galleries and categories based on wikidata entrieslocal getArgs = require('Mô đun:Arguments').getArgslocal yesNo = require('Mô đun:Yesno')local p = {}-- Check if string is a valid QID-- Argument: QID to check-- Returns: valid (bool)local function _validQID(qid)	return qid and mw.ustring.find(qid,"^[Qq]%d+$")end-- Check if string is a valid wikidata property string-- Argument: property string to check-- Returns: valid (bool)local function _validProp(prop)	return prop and mw.ustring.find(prop,"^[Pp]%d+$")endlocal function _lcfirst(s)	return mw.ustring.lower(mw.ustring.sub(s,1,1))..mw.ustring.sub(s,2)end-- Format displayed linktext-- Arguments:--   s = string to display--   formatting = formatting table:--    formatting.linktext = if defined, override s--    formatting.lcfirst = lower case the first letter in display--    formatting.bold = whether to bold the display--    formatting.italic = whether to italicize the display--    formatting.nowrap = set nowrapping-- Returns:--   formatted stringlocal function _formatResult(s, formatting)	local resultVal = formatting.linktext or s	if formatting.lcfirst then		resultVal = _lcfirst(resultVal)	end    local style = ""	if formatting.italic then style = "font-style:italic; " end	if formatting.bold then style = style.."font-weight:bold; " end	if formatting.nowrap then style = style.."white-space:nowrap; " end    if style ~= "" then    	resultVal = '<span style="'..mw.text.trim(style)..'">'..resultVal..'</span>'    end	return resultValend-- Get title, namespace, and QID for current page-- Arguments:--   qid = testing only: get title of alternative page with QID=qid--   nsQid = whether to return the ns of the qid page or current-- Returns:--   title, namespace (string), qid of current page (or test page)local function _getTitleQID(qid,nsQid)	local titleObject = mw.title.getCurrentTitle()	-- look up qid for current page (if not testing)	local nsText = string.gsub(titleObject.nsText,"_"," ") -- [[phab:T369784]]	if not _validQID(qid) then		qid = mw.wikibase.getEntityIdForCurrentPage()		return titleObject.text, nsText, qid	end	-- testing-only path: given a qid, determine title	-- always use namespace from current page (to suppress tracking cat)	qid = qid:upper()	local title = mw.wikibase.getSitelink(qid) or ""	-- strip any namespace from sitelink	local firstColon = mw.ustring.find(title,':',1,true)	local qidNsText = ""	if firstColon then		qidNsText = mw.ustring.sub(title,1,firstColon-1)		title = mw.ustring.sub(title,firstColon+1)	end	if nsQid then		return title, qidNsText, qid	end	return title, nsText, qidend-- Lookup Commons gallery in Wikidata-- Arguments:--   qid = QID of current article--   fetch = whether to lookup Commons sitelink (bool)--   commonsSitelink = default value for Commons sitelink-- Returns:--   categoryLink = name of Commons category, nil if nothing is found--   consistent = multiple wikidata fields are examined: are they consistent?--   commonsSitelink = commons sitelink for current articlelocal function _lookupGallery(qid,fetch,commonsSitelink)	if not _validQID(qid) then		return nil, true, nil	end	qid = qid:upper()	local galleryLink = nil	local consistent = true	-- look up commons sitelink for article, use if not category	if fetch then		commonsSitelink = mw.wikibase.getSitelink(qid,"commonswiki") or commonsSitelink	end	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	return galleryLink, consistent, commonsSitelinkend-- Find fallback category by looking up Commons sitelink of different page-- Arguments:--    qid = QID for current article--    property = property that refers to other article whose sitelink to return-- Returns: either category-stripped name of article, or nillocal function _lookupFallback(qid,property)	if not _validQID(qid) or not _validProp(property) then		return nil	end	qid = qid:upper()	property = property:upper()	-- If property exists on current article, get value (other article qid)	local value = mw.wikibase.getBestStatements(qid, property)[1]	if value and value.mainsnak.datavalue and value.mainsnak.datavalue.value.id then		-- Look up Commons sitelink of other article		local sitelink = mw.wikibase.getSitelink(value.mainsnak.datavalue.value.id,"commonswiki")		-- Check to see if it starts with "Category:". If so, strip it and return		if sitelink and mw.ustring.sub(sitelink,1,9) == "Category:" then			return mw.ustring.sub(sitelink,10)		end	end	return nilend-- Find Commons category by looking in wikidata-- Arguments:--   qid = QID of current article--   fetch = whether to lookup Commons sitelink (bool)--   commonsSitelink = default value for Commons sitelink-- Returns:--   categoryLink = name of Commons category, nil if nothing is found--   consistent = multiple wikidata fields are examined: are they consistent?--   commonsSitelink = commons sitelink for current articlelocal function _lookupCategory(qid, fetch, commonsSitelink)	if not _validQID(qid) then		return nil, true, nil	end	qid = qid:upper()	local categoryLink = nil	local consistent = true	-- look up commons sitelink for article, use if starts with "Category:"	if fetch then		commonsSitelink = mw.wikibase.getSitelink(qid,"commonswiki") or commonsSitelink	end	if commonsSitelink and mw.ustring.sub(commonsSitelink,1,9) == "Category:" then		categoryLink = mw.ustring.sub(commonsSitelink,10)	end	-- P910 is the "topic's main category". Look for commons sitelink there	local fallback = _lookupFallback(qid,"P910")	if fallback then		if categoryLink and categoryLink ~= fallback then			consistent = false			qid = nil		else			categoryLink = fallback		end	end	-- P1754 is the "list's main category". Look for commons sitelink there	fallback = _lookupFallback(qid,"P1754")	if fallback then		if categoryLink and categoryLink ~= fallback then			consistent = false			qid = nil		else			categoryLink = fallback		end	end    -- P373 is the "commons category" property for this article. This is    -- a low-quality field, so should only be used as a last resort.    if categoryLink == nil and _validQID(qid) then	    local P373 = mw.wikibase.getBestStatements(qid, "P373")[1]	    if P373 and P373.mainsnak.datavalue then		    categoryLink = P373.mainsnak.datavalue.value		    consistent = true  -- P373 is never used if anything else is available		end	end	return categoryLink, consistent, commonsSitelinkend-- Does the article have a Commons gallery, and is it consistent?-- Arguments:--   qid = QID to lookup in wikidata (for testing only)-- Returns:--   filename at Commons, bool: is wikidata consistent for this article?function p._hasGalleryConsistent(qid)	local wp_title, wp_ns	wp_title, wp_ns, qid = _getTitleQID(qid)	return _lookupGallery(qid,true)end-- Does the article have a corresponding Commons gallery?-- Arguments:--   qid = QID to lookup in wikidata (for testing only)-- Returns:--   filename at Commons if so, false if notfunction p._hasGallery(qid)	local galleryLink, consistent = p._hasGalleryConsistent(qid)	return consistent and galleryLinkend-- Does the article have a Commons category? Is wikidata consistent for that?-- Arguments:--   qid = QID to lookup in wikidata (for testing only)--   prefix = whether to add "Category:" to return string (default true)-- Returns:--   filename at Commons, bool: consistentfunction p._hasCategoryConsistent(qid,prefix)	if prefix == nil then		prefix = true	end	local wp_title, wp_ns	wp_title, wp_ns, qid = _getTitleQID(qid)	local categoryLink, consistent = _lookupCategory(qid,true)	if categoryLink and prefix then		categoryLink = "Category:"..categoryLink	end	return categoryLink, consistentend-- Does the article have a corresponding Commons category?-- Arguments:--   qid = QID to lookup in wikidata (for testing only)--   prefix = whether to add "Category:" to return string (default true)-- Returns:--   filename at Commons if so, blank if notfunction p._hasCategory(qid,prefix)	local categoryLink, consistent = p._hasCategoryConsistent(qid,prefix)	return consistent and categoryLinkend-- Create Commons link corresponding to current article-- Arguments:--   namespace = namespace in Commons ("" for galleries)--   default = use as Commons link, don't access wikidata--   search = string to search for--   fallback = string to search for if wikidata fails--   formatting = formatting parameters--   qid = QID to lookup in wikidata (for testing only)-- Returns:--   formatted wikilink to Commons in specified namespacefunction p._getCommons(namespace,default,search,fallback,formatting,qid)	local nsColon	if not namespace or namespace == "" then		nsColon = ""	else		nsColon = namespace..":"	end	if default then		return "[[Commons:"..nsColon..default.."|".._formatResult(default,formatting).."]]"	end	if search then		return "[[Commons:Special:Search/"..nsColon..search.."|".._formatResult(search,formatting).."]]"	end	local wp_title, wp_ns	wp_title, wp_ns, qid = _getTitleQID(qid)	local commonsLink = nil	local consistent = true	if nsColon == "" then		commonsLink, consistent = _lookupGallery(qid,true)	elseif namespace:lower() == "category" then		commonsLink, consistent = _lookupCategory(qid,true)	end	-- use wikidata if consistent	if commonsLink and consistent then		return "[[Commons:"..nsColon..commonsLink.."|".._formatResult(commonsLink,formatting).."]]"	end	-- if not consistent, fall back to search and add to tracking cat	-- construct default result (which searches for title)	local searchResult = "[[Commons:Special:Search/"..nsColon..(fallback or wp_title)		.."|".._formatResult(fallback or wp_title,formatting).."]]"	if not consistent and wp_ns == "" then		local friendlyNS		if nsColon == "" then			friendlyNS = "thư viện"		else			friendlyNS = namespace:lower()		end		searchResult = searchResult.."[[Thể loại:Wikidata không nhất quán cho "..friendlyNS.." Commons]]"	end	return searchResultend-- Returns "best" Commons link: first look for gallery, then try category-- Arguments:--   default = use as Commons link, don't access wikidata--   search = string to search for--   fallback = string to search for if wikidata lookup fails--   formatting = formatting parameters--   qid = QID to lookup in wikidata (for testing only)-- Returns:--   formatted wikilink to Commons "best" landing pagefunction p._getGalleryOrCategory(default, search, fallback, formatting, qid)	if default then		return "[[Commons:"..default.."|".._formatResult(default,formatting).."]]"	end	if search then		return "[[Commons:Special:Search/"..search.."|".._formatResult(search,formatting).."]]"	end	local wp_title, wp_ns	wp_title, wp_ns, qid = _getTitleQID(qid)	local trackingCats = ""	local galleryLink, consistent, commonsSitelink = _lookupGallery(qid,true)	-- use wikidata if either sitelink or P935 exist, and they both agree	if galleryLink and consistent then		return "[[Commons:"..galleryLink.."|".._formatResult(galleryLink,formatting).."]]"	end	if not consistent and wp_ns == "" then		trackingCats = "[[Thể loại:Wikidata không nhất quán cho thư viện Commons]]"	end	-- if gallery is not good, fall back looking for category	local categoryLink	categoryLink, consistent = _lookupCategory(qid,false,commonsSitelink)	if categoryLink and consistent then		return "[[Commons:Category:"..categoryLink.."|".._formatResult(categoryLink,formatting).."]]"..trackingCats	end	if not consistent and wp_ns == "" then		trackingCats = trackingCats.."[[Thể loại:Wikidata không nhất quán cho thể loại Commons]]"	end	-- return search result looking for title as last attempt	return "[[Commons:Special:Search/" .. (fallback or wp_title) ..		"|" .. _formatResult(fallback or wp_title,formatting) .. "]]" .. trackingCatsend-- Return link(s) Commons gallery, or category, or both from wikidata-- Arguments:--   defaultGallery = default gallery link to use, instead of wikidata--   defaultCategory = default category link to use, instead of wikidata--   categoryText = if both gallery and category, text to use in category link ("category" by default)--   oneSearch = only emit one search result--   formatting = formatting parameters--   qid = qid of page to lookup in wikidata (testing only)function p._getGalleryAndCategory(defaultGallery, defaultCategory, 	categoryText, oneSearch, formatting, qid	)	local wp_title, wp_ns	wp_title, wp_ns, qid = _getTitleQID(qid)	categoryText = categoryText or "thể loại"	local trackingCats = ""	local galleryLink, galleryConsistent	local commonsSitelink = nil	if defaultGallery then		galleryLink = defaultGallery		galleryConsistent = true	else		galleryLink, galleryConsistent, commonsSitelink = _lookupGallery(qid,true)	end	local galleryGood = galleryLink and galleryConsistent	if not galleryConsistent and wp_ns == "" then		trackingCats = "[[Thể loại:Wikidata không nhất quán cho thư viện Commons]]"	end	local categoryLink, categoryConsistent	if defaultCategory then		categoryLink = defaultCategory		categoryConsistent = true	else		categoryLink, categoryConsistent = _lookupCategory(qid,defaultGallery,commonsSitelink)	end	local categoryGood = categoryLink and categoryConsistent	if not categoryConsistent and wp_ns == "" then		trackingCats = trackingCats.."[[Thể loại:Wikidata không nhất quán cho thể loại Commons]]"	end	local firstLink	-- construct default result (which searches for title)	local searchResult = "[[Commons:Special:Search/"..wp_title.."|".._formatResult(wp_title,formatting).."]]"	if not oneSearch then		searchResult = searchResult.." ([[Commons:Special:Search/Category:"..wp_title.."|"..categoryText.."]])"	end	local linkText = nil	if galleryGood then		firstLink = galleryLink		linkText = galleryLink	elseif categoryGood then		firstLink = "Category:"..categoryLink		linkText = categoryLink	else		return searchResult..trackingCats	end	local resultVal = "[[Commons:"..firstLink.."|".._formatResult(linkText,formatting).."]]"	if galleryGood and categoryGood then		resultVal = resultVal.." ([[Commons:Category:"..categoryLink.."|"..categoryText.."]])"	end	return resultVal..trackingCatsend-- Compare two titles with their namespaces strippedlocal function titleMatch(s1,s2)	s1 = s1 or ""	s2 = s2 or ""    s1 = mw.ustring.gsub(s1,"^[^:]+:","")    s2 = mw.ustring.gsub(s2,"^[^:]+:","")    return s1 == s2endlocal galleryTrackingCats = {	commons_link_on_wikidata = '[[Thể loại:Liên kết Commons có ở Wikidata]]',	commons_link_defined_as_pagename = '[[Thể loại:Liên kết Commons được định rõ là tên trang]]',	commons_link_locally_defined = '[[Thể loại:Liên kết Commons được định rõ cục bộ]]',	commons_link_from_wikidata = '[[Thể loại:Liên kết Commons từ Wikidata]]',	commons_link_is_pagename = '[[Thể loại:Liên kết Commons là tên trang]]',	inconsistent = '[[Thể loại:Wikidata không nhất quán cho thư viện Commons]]'}local categoryTrackingCats = {		commons_link_on_wikidata = '[[Thể loại:Liên kết thể loại Commons có ở Wikidata]]',		commons_link_defined_as_pagename = '[[Thể loại:Liên kết Commons được định rõ là tên trang]]',		commons_link_locally_defined = '[[Thể loại:Liên kết thể loại Commons được định rõ cục bộ]]',		commons_link_from_wikidata = '[[Thể loại:Liên kết thể loại Commons từ Wikidata]]',		commons_link_is_pagename = '[[Thể loại:Liên kết thể loại Commons là tên trang]]',		inconsistent = '[[Thể loại:Wikidata không nhất quán cho thể loại Commons]]'	}local function selectTrackingCat(trackingCats,wikidata,consistent,default,title)	if not consistent then		return trackingCats.inconsistent	end	if default then	-- construct warning message		if default == wikidata then			return trackingCats.commons_link_on_wikidata		end		local warning = ""		if wikidata then			local generateWarning = require('Mô đun:If preview')._warning			warning = generateWarning({					"Liên kết Commons không khớp với Wikidata – [[Bản mẫu:Thể loại Commons#Giải quyết sự không nhất quán|vui lòng kiểm tra lại]]"				})		end		if titleMatch(default,title) then			return trackingCats.commons_link_defined_as_pagename .. warning		end		return trackingCats.commons_link_locally_defined .. warning	end	if wikidata then		return trackingCats.commons_link_from_wikidata	end	return trackingCats.commons_link_is_pagenameend-- Figure out tracking categories and editor warnings-- Arguments:--   default = Commons link argument passed to template--   fetchGallery = whether to fetch a gallery from Wikidata--   fetchCategory = whether to fetch a category from Wikidata--   qid = force a qid for testing-- Returns:--   tracking category and possible user warning---- Note: the logic for the tracking is quite different than the logic-- for generating Commons links (above). Thus, it is separated into another-- function for code clarity and maintainability. This should not seriously -- affect performance: server time is dominated by fetching wikidata entities,-- and those entities should be cached and shared between the Commons generating-- code and this tracking code.function p._tracking(default, fetchGallery, fetchCategory, qid)	local title, wp_ns, wp_qid = _getTitleQID(qid,true)	if wp_ns ~= "" then		title = wp_ns..":"..title	end	-- only track if test or namespace=article or namespace=category	if not (qid or wp_ns == "" or wp_ns == "Category") then		return ""	end		-- determine title and namespace of wikidata and wp article	local wikidata = nil	local consistent = nil	-- Tracking code works for all 4 cases of states of fetchGallery/Category	-- fetchGallery takes precedence	if fetchGallery then		wikidata, consistent = p._hasGalleryConsistent(qid)		if default or not fetchCategory or (consistent and wikidata) then			return selectTrackingCat(galleryTrackingCats,wikidata,consistent,				                     default,title)		end	end    if fetchCategory then		local cat_wikidata, cat_consistent = p._hasCategoryConsistent(qid,true)		if not fetchGallery or (cat_consistent and cat_wikidata) then			return selectTrackingCat(categoryTrackingCats,cat_wikidata,			                    	 cat_consistent,default,title)		end		return selectTrackingCat(galleryTrackingCats,wikidata,consistent,			                     default,title)    end	return "" -- nothing fetched, nothing trackedendlocal function _createFormatting(args)	local formatting = {}	formatting.linktext = args.linktext	formatting.lcfirst = yesNo(args.lcfirst)	formatting.bold = yesNo(args.bold)	formatting.italic = yesNo(args.italic)	formatting.nowrap = yesNo(args.nowrap)	return formattingend-- Testing-only entry point for _getTitleQIDfunction p.getTitleQID(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	local text, ns, qid = _getTitleQID(args[1],args[2])	return text..","..ns..","..(qid or "nil")end-- Testing-only entry point for _lookupFallbackfunction p.lookupFallback(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	local fallback = _lookupFallback(args[1],args[2])	return fallback or "nil"end-- Find the Commons gallery page associated with articlefunction p.getGallery(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._getCommons("",args[1],args.search,args.fallback,_createFormatting(args),args.qid)end-- Find the Commons category page associated with articlefunction p.getCategory(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	local retval = p._getCommons("Category", args[1], 		args.search, args.fallback, _createFormatting(args), args.qid	)	if args.tracking then		local default = nil		if args[1] then			default = "Category:"..args[1]		end		retval = retval..p._tracking(default, false, true, args.qid)	end	return retvalendfunction p.getGalleryOrCategory(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	local retval = p._getGalleryOrCategory(		args[1], args.search, args.fallback, _createFormatting(args), args.qid	)	if args.tracking then		retval = retval..p._tracking(args[1],true,true,args.qid)	end	return retvalendfunction p.hasGallery(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._hasGallery(args.qid) or ""endfunction p.hasCategory(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._hasCategory(args.qid) or ""endfunction p.hasGalleryOrCategory(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._hasGallery(args.qid) or p._hasCategory(args.qid) or ""endfunction p.getGalleryAndCategory(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._getGalleryAndCategory(args[1], args[2], 		args.categoryText, args.oneSearch, _createFormatting(args), args.qid)endfunction p.tracking(frame)	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})	return p._tracking(args[1], args.fetchGallery, args.fetchCategory, args.qid)endreturn p