Module:Database report/facade
This module is used from {{Database report}}.
local Arguments = require('Module:Arguments')
local TableTools = require('Module:TableTools')
local p = {}
local function error(text)
return '\n*' .. require('Module:Error').error{ text, tag = 'p' }
end
local function str_split(inputstr, sep)
local t = {}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
local function is_integer(str)
if str:match("%D") then
return false
end
return true
end
local function trim(s)
return s:match("^%s*(.-)%s*$")
end
p.main = function(frame)
local args = Arguments.getArgs(frame)
local title = mw.title.getCurrentTitle()
local lua_config, lua_err = invoke_lua_source(args, frame)
local headContent = lua_config and lua_config.head_content or ''
local isSilent = args.silent ~= nil or (lua_config and lua_config.silent ~= nil)
local isPeriodic = args.interval ~= nil or (lua_config and lua_config.interval ~= nil)
return headContent ..
(isSilent and '' or
"<div style='float: right; padding-left: 15px;'>" ..
'[https://sdzerobot.toolforge.org/database-report?page='..mw.uri.encode(title.prefixedText)..' Update the table now]' ..
'</div>' ..
"<div style='margin-bottom: 5px; border-bottom: 3px solid #2F74D0; padding-right: 10px;'>" ..
"This table is generated by querying the [[wikitech:Help:Toolforge/Database|database replica]] "..(isPeriodic and 'and is periodically updated' or '').." by [[User:SDZeroBot|a bot]].<br> " ..
'<mark>Edits made within the table area will be removed on the next update!</mark>' ..
'</div>')
.. '[[Category:SDZeroBot database report subscriptions]]'
.. (lua_err or validate(args))
end
function validate(args)
-- sql param is required, except if the config is lua-generated
if not args.sql and not args.lua_source then
return error('Invalid config: required parameter "sql" is missing')
end
local deprecated_params = {
['frequency'] = 'interval'
}
-- check for invalid parameters
for param, _ in pairs(args) do
if deprecated_params[param] ~= nil then
return error(param .. ' is deprecated, please use ' .. deprecated_params[param] .. ' instead')
end
if not TableTools.inArray({
'sql', 'wikilinks', 'excerpts', 'comments', 'widths', 'hide', 'silent',
'table_style', 'table_class', 'remove_underscores', 'pagination', 'output_page',
'max_pages', 'interval', 'row_template', 'skip_table', 'header_template',
'footer_template', 'row_template_named_params', 'postprocess_js',
'lua_source', 'lua_function'
}, param) and not param:find('^lua_arg_') then
return error('Unknown parameter "' .. param .. '" used, ignoring')
end
end
-- check incompatible param combinations
if not args.row_template then
if args.skip_table then
return error('Invalid config: skip_table can only be used with row_template')
end
end
if args.output_page then
if args.pagination then
return error('pagination and output_page cannot be used together; output_page will be ignored')
end
local t1 = mw.title.getCurrentTitle()
local t2 = mw.title.new(args.output_page)
if t1.namespace ~= t2.namespace or t2.text:find(t1.text..'/', 1, true) ~= 1 then
return error('output_page must be a subpage of the current page')
end
end
-- check wikilinks config
if args.wikilinks then
local configs = str_split(args.wikilinks, ',')
for _, config in ipairs(configs) do
local parts = str_split(trim(config), ':')
local srcColNum = parts[1]
if not is_integer(srcColNum) then
return error('Invalid wikilink config: Non-numeral source column number: '..parts[1]..'. Will be ignored.')
end
local ns = parts[2]
if ns and ns:match("^c?%d+$") == nil then
return error('Invalid namespace number "'.. ns..'" in wikilinks parameter: refer to [[WP:NS]] for namespace numbers, or use "cN" to take namespace number from column number N')
end
end
end
-- check excerpts config
if args.excerpts then
local configs = str_split(args.excerpts, ',')
for _, config in ipairs(configs) do
local parts = str_split(trim(config), ':')
local srcColNum = parts[1]
if not is_integer(srcColNum) then
return error('Invalid excerpts config: Non-numeral source column number: '..parts[1]..'. Will be ignored.')
end
local dstColNum = parts[2]
if dstColNum and not is_integer(dstColNum) then
return error('Invalid excerpts config: Non-numeral destination column number: '..parts[2]..'. Will be ignored.')
end
local ns = parts[3]
if ns and ns:match("^c?%d+$") == nil then
return error('Invalid namespace number "'.. ns..'" in excerpts parameter: refer to [[WP:NS]] for namespace numbers, or use "cN" to take namespace number from column number N')
end
local charLimit = parts[4]
if charLimit and not is_integer(charLimit) then
return error('Invalid excerpts config: Non-numeral in charLimit: '..parts[4]..'. Will be ignored.')
end
local hardCharLimit = parts[5]
if hardCharLimit and not is_integer(hardCharLimit) then
return error('Invalid excerpts config: Non-numeral in hardCharLimit: '..parts[5]..'. Will be ignored.')
end
end
end
-- check column numbers in widths param
if args.widths then
local configs = str_split(args.widths, ',')
for _, config in ipairs(configs) do
local parts = str_split(trim(config), ':')
local column = parts[1]
if not is_integer(column) then
return error('Invalid widths config: Non-numeral column number: '..parts[1]..'. Will be ignored.')
end
end
end
-- check numeric configs
if args.comments then
local columns = str_split(args.comments, ',')
for _, column in ipairs(columns) do
if not is_integer(trim(column)) then
return error('Invalid comments parameter: Non-numeral column number: '..column..'. Will be ignored.')
end
end
end
if args.remove_underscores then
local columns = str_split(args.remove_underscores, ',')
for _, column in ipairs(columns) do
if not is_integer(trim(column)) then
return error('Invalid remove_underscores parameter: Non-numeral column number: '..column..'. Will be ignored.')
end
end
end
if args.hide then
local columns = str_split(args.hide, ',')
for _, column in ipairs(columns) do
if not is_integer(trim(column)) then
return error('Invalid hide parameter: Non-numeral column number: '..column..'. Will be ignored.')
end
end
end
if args.pagination and not is_integer(args.pagination) then
return error('pagination should be an integer. Will be ignored.')
end
if args.max_pages and not is_integer(args.max_pages) then
return error('max_pages should be an integer. Will be ignored.')
end
if args.interval and not is_integer(args.interval) then
return error('interval should be an integer. Will be ignored.')
end
if args.row_template_named_params and not args.row_template then
return error('row_template_named_params is only applicable when row_template is used')
end
return ''
end
function invoke_lua_source(args, frame)
if not args.lua_source then
return nil, nil
end
local module_title = mw.title.new(args.lua_source, 828)
if module_title == nil or module_title.namespace ~= 828 then
return nil, error('lua_source should be a valid Module title')
end
local module_name = module_title.text
local lua_params = ''
for key, val in pairs(args) do
if key:find('^lua_arg_') then
local argName = string.sub(key, string.len('lua_arg_') + 1)
local argValue = val
lua_params = lua_params .. '|'..argName..'='..argValue
end
end
local invoke = '{{#invoke:'..module_name..'|'..(args.lua_function or 'main')..lua_params..'}}'
local moduleOutput = frame:preprocess(invoke)
-- FIXME: more robust error detection
if moduleOutput:find('error') ~= nil then
return nil, moduleOutput
end
if not moduleOutput:match('^{{') or not moduleOutput:match('}}$') then
-- XXX: Module is returning something other than report:generate(), error out?
return {}, nil
end
local config = {}
-- Parse the configuration text to extract parameter values
for line in moduleOutput:gmatch("[^\n]+") do
local param, value = line:match("^|([^=]+) = (.*)$")
if param and value then
value = trim(value)
if value ~= "" and value ~= "nil" then
config[param] = value
end
end
end
return config, nil
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.