Package conduit :: Module ModuleWrapper
[hide private]

Source Code for Module conduit.ModuleWrapper

  1  import traceback 
  2  import logging 
  3  log = logging.getLogger("ModuleWrapper") 
  4   
  5  COMPULSORY_ATTRIBUTES = ( 
  6      "type", 
  7  ) 
  8   
9 -class ModuleWrapper:
10 """ 11 A generic wrapper for any dynamically loaded module. Wraps the complexity 12 of a stored L{conduit.DataProvider.DataProvider} behind additional 13 descriptive fields like name and description. Useful for classification 14 and searching for moldules of certain types, etc. 15 """ 16
17 - def __init__ (self, klass, initargs, category):
18 """ 19 Initializes the ModuleWrapper with an uninstantiated class 20 21 @param klass: The klass this wrapper wraps 22 @param initargs: The arguments used to instantiate klass 23 @param category: The category 24 25 @ivar name: The name of the contained module 26 @ivar description: The description of the contained module 27 @ivar icon_name: The name of an icon representing the contained module 28 @ivar module_type: The type of the contained module (e.g. sink, source) 29 @ivar category: The category of the contained module 30 @ivar in_type: The name of the datatype that the module accepts (put()) 31 @ivar out_type: The name of the datatype that the module produces (get()) 32 @ivar classname: The classname used to instanciate another module instance 33 @ivar initargs: The arguments passed to the new module if created 34 @ivar module: An instance of the described module 35 """ 36 if type(initargs) != tuple: 37 raise Exception("Module init args must be a tuple") 38 39 self.klass = klass 40 self.initargs = initargs 41 self.category = category 42 43 #extract class parameters 44 if klass: 45 self.name = getattr(klass, "_name_", "") 46 self.description = getattr(klass, "_description_", "") 47 self.icon_name = getattr(klass, "_icon_", "") 48 self.module_type = getattr(klass, "_module_type_", "") 49 self.in_type = getattr(klass, "_in_type_", "") 50 self.out_type = getattr(klass, "_out_type_", "") 51 self.configurable = getattr(klass, "_configurable_", False) 52 self.classname = klass.__name__ 53 else: 54 self.name = "Unknown" 55 self.description = "Unknown" 56 self.icon_name = "image-missing" 57 self.module_type = "" 58 self.in_type = "" 59 self.out_type = "" 60 self.classname = "" 61 self.configurable = False 62 63 self.dndKey = None 64 self.enabled = True 65 self.module = None 66 self.icon_path = "" 67 self.icon = {} 68 self.descriptiveIcon = None
69
70 - def __str__(self):
71 return "Wrapper: %s %s (UID: %s)" % (self.get_name(), self.module_type, self.get_UID())
72 73 # Keys serve two goals in conduit, nominally related to dataprovider factories. 74 # and instantiating dataproviders 75 # 76 # 1. Keys act as a match pattern for instantiating the same class multiple times 77 # with different configurations, such as when the user has multiple iPods connected. 78 # This matching is tested when conduit restores saved dataproviders, if the key 79 # is not known to Conduit, then a pending dataprovider is inserted in its place 80 # 81 # 2. They are also serve a way to show the same class in multiple categories
82 - def get_dnd_key(self):
83 if self.dndKey: 84 return self.dndKey 85 return self.get_key()
86
87 - def set_dnd_key(self, dndKey):
88 self.dndKey = dndKey
89
90 - def get_key(self):
91 """ 92 Returns a string in the form of classname:initarg0:initarg1:... 93 94 I suppose I could have used the builtin __getinitargs__ call used with 95 pickle but requires less implementation detail on the part of the DP 96 """ 97 if len(self.initargs) > 0: 98 return self.classname + ":" + ":".join(self.initargs) 99 else: 100 return self.classname
101
102 - def get_name(self):
103 """ 104 @returns: The dataproviders user readable name 105 """ 106 if self.module == None: 107 return self.name 108 else: 109 return self.module.get_name()
110
111 - def set_name(self, name):
112 """ 113 Sets the dataproviders user readable name 114 """ 115 self.name = name
116
117 - def get_UID(self):
118 """ 119 Returs a unique identifier for the module and its contained 120 dataprovider. 121 @rtype: C{string} 122 """ 123 if self.module == None: 124 muid = "None" 125 else: 126 muid = self.module.get_UID() 127 return "%s-%s" % (self.get_key(), muid)
128
129 - def get_input_type(self):
130 """ 131 Returns the in_type for the module. If the module has not yet been 132 initialised then its in_type is derived from its class attributes. 133 If it has been initialised then it can supply its own in_type 134 """ 135 if self.module == None: 136 return self.in_type 137 else: 138 return self.module.get_input_type()
139
140 - def get_output_type(self):
141 """ 142 Returns the out_type for the module. See get_input_type() 143 """ 144 if self.module == None: 145 return self.out_type 146 else: 147 return self.module.get_output_type()
148 149
150 - def get_icon(self, size=16):
151 """ 152 Returns the icon for the module contained in this wrapper. 153 In the case of a sink or source this is easy as the module 154 contains the icon. 155 156 Wrappers derived from this class (such as the CategoryWrapper) 157 may override this function 158 """ 159 import gtk 160 if not self.icon.has_key(size) or self.icon[size] is None: 161 if self.module_type in ["source", "sink", "twoway", "category"]: 162 try: 163 info = gtk.icon_theme_get_default().lookup_icon(self.icon_name, size, 0) 164 self.icon[size] = info.load_icon() 165 self.icon_path = info.get_filename() 166 except: 167 self.icon[size] = None 168 log.warn("Could not load icon %s for %s" % (self.icon_name, self.name)) 169 #Last resort: Try the non icon-naming-spec compliant icon 170 self.icon_name = "conduit" 171 info = gtk.icon_theme_get_default().lookup_icon(self.icon_name, size, 0) 172 self.icon[size] = info.load_icon() 173 self.icon_path = info.get_filename() 174 175 return self.icon[size]
176
177 - def get_descriptive_icon(self):
178 """ 179 The descriptive icon is two icons composited side by side. On the left 180 is the dataprovider icon, on the right an arrow indicating its type 181 size of each icon 182 """ 183 import gtk 184 185 # _____ 186 # | |___ 187 # | i | a | 188 # |_____|___| 189 isize = 24 190 asize = 16 191 bwidth = isize + asize 192 bheight = max(isize, asize) 193 194 if self.descriptiveIcon is None: 195 if self.module_type in ["source", "sink", "twoway"]: 196 try: 197 icon = self.get_icon(isize) 198 arrowName = "conduit-"+self.module_type 199 arrow = gtk.icon_theme_get_default().load_icon(arrowName, asize, 0) 200 201 #Composite the arrow to the right of the icon 202 dest = gtk.gdk.Pixbuf( 203 colorspace=gtk.gdk.COLORSPACE_RGB, 204 has_alpha=True, 205 bits_per_sample=8, 206 width=bwidth, 207 height=bheight 208 ) 209 dest.fill(0) 210 211 #Composite the icon on the left 212 icon.composite( 213 dest=dest, 214 dest_x=0, #right of icon 215 dest_y=0, #at the top 216 dest_width=isize, #use whole arrow 1:1 217 dest_height=isize, #ditto 218 offset_x=0, 219 offset_y=0, 220 scale_x=1, 221 scale_y=1, 222 interp_type=gtk.gdk.INTERP_NEAREST, 223 overall_alpha=255 224 ) 225 #Arrow on the right 226 arrow.composite( 227 dest=dest, 228 dest_x=isize, #right of icon 229 dest_y=isize-asize, #at the bottom 230 dest_width=asize, #use whole arrow 1:1 231 dest_height=asize, #ditto 232 offset_x=isize, #move self over to the right 233 offset_y=isize-asize,#at the bottom 234 scale_x=1, 235 scale_y=1, 236 interp_type=gtk.gdk.INTERP_NEAREST, 237 overall_alpha=255 238 ) 239 self.descriptiveIcon = dest 240 except: 241 log.warn("Error getting icon\n%s" % traceback.format_exc()) 242 243 elif self.module_type == "category": 244 self.descriptiveIcon = self.get_icon(isize) 245 246 return self.descriptiveIcon
247
248 - def set_configuration_xml(self, xmltext):
249 self.module.set_configuration_xml(xmltext)
250
251 - def get_configuration_xml(self):
252 return self.module.get_configuration_xml()
253
254 - def configure(self, window):
255 self.module.configure(window)
256
257 - def instantiate_module(self):
258 self.module = self.klass(*self.initargs)
259
260 - def is_pending(self):
261 return self.module == None
262
263 -class PendingDataproviderWrapper(ModuleWrapper):
264 - def __init__(self, key):
265 ModuleWrapper.__init__( 266 self, 267 klass=None, 268 initargs=(), 269 category=None 270 ) 271 self.icon_name="image-loading" 272 self.module_type="twoway" 273 self.classname=key.split(':')[0] 274 self.enabled=False 275 276 self.key = key 277