[kupfer: 52/67] Call initialize_plugin at plugin load. Automatically unregister



commit 1e6eaddaa434a1a99be8f6e87376fc7d39ed22cf
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Sat Mar 19 01:53:39 2011 +0100

    Call initialize_plugin at plugin load. Automatically unregister
    
    Add the symbol ``initialize_plugin`` that is called when a plugin is
    loaded. The plugin's settings are available because
    __kupfer_settings__ is initialized before initialize_plugin is called.
    
    Automatically unregister alternatives when a plugin is unloaded.

 kupfer/core/plugins.py         |   25 +++++++++++++++++++++----
 kupfer/plugin/core/__init__.py |    7 +++++--
 kupfer/plugin_support.py       |   19 ++++++++++++-------
 3 files changed, 38 insertions(+), 13 deletions(-)
---
diff --git a/kupfer/core/plugins.py b/kupfer/core/plugins.py
index 2ec6ff8..e6cd508 100644
--- a/kupfer/core/plugins.py
+++ b/kupfer/core/plugins.py
@@ -10,8 +10,9 @@ sources_attribute = "__kupfer_sources__"
 text_sources_attribute = "__kupfer_text_sources__"
 content_decorators_attribute = "__kupfer_contents__"
 action_decorators_attribute = "__kupfer_actions__"
-settings_attribute = "__kupfer_settings__"
 action_generators_attribute = "__kupfer_action_generators__"
+settings_attribute = "__kupfer_settings__"
+initialize_attribute = "initialize_plugin"
 
 info_attributes = [
 		"__kupfer_name__",
@@ -103,6 +104,7 @@ def get_plugin_desc():
 	return "\n".join(desc)
 
 _imported_plugins = {}
+_plugin_hooks = {}
 
 def _truncate_code(code, find_attributes):
 	"Truncate @code where all of @find_attributes have been stored."
@@ -368,14 +370,24 @@ def initialize_plugin(plugin_name):
 	"""
 	_load_icons(plugin_name)
 	settings_dict = get_plugin_attribute(plugin_name, settings_attribute)
-	if not settings_dict:
-		return
-	settings_dict.initialize(plugin_name)
+	if settings_dict:
+		settings_dict.initialize(plugin_name)
+	initialize = get_plugin_attribute(plugin_name, initialize_attribute)
+	if initialize:
+		initialize(plugin_name)
 
 def unimport_plugin(plugin_name):
 	"""Remove @plugin_name from the plugin list and dereference its
 	python modules.
 	"""
+	# Run unimport hooks
+	if plugin_name in _plugin_hooks:
+		try:
+			for callback, args in reversed(_plugin_hooks[plugin_name]):
+				callback(*args)
+		except:
+			prety.print_exc(__name__)
+		del _plugin_hooks[plugin_name]
 	del _imported_plugins[plugin_name]
 	plugin_module_name = ".".join(_plugin_path(plugin_name))
 	pretty.print_debug(__name__, "Dereferencing module", plugin_module_name)
@@ -386,6 +398,11 @@ def unimport_plugin(plugin_name):
 			pretty.print_debug(__name__, "Dereferencing module", mod)
 			sys.modules.pop(mod)
 
+def register_plugin_unimport_hook(plugin_name, callback, *args):
+	if plugin_name not in _imported_plugins:
+		raise ValueError("No such plugin %s" % plugin_name)
+	_plugin_hooks.setdefault(plugin_name, []).append((callback, args))
+
 def get_plugin_error(plugin_name):
 	"""
 	Return None if plugin is loaded without error, else
diff --git a/kupfer/plugin/core/__init__.py b/kupfer/plugin/core/__init__.py
index bc8a951..611575b 100644
--- a/kupfer/plugin/core/__init__.py
+++ b/kupfer/plugin/core/__init__.py
@@ -41,8 +41,7 @@ def register_subplugin(module):
 		globals()[attr] += object_names
 		globals().update((sym, getattr(module, sym)) for sym in object_names)
 
-from kupfer.plugin.core import (contents, selection, text, internal, commands,
-                                terminals)
+from kupfer.plugin.core import contents, selection, text, internal, commands
 
 register_subplugin(contents)
 register_subplugin(selection)
@@ -54,6 +53,10 @@ if _is_debug():
 	from kupfer.plugin.core import debug
 	register_subplugin(debug)
 
+def initialize_plugin(x):
+	from kupfer.plugin.core import terminals
+
+
 class _MultiSource (MultiSource):
 	def is_dynamic(self):
 		return False
diff --git a/kupfer/plugin_support.py b/kupfer/plugin_support.py
index a6ed9e9..db4a929 100644
--- a/kupfer/plugin_support.py
+++ b/kupfer/plugin_support.py
@@ -11,6 +11,7 @@ except ImportError:
 from kupfer import pretty
 from kupfer import config
 from kupfer.core import settings
+from kupfer.core import plugins
 from kupfer import terminal
 
 __all__ = [
@@ -247,25 +248,29 @@ def register_alternative(caller, category_key, id_, **kwargs):
 		return
 	_alternatives[category_key][id_] = kwargs
 	pretty.print_debug(__name__,
-		"Registered alternative %s.%s from %s" % (category_key, id_, caller))
+		"Registered alternative %s: %s" % (category_key, id_))
 	setctl = settings.GetSettingsController()
 	setctl._update_alternatives(category_key, _alternatives[category_key],
 	                            alt["filter"])
+
+	# register the alternative to be unloaded
+	plugin_id = ".".join(caller.split(".")[2:])
+	if plugin_id and not plugin_id.startswith("core."):
+		plugins.register_plugin_unimport_hook(plugin_id,
+				_unregister_alternative, caller, category_key, id_)
 	return True
 
-def unregister_alternative(caller, category_key, id_):
+def _unregister_alternative(caller, category_key, full_id_):
 	"""
 	Remove the alternative for category @category_key
+	(this is done automatically at plugin unload)
 	"""
-	caller = str(caller)
-	category_key = str(category_key)
-	id_ = str(id_)
 	if category_key not in _available_alternatives:
 		_plugin_configuration_error(caller,
 				"Category '%s' does not exist" % category_key)
 		return
 	alt = _available_alternatives[category_key]
-	id_ = caller + "." + id_
+	id_ = full_id_
 	try:
 		del _alternatives[category_key][id_]
 	except KeyError:
@@ -273,7 +278,7 @@ def unregister_alternative(caller, category_key, id_):
 				"Alternative '%s' does not exist" % (id_, ))
 		return
 	pretty.print_debug(__name__,
-		"Unregistered alternative %s.%s from %s" % (category_key, id_, caller))
+		"Unregistered alternative %s: %s" % (category_key, id_))
 	setctl = settings.GetSettingsController()
 	setctl._update_alternatives(category_key, _alternatives[category_key],
 	                            alt["filter"])



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]