Extensions: Add on_load() / on_unload() support

This allows extensions to hook into stuff and remove
the hooks when the extension is unloaded.
This commit is contained in:
Thomas Perl 2012-02-21 15:13:18 +01:00
parent 8c19f52b9a
commit 7c35131876
4 changed files with 73 additions and 16 deletions

39
examples/hello_world.py Normal file
View File

@ -0,0 +1,39 @@
# Use a logger for debug output - this will be managed by gPodder
import logging
logger = logging.getLogger(__name__)
# Provide some metadata that will be displayed in the gPodder GUI
__title__ = 'Hello World Extension'
__description__ = 'Explain in one sentence what this extension does.'
__only_for__ = 'gtk, cli, qml'
__author__ = 'Thomas Perl <m@thp.io>'
class gPodderExtension:
# The extension will be instantiated the first time it's used
# You can do some sanity checks here and raise an Exception if
# you want to prevent the extension from being loaded..
def __init__(self, container):
self.container = container
# This function will be called when the extension is enabled or
# loaded. This is when you want to create helper objects or hook
# into various parts of gPodder.
def on_load(self):
logger.info('Extension is being loaded.')
print '='*40
print 'container:', self.container
print 'container.manager:', self.container.manager
print 'container.config:', self.container.config
print 'container.manager.core:', self.container.manager.core
print 'container.manager.core.db:', self.container.manager.core.db
print 'container.manager.core.config:', self.container.manager.core.config
print 'container.manager.core.model:', self.container.manager.core.model
print '='*40
# This function will be called when the extension is disabled or
# when gPodder shuts down. You can use this to destroy/delete any
# objects that you created in on_load().
def on_unload(self):
logger.info('Extension is being unloaded.')

View File

@ -41,8 +41,15 @@ if pynotify is None:
else:
class gPodderExtension(object):
def __init__(self, container):
self.container = container
def on_load(self):
pynotify.init('gPodder')
logger.info('Notification plug-in loaded successfully.')
logger.info('PyNotify initialized.')
def on_unload(self):
logger.info('Uninitializing PyNotify.')
pynotify.uninit()
def on_notification_show(self, title, message):
notify = pynotify.Notification(title, message, gpodder.icon_file)

View File

@ -53,6 +53,9 @@ class Core(object):
self.config.mygpo.device.type = util.detect_device_type()
def shutdown(self):
# Notify all extensions that we are being shut down
gpodder.user_extensions.shutdown()
# Close the database and store outstanding changes
self.db.close()

View File

@ -152,28 +152,24 @@ class ExtensionContainer(object):
extension_py = open(filename).read()
return dict(re.findall("__([a-z_]+)__ = '([^']+)'", extension_py))
def _load_module(self):
basename, extension = os.path.splitext(os.path.basename(self.filename))
fp = open(self.filename, 'r')
module = imp.load_module(basename, fp, self.filename,
(extension, 'r', imp.PY_SOURCE))
fp.close()
# Remove the .pyc file if it was created during import
util.delete_file(self.filename + 'c')
return module
def set_enabled(self, enabled):
if enabled:
if enabled and not self.enabled:
try:
self.load_extension()
self.enabled = True
if hasattr(self.module, 'on_load'):
self.module.on_load()
except Exception, exception:
logger.error('Cannot load %s from %s: %s', self.name,
self.filename, exception, exc_info=True)
self.enabled = False
else:
elif not enabled and self.enabled:
try:
if hasattr(self.module, 'on_unload'):
self.module.on_unload()
except Exception, exception:
logger.error('Failed to on_unload %s: %s', self.name,
exception, exc_info=True)
self.enabled = False
def load_extension(self):
@ -187,7 +183,15 @@ class ExtensionContainer(object):
self.name, self.metadata.only_for)
return
module_file = self._load_module()
basename, extension = os.path.splitext(os.path.basename(self.filename))
fp = open(self.filename, 'r')
module_file = imp.load_module(basename, fp, self.filename,
(extension, 'r', imp.PY_SOURCE))
fp.close()
# Remove the .pyc file if it was created during import
util.delete_file(self.filename + 'c')
self.default_config = getattr(module_file, 'DefaultConfig', {})
self.parameters = getattr(module_file, 'Parameters', {})
@ -214,6 +218,10 @@ class ExtensionManager(object):
container.set_enabled(True)
self.containers.append(container)
def shutdown(self):
for container in self.containers:
container.set_enabled(False)
def _config_value_changed(self, name, old_value, new_value):
if name == 'extensions.enabled':
for container in self.containers: