Initial commit related to plug-in system:
- basic PluginManager class that loads plugins from *.py files in given directories - Singleton metaclass was created to use with PluginManager; notice: __init__ of class is called only once (not like in code that is included in Python Cookbook) - variable to keep paths of plugin directories has been created (common.gajim.PLUGINS_DIRS); also added initilization of these paths to common.ConfigPaths - added global variable with PluginManager object: common.gajim.plugin_manager - created customized logger for plugin system ('gajim.plugin_system') - created function decorator plugins.helpers.log_calls which logs each call of function/method; it also logs when function is left - base class Plugin for plug-in implementation added; not much here - only empty class attributes: name, short_name, authors, version, description - based on Plugin class, first plugin was created named LengthNotifierPlugin; it is used to notify users when they exceed given length of message during writing it (text entry field highlights) - first GUI extension points works when ChatControl object is created (it is used in mentioned plugin) - added 'epydoc.conf' file customized a little bit (file is also in trunk now) - fixed indentation in common.sleepy module (also in trunk now)
This commit is contained in:
parent
a5e218efba
commit
95b1e45920
|
@ -0,0 +1,28 @@
|
||||||
|
[epydoc]
|
||||||
|
|
||||||
|
# Information about the project.
|
||||||
|
name: Gajim
|
||||||
|
url: http://gajim.org
|
||||||
|
|
||||||
|
verbosity: 3
|
||||||
|
imports: yes
|
||||||
|
redundant-details: yes
|
||||||
|
docformat: restructuredtext
|
||||||
|
# top: gajim
|
||||||
|
|
||||||
|
# The list of modules to document. Modules can be named using
|
||||||
|
# dotted names, module filenames, or package directory names.
|
||||||
|
# This option may be repeated.
|
||||||
|
modules: src/plugins/*.py
|
||||||
|
|
||||||
|
# Write html output to the directory "apidocs"
|
||||||
|
#output: pdf
|
||||||
|
output: html
|
||||||
|
target: apidocs/
|
||||||
|
|
||||||
|
# Include all automatically generated graphs. These graphs are
|
||||||
|
# generated using Graphviz dot.
|
||||||
|
graph: all
|
||||||
|
dotpath: /usr/bin/dot
|
||||||
|
graph-font: Sans
|
||||||
|
graph-font-size: 10
|
|
@ -0,0 +1,95 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Message length notifier plugin.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 06/01/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import gtk
|
||||||
|
|
||||||
|
from plugins import GajimPlugin
|
||||||
|
from plugins.helpers import log, log_calls
|
||||||
|
|
||||||
|
class LengthNotifierPlugin(GajimPlugin):
|
||||||
|
name = 'Message Length Notifier'
|
||||||
|
short_name = 'length_notifier'
|
||||||
|
version = '0.1'
|
||||||
|
description = '''Highlights message entry field in chat window when given
|
||||||
|
length of message is exceeded.'''
|
||||||
|
authors = ['Mateusz Biliński <mateusz@bilinski.it>']
|
||||||
|
|
||||||
|
@log_calls('LengthNotifierPlugin')
|
||||||
|
def __init__(self):
|
||||||
|
super(LengthNotifierPlugin, self).__init__()
|
||||||
|
|
||||||
|
self.__class__.gui_extension_points = {
|
||||||
|
'chat_control' : (self.connect_with_chat_control,
|
||||||
|
self.disconnect_from_chat_control)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.MESSAGE_WARNING_LENGTH = 140
|
||||||
|
self.WARNING_COLOR = gtk.gdk.color_parse('#F0DB3E')
|
||||||
|
self.JIDS = []
|
||||||
|
|
||||||
|
@log_calls('LengthNotifierPlugin')
|
||||||
|
def textview_length_warning(self, tb, chat_control):
|
||||||
|
tv = chat_control.msg_textview
|
||||||
|
d = chat_control.length_notifier_plugin_data
|
||||||
|
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
|
||||||
|
if t:
|
||||||
|
len_t = len(t)
|
||||||
|
#print("len_t: %d"%(len_t))
|
||||||
|
if len_t>self.MESSAGE_WARNING_LENGTH:
|
||||||
|
if not d['prev_color']:
|
||||||
|
d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
|
||||||
|
tv.modify_base(gtk.STATE_NORMAL, self.WARNING_COLOR)
|
||||||
|
elif d['prev_color']:
|
||||||
|
tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
|
||||||
|
d['prev_color'] = None
|
||||||
|
|
||||||
|
@log_calls('LengthNotifierPlugin')
|
||||||
|
def connect_with_chat_control(self, chat_control):
|
||||||
|
jid = chat_control.contact.jid
|
||||||
|
if self.jid_is_ok(jid):
|
||||||
|
d = {'prev_color' : None}
|
||||||
|
tv = chat_control.msg_textview
|
||||||
|
b = tv.get_buffer()
|
||||||
|
h_id = b.connect('changed', self.textview_length_warning, chat_control)
|
||||||
|
d['h_id'] = h_id
|
||||||
|
chat_control.length_notifier_plugin_data = d
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@log_calls('LengthNotifierPlugin')
|
||||||
|
def disconnect_from_chat_control(self, chat_control):
|
||||||
|
d = chat_control.length_notifier_plugin_data
|
||||||
|
chat_control.msg_textview.get_buffer().disconnect(d['h_id'])
|
||||||
|
if d['prev_color']:
|
||||||
|
tv.modify_base(gtk.STATE_NORMAL, self.PREV_COLOR)
|
||||||
|
|
||||||
|
@log_calls('LengthNotifierPlugin')
|
||||||
|
def jid_is_ok(self, jid):
|
||||||
|
return True
|
|
@ -1140,6 +1140,8 @@ class ChatControl(ChatControlBase):
|
||||||
# restore previous conversation
|
# restore previous conversation
|
||||||
self.restore_conversation()
|
self.restore_conversation()
|
||||||
|
|
||||||
|
gajim.plugin_manager.gui_extension_point('chat_control', self)
|
||||||
|
|
||||||
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
||||||
'''we enter the eventbox area so we under conditions add a timeout
|
'''we enter the eventbox area so we under conditions add a timeout
|
||||||
to show a bigger avatar after 0.5 sec'''
|
to show a bigger avatar after 0.5 sec'''
|
||||||
|
|
|
@ -93,6 +93,10 @@ class ConfigPaths:
|
||||||
self.add('HOME', fse(os.path.expanduser('~')))
|
self.add('HOME', fse(os.path.expanduser('~')))
|
||||||
self.add('TMP', fse(tempfile.gettempdir()))
|
self.add('TMP', fse(tempfile.gettempdir()))
|
||||||
|
|
||||||
|
# dirs for plugins
|
||||||
|
self.add('PLUGINS_BASE', os.path.join(u'..', windowsify(u'plugins')))
|
||||||
|
self.add_from_root('PLUGINS_USER', u'plugins')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import svn_config
|
import svn_config
|
||||||
svn_config.configure(self)
|
svn_config.configure(self)
|
||||||
|
|
|
@ -61,6 +61,7 @@ version = config.get('version')
|
||||||
connections = {} # 'account name': 'account (connection.Connection) instance'
|
connections = {} # 'account name': 'account (connection.Connection) instance'
|
||||||
verbose = False
|
verbose = False
|
||||||
ipython_window = None
|
ipython_window = None
|
||||||
|
plugin_manager = None
|
||||||
|
|
||||||
h = logging.StreamHandler()
|
h = logging.StreamHandler()
|
||||||
f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
|
f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S')
|
||||||
|
@ -85,6 +86,8 @@ MY_CACERTS = gajimpaths['MY_CACERTS']
|
||||||
TMP = gajimpaths['TMP']
|
TMP = gajimpaths['TMP']
|
||||||
DATA_DIR = gajimpaths['DATA']
|
DATA_DIR = gajimpaths['DATA']
|
||||||
HOME_DIR = gajimpaths['HOME']
|
HOME_DIR = gajimpaths['HOME']
|
||||||
|
PLUGINS_DIRS = [gajimpaths['PLUGINS_BASE'],
|
||||||
|
gajimpaths['PLUGINS_USER']]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc..
|
LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc..
|
||||||
|
|
|
@ -35,22 +35,22 @@ STATE_AWAKE = 'awake'
|
||||||
|
|
||||||
SUPPORTED = True
|
SUPPORTED = True
|
||||||
try:
|
try:
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
GetTickCount = ctypes.windll.kernel32.GetTickCount
|
GetTickCount = ctypes.windll.kernel32.GetTickCount
|
||||||
GetLastInputInfo = ctypes.windll.user32.GetLastInputInfo
|
GetLastInputInfo = ctypes.windll.user32.GetLastInputInfo
|
||||||
|
|
||||||
class LASTINPUTINFO(ctypes.Structure):
|
class LASTINPUTINFO(ctypes.Structure):
|
||||||
_fields_ = [('cbSize', ctypes.c_uint), ('dwTime', ctypes.c_uint)]
|
_fields_ = [('cbSize', ctypes.c_uint), ('dwTime', ctypes.c_uint)]
|
||||||
|
|
||||||
lastInputInfo = LASTINPUTINFO()
|
lastInputInfo = LASTINPUTINFO()
|
||||||
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
|
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
|
||||||
|
|
||||||
elif sys.platform == 'darwin':
|
elif sys.platform == 'darwin':
|
||||||
import osx.idle as idle
|
import osx.idle as idle
|
||||||
else: # unix
|
else: # unix
|
||||||
import idle
|
import idle
|
||||||
except:
|
except:
|
||||||
gajim.log.debug('Unable to load idle module')
|
gajim.log.debug('Unable to load idle module')
|
||||||
SUPPORTED = False
|
SUPPORTED = False
|
||||||
|
|
|
@ -3462,6 +3462,10 @@ class Interface:
|
||||||
gobject.timeout_add_seconds(gajim.config.get(
|
gobject.timeout_add_seconds(gajim.config.get(
|
||||||
'check_idle_every_foo_seconds'), self.read_sleepy)
|
'check_idle_every_foo_seconds'), self.read_sleepy)
|
||||||
|
|
||||||
|
# Creating plugin manager
|
||||||
|
import plugins
|
||||||
|
gajim.plugin_manager = plugins.PluginManager()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
def sigint_cb(num, stack):
|
def sigint_cb(num, stack):
|
||||||
sys.exit(5)
|
sys.exit(5)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Main file of plugins package.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 05/30/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
from pluginmanager import PluginManager
|
||||||
|
from plugin import GajimPlugin
|
||||||
|
|
||||||
|
__all__ = ['PluginManager', 'GajimPlugin']
|
|
@ -0,0 +1,113 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Helper code related to plug-ins management system.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 05/30/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
__all__ = ['log', 'log_calls', 'Singleton']
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger('gajim.plugin_system')
|
||||||
|
'''
|
||||||
|
Logger for code related to plug-in system.
|
||||||
|
|
||||||
|
:type: logging.Logger
|
||||||
|
'''
|
||||||
|
|
||||||
|
consoleloghandler = logging.StreamHandler()
|
||||||
|
consoleloghandler.setLevel(1)
|
||||||
|
consoleloghandler.setFormatter(
|
||||||
|
logging.Formatter('%(levelname)s: %(message)s'))
|
||||||
|
#logging.Formatter('%(asctime)s %(name)s: %(levelname)s: %(message)s'))
|
||||||
|
log.setLevel(logging.DEBUG)
|
||||||
|
log.addHandler(consoleloghandler)
|
||||||
|
log.propagate = False
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
|
class log_calls(object):
|
||||||
|
'''
|
||||||
|
Decorator class for functions to easily log when they are entered and left.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, classname='', log=log):
|
||||||
|
'''
|
||||||
|
:Keywords:
|
||||||
|
classname : str
|
||||||
|
Name of class to prefix function name (if function is a method).
|
||||||
|
log : logging.Logger
|
||||||
|
Logger to use when outputing debug information on when function has
|
||||||
|
been entered and when left. By default: `plugins.helpers.log`
|
||||||
|
is used.
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.full_func_name = ''
|
||||||
|
'''
|
||||||
|
Full name of function, with class name (as prefix) if given
|
||||||
|
to decorator.
|
||||||
|
|
||||||
|
Otherwise, it's only function name retrieved from function object
|
||||||
|
for which decorator was called.
|
||||||
|
|
||||||
|
:type: str
|
||||||
|
'''
|
||||||
|
|
||||||
|
if classname:
|
||||||
|
self.full_func_name = classname+'.'
|
||||||
|
|
||||||
|
def __call__(self, f):
|
||||||
|
'''
|
||||||
|
:param f: function to be wrapped with logging statements
|
||||||
|
|
||||||
|
:return: given function wrapped by *log.debug* statements
|
||||||
|
:rtype: function
|
||||||
|
'''
|
||||||
|
self.full_func_name += f.func_name
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
log.debug('%(funcname)s() <entered>'%{
|
||||||
|
'funcname': self.full_func_name})
|
||||||
|
result = f(*args, **kwargs)
|
||||||
|
log.debug('%(funcname)s() <left>'%{
|
||||||
|
'funcname': self.full_func_name})
|
||||||
|
return result
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
class Singleton(type):
|
||||||
|
'''
|
||||||
|
Singleton metaclass.
|
||||||
|
'''
|
||||||
|
def __init__(cls,name,bases,dic):
|
||||||
|
super(Singleton,cls).__init__(name,bases,dic)
|
||||||
|
cls.instance=None
|
||||||
|
|
||||||
|
def __call__(cls,*args,**kw):
|
||||||
|
if cls.instance is None:
|
||||||
|
cls.instance=super(Singleton,cls).__call__(*args,**kw)
|
||||||
|
log.debug('%(classname)s - new instance created'%{
|
||||||
|
'classname' : cls.__name__})
|
||||||
|
else:
|
||||||
|
log.debug('%(classname)s - returning already existing instance'%{
|
||||||
|
'classname' : cls.__name__})
|
||||||
|
|
||||||
|
return cls.instance
|
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Base class for implementing plugin.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 06/01/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from plugins.helpers import log, log_calls
|
||||||
|
|
||||||
|
class GajimPlugin(object):
|
||||||
|
name = ''
|
||||||
|
short_name = ''
|
||||||
|
version = ''
|
||||||
|
description = ''
|
||||||
|
authors = []
|
||||||
|
gui_extension_points = {}
|
||||||
|
|
||||||
|
@log_calls('GajimPlugin')
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
|
@ -0,0 +1,130 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Helper code related to plug-ins management system.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 05/30/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
__all__ = ['PluginManager']
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import fnmatch
|
||||||
|
|
||||||
|
import common.gajim as gajim
|
||||||
|
|
||||||
|
from helpers import log, log_calls, Singleton
|
||||||
|
from plugin import GajimPlugin
|
||||||
|
|
||||||
|
class PluginManager(object):
|
||||||
|
__metaclass__ = Singleton
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def __init__(self):
|
||||||
|
self.plugins = []
|
||||||
|
self.active = []
|
||||||
|
self.gui_extension_points = {}
|
||||||
|
|
||||||
|
for path in gajim.PLUGINS_DIRS:
|
||||||
|
self.plugins.extend(self._scan_dir_for_plugins(path))
|
||||||
|
|
||||||
|
log.debug('plugins: %s'%(self.plugins))
|
||||||
|
|
||||||
|
self._activate_all_plugins()
|
||||||
|
|
||||||
|
log.debug('active: %s'%(self.active))
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def gui_extension_point(self, gui_extpoint_name, *args):
|
||||||
|
if gui_extpoint_name in self.gui_extension_points:
|
||||||
|
for handlers in self.gui_extension_points[gui_extpoint_name]:
|
||||||
|
handlers[0](*args)
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def _activate_plugin(self, plugin):
|
||||||
|
'''
|
||||||
|
:param plugin: Plugin to be activated.
|
||||||
|
:type plugin: class object of GajimPlugin subclass
|
||||||
|
'''
|
||||||
|
p = plugin()
|
||||||
|
|
||||||
|
success = True
|
||||||
|
|
||||||
|
# :fix: what if only some handlers are successfully connected? we should
|
||||||
|
# revert all those connections that where successfully made. Maybe
|
||||||
|
# call 'self._deactivate_plugin()' or sth similar.
|
||||||
|
# Looking closer - we only rewrite tuples here. Real check should be
|
||||||
|
# made in method that invokes gui_extpoints handlers.
|
||||||
|
for gui_extpoint_name, gui_extpoint_handlers in \
|
||||||
|
p.gui_extension_points.iteritems():
|
||||||
|
self.gui_extension_points.setdefault(gui_extpoint_name,[]).append(
|
||||||
|
gui_extpoint_handlers)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
self.active.append(p)
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def _activate_all_plugins(self):
|
||||||
|
self.active = []
|
||||||
|
for plugin in self.plugins:
|
||||||
|
self._activate_plugin(plugin)
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def _scan_dir_for_plugins(self, path):
|
||||||
|
plugins_found = []
|
||||||
|
if os.path.isdir(path):
|
||||||
|
dir_list = os.listdir(path)
|
||||||
|
log.debug(dir_list)
|
||||||
|
|
||||||
|
sys.path.insert(0, path)
|
||||||
|
log.debug(sys.path)
|
||||||
|
|
||||||
|
for file in fnmatch.filter(dir_list, '*.py'):
|
||||||
|
log.debug('- "%s"'%(file))
|
||||||
|
file_path = os.path.join(path, file)
|
||||||
|
log.debug(' "%s"'%(file_path))
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
module_name = os.path.splitext(file)[0]
|
||||||
|
module = __import__(module_name)
|
||||||
|
filter_out_bad_names = \
|
||||||
|
lambda x: not (x.startswith('__') or
|
||||||
|
x.endswith('__'))
|
||||||
|
for module_attr_name in filter(filter_out_bad_names,
|
||||||
|
dir(module)):
|
||||||
|
module_attr = getattr(module, module_attr_name)
|
||||||
|
log.debug('%s : %s'%(module_attr_name, module_attr))
|
||||||
|
|
||||||
|
try:
|
||||||
|
if issubclass(module_attr, GajimPlugin) and \
|
||||||
|
not module_attr is GajimPlugin:
|
||||||
|
log.debug('is subclass of GajimPlugin')
|
||||||
|
plugins_found.append(module_attr)
|
||||||
|
except TypeError, e:
|
||||||
|
log.debug('module_attr: %s, error : %s'%(
|
||||||
|
module_name+'.'+module_attr_name,
|
||||||
|
e))
|
||||||
|
|
||||||
|
log.debug(module)
|
||||||
|
|
||||||
|
return plugins_found
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
## This file is part of Gajim.
|
||||||
|
##
|
||||||
|
## Gajim is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 3 only.
|
||||||
|
##
|
||||||
|
## Gajim is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
'''
|
||||||
|
Testing PluginManager class.
|
||||||
|
|
||||||
|
:author: Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:since: 05/30/2008
|
||||||
|
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
||||||
|
:license: GPL
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
gajim_root = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
|
||||||
|
sys.path.append(gajim_root + '/src')
|
||||||
|
|
||||||
|
from plugins import PluginManager
|
||||||
|
|
||||||
|
class PluginManagerTestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.pluginmanager = PluginManager()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_01_Singleton(self):
|
||||||
|
""" 1. Checking whether PluginManger class is singleton. """
|
||||||
|
self.pluginmanager.test_arg = 1
|
||||||
|
secondPluginManager = PluginManager()
|
||||||
|
|
||||||
|
self.failUnlessEqual(id(secondPluginManager), id(self.pluginmanager),
|
||||||
|
'Different IDs in references to PluginManager objects (not a singleton)')
|
||||||
|
self.failUnlessEqual(secondPluginManager.test_arg, 1,
|
||||||
|
'References point to different PluginManager objects (not a singleton')
|
||||||
|
|
||||||
|
def suite():
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(PluginManagerTestCase)
|
||||||
|
return suite
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
test_suite = suite()
|
||||||
|
runner.run(test_suite)
|
Loading…
Reference in New Issue