mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
Plinth has been moved from plinth.(server).local to (server)/plinth. *plinth.py* has been updated to take a new *--server_dir* argument, which *share/init.d/plinth* now provides. *plinth.sample.config* has also been updated. Actually, the whole package has been moved to a more Debian-friendly configuration. *share/apache2/plinth.conf* has been updated to reflect the standard Debian directories. It seems to make more sense this way, as (other than FreedomMaker, which now uses this package anyway) no other tools or derivatives use this system. The configuration can be patched out by other distributions easily enough.
177 lines
6.1 KiB
Python
Executable File
177 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import os, sys, argparse
|
|
from gettext import gettext as _
|
|
import cfg
|
|
if not os.path.join(cfg.file_root, "vendor") in sys.path:
|
|
sys.path.append(os.path.join(cfg.file_root, "vendor"))
|
|
|
|
import cherrypy
|
|
from cherrypy import _cpserver
|
|
from cherrypy.process.plugins import Daemonizer
|
|
Daemonizer(cherrypy.engine).subscribe()
|
|
|
|
import plugin_mount
|
|
import util as u
|
|
|
|
from logger import Logger
|
|
#from modules.auth import AuthController, require, member_of, name_is
|
|
|
|
from withsqlite.withsqlite import sqlite_db
|
|
import socket
|
|
|
|
__version__ = "0.2.14"
|
|
__author__ = "James Vasile"
|
|
__copyright__ = "Copyright 2011-2013, James Vasile"
|
|
__license__ = "GPLv3 or later"
|
|
__maintainer__ = "James Vasile"
|
|
__email__ = "james@jamesvasile.com"
|
|
__status__ = "Development"
|
|
|
|
import urlparse
|
|
|
|
def error_page(status, dynamic_msg, stock_msg):
|
|
return u.page_template(template="err", title=status, main="<p>%s</p>%s" % (dynamic_msg, stock_msg))
|
|
|
|
def error_page_404(status, message, traceback, version):
|
|
return error_page(status, message, """<p>If you believe this
|
|
missing page should exist, please file a bug with either the Plinth
|
|
project (<a href="https://github.com/jvasile/plinth/issues">it has
|
|
an issue tracker</a>) or the people responsible for the module you
|
|
are trying to access.</p>
|
|
|
|
<p>Sorry for the mistake.</p>
|
|
""")
|
|
|
|
def error_page_500(status, message, traceback, version):
|
|
cfg.log.error("500 Internal Server Error. Trackback is above.")
|
|
more="""<p>This is an internal error and not something you caused
|
|
or can fix. Please report the error on the <a
|
|
href="https://github.com/jvasile/Plinth/issues">bug tracker</a> so
|
|
we can fix it.</p>"""
|
|
return error_page(status, message, "<p>%s</p><pre>%s</pre>" % (more, "\n".join(traceback.split("\n"))))
|
|
|
|
class Root(plugin_mount.PagePlugin):
|
|
@cherrypy.expose
|
|
def index(self):
|
|
## TODO: firstboot hijacking root should probably be in the firstboot module with a hook in plinth.py
|
|
with sqlite_db(cfg.store_file, table="firstboot") as db:
|
|
if not 'state' in db:
|
|
raise cherrypy.InternalRedirect('firstboot')
|
|
elif db['state'] < 5:
|
|
cfg.log("First Boot state = %d" % db['state'])
|
|
raise cherrypy.InternalRedirect('firstboot/state%d' % db['state'])
|
|
if cherrypy.session.get(cfg.session_key, None):
|
|
raise cherrypy.InternalRedirect('router')
|
|
else:
|
|
raise cherrypy.InternalRedirect('help/about')
|
|
|
|
def load_modules():
|
|
"""Import all the symlinked .py files in the modules directory and
|
|
all the .py files in directories linked in the modules directory
|
|
(but don't dive deeper than that). Also, ignore the installed
|
|
directory."""
|
|
for name in os.listdir("modules"):
|
|
if name.endswith(".py") and not name.startswith('.'):
|
|
cfg.log.info("importing modules/%s" % name)
|
|
try:
|
|
__import__("modules.%s" % (name[:-3]))
|
|
except ImportError, e:
|
|
cfg.log.error(_("Couldn't import modules/%s: %s") % (name, e))
|
|
else:
|
|
cfg.log("skipping %s" % name)
|
|
|
|
def parse_arguments():
|
|
parser = argparse.ArgumentParser(description='Plinth web interface for the FreedomBox.')
|
|
parser.add_argument('--pidfile',
|
|
help='specify a file in which the server may write its pid')
|
|
# FIXME make this work with basehref for static files.
|
|
parser.add_argument('--server_dir',
|
|
help='specify where to host the server.')
|
|
|
|
args=parser.parse_args()
|
|
set_config(args, "pidfile", "plinth.pid")
|
|
set_config(args, "server_dir", "/")
|
|
|
|
return cfg
|
|
|
|
def set_config(args, element, default):
|
|
"""Sets *cfg* elements based on *args* values, or uses a reasonable default.
|
|
|
|
- If values are passed in from *args*, use those.
|
|
- If values are read from the config file, use those.
|
|
- If no values have been given, use default.
|
|
|
|
"""
|
|
try:
|
|
# cfg.(element) = args.(element)
|
|
setattr(cfg, element, getattr(args, element))
|
|
except AttributeError:
|
|
# if it fails, we didn't receive that argument.
|
|
try:
|
|
# if not cfg.(element): cfg.(element) = default
|
|
if not getattr(cfg, element):
|
|
setattr(cfg, element, default)
|
|
except AttributeError:
|
|
# it wasn't in the config file, but set the default anyway.
|
|
setattr(cfg, element, default)
|
|
|
|
def setup():
|
|
cfg = parse_arguments()
|
|
|
|
try:
|
|
if cfg.pidfile:
|
|
from cherrypy.process.plugins import PIDFile
|
|
PIDFile(cherrypy.engine, cfg.pidfile).subscribe()
|
|
except AttributeError:
|
|
pass
|
|
|
|
os.chdir(cfg.python_root)
|
|
cherrypy.config.update({'error_page.404': error_page_404})
|
|
cherrypy.config.update({'error_page.500': error_page_500})
|
|
cfg.log = Logger()
|
|
load_modules()
|
|
cfg.html_root = Root()
|
|
cfg.users = plugin_mount.UserStoreModule.get_plugins()[0]
|
|
cfg.page_plugins = plugin_mount.PagePlugin.get_plugins()
|
|
cfg.log("Loaded %d page plugins" % len(cfg.page_plugins))
|
|
cfg.forms = plugin_mount.FormPlugin.get_plugins()
|
|
|
|
# Add an extra server
|
|
server = _cpserver.Server()
|
|
server.socket_host = '127.0.0.1'
|
|
server.socket_port = 52854
|
|
server.subscribe()
|
|
|
|
# Configure default server
|
|
cherrypy.config.update(
|
|
{'server.socket_host': cfg.host,
|
|
'server.socket_port': cfg.port,
|
|
'server.thread_pool':10,
|
|
'tools.staticdir.root': cfg.file_root,
|
|
'tools.sessions.on':True,
|
|
'tools.auth.on':True,
|
|
'tools.sessions.storage_type':"file",
|
|
'tools.sessions.timeout':90,
|
|
'tools.sessions.storage_path':"%s/cherrypy_sessions" % cfg.data_dir,})
|
|
|
|
config = {
|
|
'/': {'tools.staticdir.root': '%s/static' % cfg.file_root,
|
|
'tools.proxy.on': True,},
|
|
'/static': {'tools.staticdir.on': True,
|
|
'tools.staticdir.dir': "."},
|
|
'/favicon.ico':{'tools.staticfile.on': True,
|
|
'tools.staticfile.filename':
|
|
"%s/static/theme/favicon.ico" % cfg.file_root}}
|
|
cherrypy.tree.mount(cfg.html_root, cfg.server_dir, config=config)
|
|
cherrypy.engine.signal_handler.subscribe()
|
|
|
|
def main():
|
|
setup()
|
|
|
|
cherrypy.engine.start()
|
|
cherrypy.engine.block()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|