Commit 8ad6b30a authored by Laurent Bachelier's avatar Laurent Bachelier

Add support for hooks

The hooks are designed to be very generic: a name, and corresponding callable.
There can be more than one callable for a single name.
The goal is to help plugins extend key parts of ass2m, like the upcoming
cleanup (fsck/gc) command, or the prewrite/postread steps of
storage objets.
parent 9e6c1f4b
......@@ -20,6 +20,7 @@
import os
import re
from collections import defaultdict
from .plugin import Plugin
......@@ -31,6 +32,7 @@ class Butt(object):
def __init__(self, parser=None, router=None):
self.parser = parser
self.router = router
self.hooks = defaultdict(list)
self.load_plugins()
def iter_existing_plugin_names(self):
......
......@@ -35,14 +35,14 @@ class CLI(object):
self.butt = Butt(parser=self.parser)
self.parser.add_argument('-V', '--version', action='version',
version='%(prog)s ' + VERSION + ' ' + COPYRIGHT)
version='%(prog)s ' + VERSION + ' ' + COPYRIGHT)
def main(self, argv):
# TODO use cmd.Cmd to have a REPL application when no command
# is supplied.
storage = Storage.lookup(self.working_dir)
args = self.parser.parse_args(argv[1:])
cmd = args.cmd(storage, self.working_dir)
cmd = args.cmd(storage, self.working_dir, self.butt)
try:
return cmd.run(args)
except KeyboardInterrupt:
......
......@@ -100,9 +100,10 @@ class Command(ConsolePart):
def configure_parser(parser):
return
def __init__(self, storage, working_dir):
def __init__(self, storage, working_dir, butt):
self.storage = storage
self.working_dir = working_dir
self.butt = butt
def run(self, args):
if self.WORKDIR and not self.storage:
......
......@@ -83,3 +83,6 @@ class Plugin(object):
return
router.register_view(*args, **kwargs)
def register_hook(self, name, hook):
self.butt.hooks[name].append(hook)
......@@ -25,7 +25,8 @@ from paste import httpserver
from paste.auth.cookie import AuthCookieSigner, new_secret
from paste.fileapp import FileApp as PasteFileApp
from webob import Request, Response
from webob.exc import HTTPError, HTTPFound, HTTPNotFound, HTTPForbidden, HTTPMethodNotAllowed, HTTPInternalServerError
from webob.exc import HTTPError, HTTPFound, HTTPNotFound, HTTPForbidden, \
HTTPMethodNotAllowed, HTTPInternalServerError
from paste.url import URL
from paste.auth.basic import AuthBasicAuthenticator
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
......@@ -47,8 +48,8 @@ __all__ = ['ViewAction', 'Action', 'Server', 'FileApp']
class Context(object):
SANITIZE_REGEXP = re.compile(r'/[%s+r]+/|\\+|/+' % re.escape(r'/.'))
def __init__(self, router, environ, start_response):
self.router = router
def __init__(self, butt, environ, start_response):
self.router = butt.router
self.storage = Storage.lookup(environ.get("ASS2M_ROOT"))
self._environ = environ
self._start_response = start_response
......@@ -423,7 +424,7 @@ class Server(object):
if self.root:
environ.setdefault("ASS2M_ROOT", self.root)
try:
ctx = Context(self.butt.router, environ, start_response)
ctx = Context(self.butt, environ, start_response)
Dispatcher(ctx).dispatch()
return ctx.respond()
except (HTTPError, WSGIMethodException), e:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment