ccb5c8c142ec1b8b9fd0dca30df8d71ed7d8b311
[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 from backupninja import config
26
27 class Handler(object):
28     def __init__(self):
29         # Subclasses should overwrite this with their default config
30         # See backupninja.config.load_config for the structure of this
31         # value.
32         self.default_config = {}
33
34     def run(self, **kwargs):
35         """
36         Run this handler for a single target. Override this method
37         in a subclass
38         """
39         pass
40
41     def finish(self, **kwargs):
42         """
43         Called when all targets have been processed. Can be overridden
44         in a subclass.
45         """
46         pass
47
48     def load_config(self, filename):
49         """
50         Load the configuration for this action from the given filename.
51         """
52         self.conf = config.load_config(filename, self.default_config)
53
54         
55
56 def create_handler(ty):
57     """
58     Create a new (subclass of) Handler object for an action with the
59     given type.
60
61     If the handler cannot be loaded, an exception is thrown.
62     """
63     modname = 'backupninja.handlers.%s' % ty
64     # Load the handler if it is not loaded yet
65     if not modname in sys.modules:
66         log.debug('Loading handler for type "%s"', ty)
67         try:
68             __import__(modname, globals(), locals(), [])
69         except ImportError, e:
70             # Add some extra info, since the default exception does not
71             # show the full module name.
72             raise ImportError('Cannot load module %s: %s' % (modname, e))
73         log.debug('Loaded handler for type "%s" from "%s"', ty, sys.modules[modname].__file__)
74     # Get the module from the module table
75     module = sys.modules[modname]
76
77     # Check that the module has a "handler" top level function, which
78     # should create a new Handler object.
79     if not hasattr(module, 'handler'):
80         raise ImportError('%s is not valid: it '
81                           'does not have a "handler" top level function.' 
82                           % (module.__file__))
83
84     # Call the "handler" function to create the actual handler
85     handler = module.handler()
86    
87     # Check if the handler returned is really a subclass of Handler
88     if not isinstance(handler, Handler):
89         raise TypeError('%s is not valid, %s.handler did not return a '
90                         'subclass of backupninja.handlers.Handler.'
91                         % (module.__file__, modname))
92     return handler