1import logging 2from pyscreenshot import plugins 3import traceback 4 5 6log = logging.getLogger(__name__) 7 8 9class FailedBackendError(Exception): 10 pass 11 12 13class Loader(object): 14 15 def __init__(self): 16 self.plugins = dict() 17 18 self.all_names = [x.name for x in self.plugin_classes()] 19 20 self.changed = True 21 self._force_backend = None 22 self.preference = [] 23 self.default_preference = plugins.default_preference 24 self._backend = None 25 26 def plugin_classes(self): 27 return plugins.BACKENDS 28 29 def set_preference(self, x): 30 self.changed = True 31 self.preference = x 32 33 def force(self, name): 34 log.debug('forcing:' + str(name)) 35 self.changed = True 36 self._force_backend = name 37 38 @property 39 def is_forced(self): 40 return self._force_backend is not None 41 42# @property 43# def loaded_plugins(self): 44# return self.plugins.values() 45 46 def get_valid_plugin_by_name(self, name): 47 if name not in self.plugins: 48 ls = filter(lambda x: x.name == name, self.plugin_classes()) 49 ls = list(ls) 50 if len(ls): 51 try: 52 msg = '' 53 plugin = ls[0]() 54 except Exception: 55 msg = traceback.format_exc() 56 log.debug(msg) 57 plugin = None 58 else: 59 msg = 'unknown backend' 60 plugin = None 61 self.plugins[name] = (plugin, msg) 62 return self.plugins[name] 63 64 def get_valid_plugin_by_list(self, ls): 65 for name in ls: 66 x, _ = self.get_valid_plugin_by_name(name) 67 if x: 68 return x 69 70 def selected(self): 71 if self.changed: 72 if self.is_forced: 73 b, msg = self.get_valid_plugin_by_name(self._force_backend) 74 if not b: 75 raise FailedBackendError( 76 'Forced backend not found, or cannot be loaded:' + self._force_backend + '\n' + msg) 77 else: 78 biglist = self.preference + \ 79 self.default_preference + self.all_names 80 b = self.get_valid_plugin_by_list(biglist) 81 if not b: 82 self.raise_exc() 83 self.changed = False 84 self._backend = b 85 log.debug('selecting plugin:' + self._backend.name) 86 return self._backend 87 88 def raise_exc(self): 89 message = 'Install at least one backend!' 90 raise FailedBackendError(message) 91