42 def __init__(self, parent = None, doLoadPlugins = True, develPlugin = None): |
42 def __init__(self, parent = None, doLoadPlugins = True, develPlugin = None): |
43 """ |
43 """ |
44 Constructor |
44 Constructor |
45 |
45 |
46 The Plugin Manager deals with three different plugin directories. |
46 The Plugin Manager deals with three different plugin directories. |
47 The first is the one, that is part of eric4 (eric4/Plugins). The |
47 The first is the one, that is part of eric5 (eric5/Plugins). The |
48 second one is the global plugin directory called 'eric4plugins', |
48 second one is the global plugin directory called 'eric5plugins', |
49 which is located inside the site-packages directory. The last one |
49 which is located inside the site-packages directory. The last one |
50 is the user plugin directory located inside the .eric4 directory |
50 is the user plugin directory located inside the .eric5 directory |
51 of the users home directory. |
51 of the users home directory. |
52 |
52 |
53 @param parent reference to the parent object (QObject) |
53 @param parent reference to the parent object (QObject) |
54 @keyparam doLoadPlugins flag indicating, that plugins should |
54 @keyparam doLoadPlugins flag indicating, that plugins should |
55 be loaded (boolean) |
55 be loaded (boolean) |
63 self.__develPluginName = None |
63 self.__develPluginName = None |
64 |
64 |
65 self.__inactivePluginsKey = "PluginManager/InactivePlugins" |
65 self.__inactivePluginsKey = "PluginManager/InactivePlugins" |
66 |
66 |
67 self.pluginDirs = { |
67 self.pluginDirs = { |
68 "eric4" : os.path.join(getConfig('ericDir'), "Plugins"), |
68 "eric5" : os.path.join(getConfig('ericDir'), "Plugins"), |
69 "global" : os.path.join(Utilities.getPythonModulesDirectory(), |
69 "global" : os.path.join(Utilities.getPythonModulesDirectory(), |
70 "eric4plugins"), |
70 "eric5plugins"), |
71 "user" : os.path.join(Utilities.getConfigDir(), "eric4plugins"), |
71 "user" : os.path.join(Utilities.getConfigDir(), "eric5plugins"), |
72 } |
72 } |
73 self.__priorityOrder = ["eric4", "global", "user"] |
73 self.__priorityOrder = ["eric5", "global", "user"] |
74 |
74 |
75 self.__defaultDownloadDir = os.path.join(Utilities.getConfigDir(), "Downloads") |
75 self.__defaultDownloadDir = os.path.join(Utilities.getConfigDir(), "Downloads") |
76 |
76 |
77 self.__activePlugins = {} |
77 self.__activePlugins = {} |
78 self.__inactivePlugins = {} |
78 self.__inactivePlugins = {} |
175 del self.pluginDirs["global"] |
175 del self.pluginDirs["global"] |
176 else: |
176 else: |
177 del self.pluginDirs["user"] |
177 del self.pluginDirs["user"] |
178 del self.pluginDirs["global"] |
178 del self.pluginDirs["global"] |
179 |
179 |
180 if not os.path.exists(self.pluginDirs["eric4"]): |
180 if not os.path.exists(self.pluginDirs["eric5"]): |
181 return (False, |
181 return (False, |
182 self.trUtf8("The internal plugin directory <b>{0}</b> does not exits.")\ |
182 self.trUtf8("The internal plugin directory <b>{0}</b> does not exits.")\ |
183 .format(self.pluginDirs["eric4"])) |
183 .format(self.pluginDirs["eric5"])) |
184 |
184 |
185 return (True, "") |
185 return (True, "") |
186 |
186 |
187 def __pluginModulesExist(self): |
187 def __pluginModulesExist(self): |
188 """ |
188 """ |
191 @return flag indicating the availability of plugins (boolean) |
191 @return flag indicating the availability of plugins (boolean) |
192 """ |
192 """ |
193 if self.__develPluginFile and not os.path.exists(self.__develPluginFile): |
193 if self.__develPluginFile and not os.path.exists(self.__develPluginFile): |
194 return False |
194 return False |
195 |
195 |
196 self.__foundCoreModules = self.getPluginModules(self.pluginDirs["eric4"]) |
196 self.__foundCoreModules = self.getPluginModules(self.pluginDirs["eric5"]) |
197 if "global" in self.pluginDirs: |
197 if "global" in self.pluginDirs: |
198 self.__foundGlobalModules = \ |
198 self.__foundGlobalModules = \ |
199 self.getPluginModules(self.pluginDirs["global"]) |
199 self.getPluginModules(self.pluginDirs["global"]) |
200 if "user" in self.pluginDirs: |
200 if "user" in self.pluginDirs: |
201 self.__foundUserModules = \ |
201 self.__foundUserModules = \ |
256 for pluginName in self.__foundCoreModules: |
256 for pluginName in self.__foundCoreModules: |
257 # global and user plugins have priority |
257 # global and user plugins have priority |
258 if pluginName not in self.__foundGlobalModules and \ |
258 if pluginName not in self.__foundGlobalModules and \ |
259 pluginName not in self.__foundUserModules and \ |
259 pluginName not in self.__foundUserModules and \ |
260 pluginName != develPluginName: |
260 pluginName != develPluginName: |
261 self.loadPlugin(pluginName, self.pluginDirs["eric4"]) |
261 self.loadPlugin(pluginName, self.pluginDirs["eric5"]) |
262 |
262 |
263 for pluginName in self.__foundGlobalModules: |
263 for pluginName in self.__foundGlobalModules: |
264 # user plugins have priority |
264 # user plugins have priority |
265 if pluginName not in self.__foundUserModules and \ |
265 if pluginName not in self.__foundUserModules and \ |
266 pluginName != develPluginName: |
266 pluginName != develPluginName: |
305 "and/or 'pluginTypename' attributes.") |
305 "and/or 'pluginTypename' attributes.") |
306 self.__failedModules[name] = module |
306 self.__failedModules[name] = module |
307 raise PluginLoadError(name) |
307 raise PluginLoadError(name) |
308 else: |
308 else: |
309 self.__onDemandInactiveModules[name] = module |
309 self.__onDemandInactiveModules[name] = module |
310 module.eric4PluginModuleName = name |
310 module.eric5PluginModuleName = name |
311 module.eric4PluginModuleFilename = fname |
311 module.eric5PluginModuleFilename = fname |
312 self.__modulesCount += 1 |
312 self.__modulesCount += 1 |
313 if reload_: |
313 if reload_: |
314 reload(module) |
314 reload(module) |
315 except PluginLoadError: |
315 except PluginLoadError: |
316 print("Error loading plugin module:", name) |
316 print("Error loading plugin module:", name) |
330 @param directory name of the plugin directory (string) |
330 @param directory name of the plugin directory (string) |
331 @return flag indicating success (boolean) |
331 @return flag indicating success (boolean) |
332 """ |
332 """ |
333 fname = "%s.py" % os.path.join(directory, name) |
333 fname = "%s.py" % os.path.join(directory, name) |
334 if name in self.__onDemandActiveModules and \ |
334 if name in self.__onDemandActiveModules and \ |
335 self.__onDemandActiveModules[name].eric4PluginModuleFilename == fname: |
335 self.__onDemandActiveModules[name].eric5PluginModuleFilename == fname: |
336 # cannot unload an ondemand plugin, that is in use |
336 # cannot unload an ondemand plugin, that is in use |
337 return False |
337 return False |
338 |
338 |
339 if name in self.__activeModules and \ |
339 if name in self.__activeModules and \ |
340 self.__activeModules[name].eric4PluginModuleFilename == fname: |
340 self.__activeModules[name].eric5PluginModuleFilename == fname: |
341 self.deactivatePlugin(name) |
341 self.deactivatePlugin(name) |
342 |
342 |
343 if name in self.__inactiveModules and \ |
343 if name in self.__inactiveModules and \ |
344 self.__inactiveModules[name].eric4PluginModuleFilename == fname: |
344 self.__inactiveModules[name].eric5PluginModuleFilename == fname: |
345 try: |
345 try: |
346 del self.__inactivePlugins[name] |
346 del self.__inactivePlugins[name] |
347 except KeyError: |
347 except KeyError: |
348 pass |
348 pass |
349 del self.__inactiveModules[name] |
349 del self.__inactiveModules[name] |
350 elif name in self.__onDemandInactiveModules and \ |
350 elif name in self.__onDemandInactiveModules and \ |
351 self.__onDemandInactiveModules[name].eric4PluginModuleFilename == fname: |
351 self.__onDemandInactiveModules[name].eric5PluginModuleFilename == fname: |
352 try: |
352 try: |
353 del self.__onDemandInactivePlugins[name] |
353 del self.__onDemandInactivePlugins[name] |
354 except KeyError: |
354 except KeyError: |
355 pass |
355 pass |
356 del self.__onDemandInactiveModules[name] |
356 del self.__onDemandInactiveModules[name] |
400 module = self.__onDemandInactiveModules[name] |
400 module = self.__onDemandInactiveModules[name] |
401 except KeyError: |
401 except KeyError: |
402 return None |
402 return None |
403 |
403 |
404 if not self.__canActivatePlugin(module): |
404 if not self.__canActivatePlugin(module): |
405 raise PluginActivationError(module.eric4PluginModuleName) |
405 raise PluginActivationError(module.eric5PluginModuleName) |
406 version = getattr(module, "version") |
406 version = getattr(module, "version") |
407 className = getattr(module, "className") |
407 className = getattr(module, "className") |
408 pluginClass = getattr(module, className) |
408 pluginClass = getattr(module, className) |
409 pluginObject = None |
409 pluginObject = None |
410 if name not in self.__onDemandInactivePlugins: |
410 if name not in self.__onDemandInactivePlugins: |
411 pluginObject = pluginClass(self.__ui) |
411 pluginObject = pluginClass(self.__ui) |
412 pluginObject.eric4PluginModule = module |
412 pluginObject.eric5PluginModule = module |
413 pluginObject.eric4PluginName = className |
413 pluginObject.eric5PluginName = className |
414 pluginObject.eric4PluginVersion = version |
414 pluginObject.eric5PluginVersion = version |
415 self.__onDemandInactivePlugins[name] = pluginObject |
415 self.__onDemandInactivePlugins[name] = pluginObject |
416 except PluginActivationError: |
416 except PluginActivationError: |
417 return None |
417 return None |
418 |
418 |
419 def activatePlugins(self): |
419 def activatePlugins(self): |
449 module = self.__inactiveModules[name] |
449 module = self.__inactiveModules[name] |
450 except KeyError: |
450 except KeyError: |
451 return None |
451 return None |
452 |
452 |
453 if not self.__canActivatePlugin(module): |
453 if not self.__canActivatePlugin(module): |
454 raise PluginActivationError(module.eric4PluginModuleName) |
454 raise PluginActivationError(module.eric5PluginModuleName) |
455 version = getattr(module, "version") |
455 version = getattr(module, "version") |
456 className = getattr(module, "className") |
456 className = getattr(module, "className") |
457 pluginClass = getattr(module, className) |
457 pluginClass = getattr(module, className) |
458 pluginObject = None |
458 pluginObject = None |
459 if onDemand and name in self.__onDemandInactivePlugins: |
459 if onDemand and name in self.__onDemandInactivePlugins: |
475 ok = False |
475 ok = False |
476 if not ok: |
476 if not ok: |
477 return None |
477 return None |
478 |
478 |
479 self.emit(SIGNAL("pluginActivated"), name, pluginObject) |
479 self.emit(SIGNAL("pluginActivated"), name, pluginObject) |
480 pluginObject.eric4PluginModule = module |
480 pluginObject.eric5PluginModule = module |
481 pluginObject.eric4PluginName = className |
481 pluginObject.eric5PluginName = className |
482 pluginObject.eric4PluginVersion = version |
482 pluginObject.eric5PluginVersion = version |
483 |
483 |
484 if onDemand: |
484 if onDemand: |
485 self.__onDemandInactiveModules.pop(name) |
485 self.__onDemandInactiveModules.pop(name) |
486 try: |
486 try: |
487 self.__onDemandInactivePlugins.pop(name) |
487 self.__onDemandInactivePlugins.pop(name) |
509 @return flag indicating, if the module satisfies all requirements |
509 @return flag indicating, if the module satisfies all requirements |
510 for being activated (boolean) |
510 for being activated (boolean) |
511 """ |
511 """ |
512 try: |
512 try: |
513 if not hasattr(module, "version"): |
513 if not hasattr(module, "version"): |
514 raise PluginModuleFormatError(module.eric4PluginModuleName, "version") |
514 raise PluginModuleFormatError(module.eric5PluginModuleName, "version") |
515 if not hasattr(module, "className"): |
515 if not hasattr(module, "className"): |
516 raise PluginModuleFormatError(module.eric4PluginModuleName, "className") |
516 raise PluginModuleFormatError(module.eric5PluginModuleName, "className") |
517 className = getattr(module, "className") |
517 className = getattr(module, "className") |
518 if not hasattr(module, className): |
518 if not hasattr(module, className): |
519 raise PluginModuleFormatError(module.eric4PluginModuleName, className) |
519 raise PluginModuleFormatError(module.eric5PluginModuleName, className) |
520 pluginClass = getattr(module, className) |
520 pluginClass = getattr(module, className) |
521 if not hasattr(pluginClass, "__init__"): |
521 if not hasattr(pluginClass, "__init__"): |
522 raise PluginClassFormatError(module.eric4PluginModuleName, |
522 raise PluginClassFormatError(module.eric5PluginModuleName, |
523 className, "__init__") |
523 className, "__init__") |
524 if not hasattr(pluginClass, "activate"): |
524 if not hasattr(pluginClass, "activate"): |
525 raise PluginClassFormatError(module.eric4PluginModuleName, |
525 raise PluginClassFormatError(module.eric5PluginModuleName, |
526 className, "activate") |
526 className, "activate") |
527 if not hasattr(pluginClass, "deactivate"): |
527 if not hasattr(pluginClass, "deactivate"): |
528 raise PluginClassFormatError(module.eric4PluginModuleName, |
528 raise PluginClassFormatError(module.eric5PluginModuleName, |
529 className, "deactivate") |
529 className, "deactivate") |
530 return True |
530 return True |
531 except PluginModuleFormatError as e: |
531 except PluginModuleFormatError as e: |
532 print(repr(e)) |
532 print(repr(e)) |
533 return False |
533 return False |
688 else: |
688 else: |
689 # should not happen |
689 # should not happen |
690 return None |
690 return None |
691 |
691 |
692 details["moduleName"] = name |
692 details["moduleName"] = name |
693 details["moduleFileName"] = getattr(module, "eric4PluginModuleFilename", "") |
693 details["moduleFileName"] = getattr(module, "eric5PluginModuleFilename", "") |
694 details["pluginName"] = getattr(module, "name", "") |
694 details["pluginName"] = getattr(module, "name", "") |
695 details["version"] = getattr(module, "version", "") |
695 details["version"] = getattr(module, "version", "") |
696 details["author"] = getattr(module, "author", "") |
696 details["author"] = getattr(module, "author", "") |
697 details["description"] = getattr(module, "longDescription", "") |
697 details["description"] = getattr(module, "longDescription", "") |
698 details["autoactivate"] = autoactivate |
698 details["autoactivate"] = autoactivate |