summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b8c5dbd)
All callables which should handle a command should be maked with the
@handler decorator. This is for the sake of security, so users can't call
arbitrary python code (like a constructor).
# vim: set et sts=4 sw=4 encoding=utf-8 :
from services import *
# vim: set et sts=4 sw=4 encoding=utf-8 :
from services import *
+from dispatcher import handler
def test_func(*args):
print 'func:', args
def test_func(*args):
print 'func:', args
All exceptions raised by the Dispatcher inherits from this one, so you can
easily catch any dispatching exception.
All exceptions raised by the Dispatcher inherits from this one, so you can
easily catch any dispatching exception.
- command - is the command that raised the exception.
+ command - is the command that raised the exception, expressed as a list of
+ paths (or subcommands).
"""
def __init__(self, command):
"""
def __init__(self, command):
self.command = command
def __str__(self):
self.command = command
def __str__(self):
- return repr(self.command)
+ return ' '.join(self.command)
class CommandNotFoundError(Error):
r"""
class CommandNotFoundError(Error):
r"""
+def handler(f):
+ f._dispatcher_handler = True
+ return f
+
+def is_handler(handler):
+ return callable(handler) and hasattr(handler, '_dispatcher_handler') \
+ and handler._dispatcher_handler
+
class Dispatcher:
r"""Dispatcher([routes]) -> Dispatcher instance :: Command dispatcher
class Dispatcher:
r"""Dispatcher([routes]) -> Dispatcher instance :: Command dispatcher
"tree" and call it, or raises a CommandNotFoundError if the command
can't be dispatched.
"""
"tree" and call it, or raises a CommandNotFoundError if the command
can't be dispatched.
"""
route = route.split() # TODO support "" and keyword arguments
if not route:
route = route.split() # TODO support "" and keyword arguments
if not route:
- raise CommandNotFoundError('') # TODO better error reporting
+ raise CommandNotFoundError(command)
+ command.append(route[0])
handler = self.routes.get(route[0], None)
handler = self.routes.get(route[0], None)
+ if handler is None:
+ raise CommandNotFoundError(command)
- while not callable(handler):
- if not route:
- raise CommandNotFoundError('XXX') # TODO better error reporting
+ while not is_handler(handler):
+ if len(route) is 0:
+ raise CommandNotFoundError(command)
+ command.append(route[0])
if not hasattr(handler, route[0]):
if not hasattr(handler, route[0]):
- raise CommandNotFoundError(route[0]) # TODO better error rep.
+ raise CommandNotFoundError(command)
handler = getattr(handler, route[0])
route = route[1:]
handler(*route)
handler = getattr(handler, route[0])
route = route[1:]
handler(*route)
if __name__ == '__main__':
if __name__ == '__main__':
def test_func(*args):
print 'func:', args
class TestClassSubHandler:
def test_func(*args):
print 'func:', args
class TestClassSubHandler:
def subcmd(self, *args):
print 'class.subclass.subcmd:', args
class TestClass:
def subcmd(self, *args):
print 'class.subclass.subcmd:', args
class TestClass:
def cmd1(self, *args):
print 'class.cmd1:', args
def cmd1(self, *args):
print 'class.cmd1:', args
def cmd2(self, *args):
print 'class.cmd2:', args
subclass = TestClassSubHandler()
def cmd2(self, *args):
print 'class.cmd2:', args
subclass = TestClassSubHandler()
except CommandNotFoundError, e:
print 'Not found:', e
try:
except CommandNotFoundError, e:
print 'Not found:', e
try:
- d.dispatch('sucutrule')
+ d.dispatch('sucutrule piquete culete')
except CommandNotFoundError, e:
print 'Not found:', e
try:
except CommandNotFoundError, e:
print 'Not found:', e
try:
- d.dispatch('inst cmd3')
+ d.dispatch('inst cmd3 arg1 arg2 arg3')
except CommandNotFoundError, e:
print 'Not found:', e
except CommandNotFoundError, e:
print 'Not found:', e
import cPickle as pickle
except ImportError:
import pickle
import cPickle as pickle
except ImportError:
import pickle
+try:
+ from dispatcher import handler
+except ImportError:
+ def handler(f): return f # NOP for testing
__ALL__ = ('DhcpHandler',)
__ALL__ = ('DhcpHandler',)
r"Initialize HostHandler object, see class documentation for details."
self.hosts = hosts
r"Initialize HostHandler object, see class documentation for details."
self.hosts = hosts
def add(self, name, ip, mac):
r"add(name, ip, mac) -> None :: Add a host to the hosts list."
# XXX deberia indexar por hostname o por ip? o por mac? :)
def add(self, name, ip, mac):
r"add(name, ip, mac) -> None :: Add a host to the hosts list."
# XXX deberia indexar por hostname o por ip? o por mac? :)
# nombres? Una MAC con muchas IP? una MAC con muchos nombre? Etc...
self.hosts[name] = Host(name, ip, mac)
# nombres? Una MAC con muchas IP? una MAC con muchos nombre? Etc...
self.hosts[name] = Host(name, ip, mac)
def update(self, name, ip=None, mac=None):
r"update(name[, ip[, mac]]) -> None :: Update a host of the hosts list."
if not name in self.hosts:
def update(self, name, ip=None, mac=None):
r"update(name[, ip[, mac]]) -> None :: Update a host of the hosts list."
if not name in self.hosts:
if mac is not None:
self.hosts[name].mac = mac
if mac is not None:
self.hosts[name].mac = mac
def delete(self, name):
r"delete(name) -> None :: Delete a host of the hosts list."
if not name in self.hosts:
raise KeyError('Host not found')
del self.hosts[name]
def delete(self, name):
r"delete(name) -> None :: Delete a host of the hosts list."
if not name in self.hosts:
raise KeyError('Host not found')
del self.hosts[name]
def list(self):
r"""list() -> CSV string :: List all the hostnames.
def list(self):
r"""list() -> CSV string :: List all the hostnames.
"""
return ','.join(self.hosts)
"""
return ','.join(self.hosts)
def show(self):
r"""show() -> CSV string :: List all the complete hosts information.
def show(self):
r"""show() -> CSV string :: List all the complete hosts information.
self._write_config()
self.host = HostHandler(self.hosts)
self._write_config()
self.host = HostHandler(self.hosts)
def set(self, param, value):
r"set(param, value) -> None :: Set a DHCP parameter."
if not param in self.vars:
raise KeyError('Parameter ' + param + ' not found')
self.vars[param] = value
def set(self, param, value):
r"set(param, value) -> None :: Set a DHCP parameter."
if not param in self.vars:
raise KeyError('Parameter ' + param + ' not found')
self.vars[param] = value
def list(self):
r"""list() -> CSV string :: List all the parameter names.
def list(self):
r"""list() -> CSV string :: List all the parameter names.
"""
return ','.join(self.vars)
"""
return ','.join(self.vars)
def show(self):
r"""show() -> CSV string :: List all the parameters (with their values).
def show(self):
r"""show() -> CSV string :: List all the parameters (with their values).
"""
return '\n'.join(('%s,%s' % (k, v) for (k, v) in self.vars.items()))
"""
return '\n'.join(('%s,%s' % (k, v) for (k, v) in self.vars.items()))
def start(self):
r"start() -> None :: Start the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def start(self):
r"start() -> None :: Start the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def stop(self):
r"stop() -> None :: Stop the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def stop(self):
r"stop() -> None :: Stop the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def restart(self):
r"restart() -> None :: Restart the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def restart(self):
r"restart() -> None :: Restart the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def reload(self):
r"reload() -> None :: Reload the configuration of the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def reload(self):
r"reload() -> None :: Reload the configuration of the DHCP service."
#esto seria para poner en una interfaz
#y seria el hook para arrancar el servicio
pass
def commit(self):
r"commit() -> None :: Commit the changes and reload the DHCP service."
#esto seria para poner en una interfaz
def commit(self):
r"commit() -> None :: Commit the changes and reload the DHCP service."
#esto seria para poner en una interfaz
self._write_config()
self.reload()
self._write_config()
self.reload()
def rollback(self):
r"rollback() -> None :: Discard the changes not yet commited."
self._load()
def rollback(self):
r"rollback() -> None :: Discard the changes not yet commited."
self._load()