Moduł:Sprawdź
Przejdź do nawigacji
Przejdź do wyszukiwania
Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Sprawdź/opis
Błąd skryptu: Błąd Lua: Nie można utworzyć procesu: proc_open(/dev/null): failed to open stream: Operation not permitted
local function checkUri(uri) local urilen = #uri for _,v in ipairs(mw.loadData("Moduł:Cytuj/dane").supportedUriSchemas) do if (#v < urilen) and (string.lower(string.sub(uri,1, #v)) == v) then return not string.match(uri, '%s') end end end function checkImageName(name) if not name or (#name==0) or string.match(name, "[#<>%[%]|{}]") then return false end local title = mw.title.makeTitle("Plik", name) if not title then return false end local res = { prefix = { plik = true, image = true, grafika = true, file = true, }, extension = { jpg = true, jpeg = true, jpe = true, png = true, svg = true, tif = true, tiff = true, gif = true, xcf = true, pdf = true, djvu = true, webp = true, }, } local prefix = string.match(name, "^:? *([^:]+) *:") if prefix and res.prefix[string.lower(prefix)] then return false end local extension = string.match(name, "%S.*%.([^%.]+)$") return extension and res.extension[string.lower(extension)] end local function findPlainHttp(text) if text then text = mw.ustring.gsub(text, "%[[hH][tT][tT][pP][sS]?://%S+", "_") return string.match(text, "[hH][tT][tT][pP][sS]?://%S") end end local function findFile(text) -- schowaj wyjątek: obrazek generowany przez Szablon:Link-interwiki text = mw.ustring.gsub(text, "%[%[Plik:Wikidata%-logo%-en%.svg|10x9px|link=:d:Q%d+|Informacje powiązane z artykułem „.-” w Wikidanych%]%]", "") -- normalize text = mw.ustring.gsub(text, "%s*[Pp]lik%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Ff]ile%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Gg]rafika%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Ii]mage%s*:%s*", "Plik:") return mw.ustring.match(text, "%[%[Plik:([^%[%]|]+)[|%]]") end -- Lista of template params for wikicode. Like this: -- | grafika = | data śmierci = | www = local function listToTplParams(strArray) return "| " .. table.concat(strArray, " = | ") .. " ="; end local function showTemplate(templateName, args) local result = {} local flags = {} table.insert(result, mw.text.nowiki("{{")) if mw.isSubsting() then table.insert(result, "subst:") end local title = mw.title.new(templateName) if title.namespace ~= 10 then table.insert(result, title.nsText) table.insert(result, ":") end table.insert(result, title.text) if args then local i = 1 while args[i] do table.insert(result, "|") table.insert(result, mw.text.nowiki(args[i])) i = i + 1 end for k, v in pairs(args) do local index = tonumber(k) if (type(k) == "string") or (index and ((index < 1) or (index > i))) then table.insert(result, "|") table.insert(result, tostring(k)) table.insert(result, "=") table.insert(result, mw.text.nowiki(v)) end end end table.insert(result, mw.text.nowiki("}}")) return table.concat(result) end local function infoboxCatTitle(infobox, class) local catTitle = mw.title.makeTitle(14, "Infoboksy – "..class.." – "..infobox) if not catTitle.exists then mw.logObject(catTitle, "Dedykowana kategoria błędów w infoboksie nie istnieje") catTitle = mw.title.makeTitle(14, "Infoboksy – "..class) end mw.logObject(catTitle, "infoboxCatTitle") return catTitle end local function daysInMonth(year, month) if month == 1 then return 31 end if month == 2 then return ((year % 4) == 0) and 29 or 28 end if month == 3 then return 31 end if month == 4 then return 30 end if month == 5 then return 31 end if month == 6 then return 30 end if month == 7 then return 31 end if month == 8 then return 31 end if month == 9 then return 30 end if month == 10 then return 31 end if month == 11 then return 30 end if month == 12 then return 31 end return 0 end local function isDate20YYMMDD(date) local y, m, d = mw.ustring.match(date, "^(20[0-9][0-9])%-([01][0-9])%-([0123][0-9])$") local year = tonumber(y) local month = tonumber(m) local day = tonumber(d) local result = year and month and day and (year >= 2001) and (month >= 1) and (month <= 12) and (day >= 1) and (day <= daysInMonth(year, month)) if not result then mw.logObject({date=date,year=year,month=month,day=day}, "isDate20YYMMDD") end return result end return { ["Porównaj"] = function(frame) local config = frame:getParent().args[""] or "" local options = mw.text.split(config, "|") local templateName = mw.text.trim(options[1]) if #templateName == 0 then local title = mw.title.getCurrentTitle() if title.namespace == 10 then templateName = mw.ustring.match(title.text, "^(.-)/opis") or mw.ustring.match(title.text, "^(.-)/test") or mw.ustring.match(title.text, "^(.-)/brudnopis") or title.text end if #templateName == 0 then mw.log("brak nazwy szablonu") return end end local templateTitle = mw.title.new(templateName, 10) if templateTitle.id == 0 then mw.log("szablon '"..templateName.."' nie istnieje") return end local sandboxName = templateName.."/brudnopis" local sandboxTitle = mw.title.new(sandboxName, 10) if sandboxTitle.id == 0 then mw.log("brudnopis '"..sandboxName.."' nie istnieje") return end local i = 2 local showparams = true local showinfo = true local vertical = false while i <= #options do local option = mw.text.trim(options[i]) if option == "bez wikikodu" then showparams = false elseif option == "bez opisu" then showinfo = false elseif option == "pionowo" then vertical = true end i = i + 1 end local templateParams = {} local params = {} for k, v in pairs(frame:getParent().args) do if k ~= "" then templateParams[k] = v table.insert(params, k) end end local result = {} table.insert(result, '<table style="width: 100%;">') if showparams and (#params > 0) then local compare = function(a, b) -- return a < b if (type(a) == "number") and (type(b) == "number") then return a < b end if (type(a) == "string") and (type(b) == "string") then return a < b end if (type(a) == "number") and (type(b) == "string") then return true end return false end table.sort(params, compare) table.insert(result, "<caption><code>{{") table.insert(result, templateName) for i, k in ipairs(params) do table.insert(result, " | ") local p = mw.text.nowiki(tostring(k)) local v = mw.text.nowiki(templateParams[k]) table.insert(result, p) table.insert(result, " = ") table.insert(result, v) end table.insert(result, "}}</code></caption>") end local templateResult = frame:expandTemplate{ title=templateName, args=templateParams} local sandboxResult = frame:expandTemplate{ title=sandboxName, args=templateParams} if templateResult and string.match(templateResult, "^{|") then templateResult = "\n"..templateResult end if sandboxResult and string.match(sandboxResult, "^{|") then sandboxResult = "\n"..sandboxResult end if vertical and showinfo then table.insert(result, '<tr><th style="width: 15em">[[Szablon:') table.insert(result, templateName) table.insert(result, '|Szablon]]</th><td>') table.insert(result, templateResult) table.insert(result, '</td></tr><tr><th>[[Szablon:') table.insert(result, sandboxName) table.insert(result, '|Brudnopis szablonu]]</th><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') elseif vertical then table.insert(result, '<tr><td>') table.insert(result, templateResult) table.insert(result, '</td></tr><tr><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') else if showinfo then table.insert(result, '<tr><th style="width: 50%;">[[Szablon:') table.insert(result, templateName) table.insert(result, '|Szablon]]</th><th style="width: 50%;">[[Szablon:') table.insert(result, sandboxName) table.insert(result, '|Brudnopis szablonu]]</th></tr>') end table.insert(result, '<tr style="vertical-align: top;"><td>') table.insert(result, templateResult) table.insert(result, '</td><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') end table.insert(result, "</table>") return table.concat(result) end, ["Parametry"] = function(frame) if mw.title.getCurrentTitle().contentModel ~= "wikitext" then mw.logObject(mw.title.getCurrentTitle().contentModel, "mw.title.getCurrentTitle().contentModel") return -- to nie ma sensu w takim wypadku end local unknown = {} local invalid = {} local deprecated = {} local nakedurl = {} local files = {} local templateName = frame:getParent():getTitle() local infobox = mw.ustring.match(templateName, "^Szablon:(.- infobox)$") local config = frame.args[""] local class, space, category = string.match(config or "", "^%s*(%S+)(%s+)(.-)%s*$") local nl = space and string.match(space, "\n") or "" class = class or config local function argName(arg) return type(arg) ~= "string" and tostring(arg) or ('"'..arg..'"') end local required = {} for k, v in pairs(frame.args) do if mw.ustring.match(v, "!$") then required[k] = true if infobox then -- odróżniaj pola sugerowane w infoboksach, które mogą być puste if v == "!" or mw.ustring.match(v, "%?!$") then required[k] = false else local pattern = string.match(v,"^(^.-$)!?$") if pattern and mw.ustring.match("", pattern) then required[k] = false end end end end end local emptyArg = false for k, v in pairs(frame:getParent().args) do required[k] = nil local kind = frame.args[k] if kind == "" or kind == "!" then kind = "text?" end if k == "" then emptyArg = v elseif not kind then table.insert(unknown, argName(k)) elseif (kind == "num") or (kind == "num!") then local n = tonumber(v) if not n then table.insert(invalid, argName(k)) end elseif (kind == "num?") or (kind == "num?!") then local n = (#v == 0) or tonumber(v) if not n then table.insert(invalid, argName(k)) end elseif (kind == "grafika") or (kind == "grafika!") then if findPlainHttp(v) then table.insert(nakedurl, argName(k)) else local g = checkImageName(v) if not g then table.insert(invalid, argName(k)) end end elseif (kind == "grafika?") or (kind == "grafika?!") then if findPlainHttp(v) then table.insert(nakedurl, argName(k)) else local g = (#v == 0) or checkImageName(v) if not g then table.insert(invalid, argName(k)) end end elseif (kind == "uri") or (kind == "uri!") then local u = checkUri(v) if not u then table.insert(invalid, argName(k)) end elseif (kind == "uri?") or (kind == "uri?!") then local u = (#v == 0) or checkUri(v) if not u then table.insert(invalid, argName(k)) end elseif (kind == "txt") or (kind == "txt!") then if #v == 0 then table.insert(invalid, argName(k)) elseif checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end elseif (kind == "text") or (kind == "text!") or (kind == "text?") then if ((kind ~= "text?") and (#v == 0)) then table.insert(invalid, argName(k)) elseif findFile(v) then table.insert(files, argName(k)) elseif checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end elseif kind == "old" then table.insert(deprecated, argName(k)) elseif kind == "uri*" then -- specjalny przpadek dla pola 'url' w [[Szablon:Cytuj]] local u = checkUri(v) or checkUri(mw.text.unstripNoWiki(v)) if not u then table.insert(invalid, argName(k)) end else local pattern = string.match(kind,"^(^.-$)!?$") if pattern and not mw.ustring.match(v, pattern) then table.insert(invalid, argName(k)) elseif (#v > 0) and checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end end end local missing = {} local suggested = {} mw.logObject(required, "required") for k, v in pairs(required) do table.insert(v and missing or suggested, k) end if (#missing == 0) and (#suggested == 0) and (#unknown == 0) and (#invalid == 0) and (#deprecated == 0) and (#nakedurl == 0) and (#files == 0) then return nil end local errorClasses = 0 -- generate messages for each category of problems local messages = {} if #invalid > 0 then errorClasses = errorClasses + 2 table.insert(messages, "Nieprawidłowe/puste pola: " .. mw.text.listToText(invalid) .. ".") end if (#missing > 0) or (#suggested > 0) then errorClasses = errorClasses + 1 if (#missing > 0) then table.insert(messages, "Brakujące pola: " .. mw.text.listToText(missing) .. ".") end if (#suggested > 0) then table.insert(messages, "Sugerowane pola (wstaw w kodzie): <code>" .. listToTplParams(suggested) .. "</code>") end end if #unknown > 0 then errorClasses = errorClasses + 4 table.insert(messages, "Nieznane pola: " .. mw.text.listToText(unknown) .. ".") end if #deprecated > 0 then errorClasses = errorClasses + 8 table.insert(messages, "Przestarzałe pola: " .. mw.text.listToText(deprecated) .. ".") end if #nakedurl > 0 then errorClasses = errorClasses + 16 table.insert(messages, "Gołe linki: " .. mw.text.listToText(nakedurl) .. ".") end if #files > 0 then errorClasses = errorClasses + 32 table.insert(messages, "Nieoczekiwana grafika: " .. mw.text.listToText(files) .. ".") end -- nop? if templateName then showTemplate(templateName, frame:getParent().args) end -- render messages local message = mw.html.create() if emptyArg then message:wikitext("|=", emptyArg, "| ") end if infobox then message:wikitext("\n* ", table.concat(messages, "\n* ")) else message:wikitext(table.concat(messages, " ")) end message = tostring(message) -- result container local result = mw.html.create(infobox and "table" or "span") result:addClass("problemy") :addClass(class or nil) :attr("aria-hidden", "true") local restext = result if infobox then result:addClass("infobox") restext = result:tag("tr"):tag("td") else result:attr("data-nosnippet", "") end if templateName then restext:wikitext(showTemplate(templateName).." ") -- pomiń ten komunikat jeśli zabraknie tylko pól sugerowanych w infoboksie if not infobox or (errorClasses ~= 1) or (#missing > 0) then local warning = mw.html.create() warning:tag("code"):wikitext(showTemplate(templateName, frame:getParent().args)) warning:wikitext(" ") warning:tag("span"):addClass("problemy"):wikitext(message) mw.addWarning(tostring(warning)) end end restext:wikitext(message) if category then result:wikitext(category) end if infobox then if (errorClasses == 1) and (#missing <= 0) then result:addClass("tylko-braki") -- tylko SUGEROWANE braki end if (#missing > 0) or (#suggested > 0) then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "brakujące parametry").text, "]]") end if mw.title.getCurrentTitle().namespace == 0 then if #invalid > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "nieprawidłowe parametry").text, "]]") end if #unknown > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "nieznane parametry").text, "]]") end if #deprecated > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "przestarzałe parametry").text, "]]") end if #nakedurl > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "gołe linki").text, "]]") end if #files > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "grafika w nieodpowiednim miejscu").text, "]]") end end end return nl..tostring(result) end, ["odn"] = function(frame) local pf = frame:getParent() local i = 1 local problems = false local yeardetected = false while true do local arg = pf.args[i] if not arg then problems = i == 1 and "brak argumentów" or false break end if (i > 5) or yeardetected then problems = "za dużo argumentów pozycyjnych" break end if #arg == 0 then problems = "pusty argument" break end if arg ~= mw.text.trim(arg) then problems = "nieoczekiwane odstępy na początku lub końcu argumentu" break end if string.match(arg, "^%d+%l?$") then yeardetected = true if i == 1 then problems = "rok musi być ostatnim parametrem po nazwiskach autorów" break end elseif string.match(arg, "^s[%-%.:]%s*%d+") then problems = "prawdopodobnie nieprawidłowo podany numer strony" break elseif string.match(arg, "%s%s") then problems = "podwójne odstępy" break elseif mw.ustring.match(arg, "^%a+%d") then if not mw.ustring.match(arg, "^[%u%d]+$") then problems = "prawdopodobnie sklejone argumenty (brak pionowej kreski)" break end elseif mw.ustring.match(arg, "^OdeB ") then -- [[Ordre de Bataille]] elseif mw.ustring.match(arg, "^%u%l+%u") then local justification = { ["De"] = true, ["Del"] = true, ["Di"] = true, ["Le"] = true, ["Mac"] = true, ["Mc"] = true, ["Te"] = true, -- TeSelle ["Sar"] = true, -- SarDesai ["Van"] = true, -- VanBuren ["La"] = true, -- LaSalle } if not justification[mw.ustring.match(arg, "^%u%l+")] then problems = "prawdopodobnie sklejone argumenty (brak pionowej kreski)" break end end i = i + 1 end if not problems then local odn = pf.args.odn if odn and ((#odn ~= 1) or (odn < "a") or (odn > "z")) then problems = "nieoczekiwany parametr odn" end end if not problems then local s = pf.args.s if s and string.match(s, "&[a-z]+;") then problems = "użyto encji HTML w numerze strony" end end if not problems then if pf.args.strona or pf.args.ss or pf.args.strony or pf.args.p or pf.args.page or pf.args.pp or pf.args.pages then problems = "przestarzały parametr z numerem strony" end end if not problems then return nil end local result = mw.html.create("span") :addClass("problemy") :addClass("problemy-w-odn") if mw.title.getCurrentTitle().namespace == 0 then result:wikitext("[[Kategoria:Szablon odn do sprawdzenia]]") end result:wikitext("ODN: ", problems) return tostring(result) end, ["Wikidane"] = function(frame) local property = frame.args.cecha local field = frame.args.pole local value = frame.args[1] if not property or not field then return end if not value then value = frame:getParent().args[field] if not value or (#value == 0) then return end end local entity = mw.wikibase.getEntity() if not entity or not entity.claims or not entity.claims[property] then return end for i, v in ipairs(entity.claims[property]) do if v.mainsnak.snaktype == "value" then if value == v.mainsnak.datavalue.value then return end end end local template = frame:getParent():getTitle() local infobox = mw.ustring.match(template, "^Szablon:(.- infobox)$") return mw.ustring.format("[[Kategoria:%s – niezgodność w Wikidanych – %s – %s]]", infobox and "Infoboksy" or "Szablony", infobox or template, field) end, ["bez parametrów"] = function(frame) for k, v in pairs(frame:getParent().args) do return nil end return "tak" end, ["pole z hostem"] = function (frame) local host = frame.args.host if host and (#host > 0) then for k, v in pairs(frame:getParent().args) do local link = string.match(v, "[hH][tT][tT][pP][sS]?://[%S]+") if link then local uri = mw.uri.new(link) local valid, _ = mw.uri.validate(uri) if valid and uri.host and (#uri.host > 0) then if host == uri.host then mw.logObject({k, link}, "cały") return k end if #host < #uri.host then local s1 = '.'..host local s2 = string.sub(uri.host, -#s1) if s1 == s2 then mw.logObject({k, link}, "fragment") return k end end end end end end end, ["pola z autorami"] = function (frame) local result = {} local nazwisko = frame.args["nazwisko"] local imie = frame.args["imię"] local autor = frame.args["autor"] local link = frame.args["link"] local maxIndex = tonumber(frame.args["max"]) local prefix = frame.args["przed"] or "" local suffix = frame.args["po"] or "" for i = 1, maxIndex do local s = i == 1 and "" or tostring(i) local nin = string.gsub(nazwisko, '#', s) local iin = string.gsub(imie, '#', s) local ain = string.gsub(autor, '#', s) local lin = string.gsub(link, '#', s) local niv = frame:getParent().args[nin] local iiv = frame:getParent().args[iin] local aiv = frame:getParent().args[ain] local liv = frame:getParent().args[lin] local nis = niv and (#niv > 0) local iis = iiv and (#iiv > 0) local ais = aiv and (#aiv > 0) local lis = liv and (#liv > 0) local bad = (nis and ais) -- nazwisko -> zbędny autor or (nis and not iis) -- nazwisko bez imienia or (lis and not nis and not ais) -- tylko link or (iis and not nis) -- imię bez nazwiska if bad then table.insert(result, i) end end if #result > 0 then return prefix..mw.text.listToText(result)..suffix end end, ["uri"] = function(frame) mw.logObject(frame:getParent():getTitle(), "parent:title") _ = mw.title.new("Moduł:Sprawdź/deprecated/uri").id local link = frame.args["link"] local space = frame.args["spacja"] local check = checkUri(link) if check then return link end return (space and (check ~= nil)) and link or "" end, --[[Sprawdzanie url do szablonów Wykorzystanie: {{#invoke:Sprawdź|url|{{{www|}}}|[{{{www}}} Strona internetowa]}} {{#invoke:Sprawdź|url|{{{www}}}|[{{{www}}} Strona internetowa]}} @param #1 Url do sprawdzenia. Ciąg typu "{{{abc}}}" pominie sprawdzenie, żeby pokazać wartość na stronie szablonu. @param #2 Tekst do wyświetlenia gdy OK. @return pusty string gdy błędny, "ok" lub zawartość #2 gdy OK. ]] ["url"] = function(frame) local link = frame.args[1] local okText = frame.args[2] or "ok" local isValid = string.find(link, '{{{') == 1 or checkUri(link) if isValid then return okText end return "" end, ["lista nazw niepustych argumentów"] = function(frame) local argNames = {} for k, v in pairs(frame:getParent().args) do if #mw.text.trim(v) > 0 then table.insert(argNames, tostring(k)) end end return table.concat(argNames, ", ") end, ["zapis daty dostępu"] = function(frame) local accessDate = frame:getParent().args["data dostępu"] if accessDate and (#accessDate > 0) then if not isDate20YYMMDD(accessDate) then local builder = mw.html.create('span') :addClass('problemy') :wikitext('zły zapis daty dostępu') if mw.title.getCurrentTitle().namespace == 0 then builder:wikitext('[[Kategoria:Szablon cytowania – zły zapis daty dostępu]]') end return builder end end end, }