Module:Report

--Get Required Modules local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local string = require('Module:String') local table = require('Module:Table') local lu = require('Module:LibraryUtil') local checkType = lu.checkType local checkType = lu.checkType

local sep = ' • '

--Begin Exports local p = {}

--Helper Functions local function trimWhitespace(s) checkType('trimWhitespace', 1, s, 'string') return s:match( "^%s*(.-)%s*$" ) end

local function gsubMulti(s, t, lim) checkType('gsubMulti', 1, s, 'string') checkType('gsubMulti', 2, t, 'table') checkType('gsubMulti', 3, lim, {'number', 'string', 'nil'}) for k, v in pairs(t) do		s = s:gsub(k, v or '', tonumber(lim)) end return s end

function p._trimUser(frame) local args = getArgs(frame) return p.trimUser(args[1], yesno(args[2], false)) end

function p.trimUser(s, link) checkType(1, s, 'string') local s = trimWhitespace(s) local matches = { {				['^.-%[%[.-%:([^%|]-)%|.*%]%].*$']='%1';				['^.-%[%[.-%:(.-)%]%].*$']='%1';			},			{				['^.-%{%{.+%:(.-)%/.+%|?.*%}%}.*$']='%1';			},			{				['^.-%[?https?%:/%/%S-%/wiki%/.-%:(.+) ?.-%]?.*$']='%1'; ['^AbuseLog%?wpSearchUser=(.+)$']='%1'; ['Contribu?t?i?o?n?s%/']=''; ['^(.-)%?.+$']='%1';				[' .-%]$']='';			}		}	if s:match('^.-(%[%[.-%]%]).*$') then s = gsubMulti(s, matches[1]) elseif s:match('^.-%{%{.+%:(.-)%/.+%|?.*%}%}.*$') then s = gsubMulti(s, matches[2]) elseif s:match('^.-%[?https?%:/%/%S-%/wiki%/.-%:(.+) ?.-%]?.*$') then s = gsubMulti(s, matches[3]) end return link and table.concat{ , s,  } or s end

local function isIp(ip) if ip == nil or type(ip) ~= "string" then return false end -- Check IPv4 local chunks = {ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")} if (#chunks == 4) then for _,v in pairs(chunks) do			if (tonumber(v) < 0 or tonumber(v) > 255) then return false end end return true end -- Check IPv6 local _, chunks = ip:gsub("%:", "") if chunks == 7 then return true end -- Otherwise return false end local function buildLinks(user, isIp) checkType(1, user, 'string') checkType(2, isIp, { 'boolean', 'nil' }) return table.concat{ string.wrapLink({ isIp and 'Special:Contributions/' or 'User:', user }, user), ' ',		string.wrapHtml{ {				'(',				not isIp and table.concat{ 					string.fullUrl({ 'Message_wall:', user }, nil, 'wall'), -- this uses 'fullUrl' since message wall links show up as wanted pages, so full url is used instead [Oct 2021]					sep,					string.wrapLink({ 'Special:Contributions/', user }, 'contribs'),					sep				} or '',				string.wrapLink({ 'Special:UserProfileActivity/', user }, 'posts'),				sep,				string.wrapLink({ 'Special:DeletedContributions/', user }, 'DelContribs'),				sep,				string.wrapLink({ 'Special:Log/', user }, 'logs'),				sep,				string.fullUrl( 'Special:Log/block', { ['page']=user }, 'block log'),				sep,				string.fullUrl('Special:AbuseLog', { ['wpSearchUser']=user }, 'abuse log'),				sep,				string.wrapLink({ 'Special:Block/', user }, 'Block'),				sep,				string.fullUrl('Special:BlankPage', { ['blankspecial']='nuke', ['nukeuser']=user }, 'Nuke'),				isIp and table.concat{					sep, string.externalUrl({ 'https://cleantalk.org/whois/', user }, nil, 'WHOIS'), sep, string.externalUrl({ 'https://www.ipqualityscore.com/free-ip-lookup-proxy-vpn-test/lookup/', user }, nil, 'Proxy check'), sep, string.externalUrl({ 'https://cleantalk.org/blacklists/', user }, nil, 'Spam BL check'), } or '', ')',			},			' ',			{				style="font-size: 10px"			}		}	} end p.buildLinks = buildLinks

local function userLink(user, disableOthers) return table.concat{ string.makeLink({ 'User:', user }, user), disableOthers and '' or ' ', not disableOthers and string.wrapHtml{ {				'(',				string.fullUrl({ 'Message wall:', user }, nil, 'wall'), -- this uses 'fullUrl' since message wall links show up as wanted pages, so full url is used instead [Oct 2021]				sep,				string.makeLink({ 'Special:Contribs/', user }, 'contribs'),				sep,				string.makeLink({ 'Special:UserProfileActivity/', user }, 'posts'),				')', }, ' '		} or '', } end p.userLink = userLink

- -- Template: Userlinks -- -- Creates a link to a user's Userpage, wall, contributions, and posts. - function p._userLink(frame) local args = getArgs(frame) local value = args[1]

return p.userLink(value, args['disableOther'] or args['disable']) end

local function buildPageLinks(page) checkType(1, page, 'string', true) page = page or mw.title.getCurrentTitle.fullText return table.concat{ string.wrapLink(page), string.wrapHtml{ {				"(",				string.fullUrl(page, { action="edit" }, 'edit'),				sep,				string.fullUrl(page, { action="history" }, 'history'),				sep,				string.fullUrl(page, { diff="cur" }, 'latest edit'),				sep,				string.makeLink({ "Special:WhatLinksHere/", page }, 'whl'),				sep,				string.makeLink({ 'Special:PrefixIndex/', page, '/' }, 'subpages'),				sep,				string.fullUrl('Special:Log', { page=page }, 'logs'),				sep,				string.fullUrl('Special:AbuseLog', { wpSearchTitle=page }, 'abuse log'),				sep,				string.makeLink({ 'Special:Undelete/', page }, 'del. revisions'),				sep,				string.fullUrl(page, { action="protect" }, 'protect'),				sep,				string.fullUrl(page, { action="delete" }, 'delete'),				sep,				string.makeLink({ 'Special:MovePage/', page }, 'move'),				")", }, ' '		}	} end - -- Template: Report -- -- Generates a Report about a user - function p.main(frame) local args = getArgs(frame) local user = args["reported_user"] or args["ru"] or args["user"] or args["u"] or args[1] local reporter = args["reporter"] or args["r"] or args[2] local timestamp = args["timestamp"] or args["ts"] or args[3] local reason = args["reason"] or args["res"] or args[4] if not user then return string.error('Please provide a username to report!') elseif not reporter then return string.error('Please provide your signature!') elseif not reason then return string.error('Please provide a reason why you are reporting %s!', p.trimUser(user)) end return string.pcall(p._main, user, reporter, timestamp, reason) end local function reportLink(user) return buildLinks(p.trimUser(user), isIp(user)) end - -- Template: Report Module access point - function p._main(user, reporter, timestamp, reason) checkType(1, user, 'string') checkType(2, reporter, 'string') checkType(3, timestamp, 'string') checkType(4, reason, 'string') local links = reportLink(user) local reporter = p.trimUser(reporter) local split = mw.text.split(user, '%s*,%s*') if #split > 1 and type(split) == 'table' then local tmp = {} for i, v in ipairs(split) do			table.push(tmp, v)		end links = pipeline(table.map(split, function(v) return string.wrapTag(reportLink(v), 'li') end), 'ul', string.wrapTag) end return tostring(		mw.html.create('ul')			:tag('li')				:wikitext( 'Reported User', (#split > 1 and type(split) == 'table') and 's' or '', ': ', links )			:done			:tag('li')				:wikitext( 'Signature:  ', string.wrapLink({ 'User:', reporter }, reporter), ' ',					string.wrapHtml{ {							'(',							string.fullUrl({ 'Message wall:', reporter }, nil, 'wall'), -- this uses 'fullUrl' since message wall links show up as wanted pages, so full url is used instead [Oct 2021]							sep,							string.wrapLink({ 'Special:Contributions/', reporter }, 'contribs'),							')', },						' ',						{							style="font-size: 10px" }					}				)			:done			:tag('li')				:wikitext( 'Timestamp: ', timestamp )			:done			:tag('li')				:wikitext( 'Reason: ', reason )			:done		:done	) end

- -- Template: UserList -- -- Creates a user list with links. - function p._userList(frame) return p.userList(table.unpackRaw(getArgs(frame))) end

- -- function: userList(users) -- -- Invoked by. - function p.userList(users, ...) local split = string.split(users, '%s*,%s*') if not users:match"," then split = { users, ... }	end return table.concat(table.map(split, function(v) return userLink(v) end), ', ') end

- -- Template: Deletion request -- -- Generates a deletion request for a page - function p.delete(frame) local args = getArgs(frame) return p._delete(table.unpack(table.deepCopy(args))) end

- -- Template: Deletion request Module access point - function p._delete(...) local page, reporter, timestamp, reason, comments = ... checkTypeArgs({		'string',		'string',		'string',		'string',		'string',	}, ...)

local page = trimWhitespace(page) local reason = trimWhitespace(reason) local links = buildPageLinks(page) local reporter = p.trimUser(reporter) local comments = trimWhitespace(comments) local timestamp = trimWhitespace(timestamp) return tostring(		mw.html.create('ul')			:tag('li')				:wikitext("Page: ", links)			:done			:tag('li')				:wikitext("Timestamp: ", timestamp)			:done			:tag('li')				:wikitext("Reporter: ", reporter)			:done			:tag('li')				:wikitext("Reason for report: ", reason)			:done			:tag('li')				:wikitext("Addtional comments: ", reason)			:done		:allDone	) end

--Finish Module/Exports return p