1: -----------------------------------------------------------------------------
    2: -- Defines the main class for Sputnik - an extensible wiki implemented in Lua.
    3: -- (For usage, see sputnik.wsapi_app.)
    4: --
    5: -- (c) 2007, 2008  Yuri Takhteyev (yuri@freewisdom.org)
    6: -- License: MIT/X, see http://sputnik.freewisdom.org/en/License
    7: -----------------------------------------------------------------------------
    8: 
    9: moduleglobal probably-defined
module (name [, ···])
(..., packageglobal probably-defined
(table) package library
.seeall) 10: 11: requireglobal probably-defined
require (modname)
("md5") 12: requireglobal probably-defined
require (modname)
("wsapi.util") 13: requireglobal probably-defined
require (modname)
("cosmo") 14: 15: requireglobal probably-defined
require (modname)
("saci") 16: requireglobal probably-defined
require (modname)
("sputnik.actions.wiki") 17: requireglobal probably-defined
require (modname)
("sputnik.i18n") 18: requireglobal probably-defined
require (modname)
("sputnik.util") 19: requireglobal probably-defined
require (modname)
("sputnik.wsapi_app") 20: 21: local zlib_loadedlocal defined-line:21, zliblocal defined-line:21 = pcallglobal probably-defined
pcall (f, arg1, ···)
(requireglobal probably-defined
require (modname)
, "zlib") 22: 23: new_wsapi_run_fnglobal probably-defined = sputnikglobal undefined?.wsapi_app.new -- for backwards compatibility 24: 25: ----------------------------------------------------------------------------- 26: -- Applies default config values. 27: ----------------------------------------------------------------------------- 28: local function apply_defaultslocal defined-line:28(configlocal param mutate-bind defined-line:28) 29: configlocal param mutate-bind defined-line:28 = configlocal param mutate-bind defined-line:28 or {} 30: assertglobal probably-defined
assert (v [, message])
(configlocal param mutate-bind defined-line:28.TOKEN_SALT, "TOKEN_SALT must be set") 31: assertglobal probably-defined
assert (v [, message])
(configlocal param mutate-bind defined-line:28.BASE_URL, "BASE_URL must be set") 32: 33: -- Set some defaults on the configuration table 34: local defaultslocal defined-line:34 = {} 35: setmetatableglobal probably-defined
setmetatable (table, metatable)
(configlocal param mutate-bind defined-line:28, {__index = defaultslocal defined-line:34}) 36: 37: defaultslocal defined-line:34.ROOT_PROTOTYPE = "@Root" 38: defaultslocal defined-line:34.PASSWORD_SALT = "2348979898237082394172309847123" 39: defaultslocal defined-line:34.CONFIG_PAGE_NAME = "sputnik/config" 40: 41: return configlocal param mutate-bind defined-line:28 42: end 43: 44: ----------------------------------------------------------------------------- 45: -- THE SPUTNIK CLASS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 46: ----------------------------------------------------------------------------- 47: local Sputniklocal defined-line:47 = {} 48: local Sputnik_mtlocal defined-line:48 = {__metatable = {}, __index = Sputniklocal defined-line:47} 49: 50: ----------------------------------------------------------------------------- 51: -- Creates a new instance of Sputnik. 52: -- 53: -- @param config a table of bootstrap configurations. 54: -- @param logger a lualogging-compatible logger or nil. 55: -- @return an instance of Sputnik. 56: ----------------------------------------------------------------------------- 57: function newglobal probably-defined(configlocal param mutate-bind defined-line:57, loggerlocal param defined-line:57) 58: -- Set up default configuration variables 59: configlocal param mutate-bind defined-line:57 = apply_defaultslocal defined-line:28(configlocal param mutate-bind defined-line:57) 60: -- Create and return the new initialized Sputnik instance 61: local objlocal defined-line:61 = setmetatableglobal probably-defined
setmetatable (table, metatable)
({logger=loggerlocal param defined-line:57 or utilglobal undefined?.make_logger()}, Sputnik_mtlocal defined-line:48) 62: objlocal defined-line:61:init(configlocal param mutate-bind defined-line:57) 63: return objlocal defined-line:61 64: end 65: 66: ----------------------------------------------------------------------------- 67: -- Initializes a the new Sputnik instance. 68: -- 69: -- @param initial_config a table representing bootrastrap configurations. 70: ----------------------------------------------------------------------------- 71: function Sputniklocal defined-line:47:init(initial_configlocal param mutate-bind defined-line:71) 72: -- setup the logger -- do this before loading user configuration 73: selflocal param.initial_config = initial_configlocal param mutate-bind defined-line:71 -- for reloading 74: 75: --- Turns a string into something that can be used as a node name. 76: local dirifylocal defined-line:76 = initial_configlocal param mutate-bind defined-line:71.DIRIFY_FN or sputnikglobal undefined?.util.dirify 77: selflocal param.dirify = function(selflocal param defined-line:77, textlocal param defined-line:77) return dirifylocal defined-line:76(textlocal param defined-line:77) end 78: -- setup the repository -- do this before loading user configuration 79: selflocal param.saci = saciglobal undefined?.new(initial_configlocal param mutate-bind defined-line:71.VERSIUM_STORAGE_MODULE or "versium.filedir", 80: initial_configlocal param mutate-bind defined-line:71.VERSIUM_PARAMS, 81: initial_configlocal param mutate-bind defined-line:71.ROOT_PROTOTYPE) 82: selflocal param.saci.sandbox_values = setmetatableglobal probably-defined
setmetatable (table, metatable)
({}, {__index = initial_configlocal param mutate-bind defined-line:71}) 83: assertglobal probably-defined
assert (v [, message])
(selflocal param.saci) 84: assertglobal probably-defined
assert (v [, message])
(selflocal param.saci.root_prototype_id) 85: selflocal param.repo = selflocal param.saci -- for backwards compatibility 86: 87: selflocal param.saci.get_fallback_node = function(repolocal param defined-line:87, idlocal param defined-line:87, versionlocal param defined-line:87) 88: local statuslocal mutate-bind defined-line:88, page_modulelocal mutate-bind defined-line:88 = pcallglobal probably-defined
pcall (f, arg1, ···)
(requireglobal probably-defined
require (modname)
, "sputnik.node_defaults."..idlocal param defined-line:87:gsub("/", ".")) 89: if not statuslocal mutate-bind defined-line:88 then 90: -- Attempt to escape the node_id using basic filesystem rules 91: local esc_idlocal defined-line:91 = idlocal param defined-line:87:gsub("%%", "%%25"):gsub(":", "%%3A"):gsub("/", ".") 92: statuslocal mutate-bind defined-line:88, page_modulelocal mutate-bind defined-line:88 = pcallglobal probably-defined
pcall (f, arg1, ···)
(requireglobal probably-defined
require (modname)
, "sputnik.node_defaults."..esc_idlocal defined-line:91) 93: end 94: 95: if statuslocal mutate-bind defined-line:88 then 96: local datalocal defined-line:96 = selflocal param.saci:deflate(page_modulelocal mutate-bind defined-line:88.NODE) 97: local nodelocal mutate-bind defined-line:97 = selflocal param.saci:make_node(datalocal defined-line:96, idlocal param defined-line:87) 98: assertglobal probably-defined
assert (v [, message])
(nodelocal mutate-bind defined-line:97) 99: if page_modulelocal mutate-bind defined-line:88.CREATE_DEFAULT then 100: nodelocal mutate-bind defined-line:97 = selflocal param:save_node(nodelocal mutate-bind defined-line:97, nil) 101: nodelocal mutate-bind defined-line:97 = selflocal param.saci:get_node(idlocal param defined-line:87) 102: end 103: return nodelocal mutate-bind defined-line:97 104: else 105: return selflocal param.saci:make_node("", idlocal param defined-line:87), true -- set stub=true 106: end 107: end 108: 109: assertglobal probably-defined
assert (v [, message])
(selflocal param.saci) 110: selflocal param.saci.logger = selflocal param.logger 111: 112: -- WARNING --------------------------------------------------------------- 113: -- Up to now we were using "initial_config" which is loaded from 114: -- sputnik/config.lua We are now going to load values from the 115: -- configuration node. This means that the config values can no longer be 116: -- trusted quite as much. 117: 118: selflocal param.config = initial_configlocal param mutate-bind defined-line:71 119: initial_configlocal param mutate-bind defined-line:71 = nil -- just to keep us honest 120: 121: local config_nodelocal defined-line:121 = selflocal param:get_node(selflocal param.config.CONFIG_PAGE_NAME) 122: assertglobal probably-defined
assert (v [, message])
(config_nodelocal defined-line:121, "Failed to retrieve the config node " 123: ..tostringglobal probably-defined
tostring (e)
(selflocal param.config.CONFIG_PAGE_NAME)) 124: assertglobal probably-defined
assert (v [, message])
(typeglobal probably-defined
type (v)
(config_nodelocal defined-line:121)=="table") 125: --print(config_node.content, "XX", config_node.fields.content.activate) 126: for klocal defined-line:126,vlocal defined-line:126 in pairsglobal probably-defined
pairs (t)
(config_nodelocal defined-line:121.content) do 127: selflocal param.config[klocal defined-line:126] = vlocal defined-line:126 128: end 129: 130: -- setup cache 131: if selflocal param.config.CACHE_MODULE then 132: local cache_modlocal defined-line:132 = requireglobal probably-defined
require (modname)
(selflocal param.config.CACHE_MODULE) 133: selflocal param.cache = cache_modlocal defined-line:132.new(selflocal param, selflocal param.config.CACHE_MODULE_PARAMS) 134: else 135: selflocal param.cache = { 136: add = function() end, 137: del = function() end, 138: get = function() end, 139: } 140: end 141: 142: -- setup app cache 143: if selflocal param.config.APP_CACHE_STORAGE_MODULE then 144: local cache_modlocal defined-line:144 = requireglobal probably-defined
require (modname)
(selflocal param.config.APP_CACHE_STORAGE_MODULE) 145: selflocal param.app_cache = cache_modlocal defined-line:144.new(selflocal param.config.APP_CACHE_PARAMS) 146: end 147: 148: -- setup captcha 149: 150: if selflocal param.config.CAPTCHA_MODULE then 151: local captcha_modlocal defined-line:151 = requireglobal probably-defined
require (modname)
(selflocal param.config.CAPTCHA_MODULE) 152: selflocal param.captcha = captcha_modlocal defined-line:151.new(selflocal param.config.CAPTCHA_PARAMS) 153: end 154: 155: -- setup authentication 156: selflocal param.auth_mod = requireglobal probably-defined
require (modname)
(selflocal param.config.AUTH_MODULE or "sputnik.auth.simple") 157: selflocal param.auth = selflocal param.auth_mod.new(selflocal param, selflocal param.config.AUTH_MODULE_PARAMS) 158: selflocal param.saci.permission_groups.Admin = function(userlocal param defined-line:158) 159: return userlocal param defined-line:158 and selflocal param.auth:get_metadata(userlocal param defined-line:158, "is_admin") == "true" 160: end 161: 162: local groups_mtlocal defined-line:162 = { 163: __index = function(tablelocal param defined-line:163, keylocal param defined-line:163) 164: return function (userlocal param defined-line:164) 165: return userlocal param defined-line:164 and selflocal param.auth:get_metadata(userlocal param defined-line:164, "is_"..keylocal param defined-line:163) == "true" 166: end 167: end 168: } 169: selflocal param.saci.permission_groups.is = setmetatableglobal probably-defined
setmetatable (table, metatable)
({}, groups_mtlocal defined-line:162) 170: selflocal param.saci.permission_groups.edit_and_save = {"save", "edit", "preview"} 171: selflocal param.saci.permission_groups.show = {"show", "show_content", "cancel"} 172: selflocal param.saci.permission_groups.history_and_diff = {"history", "diff"} 173: selflocal param.saci.permission_groups.show_etc = {"show", "show_content", "cancel", "history", "diff"} 174: 175: -- setup wrappers 176: selflocal param.wrappers = sputnikglobal undefined?.actions.wiki.wrappers -- same for "wiki" wrappers 177: end 178: 179: ----------------------------------------------------------------------------- 180: -- Converts a versium time stamp into the requested format. (Same as 181: -- versium.util.format_time, except that config parameters are applied.) 182: -- 183: -- @param timestamp Versium timestamp (string) 184: -- @param format Lua time format (string) 185: -- @param tzoffset time zone offset as "+hh:mm" or "-hh:mm" 186: -- (ISO 8601) or "local" [string, optional, defaults 187: -- to "local"] 188: -- @param tzname name/description of the time zone [string, optional, 189: -- defaults to tzoffset, valid XHTML is ok] 190: -- @return formatted time (string) 191: ----------------------------------------------------------------------------- 192: function Sputniklocal defined-line:47:format_time(timestamplocal param mutate-bind defined-line:192, formatlocal param defined-line:192, tzoffsetlocal param defined-line:192, tznamelocal param defined-line:192) 193: if typeglobal probably-defined
type (v)
(timestamplocal param mutate-bind defined-line:192) == "number" or timestamplocal param mutate-bind defined-line:192:match("^[0-9]*$") then 194: timestamplocal param mutate-bind defined-line:192 = osglobal probably-defined
(table) OS facilities library
.date("!%Y-%m-%d %H:%M:%S", timestamplocal param mutate-bind defined-line:192) 195: end 196: return versiumglobal undefined?.util.format_time(timestamplocal param mutate-bind defined-line:192,formatlocal param defined-line:192, 197: tzoffsetlocal param defined-line:192 or selflocal param.config.TIME_ZONE, 198: tznamelocal param defined-line:192 or selflocal param.config.TIME_ZONE_NAME) 199: end 200: 201: ----------------------------------------------------------------------------- 202: -- Converts a versium time stamp into the format specified in RFC-822. This 203: -- format will always be given in GMT for simplicity, which will be correctly 204: -- altered by the reader. 205: -- 206: -- @param timestamp Versium timestamp (string) 207: -- @return Time string that complied with RFC-822 (string) 208: ----------------------------------------------------------------------------- 209: function Sputniklocal defined-line:47:format_time_RFC822(timestamplocal param defined-line:209) 210: return selflocal param:format_time(timestamplocal param defined-line:209, "!%a, %d %b %Y %H:%M:%S +0000") 211: end 212: 213: function Sputniklocal defined-line:47:get_gravatar_for_email(emaillocal param defined-line:213) 214: if selflocal param.config.USE_GRAVATAR then 215: return "http://www.gravatar.com/avatar/"..md5global undefined?.sumhexa(emaillocal param defined-line:213) 216: .."?s=22&d=" 217: ..sputnikglobal undefined?.util.escape_url("http://" 218: ..selflocal param.config.DOMAIN..selflocal param:make_url("icons/user", "png")) 219: else 220: return selflocal param:make_url("icons/user", "png") 221: end 222: end 223: 224: 225: ----------------------------------------------------------------------------- 226: -- Returns a small icon to represent a given user. 227: -- 228: -- @param user username 229: -- @return a url of an icon 230: ----------------------------------------------------------------------------- 231: function Sputniklocal defined-line:47:get_user_icon(userlocal param defined-line:231) 232: selflocal param.user_icon_hash = selflocal param.user_icon_hash or {} 233: if selflocal param.user_icon_hash[userlocal param defined-line:231] then 234: return selflocal param.user_icon_hash[userlocal param defined-line:231] 235: end 236: local iconlocal mutate-bind defined-line:236 237: if not userlocal param defined-line:231 or userlocal param defined-line:231:len()==0 then 238: iconlocal mutate-bind defined-line:236 = selflocal param:make_url("icons/anon", "png") 239: elseif userlocal param defined-line:231=="admin" or userlocal param defined-line:231=="Admin" then 240: iconlocal mutate-bind defined-line:236 = selflocal param:make_url("icons/admin", "png") 241: elseif userlocal param defined-line:231=="Sputnik-UID" or userlocal param defined-line:231=="Sputnik" then 242: iconlocal mutate-bind defined-line:236 = selflocal param:make_url("icons/system", "png") 243: elseif selflocal param.auth:user_exists(userlocal param defined-line:231) then 244: local emaillocal defined-line:244 = selflocal param.auth:get_metadata(userlocal param defined-line:231, "email") 245: if emaillocal defined-line:244 then 246: iconlocal mutate-bind defined-line:236 = selflocal param:get_gravatar_for_email(emaillocal defined-line:244) 247: end 248: end 249: if (not iconlocal mutate-bind defined-line:236) and userlocal param defined-line:231:match("@") then 250: iconlocal mutate-bind defined-line:236 = selflocal param:get_gravatar_for_email(userlocal param defined-line:231) 251: end 252: selflocal param.user_icon_hash[userlocal param defined-line:231] = iconlocal mutate-bind defined-line:236 or selflocal param:make_url("icons/user", "png") 253: return selflocal param:escape(selflocal param.user_icon_hash[userlocal param defined-line:231]) 254: end 255: 256: ----------------------------------------------------------------------------- 257: -- Escapes a text for using in a textarea. 258: -- 259: -- @param text text to be escaped. 260: -- @return escaped text. 261: ----------------------------------------------------------------------------- 262: function Sputniklocal defined-line:47:escape(textlocal param defined-line:262) 263: return sputnikglobal undefined?.util.escape(textlocal param defined-line:262) 264: end 265: 266: ----------------------------------------------------------------------------- 267: -- Escapes a URL. 268: -- 269: -- @param url a URL to be escaped. 270: -- @return the escaped URL 271: ----------------------------------------------------------------------------- 272: function Sputniklocal defined-line:47:escape_url (urllocal param defined-line:272) 273: return sputnikglobal undefined?.util.escape_url(urllocal param defined-line:272) 274: end 275: 276: ----------------------------------------------------------------------------- 277: -- Checks if a node with the given ID exists. 278: -- 279: -- @param id the id of a node. 280: -- @return true or false. 281: ----------------------------------------------------------------------------- 282: function Sputniklocal defined-line:47:node_exists(idlocal param mutate-bind defined-line:282) 283: idlocal param mutate-bind defined-line:282 = selflocal param:dirify(idlocal param mutate-bind defined-line:282) 284: return selflocal param.saci:node_exists(idlocal param mutate-bind defined-line:282) or pcallglobal probably-defined
pcall (f, arg1, ···)
(requireglobal probably-defined
require (modname)
, 285: "sputnik.node_defaults."..idlocal param mutate-bind defined-line:282) 286: end 287: 288: ----------------------------------------------------------------------------- 289: -- Makes a URL from a table of parameters. 290: -- 291: -- @param node_name a node id. 292: -- @param action action/command as a string. 293: -- @param params query parameters 294: -- @param anchor link anchor 295: -- @return a URL. 296: ----------------------------------------------------------------------------- 297: function Sputniklocal defined-line:47:make_url(node_namelocal param mutate-bind defined-line:297, actionlocal param defined-line:297, paramslocal param defined-line:297, anchorlocal param defined-line:297) 298: if not node_namelocal param mutate-bind defined-line:297 or node_namelocal param mutate-bind defined-line:297=="" then 299: node_namelocal param mutate-bind defined-line:297 = selflocal param.config.HOME_PAGE 300: end 301: 302: local interwiki_codelocal defined-line:302 = node_namelocal param mutate-bind defined-line:297:match("^([^%:]*)%:") 303: local interwiki_handlerlocal defined-line:303 = selflocal param.config.INTERWIKI[interwiki_codelocal defined-line:302] 304: if interwiki_handlerlocal defined-line:303 then 305: node_namelocal param mutate-bind defined-line:297 = node_namelocal param mutate-bind defined-line:297:gsub("^[^%:]*%:", "") -- crop the code 306: end 307: 308: local dirifiedlocal defined-line:308 = selflocal param:dirify(node_namelocal param mutate-bind defined-line:297) --wsapi.util.url_encode() 309: 310: local urllocal mutate-bind defined-line:310 311: 312: -- first the node name 313: if interwiki_handlerlocal defined-line:303 then 314: local handler_typelocal defined-line:314 = typeglobal probably-defined
type (v)
(interwiki_handlerlocal defined-line:303) 315: if handler_typelocal defined-line:314 == "string" then 316: if interwiki_handlerlocal defined-line:303:match("%%s") then 317: urllocal mutate-bind defined-line:310 = stringglobal probably-defined
(table) string manipulation library
.format(interwiki_handlerlocal defined-line:303, node_namelocal param mutate-bind defined-line:297) 318: else 319: urllocal mutate-bind defined-line:310 = interwiki_handlerlocal defined-line:303..node_namelocal param mutate-bind defined-line:297 320: end 321: elseif handler_typelocal defined-line:314 == "function" then 322: urllocal mutate-bind defined-line:310 = interwiki_handlerlocal defined-line:303(node_namelocal param mutate-bind defined-line:297) 323: else 324: errorglobal probably-defined
error (message [, level])
("Interwiki handler should be string or function, but is "..handler_typelocal defined-line:314) 325: end 326: else 327: urllocal mutate-bind defined-line:310 = selflocal param.config.NICE_URL..dirifiedlocal defined-line:308 328: end 329: 330: -- then the action and HOME_PAGE 331: if actionlocal param defined-line:297 and actionlocal param defined-line:297~="show" then 332: urllocal mutate-bind defined-line:310 = urllocal mutate-bind defined-line:310.."."..actionlocal param defined-line:297 333: elseif dirifiedlocal defined-line:308==selflocal param.config.HOME_PAGE and #(paramslocal param defined-line:297 or {})==0 then 334: urllocal mutate-bind defined-line:310 = selflocal param.config.HOME_PAGE_URL 335: end 336: 337: -- then the parameters 338: if paramslocal param defined-line:297 and nextglobal probably-defined
next (table [, index])
(paramslocal param defined-line:297) then 339: for klocal defined-line:339, vlocal defined-line:339 in pairsglobal probably-defined
pairs (t)
(paramslocal param defined-line:297 or {}) do 340: if klocal defined-line:339~="p" then 341: urllocal mutate-bind defined-line:310 = urllocal mutate-bind defined-line:310.."&"..wsapiglobal undefined?.util.url_encode(klocal defined-line:339).."=" 342: ..wsapiglobal undefined?.util.url_encode(vlocal defined-line:339 or "") 343: end 344: end 345: end 346: 347: -- finally the anchor 348: if anchorlocal param defined-line:297 then 349: urllocal mutate-bind defined-line:310 = urllocal mutate-bind defined-line:310.."#"..anchorlocal param defined-line:297 350: end 351: 352: return selflocal param:escape(urllocal mutate-bind defined-line:310), node_namelocal param mutate-bind defined-line:297 353: end 354: 355: ----------------------------------------------------------------------------- 356: -- Makes a link from a table of parameters. 357: -- 358: -- @param node_name a node id. 359: -- @param action action/command as a string. 360: -- @param params query parameters 361: -- @param anchor link anchor 362: -- @return a URL. 363: ----------------------------------------------------------------------------- 364: function Sputniklocal defined-line:47:make_link(node_namelocal param mutate-bind defined-line:364, actionlocal param mutate-bind defined-line:364, paramslocal param defined-line:364, anchorlocal param defined-line:364, optionslocal param mutate-bind defined-line:364) 365: assertglobal probably-defined
assert (v [, message])
(node_namelocal param mutate-bind defined-line:364) 366: optionslocal param mutate-bind defined-line:364=optionslocal param mutate-bind defined-line:364 or {} 367: -- check if we have a command attached to the node name 368: if node_namelocal param mutate-bind defined-line:364:find("%.") then 369: node_namelocal param mutate-bind defined-line:364, actionlocal param mutate-bind defined-line:364 = node_namelocal param mutate-bind defined-line:364:match("(.+)%.(.+)") 370: end 371: --local css_class = "local" 372: local urllocal mutate-bind defined-line:372 = selflocal param:make_url(node_namelocal param mutate-bind defined-line:364, actionlocal param mutate-bind defined-line:364, paramslocal param defined-line:364, anchorlocal param defined-line:364) 373: selflocal param.logger:debug("Creating a link to "..node_namelocal param mutate-bind defined-line:364) 374: if (not optionslocal param mutate-bind defined-line:364.mark_missing==false) 375: and (not selflocal param:node_exists(node_namelocal param mutate-bind defined-line:364)) then 376: css_classglobal probably-defined="no_such_node" 377: urllocal mutate-bind defined-line:372 = selflocal param:make_url(node_namelocal param mutate-bind defined-line:364, actionlocal param mutate-bind defined-line:364, paramslocal param defined-line:364, anchorlocal param defined-line:364) 378: selflocal param.logger:debug("No such node, will link to .edit") 379: end 380: --return string.format("href='%s' class='%s'", url, css_class) 381: return stringglobal probably-defined
(table) string manipulation library
.format("href='%s'", urllocal mutate-bind defined-line:372, css_classglobal probably-defined) 382: end 383: 384: ----------------------------------------------------------------------------- 385: -- Further "activates" a node for use in Sputnik. 386: -- 387: -- @param node a Saci node. 388: -- @return the same node with some extra methods added. 389: ----------------------------------------------------------------------------- 390: function Sputniklocal defined-line:47:activate_node(nodelocal param defined-line:390) 391: 392: -- setup the page-specific translator 393: for ilocal defined-line:393, translation_nodelocal defined-line:393 in ipairsglobal probably-defined
ipairs (t)
(nodelocal param defined-line:390.translations) do 394: local translationslocal defined-line:394 = selflocal param:get_node(translation_nodelocal defined-line:393).content 395: assertglobal probably-defined
assert (v [, message])
(typeglobal probably-defined
type (v)
(translationslocal defined-line:394) == "table", 396: "Could not load translation node") 397: for klocal defined-line:397, translationlocal defined-line:397 in pairsglobal probably-defined
pairs (t)
(translationslocal defined-line:394) do 398: nodelocal param defined-line:390.translations[klocal defined-line:397] = translationlocal defined-line:397 399: end 400: end 401: nodelocal param defined-line:390.translator = sputnikglobal undefined?.i18n.make_translator(nodelocal param defined-line:390.translations, 402: selflocal param.config.INTERFACE_LANGUAGE) 403: 404: -- translate the templates 405: for ilocal defined-line:405, template_node_idlocal defined-line:405 in ipairsglobal probably-defined
ipairs (t)
(nodelocal param defined-line:390.templates) do 406: local template_nodelocal defined-line:406 = selflocal param:get_node(template_node_idlocal defined-line:405) 407: local templateslocal defined-line:407 = template_nodelocal defined-line:406.content 408: --templates.MAIN = template_node.main 409: --templates.HEAD = template_node.head 410: --templates.BODY = template_node.body 411: assertglobal probably-defined
assert (v [, message])
(typeglobal probably-defined
type (v)
(templateslocal defined-line:407) == "table", "Could not load templates node") 412: for klocal defined-line:412, templatelocal defined-line:412 in pairsglobal probably-defined
pairs (t)
(templateslocal defined-line:407) do 413: nodelocal param defined-line:390.templates[klocal defined-line:412] = nodelocal param defined-line:390.translator.translate(templatelocal defined-line:412) 414: end 415: 416: end 417: 418: -- load the actions (turn them into callable functions) 419: local function action_loaderlocal defined-line:419() 420: local mod_cachelocal defined-line:420 = {} 421: return { 422: load = function(mod_namelocal param defined-line:422) 423: if not mod_cachelocal defined-line:420[mod_namelocal param defined-line:422] then 424: mod_cachelocal defined-line:420[mod_namelocal param defined-line:422] = requireglobal probably-defined
require (modname)
("sputnik.actions." .. mod_namelocal param defined-line:422) 425: end 426: return mod_cachelocal defined-line:420[mod_namelocal param defined-line:422].actions 427: end 428: } 429: end 430: local action_loaderlocal defined-line:430 = action_loaderlocal defined-line:430() 431: 432: for commandlocal defined-line:432, action_functionlocal defined-line:432 in pairsglobal probably-defined
pairs (t)
(nodelocal param defined-line:390.actions) do 433: if typeglobal probably-defined
type (v)
(action_functionlocal defined-line:432) == "string" then 434: local mod_namelocal defined-line:434, dot_actionlocal defined-line:434 = sputnikglobal undefined?.util.split(action_functionlocal defined-line:432, "%.") 435: nodelocal param defined-line:390.actions[commandlocal defined-line:432] = action_loaderlocal defined-line:430.load(mod_namelocal defined-line:434)[dot_actionlocal defined-line:434] 436: end 437: end 438: 439: -- set wrappers ----------------------------------------------------- 440: nodelocal param defined-line:390.wrappers = selflocal param.wrappers 441: 442: return nodelocal param defined-line:390 443: end 444: 445: ----------------------------------------------------------------------------- 446: -- Returns the node with this name (without additional activation). 447: ----------------------------------------------------------------------------- 448: function Sputniklocal defined-line:47:get_node(idlocal param defined-line:448, versionlocal param defined-line:448, modelocal param defined-line:448) 449: local nodelocal defined-line:449, stublocal defined-line:449 = selflocal param.saci:get_node(idlocal param defined-line:448, versionlocal param defined-line:448) 450: 451: nodelocal defined-line:449.name = idlocal param defined-line:448 452: if not nodelocal defined-line:449.title then 453: local temp_titlelocal defined-line:453 = stringglobal probably-defined
(table) string manipulation library
.gsub(nodelocal defined-line:449.name, "_", " ") 454: nodelocal defined-line:449.title = temp_titlelocal defined-line:453 455: nodelocal defined-line:449.raw_values.title = temp_titlelocal defined-line:453 456: end 457: return nodelocal defined-line:449, stublocal defined-line:449 458: end 459: 460: ----------------------------------------------------------------------------- 461: -- Adds extra sputnik-specific fields to a node. 462: ----------------------------------------------------------------------------- 463: function Sputniklocal defined-line:47:decorate_node(nodelocal param defined-line:463) 464: -- Determine which markup module the node should be using based on 465: -- the markup_module field, or the default 466: local markup_module_namelocal mutate-bind defined-line:466 467: if nodelocal param defined-line:463.markup_module and nodelocal param defined-line:463.markup_module:len() > 0 then 468: markup_module_namelocal mutate-bind defined-line:466 = "sputnik.markup."..nodelocal param defined-line:463.markup_module 469: else 470: markup_module_namelocal mutate-bind defined-line:466 = "sputnik.markup.markdown" 471: end 472: 473: local markup_modulelocal defined-line:473 = requireglobal probably-defined
require (modname)
(markup_module_namelocal mutate-bind defined-line:466) 474: nodelocal param defined-line:463.markup = markup_modulelocal defined-line:473.new(selflocal param) 475: 476: nodelocal param defined-line:463.messages = {} 477: for ilocal defined-line:477, classlocal defined-line:477 in ipairsglobal probably-defined
ipairs (t)
{"error", "warning", "success", "notice"} do 478: nodelocal param defined-line:463["post_"..classlocal defined-line:477] = function(selflocal param defined-line:478, messagelocal param defined-line:478) 479: tableglobal probably-defined
(table) table manipulation library
.insert(selflocal param defined-line:478.messages, {message=messagelocal param defined-line:478, class=classlocal defined-line:477}) 480: end 481: end 482: -- Table/Function that allow the developer to add custom HTML response headers 483: nodelocal param defined-line:463.headers = {} 484: nodelocal param defined-line:463.add_header = function(selflocal param defined-line:484, headerlocal param defined-line:484, valuelocal param defined-line:484) selflocal param defined-line:484.headers[headerlocal param defined-line:484] = valuelocal param defined-line:484 end 485: nodelocal param defined-line:463.redirect = function(node_selflocal param defined-line:485, urllocal param defined-line:485) 486: node_selflocal param defined-line:485.headers["Location"] = urllocal param defined-line:485 487: end 488: 489: nodelocal param defined-line:463.css_links = {} 490: nodelocal param defined-line:463.css_snippets = {} 491: nodelocal param defined-line:463.javascript_links = {} 492: nodelocal param defined-line:463.javascript_snippets = {} 493: 494: local function addlocal defined-line:494(tablocal param defined-line:494, keylocal param defined-line:494, valueslocal param defined-line:494, defaultslocal param defined-line:494) 495: if tablocal param defined-line:494[keylocal param defined-line:494] then return end 496: tablocal param defined-line:494[keylocal param defined-line:494] = true 497: tableglobal probably-defined
(table) table manipulation library
.insert(tablocal param defined-line:494, valueslocal param defined-line:494) 498: end 499: function nodelocal param defined-line:463:add_css_link(hreflocal param defined-line:499, medialocal param mutate-bind defined-line:499) 500: medialocal param mutate-bind defined-line:499 = medialocal param mutate-bind defined-line:499 or "screen" 501: return addlocal defined-line:494(selflocal param.css_links, hreflocal param defined-line:499.."|"..medialocal param mutate-bind defined-line:499, {href = hreflocal param defined-line:499, media = medialocal param mutate-bind defined-line:499}) 502: end 503: function nodelocal param defined-line:463:add_css_snippet(hreflocal param defined-line:503, snippetlocal param defined-line:503, medialocal param mutate-bind defined-line:503) 504: medialocal param mutate-bind defined-line:503 = medialocal param mutate-bind defined-line:503 or "screen" 505: return addlocal defined-line:494(selflocal param.css_snippets, hreflocal param defined-line:503.."|"..medialocal param mutate-bind defined-line:503, {snippet = snippetlocal param defined-line:503, media = medialocal param mutate-bind defined-line:503}) 506: end 507: function nodelocal param defined-line:463:add_javascript_link(hreflocal param defined-line:507) 508: addlocal defined-line:494(selflocal param.javascript_links, hreflocal param defined-line:507, {href=hreflocal param defined-line:507}) 509: end 510: function nodelocal param defined-line:463:add_javascript_snippet(snippetlocal param defined-line:510) 511: return addlocal defined-line:494(selflocal param.javascript_snippets, snippetlocal param defined-line:510, {snippet=snippetlocal param defined-line:510}) 512: end 513: return nodelocal param defined-line:463 514: end 515: 516: ----------------------------------------------------------------------------- 517: --- Updates node with values from params table. 518: ----------------------------------------------------------------------------- 519: function Sputniklocal defined-line:47:update_node_with_params(nodelocal param defined-line:519, paramslocal param defined-line:519) 520: nodelocal param defined-line:519:update(paramslocal param defined-line:519, nodelocal param defined-line:519.fields) 521: --new_node.name = node.name 522: selflocal param:decorate_node(nodelocal param defined-line:519) 523: return nodelocal param defined-line:519 524: end 525: 526: ----------------------------------------------------------------------------- 527: -- This function is provided as a wrapper to node:save(...) that respects the 528: -- save_hook field in a node. This field defines a module and function name 529: -- that are called when the node is being saved, allowing for last minute 530: -- changes to the node parameters, or for other actions to be taken alongside 531: -- the save. 532: -- 533: -- NODE: A save hook is passed the node, the request object and the sputnik 534: -- instance, although request and sputnik are not guaranteed to be available 535: -- for certain types of nodes. 536: ----------------------------------------------------------------------------- 537: function Sputniklocal defined-line:47:save_node(nodelocal param defined-line:537, requestlocal param defined-line:537, ...) 538: local new_nodelocal mutate-bind defined-line:538 = nodelocal param defined-line:537 539: if typeglobal probably-defined
type (v)
(nodelocal param defined-line:537.save_hook) == "string" and #nodelocal param defined-line:537.save_hook > 0 then 540: local mod_namelocal defined-line:540, func_namelocal defined-line:540 = sputnikglobal undefined?.util.split(nodelocal param defined-line:537.save_hook, "%.") 541: local modulelocal defined-line:541 = requireglobal probably-defined
require (modname)
("sputnik.hooks." .. mod_namelocal defined-line:540) 542: local save_hooklocal defined-line:542 = modulelocal defined-line:541[func_namelocal defined-line:540] 543: new_nodelocal mutate-bind defined-line:538 = save_hooklocal defined-line:542(nodelocal param defined-line:537, requestlocal param defined-line:537, selflocal param) 544: end 545: -- Actually perform the save at the saci layer 546: new_nodelocal mutate-bind defined-line:538:save(...) 547: return new_nodelocal mutate-bind defined-line:538 548: end 549: 550: ----------------------------------------------------------------------------- 551: -- Returns node's history. 552: ----------------------------------------------------------------------------- 553: function Sputniklocal defined-line:47:get_history(node_namelocal param defined-line:553, limitlocal param defined-line:553, date_prefixlocal param defined-line:553) 554: local editslocal defined-line:554 = selflocal param.saci:get_node_history(node_namelocal param defined-line:553, date_prefixlocal param defined-line:553, limitlocal param defined-line:553) 555: if limitlocal param defined-line:553 then 556: for ilocal defined-line:556=limitlocal param defined-line:553, #editslocal defined-line:554 do 557: tableglobal probably-defined
(table) table manipulation library
.remove(editslocal defined-line:554, ilocal defined-line:556) 558: end 559: end 560: return editslocal defined-line:554 561: end 562: 563: ----------------------------------------------------------------------------- 564: -- Returns history for all nodes. 565: ----------------------------------------------------------------------------- 566: function Sputniklocal defined-line:47:get_complete_history(limitlocal param defined-line:566, date_prefixlocal param defined-line:566, id_prefixlocal param defined-line:566) 567: return selflocal param.saci:get_complete_history(id_prefixlocal param defined-line:566, date_prefixlocal param defined-line:566, limitlocal param defined-line:566) 568: end 569: 570: ----------------------------------------------------------------------------- 571: -- Returns a list of all node ids. 572: ----------------------------------------------------------------------------- 573: function Sputniklocal defined-line:47.get_node_names(selflocal param defined-line:573, argslocal param defined-line:573) 574: return selflocal param defined-line:573.saci.versium:get_node_ids(argslocal param defined-line:573 and argslocal param defined-line:573.prefix or nil, 575: argslocal param defined-line:573 and argslocal param defined-line:573.limit or nil) 576: end 577: 578: ----------------------------------------------------------------------------- 579: -- Generates a hash for a POST field name. 580: ----------------------------------------------------------------------------- 581: function Sputniklocal defined-line:47:hash_field_name(field_namelocal param defined-line:581, tokenlocal param defined-line:581) 582: return "field_"..md5global undefined?.sumhexa(field_namelocal param defined-line:581..tokenlocal param defined-line:581..selflocal param.config.TOKEN_SALT) 583: end 584: 585: ----------------------------------------------------------------------------- 586: -- Generates a unique numeric or hashed identifier using sputnik's default 587: -- storage repository as the shared state. 588: -- 589: -- @param namespace [optional] a namespace idenfier string (defaults to 590: -- "sputnik"). 591: -- @param type [optional] the type of uid to generate ("hash" or 592: -- "number", defaults to "number"). 593: -- @return uid a unique identifier for the given namespace. 594: ----------------------------------------------------------------------------- 595: function Sputniklocal defined-line:47:get_uid(namespacelocal param mutate-bind defined-line:595, typelocal param mutate-bind defined-line:595) 596: -- Initialize the default values 597: namespacelocal param mutate-bind defined-line:595 = namespacelocal param mutate-bind defined-line:595 or "sputnik" 598: typelocal param mutate-bind defined-line:595 = typelocal param mutate-bind defined-line:595 or "number" 599: 600: -- Generate the values we'll use in the initial hash 601: local memorylocal defined-line:601 = collectgarbageglobal probably-defined
collectgarbage (opt [, arg])
("count") 602: local timelocal defined-line:602 = osglobal probably-defined
(table) OS facilities library
.time() + osglobal probably-defined
(table) OS facilities library
.clock() 603: local hashlocal defined-line:603 = md5global undefined?.sumhexa(namespacelocal param mutate-bind defined-line:595 .. memorylocal defined-line:601 .. timelocal defined-line:602) 604: 605: -- Create and store a node 606: local node_namelocal defined-line:606 = "_uid:" .. namespacelocal param mutate-bind defined-line:595 607: local nodelocal mutate-bind defined-line:607 = selflocal param:get_node(node_namelocal defined-line:606) 608: nodelocal mutate-bind defined-line:607 = selflocal param:update_node_with_params(nodelocal mutate-bind defined-line:607, {content=hashlocal defined-line:603}) 609: nodelocal mutate-bind defined-line:607 = selflocal param:save_node(nodelocal mutate-bind defined-line:607, nil, "Sputnik-UID", hashlocal defined-line:603) 610: 611: -- Retrieve the node history 612: local historylocal defined-line:612 = selflocal param:get_history(node_namelocal defined-line:606) 613: local history_idlocal mutate-bind defined-line:613 614: 615: -- Find our specific hash in the history 616: for ilocal defined-line:616=1,#historylocal defined-line:612 do 617: if historylocal defined-line:612[ilocal defined-line:616].comment == hashlocal defined-line:603 then 618: -- This is our node, it will likely be the first entry 619: -- So add it to the total number of entries 620: history_idlocal mutate-bind defined-line:613 = #historylocal defined-line:612 + (ilocal defined-line:616 - 1) 621: break 622: end 623: end 624: 625: assertglobal probably-defined
assert (v [, message])
(history_idlocal mutate-bind defined-line:613) 626: if typelocal param mutate-bind defined-line:595 == "number" then 627: return history_idlocal mutate-bind defined-line:613 628: else 629: return md5global undefined?.sumhexa(namespacelocal param mutate-bind defined-line:595 .. memorylocal defined-line:601 .. timelocal defined-line:602 .. history_idlocal mutate-bind defined-line:613) 630: end 631: end 632: 633: ----------------------------------------------------------------------------- 634: -- Sends email on Sputnik's behalf. 635: ----------------------------------------------------------------------------- 636: function Sputniklocal defined-line:47:sendmail(argslocal param defined-line:636) 637: return sputnikglobal undefined?.util.sendmail(argslocal param defined-line:636, selflocal param) 638: end 639: 640: ----------------------------------------------------------------------------- 641: -- Pre-processes CGI parameters and does authentication. 642: ----------------------------------------------------------------------------- 643: function Sputniklocal defined-line:47:translate_request (requestlocal param defined-line:643) 644: if requestlocal param defined-line:643.method=="POST" then 645: requestlocal param defined-line:643.params = requestlocal param defined-line:643.POST or {} 646: else 647: requestlocal param defined-line:643.params = requestlocal param defined-line:643.GET or {} 648: end 649: 650: -- For a post action we'll need to unhash the parameters first. Note that 651: -- we don't care if the action was actually submitted via get or post: if 652: -- an idempotent request was sent via POST, that's ok. Instead, we divide 653: -- actions into two types: those that were submitted with a post token and 654: -- those that were submitted without. Requests submitted with a post token 655: -- are allowed to make changes to the state of the wiki. They get their 656: -- fields unhashed. This means that if an action is submitted with a post 657: -- token but its fields are not hashed, it will be processed as if 658: -- submitted with no arguments. 659: if requestlocal param defined-line:643.params.post_token then 660: assertglobal probably-defined
assert (v [, message])
(requestlocal param defined-line:643.params.post_fields) 661: selflocal param.logger:debug("handling post parameters") 662: local new_paramslocal defined-line:662 = {} 663: for klocal defined-line:663,vlocal defined-line:663 in pairsglobal probably-defined
pairs (t)
(requestlocal param defined-line:643.params) do 664: if klocal defined-line:663:sub(0,7) == "action_" then 665: new_paramslocal defined-line:662[klocal defined-line:663] = vlocal defined-line:663 666: end 667: end 668: for namelocal defined-line:668 in stringglobal probably-defined
(table) string manipulation library
.gmatch(requestlocal param defined-line:643.params.post_fields, "[%a_]+") do 669: selflocal param.logger:debug(namelocal defined-line:668) 670: local fieldlocal defined-line:670 = selflocal param:hash_field_name(namelocal defined-line:668, requestlocal param defined-line:643.params.post_token) 671: new_paramslocal defined-line:662[namelocal defined-line:668] = requestlocal param defined-line:643.params[fieldlocal defined-line:670] or "" 672: --self.logger:debug(new_params[name]) 673: end 674: new_paramslocal defined-line:662.p = requestlocal param defined-line:643.params.p 675: new_paramslocal defined-line:662.post_token = requestlocal param defined-line:643.params.post_token 676: new_paramslocal defined-line:662.post_timestamp = requestlocal param defined-line:643.params.post_timestamp 677: requestlocal param defined-line:643.params = new_paramslocal defined-line:662 678: end 679: 680: -- break "p" parameter into node name and the action 681: if requestlocal param defined-line:643.params.p and requestlocal param defined-line:643.params.p~="" then 682: requestlocal param defined-line:643.node_name, requestlocal param defined-line:643.action = sputnikglobal undefined?.util.split(requestlocal param defined-line:643.params.p, "%.") 683: else 684: requestlocal param defined-line:643.node_name = selflocal param.config.HOME_PAGE 685: end 686: requestlocal param defined-line:643.node_name = requestlocal param defined-line:643.node_name:gsub("/$", "") -- remove the trailing slash 687: requestlocal param defined-line:643.action = requestlocal param defined-line:643.action or "show" 688: 689: -- now login/logout/register the user 690: if requestlocal param defined-line:643.params.logout then 691: requestlocal param defined-line:643.user = nil 692: elseif (requestlocal param defined-line:643.params.user or ""):len() > 0 then 693: requestlocal param defined-line:643.user, requestlocal param defined-line:643.auth_token = selflocal param.auth:authenticate( 694: requestlocal param defined-line:643.params.user, 695: requestlocal param defined-line:643.params.password) 696: if not requestlocal param defined-line:643.user then 697: requestlocal param defined-line:643.auth_message = "INCORRECT_PASSWORD" 698: -- TODO: I am unsure what the behavior here should be.. 699: requestlocal param defined-line:643.node_name = selflocal param.config.LOGIN_NODE 700: else 701: if requestlocal param defined-line:643.params.next then 702: requestlocal param defined-line:643.redirect = selflocal param:make_url(requestlocal param defined-line:643.params.next) 703: end 704: 705: selflocal param.logger:debug(requestlocal param defined-line:643.user..","..requestlocal param defined-line:643.auth_token) 706: end 707: else 708: local cookielocal defined-line:708 = requestlocal param defined-line:643.cookies[selflocal param.cookie_name] or "" 709: local user_from_cookielocal defined-line:709, auth_tokenlocal defined-line:709 = sputnikglobal undefined?.util.split(cookielocal defined-line:708, "|") 710: if user_from_cookielocal defined-line:709 then 711: requestlocal param defined-line:643.user = selflocal param.auth:validate_token(user_from_cookielocal defined-line:709, auth_tokenlocal defined-line:709) 712: if requestlocal param defined-line:643.user then 713: requestlocal param defined-line:643.auth_token = auth_tokenlocal defined-line:709 714: end 715: end 716: end 717: return requestlocal param defined-line:643 718: end 719: 720: ----------------------------------------------------------------------------- 721: -- Handles a request. 722: -- 723: -- @param request a WSAPI request table. 724: -- @param response a WSAPI response table. 725: -- @return the response 726: ----------------------------------------------------------------------------- 727: function Sputniklocal defined-line:47:handle_request(requestlocal param mutate-bind defined-line:727, responselocal param defined-line:727) 728: selflocal param.auth = selflocal param.auth_mod.new(selflocal param, selflocal param.config.AUTH_MODULE_PARAMS) 729: 730: selflocal param.cookie_name = selflocal param.config.COOKIE_NAME.."_"..md5global undefined?.sumhexa(selflocal param.config.BASE_URL) 731: requestlocal param mutate-bind defined-line:727 = selflocal param:translate_request(requestlocal param mutate-bind defined-line:727) 732: requestlocal param mutate-bind defined-line:727.is_indexable = true 733: 734: local dirifiedlocal defined-line:734 = selflocal param:dirify(requestlocal param mutate-bind defined-line:727.node_name) 735: 736: local nodelocal mutate-bind defined-line:736, stublocal defined-line:736 = selflocal param:get_node(requestlocal param mutate-bind defined-line:727.node_name, requestlocal param mutate-bind defined-line:727.params.version) 737: nodelocal mutate-bind defined-line:736.is_a_stub = stublocal defined-line:736 738: selflocal param:decorate_node(nodelocal mutate-bind defined-line:736) 739: 740: if requestlocal param mutate-bind defined-line:727.redirect then 741: selflocal param.logger:debug("Sending redirect") 742: -- Set the authentication cookie so it's not lost 743: local cookie_valuelocal defined-line:743 = (requestlocal param mutate-bind defined-line:727.user or "").."|"..(requestlocal param mutate-bind defined-line:727.auth_token or "") 744: responselocal param defined-line:727:set_cookie(selflocal param.cookie_name, {value=cookie_valuelocal defined-line:743, path="/"}) 745: 746: responselocal param defined-line:727.headers["Content-Type"] = "text/html" 747: responselocal param defined-line:727.headers["Location"] = requestlocal param mutate-bind defined-line:727.redirect 748: responselocal param defined-line:727:write("redirect") 749: return responselocal param defined-line:727 750: end 751: 752: if dirifiedlocal defined-line:734 ~= requestlocal param mutate-bind defined-line:727.node_name then 753: responselocal param defined-line:727.headers["Content-Type"] = content_typeglobal undefined? or "text/html" 754: responselocal param defined-line:727.headers["Location"] = selflocal param:make_url(dirifiedlocal defined-line:734, requestlocal param mutate-bind defined-line:727.action, requestlocal param mutate-bind defined-line:727.params) 755: responselocal param defined-line:727:write("redirect") 756: return responselocal param defined-line:727 757: end 758: 759: if stublocal defined-line:736 and selflocal param.config.PROTOTYPE_PATTERNS then 760: -- If an empty stub was returned, check the PROTOTYPE_PATTERNS table to 761: -- see if we should apply a prototype. 762: local node_namelocal defined-line:762 = requestlocal param mutate-bind defined-line:727.node_name 763: for patternlocal defined-line:763,prototypelocal defined-line:763 in pairsglobal probably-defined
pairs (t)
(selflocal param.config.PROTOTYPE_PATTERNS or {}) do 764: if node_namelocal defined-line:762:find(patternlocal defined-line:763) then 765: requestlocal param mutate-bind defined-line:727.params.prototype = prototypelocal defined-line:763; 766: break 767: end 768: end 769: end 770: 771: if requestlocal param mutate-bind defined-line:727.params.prototype then 772: selflocal param:update_node_with_params(nodelocal mutate-bind defined-line:736, {prototype = requestlocal param mutate-bind defined-line:727.params.prototype}) 773: end 774: 775: nodelocal mutate-bind defined-line:736 = selflocal param:activate_node(nodelocal mutate-bind defined-line:736, requestlocal param mutate-bind defined-line:727) 776: 777: local actionlocal defined-line:777 = requestlocal param mutate-bind defined-line:727.action or "show" 778: local action_functionlocal defined-line:778 = nodelocal mutate-bind defined-line:736.actions[actionlocal defined-line:777] 779: 780: local contentlocal mutate-bind defined-line:780, content_typelocal mutate-bind defined-line:780 781: 782: if not action_functionlocal defined-line:778 then 783: contentlocal mutate-bind defined-line:780, content_typelocal mutate-bind defined-line:780 = sputnikglobal undefined?.actions.wiki.actions.action_not_found(nodelocal mutate-bind defined-line:736, requestlocal param mutate-bind defined-line:727, selflocal param) 784: elseif nodelocal mutate-bind defined-line:736:check_permissions(requestlocal param mutate-bind defined-line:727.user, actionlocal defined-line:777) then 785: -- Check permissions on the node, for the given action 786: contentlocal mutate-bind defined-line:780, content_typelocal mutate-bind defined-line:780 = action_functionlocal defined-line:778(nodelocal mutate-bind defined-line:736, requestlocal param mutate-bind defined-line:727, selflocal param) 787: else 788: -- The user did not have permission, so give a message stating this 789: nodelocal mutate-bind defined-line:736:post_error("Sorry, that action is not allowed") 790: nodelocal mutate-bind defined-line:736.inner_html = "" 791: contentlocal mutate-bind defined-line:780, content_typelocal mutate-bind defined-line:780 = nodelocal mutate-bind defined-line:736.wrappers.default(nodelocal mutate-bind defined-line:736, requestlocal param mutate-bind defined-line:727, selflocal param) 792: end 793: 794: if requestlocal param mutate-bind defined-line:727.redirect then 795: selflocal param.logger:debug("Sending redirect") 796: -- Set the authentication cookie so it's not lost 797: local cookie_valuelocal defined-line:797 = (requestlocal param mutate-bind defined-line:727.user or "").."|"..(requestlocal param mutate-bind defined-line:727.auth_token or "") 798: responselocal param defined-line:727:set_cookie(selflocal param.cookie_name, {value=cookie_valuelocal defined-line:797, path="/"}) 799: 800: responselocal param defined-line:727.headers["Content-Type"] = "text/html" 801: responselocal param defined-line:727.headers["Location"] = requestlocal param mutate-bind defined-line:727.redirect 802: responselocal param defined-line:727:write("redirect") 803: return responselocal param defined-line:727 804: end 805: 806: assertglobal probably-defined
assert (v [, message])
(contentlocal mutate-bind defined-line:780) 807: responselocal param defined-line:727.headers["Content-Type"] = content_typelocal mutate-bind defined-line:780 or "text/html" 808: 809: if nodelocal mutate-bind defined-line:736.http_cache_control and nodelocal mutate-bind defined-line:736.http_cache_control~="" then 810: nodelocal mutate-bind defined-line:736.headers["Cache-Control"] = nodelocal mutate-bind defined-line:736.http_cache_control 811: end 812: if nodelocal mutate-bind defined-line:736.http_expires and nodelocal mutate-bind defined-line:736.http_expires~="" then 813: nodelocal mutate-bind defined-line:736.headers["Expires"] = osglobal probably-defined
(table) OS facilities library
.date("!%a, %d %b %Y %H:%M:%S GMT", 814: osglobal probably-defined
(table) OS facilities library
.time()+3600*1000*tonumberglobal probably-defined
tonumber (e [, base])
(nodelocal mutate-bind defined-line:736.http_expires)) 815: end 816: 817: -- If we have any custom HTML headers, add them to the response 818: for headerlocal defined-line:818,valuelocal defined-line:818 in pairsglobal probably-defined
pairs (t)
(nodelocal mutate-bind defined-line:736.headers) do 819: responselocal param defined-line:727.headers[headerlocal defined-line:818] = valuelocal defined-line:818 820: end 821: 822: local cookie_valuelocal defined-line:822 = (requestlocal param mutate-bind defined-line:727.user or "").."|"..(requestlocal param mutate-bind defined-line:727.auth_token or "") 823: responselocal param defined-line:727:set_cookie(selflocal param.cookie_name, {value=cookie_valuelocal defined-line:822, path="/"}) 824: 825: -- gzip compression code borrowed from Ignacio Burgeno 826: if selflocal param.config.USE_COMPRESSION and zlib_loadedlocal defined-line:21 827: and stringglobal probably-defined
(table) string manipulation library
.find(requestlocal param mutate-bind defined-line:727.wsapi_env["HTTP_ACCEPT_ENCODING"], "gzip") then 828: --zlib.compress(string buffer [, int level] [, int method] [, int windowBits] [, int memLevel] [, int strategy]) 829: --that magic came from http://lua-users.org/lists/lua-l/2005-03/msg00221.html 830: local gz_contentlocal defined-line:830 = zliblocal defined-line:21.compress(contentlocal mutate-bind defined-line:780, 9, nil, 15 + 16) 831: responselocal param defined-line:727.headers["Content-Encoding"] = "gzip" 832: responselocal param defined-line:727.headers["Content-Length"] = #gz_contentlocal defined-line:830 833: responselocal param defined-line:727.headers["Vary"] = "accept-encoding" 834: responselocal param defined-line:727:write(gz_contentlocal defined-line:830) 835: else 836: responselocal param defined-line:727:write(contentlocal mutate-bind defined-line:780) 837: end 838: 839: if selflocal param.saci.reset_cache then selflocal param.saci:reset_cache() end 840: return responselocal param defined-line:727 841: end 842: 843: -- vim:ts=3 ss=3 sw=3 expandtab