summaryrefslogtreecommitdiffstats
path: root/app/acf_www-controller.lua
diff options
context:
space:
mode:
Diffstat (limited to 'app/acf_www-controller.lua')
-rw-r--r--app/acf_www-controller.lua202
1 files changed, 202 insertions, 0 deletions
diff --git a/app/acf_www-controller.lua b/app/acf_www-controller.lua
new file mode 100644
index 0000000..742533a
--- /dev/null
+++ b/app/acf_www-controller.lua
@@ -0,0 +1,202 @@
+--[[ Code for the Alpine Configuration WEB framework
+ Written for Alpine Configuration Framework (ACF) -- see www.alpinelinux.org
+ Copyright (C) 2007 Nathan Angelacos
+ Licensed under the terms of GPL2
+ ]]--
+module(..., package.seeall)
+
+-- We use the parent exception handler in a last-case situation
+local parent_exception_handler
+
+mvc = {}
+mvc.on_load = function (self, parent)
+
+ -- Make sure we have some kind of sane defaults for libdir and sessiondir
+ self.conf.libdir = self.conf.libdir or ( self.conf.appdir .. "/lib/" )
+ self.conf.sessiondir = self.conf.sessiondir or "/tmp/"
+ self.conf.appuri = "http://" .. ENV.HTTP_HOST .. ENV.SCRIPT_NAME
+ self.conf.default_controller = "welcome"
+ self.clientdata = FORM
+
+
+ parent_exception_handler = parent.exception_handler
+
+ -- this sets the package path for us and our children
+ package.path= self.conf.libdir .. "?.lua;" .. package.path
+
+ self.session = {}
+ local x=require("session")
+ if FORM.sessionid then
+ local timestamp
+ timestamp , self.session = x.load_session(self.conf.sessiondir , FORM.sessionid)
+ self.session.id = FORM.sessionid
+ else
+ self.session.id = nil
+ end
+ logit ("acf_www-controller mvc.on_load activated" )
+end
+
+mvc.pre_exec = function ()
+ logit ("acf_www-controller mvc.pre_exec activated")
+end
+
+mvc.post_exec = function ()
+ logit ("acf_www-controller mvc.post_exec activated")
+end
+
+
+-- look for a template
+-- ctlr-action-view, then ctlr-view, then action-view, then view
+
+find_template = function ( appdir, prefix, controller, action, viewtype )
+ local targets = {
+ appdir .. prefix .. "template-" .. controller .. "-" ..
+ action .. "-" .. viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. controller .. "-" ..
+ viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. action .. "-" ..
+ viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. viewtype .. ".lsp"
+ }
+ local file
+ for k,v in pairs(targets) do
+ file = io.open (v)
+ if file then
+ io.close (file)
+ return v
+ end
+ end
+ -- not found, so try one level higher
+ if prefix == "" then -- already at the top level - fail
+ return false
+ end
+ prefix = dirname (prefix)
+ return find_template ( appdir, prefix, controller, action, viewtype )
+end
+
+
+
+-- Overload the MVC's view resolver with our own
+
+view_resolver = function(self)
+ local file
+ local viewname
+ local viewtype = self.conf.viewtype or "html"
+ local names = { self.conf.appdir .. self.conf.prefix .. self.conf.controller ..
+ "-" .. self.conf.action .. "-" .. viewtype .. ".lsp",
+ self.conf.appdir .. self.conf.prefix .. self.conf.controller ..
+ "-" .. viewtype .. ".lsp" }
+
+
+ -- FIXME: MVC doesn't have a way to call a function after the controller is run
+ -- so we serialize the session in the view resolver. MVC probably should have
+ -- a postinit or postrun method...
+ if self.session.id then
+ local x = require("session")
+ x.save_session(self.conf.sessiondir, self.session.id, self.session)
+ x=nil
+ end
+
+ -- search for template
+ local template = find_template ( self.conf.appdir, self.conf.prefix,
+ self.conf.controller, self.conf.action, "html")
+
+ -- search for view
+ for i,filename in ipairs (names) do
+ file = io.open(filename)
+ if file then
+ file:close()
+ viewname = filename
+ break
+ end
+ end
+
+ -- We have a template
+ if template then
+ -- ***************************************************
+ -- This is how to call another controller (APP or self
+ -- can be used... m will contain worker and model,
+ -- with conf, and other "missing" parts pointing back
+ -- to APP or self
+ -- ***************************************************
+ local m = self:new("alpine-baselayout/hostname")
+ local h = m.worker.read(m)
+
+ local pageinfo = { viewfile = viewname,
+ controller = m.conf.controller,
+ -- ^^^ see.. m.conf doesnt exist - but it works
+ action = self.conf.action,
+ hostname = h.hostname.value,
+ prefix = self.conf.prefix,
+ script = self.conf.appuri
+ }
+
+ -- Build the menu table
+ m=require("menubuilder")
+ local menu = m.get_menuitems(self.conf.appdir)
+
+ -- A quick hack
+ submenu = {}
+ for k,v in pairs ( self.worker ) do
+ if type ( self.worker[k] ) == "function" then
+ table.insert (submenu, k)
+ end
+ end
+
+ return function (viewtable)
+ local template = haserl.loadfile (template)
+ return template ( pageinfo, menu, submenu, viewtable, self.session )
+ end
+ end
+
+ -- No template, but have a view
+ if viewname then
+ return haserl.loadfile (viewname)
+ else
+ return function() end
+ end
+end
+
+exception_handler = function (self, message )
+ local html = require ("html")
+ if type(message) == "table" then
+ if message.type == "redir" then
+ io.write ("Status: 302 Moved\n")
+ io.write ("Location: " .. ENV["SCRIPT_NAME"] ..
+ message.prefix .. message.controller ..
+ "/" .. message.action ..
+ (message.extra or "" ) .. "\n")
+ if self.session.id then
+ io.write (html.cookie.set("sessionid", self.session.id))
+ else
+ io.write (html.cookie.unset("sessionid"))
+ end
+ io.write ( "Content-Type: text/html\n\n" )
+ elseif message.type == "dispatch" then
+ parent_exception_handler(self, message)
+ end
+ else
+ parent_exception_handler( self, message)
+ end
+end
+
+-- create a Configuration Framework Entity (cfe)
+-- returns a table with at least "value", "type", "option" and "errtxt"
+cfe = function ( optiontable )
+ optiontable = optiontable or {}
+ me = { value="",
+ type="text",
+ option="",
+ errtxt="",
+ name="" }
+ for key,value in pairs(optiontable) do
+ me[key] = value
+ end
+ return me
+end
+
+
+-- syslog something
+logit = function ( ... )
+ os.execute ( "logger \"" .. ... .. "\"" )
+end