Modul:AccountUtl
| Vorlagenprogrammierung | Diskussionen | Lua | Test | Unterseiten | |||
| Modul | Deutsch | English
|
Modul: | Dokumentation | |||
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus
Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData:
2026-04-15local AccountUtl = { suite = "AccountUtl",
serial = "2026-04-15",
item = 139309150 }
--[=[
Utilities for user accounts.
isAnon()
isIP()
isTemp()
isUser()
isValid()
scope()
signer()
]=]
local Failsafe = AccountUtl
function isIP( account )
-- Check whether username is matching IPv4 scheme
-- Precondition:
-- account -- string, starting with nonzero digit
-- Postcondition:
-- Returns boolean
local sub = "([12]?[0-9]?[0-9])"
local seek = string.format( "^%s%%.%s%%.%s%%.%s$",
sub, sub, sub, sub )
local p1, p2, p3, p4 = account:match( seek )
if p1 and p2 and p3 and p4 then
local function legal( a )
if a:sub( 1, 1 ):find( "[1-9]" ) and
tonumber( a ) < 256 then
return true
end
end -- legal()
r = legal( p1 ) and
legal( p2 ) and
legal( p3 ) and
legal( p4 )
end
return r or false
end -- isIP()
function isTemp( account )
-- Check whether username is matching temporary scheme
-- Precondition:
-- account -- string, starting with "~"
-- Postcondition:
-- Returns boolean
local seek = "^~(20[2-9]%d)%-([1-9]%d%d%d[%d%-]*)$"
local y, s = account:match( seek )
if y then
y = tonumber( y )
if y >= 2024 then
local g
s = s .. "-"
g = s:match( "^(%d+)%-" )
if tonumber( g ) >= 1500 then
if s:match( "^%d+%-$" ) then
r = true
elseif g:len() == 5 then
s = s:sub( 7 )
g = s:match( "^(%d+)%-" )
if g then
local n = g:len()
if n <= 5 then
if s:match( "^%d+%-$" ) then
r = true
elseif n == 5 then
s = s:sub( 7 )
if s:match( "^%d+%-$" ) then
r = true
end
end
end
end
end
end
end
end
return r or false
end -- isTemp()
function isAnon( account )
-- Check whether username is matching IP or temporary scheme
-- Precondition:
-- account -- string
-- Postcondition:
-- Returns boolean
local s1 = account:sub( 1, 1 )
local r
if s1 == "~" then
r = isTemp( account )
elseif s1:find( "[1-9]" ) then
r = isIP( account )
end
return r or false
end -- isAnon()
function noIP( account )
-- Check whether lookalike username is not matching IPv4 scheme
-- Precondition:
-- account -- string, starting with digit
-- Postcondition:
-- Returns boolean, if not an IP
local sub = "(%d%d?%d?)"
local seek = string.format( "^%s%%.%s%%.%s%%.%s$",
sub, sub, sub, sub )
local p1, p2, p3, p4 = account:match( seek )
local r
if p1 and p2 and p3 and p4 then
local function lapsus( a )
if tonumber( a ) >= 256 then
return true
end
end -- lapsus()
r = lapsus( p1 ) or
lapsus( p2 ) or
lapsus( p3 ) or
lapsus( p4 )
else
r = true
end
return r
end -- noIP()
function isUser( account )
-- Check whether username might be any valid account
-- Precondition:
-- account -- string
-- Postcondition:
-- Returns boolean
local r
if isAnon( account ) then
r = true
elseif account:sub( 1, 1 ):find( "%d" ) then
r = noIP( account )
elseif account:sub( 1, 2 ) ~= "~2" then
r = true
end
return r or false
end -- isUser()
AccountUtl.isAnon = function ( account )
-- Check whether username is matching IP or temporary scheme
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns boolean
local s = AccountUtl.signer( account )
local r
if s then
r = isAnon( s )
end
return r or false
end -- AccountUtl.isAnon()
AccountUtl.isIP = function ( account )
-- Check whether username is matching IPv4 scheme
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns boolean
local s = AccountUtl.signer( account )
local r
if s then
if s:sub( 1, 1 ):find( "[1-9]" ) then
r = isIP( s )
end
end
return r or false
end -- AccountUtl.isIP()
AccountUtl.isTemp = function ( account )
-- Check whether username is matching temporary scheme
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns boolean
local s = AccountUtl.signer( account )
local r
if s then
if s:sub( 1, 1 ) == "~" then
local seek = "^~(20[2-9]%d)%-([1-9]%d%d%d[%d%-]*)$"
local y
y, s = s:match( seek )
if y then
y = tonumber( y )
if y >= 2024 then
local g
s = s .. "-"
g = s:match( "^(%d+)%-" )
if tonumber( g ) >= 1500 then
if s:match( "^%d+%-$" ) then
r = true
elseif g:len() == 5 then
s = s:sub( 7 )
g = s:match( "^(%d+)%-" )
if g then
local n = g:len()
if n <= 5 then
if s:match( "^%d+%-$" ) then
r = true
elseif n == 5 then
s = s:sub( 7 )
if s:match( "^%d+%-$" ) then
r = true
end
end
end
end
end
end
end
end
end
end
return r or false
end -- AccountUtl.isTemp()
AccountUtl.isUser = function ( account )
-- Check whether username might be any valid account
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns boolean
local r
if AccountUtl.signer( account ) then
r = true
end
return r or false
end -- AccountUtl.isUser()
AccountUtl.isValid = function ( account )
-- Check whether username can be used as nick for registration
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns boolean
local s = AccountUtl.signer( account )
local r
if s then
if not isAnon( s ) then
if s:sub( 1, 1 ):find( "%d" ) then
r = noIP( s )
else
r = true
end
end
end
return r or false
end -- AccountUtl.isValid()
AccountUtl.scope = function ( account )
-- Identify the type of a presumed account name
-- Precondition:
-- account -- string, or nil derived from current page
-- Postcondition:
-- Returns string, or false
-- "R" -- registered
-- "I" -- IP
-- "T" -- temporary
local s = AccountUtl.signer( account )
local r
if s then
local s1 = s:sub( 1, 1 )
r = "R"
if s1 == "~" then
if isTemp( s ) then
r = "T"
elseif s:sub( 2, 2 ) == "2" then
r = false
end
elseif s1:find( "[1-9]" ) then
if isIP( s ) then
r = "I"
elseif noIP( s ) then
r = false
end
end
end
return r or false
end -- AccountUtl.scope()
AccountUtl.signer = function ( adjust )
-- Normalize username string, or derive from page
-- Precondition:
-- adjust -- string, or not
-- Postcondition:
-- Returns normalized string of a username, or not
local r = adjust
local scan
if type( r ) == "string" then
if r:find( "&", 1, true ) then
r = mw.text.decode( r )
if r:find( "&#?[%a]+;" ) then
r = mw.text.decode( r, true )
end
end
scan = string.format( "[_%%s%c]+", 0x0A )
r = mw.ustring.gsub( r, scan, " " )
r = mw.text.trim( r )
if r == "" then
r = false
elseif r:find( ":", 2, true ) then
local s1, s2 = mw.ustring.match( r, "^([^:]+):(.+)$" )
if s1 then
local o = mw.site.namespaces[ s1 ]
if o then
local n = o.id
if n == 2 or n == 3 then
r = mw.text.trim( s2 )
n = r:find( "/", 1, true )
if n then
if n == 1 then
r = false
else
r = mw.text.trim( r:sub( 1, n - 1 ) )
end
end
end
end
end
end
end
if type( r ) == "string" then
if mw.ustring.len( r ) > 255 then
r = false
-- mw:Manual:$wgMaxNameChars MW 1.2...1.4: 32
else
scan = "[@#<>|%[%]%{%}:/]"
-- mw:Manual:$wgInvalidUsernameCharacters
if mw.ustring.find( r, scan ) or
not isUser( r ) then
r = false
end
end
else
local t = mw.title.getCurrentTitle()
if t.namespace == 2 or t.namespace == 3 then
r = t.rootText
if isUser( r ) then
if mw.ustring.find( r, "@<>:" ) or
mw.ustring.len( r ) > 255 then
r = false
end
else
r = false
end
else
r = false
end
end
return r
end -- AccountUtl.signer()
Failsafe.failsafe = function ( atleast )
-- Retrieve versioning and check for compliance
-- Precondition:
-- atleast -- string, with required version
-- or wikidata|item|~|@ or false
-- Postcondition:
-- Returns string -- with queried version/item, also if problem
-- false -- if appropriate
-- 2024-03-01
local since = atleast
local last = ( since == "~" )
local linked = ( since == "@" )
local link = ( since == "item" )
local r
if last or link or linked or since == "wikidata" then
local item = Failsafe.item
since = false
if type( item ) == "number" and item > 0 then
local suited = string.format( "Q%d", item )
if link then
r = suited
else
local entity = mw.wikibase.getEntity( suited )
if type( entity ) == "table" then
local seek = Failsafe.serialProperty or "P348"
local vsn = entity:formatPropertyValues( seek )
if type( vsn ) == "table" and
type( vsn.value ) == "string" and
vsn.value ~= "" then
if last and vsn.value == Failsafe.serial then
r = false
elseif linked then
if mw.title.getCurrentTitle().prefixedText
== mw.wikibase.getSitelink( suited ) then
r = false
else
r = suited
end
else
r = vsn.value
end
end
end
end
elseif link then
r = false
end
end
if type( r ) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial
else
r = false
end
end
return r
end -- Failsafe.failsafe()
-- Export
local p = { }
function is( access, frame )
return AccountUtl[ access ]( frame.args[ 1 ] ) and "1" or ""
end -- is()
function p.isAnon( frame )
return is( "isAnon", frame )
end -- p.isAnon
function p.isIP( frame )
return is( "isIP", frame )
end -- p.isIP
function p.isTemp( frame )
return is( "isTemp", frame )
end -- p.isTemp
function p.isUser( frame )
return is( "isUser", frame )
end -- p.isUser
function p.isValid( frame )
return is( "isValid", frame )
end -- p.isValid
function p.scope( frame )
return AccountUtl.scope( frame.args[ 1 ] )
end -- p.scope
function p.signer( frame )
return AccountUtl.signer( frame.args[ 1 ] )
end -- p.signer
p.failsafe = function ( frame )
-- Versioning interface
local s = type( frame )
local since
if s == "table" then
since = frame.args[ 1 ]
elseif s == "string" then
since = frame
end
if since then
since = mw.text.trim( since )
if since == "" then
since = false
end
end
return Failsafe.failsafe( since ) or ""
end -- p.failsafe
setmetatable( p, { __call = function ( func, ... )
setmetatable( p, nil )
return Failsafe
end } )
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.