Skip to content
Browse files

Default options, proper unload / reload

  • Loading branch information...
1 parent 608866e commit a2c32bd98c32819f8194408a866397b657e0a91c @parente committed Dec 10, 2010
Showing with 110 additions and 46 deletions.
  1. +53 −29 handlerbag.py
  2. +2 −2 hbag/admin/__init__.py
  3. +1 −1 hbag/admin/admin.html
  4. +1 −7 hbag/admin/admin.py
  5. +10 −3 hbag/hello.py
  6. +43 −0 hbag/xhrdrop.py
  7. +0 −4 hbag/xhrdrop/__init__.py
View
82 handlerbag.py
@@ -63,7 +63,7 @@ def add_dynamic_handlers(self, host_pattern, host_handlers, pos=0):
spec = tornado.web.URLSpec(pattern, handler, kwargs)
handlers.insert(pos, spec)
- def remove_dynamic_handler(self, host_pattern, url):
+ def remove_dynamic_handler(self, host_pattern, url_pattern):
handlers = None
for regex, h in self.handlers:
if regex.pattern == host_pattern:
@@ -91,13 +91,44 @@ def refresh_handlers_in_db(self):
for d in g if not d.endswith('__init__.py')))
known = set(self.db.keys())
- new = avail - known
- for name in new:
- self.db[name] = {'enabled' : False, 'options' : {}}
+ for name in avail:
+ info = self.db.get(name, {})
+ mod = self.load_module(name)
+ opts = mod.get_default_options(self)
+ try:
+ desc = mod.__doc__.split('\n')[0]
+ except (AttributeError, IndexError):
+ desc = ''
+ enabled = info.get('enabled', False)
+
+ if (info is None or
+ desc != info.get('description') or
+ set(opts) ^ set(info.get('options', []))):
+ # put new metadata into the db
+ self.db[name] = {
+ 'enabled' : enabled,
+ 'description' : desc,
+ 'options' : opts
+ }
+
old = known - avail
for name in old:
del self.db[name]
return self.db
+
+ def load_module(self, name):
+ # check if module already loaded
+ try:
+ mod = self.modules[name]
+ except KeyError:
+ # load the module for the first time
+ mod = __import__('hbag.'+name, fromlist=[name])
+ self.modules[name] = mod
+ else:
+ # reload the module if loaded
+ mod = reload(mod)
+ self.modules[name] = mod
+ return mod
def set_handler_status(self, name, enable):
# not a known handler
@@ -108,34 +139,27 @@ def set_handler_status(self, name, enable):
info = self.db[name]
info['enabled'] = enable
self.db[name] = info
+
+ # unregister existing handlers
+ try:
+ mod = self.modules[name]
+ except KeyError:
+ # nothing to do if never loaded and not enabling
+ if not enable: return
+ else:
+ handlers = mod.get_handler_map(self, options.webroot, **info['options'])
+ for bag in handlers:
+ try:
+ self.remove_dynamic_handler('.*$', bag[0])
+ except ValueError:
+ pass
+ # keep tracking module for later reload
if enable:
- # check if module already loaded
- try:
- mod = self.modules[name]
- except KeyError:
- # load the module for the first time
- mod = __import__('hbag.'+name, fromlist=[name])
- self.modules[name] = mod
- else:
- # reload the module if loaded
- mod = reload(mod)
- self.modules[name] = mod
-
- # register the handlers
- handlers = mod.get_handler_map(options.webroot)
+ # register new handler
+ mod = self.load_module(name)
+ handlers = mod.get_handler_map(self, options.webroot, **info['options'])
self.add_dynamic_handlers('.*$', handlers)
- else:
- # unregister the handlers
- try:
- mod = self.modules[name]
- except KeyError:
- # nothing to do if never loaded
- return
- handlers = mod.get_handler_map(options.webroot)
- for url, cls in handlers:
- self.remove_dynamic_handler('.*$', url)
- # keep tracking module for later reload
if __name__ == '__main__':
define('webroot', default='/', help='absolute root url of all handlers (default: /)')
View
4 hbag/admin/__init__.py
@@ -1,7 +1,7 @@
from admin import AdminHandler
-def get_handler_map(webroot):
+def get_handler_map(app, webroot, **options):
return [(webroot+'admin/?', AdminHandler)]
-def get_handler_opts():
+def get_default_options(app):
return {}
View
2 hbag/admin/admin.html
@@ -42,7 +42,7 @@
{% for key, info in items %}
<p>
<input type="checkbox" id="{{ key }}" {{ 'checked' if info['enabled'] else '' }}/>
- <label for="{{ key }}">{{ escape(key) }}</label>
+ <label for="{{ key }}">{{ escape(key) }} - {{ escape(info['description']) or 'no description' }}</label>
</p>
{% end %}
</fieldset>
View
8 hbag/admin/admin.py
@@ -1,10 +1,4 @@
-'''
-
-
-:requires: Python 2.6, Tornado 1.0
-:copyright: Peter Parente 2010
-:license: BSD
-'''
+'''Simple admin panel for handler config.'''
# tornado
import tornado.web
# std lib
View
13 hbag/hello.py
@@ -1,9 +1,16 @@
+'''Says hello world.'''
# tornado
import tornado.web
class HelloHandler(tornado.web.RequestHandler):
+ def initialize(self, **options):
+ self.options = options
+
def get(self, *args, **kwargs):
- self.write('Hello world!')
+ self.write(self.options['greeting'])
-def get_handler_map(webroot):
- return [(webroot+'hello/?', HelloHandler)]
+def get_handler_map(app, webroot, **options):
+ return [(webroot+'hello/?', HelloHandler, options)]
+
+def get_default_options(app):
+ return {'greeting' : 'Hello world!'}
View
43 hbag/xhrdrop.py
@@ -0,0 +1,43 @@
+'''Cross-domain dropbox with optional GET.'''
+# tornado
+import tornado.web
+# std lib
+import os.path
+import datetime
+import urlparse
+
+class DropHandler(tornado.web.StaticFileHandler):
+ def initialize(self, **options):
+ self.options = options
+
+ def options(self, *args, **kwargs):
+ # allow preflights from all
+ self.set_header('Access-Control-Allow-Origin', '*')
+ self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
+ self.set_header('Access-Control-Max-Age', '0')
+ self.set_header('Access-Control-Allow-Headers', 'Content-Type')
+ self.set_header('Content-Type', 'text/plain')
+
+ def post(self, *args, **kwargs):
+ self.set_header('Access-Control-Allow-Origin', '*')
+ self.set_header('Content-Type', 'text/plain')
+ origin = self.request.headers.get('Origin')
+ urlObj = urlparse.urlsplit(origin)
+ dt = datetime.datetime.now().isoformat()
+ fn = '%s-%s.txt' % (urlObj.netloc.replace(':', '-'), dt)
+ with file(os.path.join(self.options['path'], fn), 'w') as f:
+ f.write(self.request.body)
+ self.write(fn)
+
+ def get(self, *args, **kwargs):
+ if not self.options['get_enabled']:
+ raise tornado.web.HTTPError(405)
+ super(DropHandler, self).get(*args, **kwargs)
+
+def get_handler_map(app, webroot, **options):
+ tmp = {'path' : os.path.join(app.bagPath, 'xhrdrop')}
+ tmp.update(options)
+ return [(webroot+'xhrdrop//?(.*)', DropHandler, tmp)]
+
+def get_default_options(app):
+ return {'get_enabled' : False}
View
4 hbag/xhrdrop/__init__.py
@@ -1,4 +0,0 @@
-from xhrdrop import DropHandler
-
-def get_handler_map(webroot):
- return [(webroot+'xhrdrop', DropHandler)]

0 comments on commit a2c32bd

Please sign in to comment.
Something went wrong with that request. Please try again.