×
Create a new article
Write your page title here:
We currently have 33 articles on Ballmedia. Type your article name above or create one of the articles listed here!



    Ballmedia

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

    --------------------------------------------------------------------------------
    --                                 UserLinks                                  --
    -- This module creates a list of links about a given user. It can be used on  --
    -- its own or from a template. See the /doc page for more documentation.      --
    --------------------------------------------------------------------------------
    
    -- Require necessary modules
    local yesno = require('Module:Yesno')
    
    -- Lazily initialise modules that we might or might not need
    local mExtra -- [[Module:UserLinks/extra]]
    local mArguments -- [[Module:Arguments]]
    local mToolbar -- [[Module:Toolbar]]
    local mCategoryHandler -- [[Module:Category handler]]
    local mTableTools -- [[Module:TableTools]]
    local interwikiTable -- [[Module:InterwikiTable]], loaded with mw.loadData
    
    -- Load shared helper functions
    local mShared = require('Module:UserLinks/shared')
    local raiseError = mShared.raiseError
    local maybeLoadModule = mShared.maybeLoadModule
    local makeWikitextError = mShared.makeWikitextError
    local makeWikilink = mShared.makeWikilink
    local makeUrlLink = mShared.makeUrlLink
    local makeFullUrlLink = mShared.makeFullUrlLink
    local message = mShared.message
    
    local p = {}
    
    --------------------------------------------------------------------------------
    -- Link table
    --------------------------------------------------------------------------------
    
    function p.getLinks(snippets)
    	--[=[
    	-- Get a table of links that can be indexed with link codes. The table
    	-- returned is blank, but links are added to it on demand when it is
    	-- indexed. This is made possible by the metatable and by the various link
    	-- functions, some of which are defined here, and some of which are defined
    	-- at [[Module:UserLinks/extra]].
    	--]=]
    	local links, linkFunctions = {}, {}
    
    	----------------------------------------------------------------------------
    	-- Link functions
    	--
    	-- The following functions make the links from the link codes and the user
    	-- data snippets. New link functions should be added below the existing
    	-- functions.
    	----------------------------------------------------------------------------
    
    	function linkFunctions.u(snippets)
    		-- User page
    		return makeWikilink(
    			snippets.interwiki,
    			2,
    			snippets.username,
    			snippets.username
    		)
    	end
    
    	function linkFunctions.t(snippets)
    		-- User talk page
    		return makeWikilink(
    			snippets.interwiki,
    			3,
    			snippets.username,
    			message('display-talk')
    		)
    	end
    
    	function linkFunctions.c(snippets)
    		-- Contributions
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Contribs/' .. snippets.username,
    			message('display-contributions')
    		)
    	end
    	
    	function linkFunctions.c64(snippets)
    		-- Contributions
    		local first64 = snippets.username:match('^%x+:%x+:%x+:%x+:')
    			or snippets.username:match('^%x+:%x+:%x+:')
    			or snippets.username:match('^%x+:%x+:')
    			or snippets.username:match('^%x+:')
    		return first64 and makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Contribs/' .. first64 .. ':/64',
    			'(/64)'
    		) or ''
    	end
    
    	function linkFunctions.ct(snippets)
    		-- Edit count
    		return makeUrlLink(
    			{
    				host = 'xtools.wmflabs.org',
    				path = '/ec/',
    				query = {
    					username = snippets.username,
    					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'
    				}
    			},
    			message('display-count')
    		)
    	end
    
    	function linkFunctions.m(snippets)
    		-- Page moves
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/move/' .. snippets.username,
    			message('display-moves')
    		)
    	end
    
    	function linkFunctions.l(snippets)
    		-- Logs
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/' .. snippets.username,
    			message('display-logs')
    		)
    	end
    
    	function linkFunctions.ae(snippets)
    		-- Automated edits (and non-automated contributions).
    		return makeUrlLink(
    			{
    				host = 'xtools.wmflabs.org',
    				path = '/autoedits/',
    				query = {
    					username = snippets.username,
    					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'
    				}
    			},
    			message('display-autoedits')
    		)
    	end
    
    	function linkFunctions.bl(snippets)
    		-- Block log
    		return makeFullUrlLink(
    			snippets.interwiki,
    			-1,
    			'Log/block',
    			{page = 'User:' .. snippets.username},
    			message('display-blocklog')
    		)
    	end
    
    	function linkFunctions.bls(snippets)
    		-- Blocks
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/block/' .. snippets.username,
    			message('display-blocks')
    		)
    	end
    
    	function linkFunctions.bu(snippets)
    		-- Block user
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Block/' .. snippets.username,
    			message('display-blockuser')
    		)
    	end
    
    	function linkFunctions.ca(snippets)
    		-- Central auth
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'CentralAuth/' .. snippets.username,
    			message('display-centralauth')
    		)
    	end
    
    	function linkFunctions.dc(snippets)
    		-- Deleted contribs
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'DeletedContributions/' .. snippets.username,
    			message('display-deletedcontributions')
    		)
    	end
    
    	function linkFunctions.e(snippets)
    		-- Email
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'EmailUser/' .. snippets.username,
    			message('display-email')
    		)
    	end
    
    	function linkFunctions.es(snippets)
    		-- Edit summaries
    		return makeUrlLink(
    			{
    				host = 'xtools.wmflabs.org',
    				path = '/editsummary/',
    				query = {
    					username = snippets.username,
    					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'
    				}
    			},
    			message('display-editsummaries')
    		)
    	end
    
    	function linkFunctions.del(snippets)
    		-- Deletions
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/delete/' .. snippets.username,
    			message('display-deletions')
    		)
    	end
    
    	function linkFunctions.lu(snippets)
    		-- List user
    		return makeFullUrlLink(
    			snippets.interwiki,
    			-1,
    			'ListUsers',
    			{limit = 1, username = snippets.username},
    			message('display-listuser')
    		)
    	end
    
    	function linkFunctions.sul(snippets)
    		-- SUL
    		return makeWikilink(
    			nil,
    			nil,
    			'sulutil:' .. snippets.username,
    			message('display-sul')
    		)
    	end
    
    	function linkFunctions.tl(snippets)
    		-- Target logs
    		return makeFullUrlLink(
    			snippets.interwiki,
    			-1,
    			'Log',
    			{page = mw.site.namespaces[2].name .. ':' .. snippets.username},
    			message('display-targetlogs')
    		)
    	end
    
    	function linkFunctions.efl(snippets)
    		-- Edit filter log
    		return makeFullUrlLink(
    			snippets.interwiki,
    			-1,
    			'AbuseLog',
    			{wpSearchUser = snippets.username},
    			message('display-abuselog')
    		)
    	end
    
    	function linkFunctions.pr(snippets)
    		-- Protections
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/protect/' .. snippets.username,
    			message('display-protections')
    		)
    	end
    
    	function linkFunctions.rl(snippets)
    		-- User rights
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/rights/' .. snippets.username,
    			message('display-rights')
    		)
    	end
    
    	function linkFunctions.ren(snippets)
    		-- Renames
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'Log/renameuser/' .. snippets.username,
    			message('display-renames')
    		)
    	end
    
    	function linkFunctions.rfa(snippets)
    		-- Requests for adminship
    		return makeWikilink(
    			nil,
    			-1,
    			'PrefixIndex/' .. message('page-rfa') .. '/' .. snippets.username,
    			message('display-rfa')
    		)
    	end
    
    	function linkFunctions.api(snippets)
    		-- API user data
    		return makeUrlLink(
    			{
    				host = snippets.fullDomain,
    				path = '/w/api.php',
    				query = {
    					action = 'query',
    					list = 'users',
    					usprop = 'groups|editcount',
    					ususers = snippets.username
    				}
    			},
    			message('display-api')
    		)
    	end
    
    	function linkFunctions.up(snippets)
    		-- Uploads
    		return makeWikilink(
    			snippets.interwiki,
    			-1,
    			'ListFiles/' .. snippets.username,
    			message('display-uploads')
    		)
    	end
    	
    	----------------------------------------------------------------------------
    	-- End of link functions
    	----------------------------------------------------------------------------
    
    	-- Define the metatable that memoizes the link functions, and fetches link
    	-- functions from [[Module:UserLinks/extra]] if necessary.
    
    	-- Lazily initialise the extraLinkFunctions table. We only want to load
    	-- [[Module:UserLinks/extra]] as necessary, so it has a low transclusion
    	-- count.
    	local extraLinkFunctions
    
    	-- Define functions for shared code in the metatable.
    	local function validateCode(code)
    		-- Checks whether code is a valid link code - i.e. checks that it is a
    		-- string and that it is not the blank string. Returns the code if
    		-- the check passes, and nil if not.
    		if type(code) == 'string' and code ~= '' then
    			return code
    		else
    			return nil
    		end
    	end
    
    	local function getExtraLinkFunctions()
    		-- Loads the table of extra link functions from the /extra module.
    		-- If there is a problem with loading it, return false. We use the
    		-- distinction between false and nil to record whether we have already
    		-- tried to load it.
    		if extraLinkFunctions ~= nil then
    			return extraLinkFunctions
    		end
    		if mExtra == nil then
    			-- If loading the module fails, maybeLoadModule returns false.
    			-- Here we use the distinction between false and nil to record
    			-- whether we have already tried to load the /extra module.
    			mExtra = maybeLoadModule('Module:UserLinks/extra')
    		end
    		if type(mExtra) == 'table'
    			and type(mExtra.linkFunctions) == 'table'
    		then
    			extraLinkFunctions = mExtra.linkFunctions
    		else
    			extraLinkFunctions = false
    		end
    		return extraLinkFunctions
    	end
    
    	local function memoizeExtraLink(code, func)
    		local success, link = pcall(func, snippets)
    		if success and type(link) == 'string' then
    			links[code] = link
    			return link
    		end
    		return nil
    	end
    
    	-- Define the metatable.
    	setmetatable(links, {
    		__index = function (t, key)
    			local code = validateCode(key)
    			if not code then
    				raiseError(
    					message('error-malformedlinkcode'),
    					message('error-malformedlinkcode-section')
    				)
    			end
    			local linkFunction = linkFunctions[code]
    			local link
    			if linkFunction then
    				link = linkFunction(snippets)
    				links[code] = link
    			else
    				extraLinkFunctions = getExtraLinkFunctions()
    				if extraLinkFunctions then
    					local extraLinkFunction = extraLinkFunctions[code]
    					if type(extraLinkFunction) == 'function' then
    						link = memoizeExtraLink(code, extraLinkFunction)
    					end
    				end
    			end
    			if link then
    				return link
    			else
    				raiseError(
    					message('error-invalidlinkcode', code),
    					message('error-invalidlinkcode-section')
    				)
    			end
    		end,
    		__pairs = function ()
    			extraLinkFunctions = getExtraLinkFunctions()
    			if extraLinkFunctions then
    				for code, func in pairs(extraLinkFunctions) do
    					if validateCode(code) and type(func) == 'function' then
    						memoizeExtraLink(code, func)
    					end
    				end
    			end
    			-- Allow built-in functions to overwrite extra functions.
    			for code, func in pairs(linkFunctions) do
    				local link = func(snippets)
    				links[code] = link
    			end
    			return function (t, key)
    				return next(links, key)
    			end
    		end
    	})
    	return links
    end
    
    --------------------------------------------------------------------------------
    -- User data snippets
    --------------------------------------------------------------------------------
    
    function p.getSnippets(args)
    	--[=[
    	-- This function gets user data snippets from the arguments, and from
    	-- [[Module:InterwikiTable]]. The data is loaded as necessary and memoized
    	-- in the snippets table for performance. 
    	--
    	-- Snippets default to the blank string, '', so they can be used in
    	-- concatenation operations without coders having to worry about raising
    	-- errors. Because of this, the local functions snippetExists and
    	-- getSnippet have been written to aid people writing new snippets. These
    	-- functions treat the blank string as false. It is not necessary to return
    	-- the blank string from a snippet function, as nil and false values are
    	-- automatically converted into the blank string by the metatable.
    	--
    	-- If you add a new snippet, please document it at
    	-- [[Module:UserLinks#Adding new links]].
    	--]=]
    	local snippets, snippetFunctions = {}, {}
    	setmetatable(snippets, {
    		__index = function (t, key)
    			local snippetFunction = snippetFunctions[key]
    			if snippetFunction then
    				snippets[key] = snippetFunction() or ''
    				return snippets[key]
    			else
    				raiseError(
    					message('error-nosnippet', key),
    					message('error-nosnippet-section')
    				)
    			end
    		end
    	})
    
    	-- Define helper functions for writting the snippet functions.
    	local function snippetExists(key)
    		-- We have set the metatable up to make snippets default to '', so we
    		-- don't have to test for false or nil.
    		return snippets[key] ~= ''
    	end
    
    	local function getSnippet(key)
    		local ret = snippets[key]
    		if ret == '' then
    			return nil
    		else
    			return ret
    		end
    	end
    
    	-- Start snippet functions.
    
    	function snippetFunctions.username()
    		-- The username.
    		local username = args.user or args.User
    		return username or raiseError(
    			message('error-nousername'),
    			message('error-nousername-section')
    		)
    	end
    
    	function snippetFunctions.usernameHtml()
    		-- The username html-encoded. Spaces are encoded as pluses.
    		return mw.uri.encode(snippets.username)
    	end
    
    	function snippetFunctions.project()
    		-- The project name.
    		-- Also does the work for snippetFunctions.interwikiTableKey, and adds
    		-- the project value to snippets.lang if it is a valid language code.
    		local project = args.Project or args.project
    		if not project then
    			return nil
    		end
    		local projectValidated, interwikiTableKey = p.validateProjectCode(project)
    		if not projectValidated then
    			if mw.language.isKnownLanguageTag(project) then
    				if not snippetExists('lang') then
    					snippets.lang = project
    				end
    			else
    				raiseError(
    					message('error-invalidproject', project),
    					message('error-invalidproject-section')
    				)
    			end
    		end
    		snippets.interwikiTableKey = interwikiTableKey
    		return project
    	end
    
    	function snippetFunctions.interwikiTableKey()
    		-- The key for the project in Module:InterwikiTable.
    		-- Relies on snippetFunctions.project to do the real work.
    		local temp = snippets.project -- required; puts key in snippets table
    		return rawget(snippets, 'interwikiTableKey')
    	end
    
    	function snippetFunctions.toolProject()
    		-- The short project code for use with toolserver or labs. It is always
    		-- present, even if the "project" argument is absent. The default value
    		-- is the "snippet-project-default" message.
    		local project = getSnippet('project')
    		if not project then
    			return message('snippet-project-default')
    		else
    			return project
    		end
    	end
    
    	function snippetFunctions.projectLong()
    		-- The long form of the project name, e.g. "wikipedia" or "wikibooks".
    		local key = getSnippet('interwikiTableKey')
    		if not key then
    			return message('snippet-projectlong-default')
    		end
    		interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
    		local prefixes = interwikiTable[key].iw_prefix
    		-- Using prefixes[2] is a bit of a hack, but should find the long name
    		-- most of the time.
    		return prefixes[2] or prefixes[1] 
    	end
    
    	function snippetFunctions.lang()
    		-- The language code.
    		local lang = args.lang or args.Lang
    		if not lang then
    			return nil
    		end
    		if mw.language.isKnownLanguageTag(lang) then
    			return lang
    		else
    			raiseError(
    				message('error-invalidlanguage', lang),
    				message('error-invalidlanguage-section')
    			)
    		end
    	end
    
    	function snippetFunctions.toolLang()
    		-- The language code for use with toolserver or labs tools. It is always
    		-- present, even if the "lang" argument is absent. The default value is
    		-- the "snippet-lang-default" message. 
    		return getSnippet('lang') or message('snippet-lang-default')
    	end
    
    	function snippetFunctions.interwiki()
    		-- The interwiki prefix, consisting of the project and language values,
    		-- separated by colons, e.g. ":wikt:es:".
    		local project = getSnippet('project')
    		local lang = getSnippet('lang')
    		if not project and not lang then
    			return nil
    		end
    		local ret = {}
    		ret[#ret + 1] = project
    		ret[#ret + 1] = lang
    		return table.concat(ret, ':')
    	end
    
    	function snippetFunctions.fullDomain()
    		-- The full domain name of the site, e.g. www.mediawiki.org,
    		-- en.wikpedia.org, or ja.wikibooks.org.
    		local fullDomain
    		local lang = getSnippet('toolLang')
    		local key = getSnippet('interwikiTableKey')
    		if key then
    			interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
    			local domain = interwikiTable[key].domain
    			local takesLangPrefix = interwikiTable[key].takes_lang_prefix
    			if takesLangPrefix then
    				fullDomain = lang .. '.' .. domain
    			else
    				fullDomain = domain
    			end
    		else
    			fullDomain = lang .. '.wikipedia.org'
    		end
    		return fullDomain
    	end
    
    	-- End snippet functions. If you add a new snippet function, please
    	-- document it at [[Module:UserLinks#Adding new links]].
    
    	return snippets
    end 
    
    function p.validateProjectCode(s)
    	-- Validates a project code, by seeing whether it is present in
    	-- [[Module:InterwikiTable]]. If it is present, returns the code and the
    	-- InterwikiTable key for the corresponding site. If not present,
    	-- returns nil for both.
    	interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
    	for key, t in pairs(interwikiTable) do
    		for i, prefix in ipairs(t.iw_prefix) do
    			if s == prefix then
    				return s, key
    			end
    		end
    	end
    	return nil, nil
    end
    
    --------------------------------------------------------------------------------
    -- Main functions
    --------------------------------------------------------------------------------
    
    local function makeInvokeFunction(funcName)
    	-- Makes a function that can be accessed from #invoke. This is only required
    	-- for functions that need to access arguments.
    	return function (frame)
    		mArguments = require('Module:Arguments')
    		local args = mArguments.getArgs(frame)
    		return p[funcName](args)
    	end
    end
    
    p.main = makeInvokeFunction('_main')
    
    function p._main(args)
    	-- The main function. This is the one called from [[Template:User-multi]],
    	-- via p.main.
    	local options = p.getOptions(args)
    	local snippets = p.getSnippets(args)
    	local codes = p.getCodes(args)
    	local links = p.getLinks(snippets)
    	-- Overload the built-in Lua error function to generate wikitext errors
    	-- meant for end users to see. This makes things harder to debug when
    	-- real errors occur, but it is the only realistic way to show wikitext
    	-- errors and and still have sane code when using metatables, etc.
    	local success, result = pcall(p.export, codes, links, options)
    	if success then
    		return result
    	else
    		return makeWikitextError(result, options.isDemo)
    	end
    end
    
    function p.getOptions(args)
    	-- Gets the options from the args table, so that we don't have to pass
    	-- around the whole args table all the time.
    	local options = {}
    	options.isDemo = yesno(args.demo) or false
    	options.toolbarStyle = yesno(args.small) and 'font-size: 90%;' or nil
    	options.sup = yesno(args.sup, true)
    	options.separator = args.separator
    	options.span = args.span
    	return options
    end
    
    function p.getCodes(args)
    	-- Gets the link codes from the arguments. The codes aren't validated
    	-- at this point.
    	mTableTools = maybeLoadModule('Module:TableTools')
    	local codes
    	if mTableTools then
    		codes = mTableTools.compressSparseArray(args)
    	else
    		codes = {}
    		for i, code in ipairs(args) do
    			codes[i] = code
    		end
    	end
    	return codes
    end
    
    function p.export(codes, links, options)
    	-- Make the user link.
    	local userLink = links.u
    
    	-- If we weren't passed any link codes, just return the user link.
    	if #codes < 1 then
    		return userLink
    	end
    
    	-- Make the toolbar.
    	mToolbar = require('Module:Toolbar')
    	local toolbarArgs = {}
    	for i, code in ipairs(codes) do
    		local link = links[code]
    		toolbarArgs[#toolbarArgs + 1] = link
    	end
    	toolbarArgs.style = options.toolbarStyle
    	toolbarArgs.separator = options.separator or 'dot'
    	toolbarArgs.span = options.span
    	local toolbar = mToolbar.main(toolbarArgs)
    
    	-- Apply the sup option.
    	if options.sup then
    		toolbar = '<sup>' .. toolbar .. '</sup>'
    	end
    	
    	-- If we are transcluding, add a non-breaking space, but if we are substing
    	-- just use a normal space
    	local space = mw.isSubsting() and ' ' or '&nbsp;'
    	
    	return userLink .. space .. toolbar
    end
    
    --------------------------------------------------------------------------------
    -- Single link function
    --------------------------------------------------------------------------------
    
    p.single = makeInvokeFunction('_single')
    
    function p._single(args)
    	-- Fetches a single link from the link table.
    	local options = p.getOptions(args)
    	local snippets = p.getSnippets(args)
    	local links = p.getLinks(snippets)
    	local code = args[1]
    	local success, link = pcall(p.exportSingle, links, code)
    	if success then
    		return link
    	else
    		return makeWikitextError(link, options.isDemo)
    	end
    end
    
    function p.exportSingle(links, code)
    	-- If any errors occur, they will probably occur here. This function
    	-- exists purely so that all the errors that will occur in p._single can
    	-- be handled using a single pcall.
    	if not code then
    		raiseError(
    			message('error-nolinkcode'),
    			message('error-nolinkcode-section')
    		)
    	end
    	return links[code]
    end
    
    --------------------------------------------------------------------------------
    -- Link table
    --------------------------------------------------------------------------------
    
    function p.linktable()
    	-- Returns a wikitext table of link codes, with an example link for each
    	-- one. This function doesn't take any arguments, so it can be accessed
    	-- directly from wiki pages without using makeInvokeFunction.
    	local args = {user = 'Example'}
    	local snippets = p.getSnippets(args)
    	local links = p.getLinks(snippets)
    
    	-- Assemble the codes and links in order
    	local firstCodes = {'u', 't', 'c'}
    	local firstLinks, firstCodesKeys = {}, {}
    	for i, code in ipairs(firstCodes) do
    		firstCodesKeys[code] = true
    		firstLinks[#firstLinks + 1] = {code, links[code]}
    	end
    	local secondLinks = {}
    	for code, link in pairs(links) do
    		if not firstCodesKeys[code] then
    			secondLinks[#secondLinks + 1] = {code, link}
    		end
    	end
    	table.sort(secondLinks, function(t1, t2)
    		return t1[1] < t2[1]
    	end)
    	local links = {}
    	for i, t in ipairs(firstLinks) do
    		links[#links + 1] = t
    	end
    	for i, t in ipairs(secondLinks) do
    		links[#links + 1] = t
    	end
    
    	-- Output the code table in table format
    	local ret = {}
    	ret[#ret + 1] = '{| class="wikitable plainlinks sortable"'
    	ret[#ret + 1] = '|-'
    	ret[#ret + 1] = '! ' .. message('linktable-codeheader')
    	ret[#ret + 1] = '! ' .. message('linktable-previewheader')
    	for i, t in ipairs(links) do
    		local code = t[1]
    		local link = t[2]
    		ret[#ret + 1] = '|-'
    		ret[#ret + 1] = "| '''" .. code .. "'''" 
    		ret[#ret + 1] = '| ' .. link
    	end
    	ret[#ret + 1] = '|}'
    	return table.concat(ret, '\n')
    end 
    
    return p
    
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.