main: Add action loading and running infrastructure.
[matthijs/projects/backupninja.git] / src / lib / backupninja / handlers / __init__.py
1 #
2 #    Backupninja python reimplementation, based on original backupninja program
3 #    by riseup.net.
4 #    Copyright (C) 2010  Matthijs Kooijman <matthijs@stdin.nl>
5 #
6 #    This program is free software; you can redistribute it and/or modify
7 #    it under the terms of the GNU General Public License as published by
8 #    the Free Software Foundation; either version 2 of the License, or
9 #    (at your option) any later version.
10 #
11 #    This program is distributed in the hope that it will be useful,
12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #    GNU General Public License for more details.
15 #
16 #    You should have received a copy of the GNU General Public License along
17 #    with this program; if not, write to the Free Software Foundation, Inc.,
18 #    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 """ Handler superclass with common functionality """
21
22 import sys
23 import logging as log
24
25 class Handler(object):
26     def __init__(self, conf):
27         self.conf = conf
28
29     def run(self):
30         """
31         Run this handler for a single target. Override this method
32         in a subclass
33         """
34         pass
35
36     def finish(self):
37         """
38         Called when all targets have been processed. Can be overridden
39         in a subclass.
40         """
41         pass
42
43 def create_handler(ty, conf):
44     """
45     Create a new (subclass of) Handler object for an action with the
46     given type. conf is the configuration to pass to the handler.
47
48     If the handler cannot be loaded, it is logged and None is returned
49     (but any exceptions raised by the handler code itself are not
50     handled).
51     """
52     modname = 'backupninja.handlers.%s' % ty
53     # Load the handler if it is not loaded yet
54     if not modname in sys.modules:
55         try:
56             __import__(modname, globals(), locals(), [])
57         except ImportError, e:
58             log.error('Cannot load action handler for "%s": %s'
59                      , ty, e)
60             return None
61     # Get the module from the module table
62     module = sys.modules[modname]
63
64     # Check that the module has a "handler" top level function, which
65     # should create a new Handler object.
66     if not hasattr(module, 'handler'):
67         log.error('Action handler for "%s" (in "%s) is not valid: it '
68                   'does not have a "handler" top level function.'
69                  , ty, module.__file__)
70         return None
71
72     # Call the "handler" function to create the actual handler
73     handler = module.handler(conf)
74    
75     # Check if the handler returned is really a subclass of Handler
76     if not isinstance(handler, Handler):
77         log.error('Action handler for "%s" (in "%s) is not valid: it '
78                   'does not return a subclass of backupninja.handlers.Handler.'
79                  , ty, module.__file__)
80         return None
81     return handler