Importer, Bürokraten, Moderatoren (CommentStreams), Strukturierte-Diskussionen-Bots, Oberflächenadministratoren, Push-Abonnementverwalter, Oversighter, Administratoren, Kampagnenbearbeiter (Hochladeassistent)
855
Bearbeitungen
w>NordNordWest K (Änderte den Schutz von „Modul:URLutil“: per Anfrage: https://de.wikipedia.org/w/index.php?title=Wikipedia%3AAdministratoren%2FAnfragen&type=revision&diff=156076713&oldid=156073630 ([Bearbeiten=Nur Sichter] (unbeschränkt) [Verschieben=Nur Admi…) |
K (51 Versionen von wikivoyage:Modul:URLutil importiert) |
||
| (17 dazwischenliegende Versionen von 11 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
local URLutil = { suite = "URLutil", | local URLutil = { suite = "URLutil", | ||
serial = " | serial = "2022-04-05", | ||
item = 10859193 } | |||
--[=[ | --[=[ | ||
Utilities for URL etc. on www. | Utilities for URL etc. on www. | ||
* decode() | |||
* encode() | |||
* getAuthority() | * getAuthority() | ||
* getFragment() | * getFragment() | ||
| Zeile 23: | Zeile 26: | ||
* isDomainInt() | * isDomainInt() | ||
* isHost() | * isHost() | ||
* isHostPathResource() | |||
* isIP() | * isIP() | ||
* isIPlocal() | * isIPlocal() | ||
| Zeile 36: | Zeile 40: | ||
* isWebURL() | * isWebURL() | ||
* wikiEscapeURL() | * wikiEscapeURL() | ||
* failsafe() | |||
Only [[dotted decimal]] notation for IPv4 expected. | Only [[dotted decimal]] notation for IPv4 expected. | ||
Does not support dotted hexadecimal, dotted octal, or single-number formats. | Does not support dotted hexadecimal, dotted octal, or single-number formats. | ||
IPv6 URL (bracketed) not yet implemented; might need Wikintax escaping anyway. | IPv6 URL (bracketed) not yet implemented; might need Wikintax escaping anyway. | ||
]=] | ]=] | ||
local Failsafe = URLutil | |||
| Zeile 59: | Zeile 51: | ||
local decodeComponentProtect = { F = "\"#%<>[\]^`{|}", | local decodeComponentProtect = { F = "\"#%<>[\]^`{|}", | ||
P = "\"#%<>[\]^`{|}/?", | P = "\"#%<>[\]^`{|}/?", | ||
Q = "\"#%<>[\]^`{|}&=+;", | Q = "\"#%<>[\]^`{|}&=+;,", | ||
X = "\"#%<>[\]^`{|}&=+;/?" } | X = "\"#%<>[\]^`{|}&=+;,/?" } | ||
| Zeile 136: | Zeile 128: | ||
end | end | ||
n = ( ask:byte( j, j ) - 48 ) * 16 + n | n = ( ask:byte( j, j ) - 48 ) * 16 + n | ||
if decodeComponentEscape( averse, n ) then | if n == 39 and | ||
ask:sub( i + 3, i + 5 ) == "%27" then | |||
j = i + 6 | |||
while ( ask:sub( j, j + 2 ) == "%27" ) do | |||
j = j + 3 | |||
end -- while "%27" | |||
elseif decodeComponentEscape( averse, n ) then | |||
if m then | if m then | ||
ask = string.format( "%s%c%s", | ask = string.format( "%s%c%s", | ||
| Zeile 162: | Zeile 160: | ||
local r = URLutil.getHost( url ) | local r = URLutil.getHost( url ) | ||
if r then | if r then | ||
local pattern = "[%w%%]+%.%a[%w-]*%a)$" | local pattern = "[%w%%%-]+%.%a[%w%-]*%a)$" | ||
if mode == 3 then | if mode == 3 then | ||
pattern = "[%w%%]+%." .. pattern | pattern = "[%w%%%-]+%." .. pattern | ||
end | end | ||
r = mw.ustring.match( "." .. r, "%.(" .. pattern ) | r = mw.ustring.match( "." .. r, "%.(" .. pattern ) | ||
| Zeile 202: | Zeile 200: | ||
return r | return r | ||
end -- getHash() | end -- getHash() | ||
URLutil.decode = function ( url, enctype ) | |||
local r, s | |||
if type( enctype ) == "string" then | |||
s = mw.text.trim( enctype ) | |||
if s == "" then | |||
s = false | |||
else | |||
s = s:upper() | |||
end | |||
end | |||
r = mw.text.encode( mw.uri.decode( url, s ) ) | |||
if r:find( "[%[|%]]" ) then | |||
local k | |||
r, k = r:gsub( "%[", "[" ) | |||
:gsub( "|", "|" ) | |||
:gsub( "%]", "]" ) | |||
end | |||
return r | |||
end -- URLutil.decode() | |||
URLutil.encode = function ( url, enctype ) | |||
local k, r, s | |||
if type( enctype ) == "string" then | |||
s = mw.text.trim( enctype ) | |||
if s == "" then | |||
s = false | |||
else | |||
s = s:upper() | |||
end | |||
end | |||
r = mw.uri.encode( url, s ) | |||
k = r:byte( 1, 1 ) | |||
if -- k == 35 or -- # | |||
k == 42 or -- * | |||
k == 58 or -- : | |||
k == 59 then -- ; | |||
r = string.format( "%%%X%s", k, r:sub( 2 ) ) | |||
end | |||
if r:find( "[%[|%]]" ) then | |||
r, k = r:gsub( "%[", "%5B" ) | |||
:gsub( "|", "%7C" ) | |||
:gsub( "%]", "%5D" ) | |||
end | |||
return r | |||
end -- URLutil.encode() | |||
| Zeile 270: | Zeile 318: | ||
local r = URLutil.getAuthority( url ) | local r = URLutil.getAuthority( url ) | ||
if r then | if r then | ||
r = mw.ustring.match( r, "^([%w%.%%_-]+):?[%d]*$" ) | r = mw.ustring.match( r, "^([%w%.%%_%-]+):?[%d]*$" ) | ||
end | end | ||
return r | return r | ||
| Zeile 341: | Zeile 389: | ||
sP = decodeComponentPercent( sP, "P" ) | sP = decodeComponentPercent( sP, "P" ) | ||
end | end | ||
r | r = r:sub( 1, j - 1 ) | ||
end | end | ||
elseif j then | elseif j then | ||
| Zeile 365: | Zeile 413: | ||
end | end | ||
end | end | ||
r = r:gsub( "%[", "%%5B" ) | r = r:gsub( " ", "%%20" ) | ||
:gsub( "%[", "%%5B" ) | |||
:gsub( "|", "%%7C" ) | :gsub( "|", "%%7C" ) | ||
:gsub( "%]", "%%5D" ) | :gsub( "%]", "%%5D" ) | ||
:gsub( "%<", "%%3C" ) | |||
:gsub( "%>", "%%3E" ) | |||
end | end | ||
return r | return r | ||
| Zeile 564: | Zeile 615: | ||
local r = URLutil.getHost( url ) | local r = URLutil.getHost( url ) | ||
if r then | if r then | ||
r = mw.ustring.match( r, " | r = mw.ustring.match( r, "%w+%.(%a[%w%-]*%a)$" ) | ||
if not r then | if not r then | ||
r = false | r = false | ||
| Zeile 611: | Zeile 662: | ||
local r | local r | ||
if type( s ) == "string" then | if type( s ) == "string" then | ||
local scan = "^%s*([%w%.%%_-] | local scan = "^%s*([%w%.%%_-]*%w)%.(%a[%w-]*%a)%s*$" | ||
local scope | local scope | ||
s, scope = mw.ustring.match( s, scan ) | s, scope = mw.ustring.match( s, scan ) | ||
| Zeile 673: | Zeile 724: | ||
return URLutil.isDomain( s ) or URLutil.isIP( s ) | return URLutil.isDomain( s ) or URLutil.isIP( s ) | ||
end -- URLutil.isHost() | end -- URLutil.isHost() | ||
URLutil.isHostPathResource = function ( s ) | |||
local r = URLutil.isResourceURL( s ) | |||
if not r and s then | |||
r = URLutil.isResourceURL( "//" .. mw.text.trim( s ) ) | |||
end | |||
return r | |||
end -- URLutil.isHostPathResource() | |||
| Zeile 807: | Zeile 868: | ||
return false | return false | ||
end -- isProtocolAccepted() | end -- isProtocolAccepted() | ||
| Zeile 840: | Zeile 894: | ||
local s1, s2 = url:match( "^([^#]+)(#.*)$" ) | local s1, s2 = url:match( "^([^#]+)(#.*)$" ) | ||
if s2 then | if s2 then | ||
if url:match( "^%s*[a-zA-Z]*://(.+)/" ) then | if url:match( "^%s*[a-zA-Z]*:?//(.+)/" ) then | ||
return true | return true | ||
end | end | ||
| Zeile 859: | Zeile 913: | ||
local s = URLutil.getAuthority( url ) | local s = URLutil.getAuthority( url ) | ||
local pat = "[%[|%]" .. | local pat = "[%[|%]" .. | ||
mw.ustring.char( 8201, 45, 8207, | mw.ustring.char( 34, | ||
8201, 45, 8207, | |||
8234, 45, 8239, | 8234, 45, 8239, | ||
8288 ) | 8288 ) | ||
| Zeile 892: | Zeile 947: | ||
URLutil.isWebURL = function ( url ) | URLutil.isWebURL = function ( url ) | ||
if URLutil.getScheme( url ) and URLutil.getAuthority( url ) then | if URLutil.getScheme( url ) and URLutil.getAuthority( url ) then | ||
if not url: | if not url:find( "%S%s+%S" ) and | ||
not url:find( "''", 1, true ) then | |||
return true | return true | ||
end | end | ||
| Zeile 913: | Zeile 969: | ||
-- | 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 | |||
-- 2020-08-17 | |||
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 | |||
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() | |||
local function Template( frame, action, amount ) | |||
-- Run actual code from template transclusion | |||
-- Precondition: | |||
-- frame -- object | |||
-- action -- string, with function name | |||
-- amount -- number, of args if > 1 | |||
-- Postcondition: | |||
-- Return string or not | |||
local n = amount or 1 | |||
local v = { } | |||
local r, s | |||
for i = 1, n do | |||
s = frame.args[ i ] | |||
if s then | |||
s = mw.text.trim( s ) | |||
if s ~= "" then | |||
v[ i ] = s | |||
end | |||
end | |||
end -- for i | |||
if v[ 1 ] then | |||
r = URLutil[ action ]( v[ 1 ], v[ 2 ], v[ 3 ] ) | |||
end | |||
return r | |||
end -- Template() | |||
local p = {} | local p = {} | ||
function p. | function p.decode( frame ) | ||
return | return Template( frame, "decode", 2 ) or "" | ||
end | |||
function p.encode( frame ) | |||
return Template( frame, "encode", 2 ) or "" | |||
end | end | ||
function p.getAuthority( frame ) | function p.getAuthority( frame ) | ||
return | return Template( frame, "getAuthority" ) or "" | ||
end | end | ||
function p.getFragment( frame ) | function p.getFragment( frame ) | ||
local r = | local r = Template( frame, "getFragment", 2 ) | ||
if r then | if r then | ||
r = "#" .. r | r = "#" .. r | ||
| Zeile 933: | Zeile 1.076: | ||
end | end | ||
function p.getHost( frame ) | function p.getHost( frame ) | ||
return | return Template( frame, "getHost" ) or "" | ||
end | end | ||
function p.getLocation( frame ) | function p.getLocation( frame ) | ||
return | return Template( frame, "getLocation" ) or "" | ||
end | end | ||
function p.getNormalized( frame ) | function p.getNormalized( frame ) | ||
return | return Template( frame, "getNormalized" ) or "" | ||
end | end | ||
function p.getPath( frame ) | function p.getPath( frame ) | ||
return | return Template( frame, "getPath" ) or "" | ||
end | end | ||
function p.getPort( frame ) | function p.getPort( frame ) | ||
return | return Template( frame, "getPort" ) or "" | ||
end | end | ||
function p.getQuery( frame ) | function p.getQuery( frame ) | ||
local r | local r = Template( frame, "getQuery", 3 ) | ||
local key = frame.args[ 2 ] | if r then | ||
local key = frame.args[ 2 ] | |||
if key then | |||
key = mw.text.trim( key ) | |||
if key == "" then | |||
key = nil | |||
end | |||
end | end | ||
if not key then | if not key then | ||
r = "?" .. r | r = "?" .. r | ||
| Zeile 967: | Zeile 1.109: | ||
end | end | ||
function p.getRelativePath( frame ) | function p.getRelativePath( frame ) | ||
return | return Template( frame, "getRelativePath" ) or "" | ||
end | end | ||
function p.getScheme( frame ) | function p.getScheme( frame ) | ||
return | return Template( frame, "getScheme" ) or "" | ||
end | end | ||
function p.getSortkey( frame ) | function p.getSortkey( frame ) | ||
return | return Template( frame, "getSortkey" ) or "" | ||
end | end | ||
function p.getTLD( frame ) | function p.getTLD( frame ) | ||
return | return Template( frame, "getTLD" ) or "" | ||
end | end | ||
function p.getTop2domain( frame ) | function p.getTop2domain( frame ) | ||
return | return Template( frame, "getTop2domain" ) or "" | ||
end | end | ||
function p.getTop3domain( frame ) | function p.getTop3domain( frame ) | ||
return | return Template( frame, "getTop3domain" ) or "" | ||
end | end | ||
function p.isAuthority( frame ) | function p.isAuthority( frame ) | ||
return | return Template( frame, "isAuthority" ) and "1" or "" | ||
end | end | ||
function p.isDomain( frame ) | function p.isDomain( frame ) | ||
return | return Template( frame, "isDomain" ) and "1" or "" | ||
end | end | ||
function p.isDomainExample( frame ) | function p.isDomainExample( frame ) | ||
return | return Template( frame, "isDomainExample" ) and "1" or "" | ||
end | end | ||
function p.isDomainInt( frame ) | function p.isDomainInt( frame ) | ||
return | return Template( frame, "isDomainInt" ) and "1" or "" | ||
end | end | ||
function p.isHost( frame ) | function p.isHost( frame ) | ||
return | return Template( frame, "isHost" ) and "1" or "" | ||
end | |||
function p.isHostPathResource( frame ) | |||
return Template( frame, "isHostPathResource" ) and "1" or "" | |||
end | end | ||
function p.isIP( frame ) | function p.isIP( frame ) | ||
return | return Template( frame, "isIP" ) or "" | ||
end | end | ||
function p.isIPlocal( frame ) | function p.isIPlocal( frame ) | ||
return | return Template( frame, "isIPlocal" ) and "1" or "" | ||
end | end | ||
function p.isIPv4( frame ) | function p.isIPv4( frame ) | ||
return | return Template( frame, "isIPv4" ) and "1" or "" | ||
end | end | ||
function p.isIPv6( frame ) | function p.isIPv6( frame ) | ||
return | return Template( frame, "isIPv6" ) and "1" or "" | ||
end | end | ||
function p.isMailAddress( frame ) | function p.isMailAddress( frame ) | ||
return | return Template( frame, "isMailAddress" ) and "1" or "" | ||
end | end | ||
function p.isMailLink( frame ) | function p.isMailLink( frame ) | ||
return | return Template( frame, "isMailLink" ) and "1" or "" | ||
end | end | ||
function p.isProtocolDialog( frame ) | function p.isProtocolDialog( frame ) | ||
return | return Template( frame, "isProtocolDialog" ) and "1" or "" | ||
end | end | ||
function p.isProtocolWiki( frame ) | function p.isProtocolWiki( frame ) | ||
return | return Template( frame, "isProtocolWiki" ) and "1" or "" | ||
end | end | ||
function p.isResourceURL( frame ) | function p.isResourceURL( frame ) | ||
return | return Template( frame, "isResourceURL" ) and "1" or "" | ||
end | end | ||
function p.isSuspiciousURL( frame ) | function p.isSuspiciousURL( frame ) | ||
return | return Template( frame, "isSuspiciousURL" ) and "1" or "" | ||
end | end | ||
function p.isUnescapedURL( frame ) | function p.isUnescapedURL( frame ) | ||
return | return Template( frame, "isUnescapedURL", 2 ) and "1" or "" | ||
end | end | ||
function p.isWebURL( frame ) | function p.isWebURL( frame ) | ||
return | return Template( frame, "isWebURL" ) and "1" or "" | ||
end | end | ||
function p.wikiEscapeURL( frame ) | function p.wikiEscapeURL( frame ) | ||
return | return Template( frame, "wikiEscapeURL" ) | ||
end | end | ||
p.failsafe = function ( frame ) | |||
return | 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 | end | ||
function p.URLutil() | function p.URLutil() | ||