Improvements to GUI extension points handling - added method to remove these from PluginManager (memory optimization).
Removed logging from most of the code.
This commit is contained in:
parent
5cce0a8ca9
commit
16ac65e58b
|
@ -38,11 +38,8 @@ class AcronymsExpanderPlugin(GajimPlugin):
|
||||||
description = u'''Replaces acronyms (or other strings) with given expansions/substitutes.'''
|
description = u'''Replaces acronyms (or other strings) with given expansions/substitutes.'''
|
||||||
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
||||||
homepage = u'http://blog.bilinski.it'
|
homepage = u'http://blog.bilinski.it'
|
||||||
|
|
||||||
#@log_calls('AcronymsExpanderPlugin')
|
|
||||||
#def __init__(self):
|
|
||||||
#super(AcronymsExpanderPlugin, self).__init__()
|
|
||||||
|
|
||||||
|
@log_calls('AcronymsExpanderPlugin')
|
||||||
def init(self):
|
def init(self):
|
||||||
self.config_dialog = None
|
self.config_dialog = None
|
||||||
|
|
||||||
|
@ -71,20 +68,20 @@ class AcronymsExpanderPlugin(GajimPlugin):
|
||||||
ACRONYMS = self.config['ACRONYMS']
|
ACRONYMS = self.config['ACRONYMS']
|
||||||
INVOKER = self.config['INVOKER']
|
INVOKER = self.config['INVOKER']
|
||||||
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
|
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
|
||||||
log.debug('%s %d'%(t, len(t)))
|
#log.debug('%s %d'%(t, len(t)))
|
||||||
if t and t[-1] == INVOKER:
|
if t and t[-1] == INVOKER:
|
||||||
log.debug("changing msg text")
|
#log.debug("changing msg text")
|
||||||
base,sep,head=t[:-1].rpartition(INVOKER)
|
base,sep,head=t[:-1].rpartition(INVOKER)
|
||||||
log.debug('%s | %s | %s'%(base, sep, head))
|
#log.debug('%s | %s | %s'%(base, sep, head))
|
||||||
if head in ACRONYMS:
|
if head in ACRONYMS:
|
||||||
head = ACRONYMS[head]
|
head = ACRONYMS[head]
|
||||||
log.debug("head: %s"%(head))
|
log.debug("head: %s"%(head))
|
||||||
t = "".join((base, sep, head, INVOKER))
|
t = "".join((base, sep, head, INVOKER))
|
||||||
log.debug("turning off notify")
|
#log.debug("turning off notify")
|
||||||
tb.freeze_notify()
|
tb.freeze_notify()
|
||||||
log.debug("setting text: '%s'"%(t))
|
#log.debug("setting text: '%s'"%(t))
|
||||||
tb.set_text(t)
|
tb.set_text(t)
|
||||||
log.debug("turning on notify")
|
#log.debug("turning on notify")
|
||||||
tb.thaw_notify()
|
tb.thaw_notify()
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
@log_calls('AcronymsExpanderPlugin')
|
||||||
|
|
|
@ -94,7 +94,6 @@ http://trac.gajim.org/attachment/ticket/4133'''
|
||||||
if self.config['show_banner_resource'] or self.config['banner_small_fonts']:
|
if self.config['show_banner_resource'] or self.config['banner_small_fonts']:
|
||||||
banner_name_label = chat_control.xml.get_widget('banner_name_label')
|
banner_name_label = chat_control.xml.get_widget('banner_name_label')
|
||||||
label_text = banner_name_label.get_label()
|
label_text = banner_name_label.get_label()
|
||||||
log.debug('label_text = "%s"'%(label_text))
|
|
||||||
|
|
||||||
contact = chat_control.contact
|
contact = chat_control.contact
|
||||||
jid = contact.jid
|
jid = contact.jid
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||||
<!--Generated with glade3 3.4.5 on Tue Jul 29 19:58:18 2008 -->
|
<!--Generated with glade3 3.4.5 on Sun Aug 3 13:57:25 2008 -->
|
||||||
<glade-interface>
|
<glade-interface>
|
||||||
<widget class="GtkWindow" id="window1">
|
<widget class="GtkWindow" id="window1">
|
||||||
<child>
|
<child>
|
||||||
|
@ -12,40 +12,58 @@
|
||||||
<property name="column_spacing">7</property>
|
<property name="column_spacing">7</property>
|
||||||
<property name="row_spacing">5</property>
|
<property name="row_spacing">5</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkHBox" id="hbox2">
|
<widget class="GtkLabel" id="label1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<child>
|
<property name="tooltip" translatable="yes">Message length at which notification is invoked.</property>
|
||||||
<widget class="GtkSpinButton" id="message_length_spinbutton">
|
<property name="xalign">0</property>
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="yes">Message length:</property>
|
||||||
<property name="can_focus">True</property>
|
</widget>
|
||||||
<property name="tooltip" translatable="yes">Message length at which notification is invoked.</property>
|
<packing>
|
||||||
<property name="width_chars">6</property>
|
<property name="x_options">GTK_FILL</property>
|
||||||
<property name="adjustment">0 0 999999 1 10 10</property>
|
<property name="y_options">GTK_FILL</property>
|
||||||
<property name="snap_to_ticks">True</property>
|
</packing>
|
||||||
<property name="numeric">True</property>
|
</child>
|
||||||
<signal name="value_changed" handler="on_message_length_spinbutton_value_changed"/>
|
<child>
|
||||||
</widget>
|
<widget class="GtkLabel" id="label2">
|
||||||
<packing>
|
<property name="visible">True</property>
|
||||||
<property name="expand">False</property>
|
<property name="tooltip" translatable="yes">Background color of text entry field in chat window when notification is invoked.</property>
|
||||||
<property name="fill">False</property>
|
<property name="xalign">0</property>
|
||||||
</packing>
|
<property name="label" translatable="yes">Notification color:</property>
|
||||||
</child>
|
</widget>
|
||||||
<child>
|
<packing>
|
||||||
<widget class="GtkAlignment" id="alignment2">
|
<property name="top_attach">1</property>
|
||||||
<property name="visible">True</property>
|
<property name="bottom_attach">2</property>
|
||||||
<child>
|
<property name="x_options">GTK_FILL</property>
|
||||||
<placeholder/>
|
<property name="y_options">GTK_FILL</property>
|
||||||
</child>
|
</packing>
|
||||||
</widget>
|
</child>
|
||||||
<packing>
|
<child>
|
||||||
<property name="position">1</property>
|
<widget class="GtkLabel" id="label3">
|
||||||
</packing>
|
<property name="visible">True</property>
|
||||||
</child>
|
<property name="tooltip" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). Use comma (without space) as separator. If empty plugin is used with every JID. </property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">JabberIDs to include:</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="bottom_attach">3</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options">GTK_FILL</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkEntry" id="jids_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). Use comma (without space) as separator. If empty plugin is used with every JID. </property>
|
||||||
|
<signal name="changed" handler="on_jids_entry_changed"/>
|
||||||
|
<signal name="editing_done" handler="on_jids_entry_editing_done"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">2</property>
|
||||||
<property name="x_options">GTK_FILL</property>
|
<property name="top_attach">2</property>
|
||||||
|
<property name="bottom_attach">3</property>
|
||||||
<property name="y_options">GTK_FILL</property>
|
<property name="y_options">GTK_FILL</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -91,57 +109,39 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkEntry" id="jids_entry">
|
<widget class="GtkHBox" id="hbox2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<child>
|
||||||
<property name="tooltip" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]</property>
|
<widget class="GtkSpinButton" id="message_length_spinbutton">
|
||||||
<signal name="changed" handler="on_jids_entry_changed"/>
|
<property name="visible">True</property>
|
||||||
<signal name="editing_done" handler="on_jids_entry_editing_done"/>
|
<property name="can_focus">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">Message length at which notification is invoked.</property>
|
||||||
|
<property name="width_chars">6</property>
|
||||||
|
<property name="adjustment">0 0 999999 1 10 10</property>
|
||||||
|
<property name="snap_to_ticks">True</property>
|
||||||
|
<property name="numeric">True</property>
|
||||||
|
<signal name="value_changed" handler="on_message_length_spinbutton_value_changed"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">2</property>
|
||||||
<property name="top_attach">2</property>
|
|
||||||
<property name="bottom_attach">3</property>
|
|
||||||
<property name="y_options">GTK_FILL</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label3">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="tooltip" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">JabberIDs to include:</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
<property name="bottom_attach">3</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options">GTK_FILL</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label2">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="tooltip" translatable="yes">Background color of text entry field in chat window when notification is invoked.</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">Notification color:</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
<property name="bottom_attach">2</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options">GTK_FILL</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="tooltip" translatable="yes">Message length at which notification is invoked.</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">Message length:</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
<property name="x_options">GTK_FILL</property>
|
||||||
<property name="y_options">GTK_FILL</property>
|
<property name="y_options">GTK_FILL</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
|
|
@ -40,10 +40,6 @@ class LengthNotifierPlugin(GajimPlugin):
|
||||||
description = u'''Highlights message entry field in chat window when given length of message is exceeded.'''
|
description = u'''Highlights message entry field in chat window when given length of message is exceeded.'''
|
||||||
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
||||||
homepage = u'http://blog.bilinski.it'
|
homepage = u'http://blog.bilinski.it'
|
||||||
|
|
||||||
#@log_calls('LengthNotifierPlugin')
|
|
||||||
#def __init__(self):
|
|
||||||
#super(LengthNotifierPlugin, self).__init__()
|
|
||||||
|
|
||||||
@log_calls('LengthNotifierPlugin')
|
@log_calls('LengthNotifierPlugin')
|
||||||
def init(self):
|
def init(self):
|
||||||
|
@ -107,7 +103,8 @@ class LengthNotifierPlugin(GajimPlugin):
|
||||||
if d['prev_color']:
|
if d['prev_color']:
|
||||||
tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
|
tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
|
||||||
except AttributeError, error:
|
except AttributeError, error:
|
||||||
log.debug('Length Notifier Plugin was (probably) never connected with this chat window.\n Error: %s' % (error))
|
pass
|
||||||
|
#log.debug('Length Notifier Plugin was (probably) never connected with this chat window.\n Error: %s' % (error))
|
||||||
|
|
||||||
@log_calls('LengthNotifierPlugin')
|
@log_calls('LengthNotifierPlugin')
|
||||||
def jid_is_ok(self, jid):
|
def jid_is_ok(self, jid):
|
||||||
|
|
|
@ -40,14 +40,9 @@ class RosterButtonsPlugin(GajimPlugin):
|
||||||
description = u'''Adds quick action buttons to roster window.'''
|
description = u'''Adds quick action buttons to roster window.'''
|
||||||
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
|
||||||
homepage = u'http://blog.bilinski.it'
|
homepage = u'http://blog.bilinski.it'
|
||||||
|
|
||||||
#@log_calls('RosterButtonsPlugin')
|
|
||||||
#def __init__(self):
|
|
||||||
#super(RosterButtonsPlugin, self).__init__()
|
|
||||||
|
|
||||||
@log_calls('RosterButtonsPlugin')
|
@log_calls('RosterButtonsPlugin')
|
||||||
def init(self):
|
def init(self):
|
||||||
#log.debug('self.__path__==%s'%(self.__path__))
|
|
||||||
self.GLADE_FILE_PATH = self.local_file_path('roster_buttons.glade')
|
self.GLADE_FILE_PATH = self.local_file_path('roster_buttons.glade')
|
||||||
|
|
||||||
self.roster_vbox = gajim.interface.roster.xml.get_widget('roster_vbox2')
|
self.roster_vbox = gajim.interface.roster.xml.get_widget('roster_vbox2')
|
||||||
|
|
|
@ -294,7 +294,15 @@ class ChatControlBase(MessageControl):
|
||||||
|
|
||||||
self.smooth = True
|
self.smooth = True
|
||||||
|
|
||||||
|
# PluginSystem: adding GUI extension point for ChatControlBase
|
||||||
|
# instance object (also subclasses, eg. ChatControl or GroupchatControl)
|
||||||
gajim.plugin_manager.gui_extension_point('chat_control_base', self)
|
gajim.plugin_manager.gui_extension_point('chat_control_base', self)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
# PluginSystem: removing GUI extension points connected with ChatControlBase
|
||||||
|
# instance object
|
||||||
|
gajim.plugin_manager.remove_gui_extension_point('chat_control_base', self)
|
||||||
|
gajim.plugin_manager.remove_gui_extension_point('chat_control_base_draw_banner', self)
|
||||||
|
|
||||||
def on_msg_textview_populate_popup(self, textview, menu):
|
def on_msg_textview_populate_popup(self, textview, menu):
|
||||||
'''we override the default context menu and we prepend an option to switch languages'''
|
'''we override the default context menu and we prepend an option to switch languages'''
|
||||||
|
@ -1144,6 +1152,8 @@ class ChatControl(ChatControlBase):
|
||||||
# restore previous conversation
|
# restore previous conversation
|
||||||
self.restore_conversation()
|
self.restore_conversation()
|
||||||
|
|
||||||
|
# PluginSystem: adding GUI extension point for this ChatControl
|
||||||
|
# instance object
|
||||||
gajim.plugin_manager.gui_extension_point('chat_control', self)
|
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):
|
||||||
|
@ -2022,6 +2032,13 @@ class ChatControl(ChatControlBase):
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
|
# PluginSystem: calling shutdown of super class (ChatControlBase) to let it remove
|
||||||
|
# it's GUI extension points
|
||||||
|
super(ChatControl, self).shutdown()
|
||||||
|
# PluginSystem: removing GUI extension points connected with ChatControl
|
||||||
|
# instance object
|
||||||
|
gajim.plugin_manager.remove_gui_extension_point('chat_control', self)
|
||||||
|
|
||||||
# destroy banner tooltip - bug #pygtk for that!
|
# destroy banner tooltip - bug #pygtk for that!
|
||||||
self.status_tooltip.destroy()
|
self.status_tooltip.destroy()
|
||||||
|
|
||||||
|
|
|
@ -1636,6 +1636,11 @@ class GroupchatControl(ChatControlBase):
|
||||||
status = self.subject)
|
status = self.subject)
|
||||||
|
|
||||||
def shutdown(self, status='offline'):
|
def shutdown(self, status='offline'):
|
||||||
|
# PluginSystem: calling shutdown of super class (ChatControlBase)
|
||||||
|
# to let it remove it's GUI extension points
|
||||||
|
super(GroupchatControl, self).shutdown()
|
||||||
|
|
||||||
|
|
||||||
# destroy banner tooltip - bug #pygtk for that!
|
# destroy banner tooltip - bug #pygtk for that!
|
||||||
self.subject_tooltip.destroy()
|
self.subject_tooltip.destroy()
|
||||||
gajim.connections[self.account].send_gc_status(self.nick, self.room_jid,
|
gajim.connections[self.account].send_gc_status(self.nick, self.room_jid,
|
||||||
|
|
|
@ -28,7 +28,7 @@ TYPE_PM = 'pm'
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
||||||
class MessageControl:
|
class MessageControl(object):
|
||||||
'''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow'''
|
'''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow'''
|
||||||
|
|
||||||
def __init__(self, type_id, parent_win, widget_name, contact, account, resource = None):
|
def __init__(self, type_id, parent_win, widget_name, contact, account, resource = None):
|
||||||
|
|
|
@ -170,7 +170,7 @@ class PluginsWindow(object):
|
||||||
|
|
||||||
@log_calls('PluginsWindow')
|
@log_calls('PluginsWindow')
|
||||||
def on_configure_plugin_button_clicked(self, widget):
|
def on_configure_plugin_button_clicked(self, widget):
|
||||||
log.debug('widget: %s'%(widget))
|
#log.debug('widget: %s'%(widget))
|
||||||
selection = self.installed_plugins_treeview.get_selection()
|
selection = self.installed_plugins_treeview.get_selection()
|
||||||
model, iter = selection.get_selected()
|
model, iter = selection.get_selected()
|
||||||
if iter:
|
if iter:
|
||||||
|
|
|
@ -50,7 +50,8 @@ class log_calls(object):
|
||||||
Decorator class for functions to easily log when they are entered and left.
|
Decorator class for functions to easily log when they are entered and left.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
filter_out_classes = ['PluginManager']
|
filter_out_classes = ['GajimPlugin', 'GajimPluginConfig',
|
||||||
|
'GajimPluginConfigDialog', 'PluginsWindow']
|
||||||
'''
|
'''
|
||||||
List of classes from which no logs should be emited when methods are called,
|
List of classes from which no logs should be emited when methods are called,
|
||||||
eventhough `log_calls` decorator is used.
|
eventhough `log_calls` decorator is used.
|
||||||
|
@ -129,10 +130,11 @@ class Singleton(type):
|
||||||
def __call__(cls,*args,**kw):
|
def __call__(cls,*args,**kw):
|
||||||
if cls.instance is None:
|
if cls.instance is None:
|
||||||
cls.instance=super(Singleton,cls).__call__(*args,**kw)
|
cls.instance=super(Singleton,cls).__call__(*args,**kw)
|
||||||
log.debug('%(classname)s - new instance created'%{
|
#log.debug('%(classname)s - new instance created'%{
|
||||||
'classname' : cls.__name__})
|
#'classname' : cls.__name__})
|
||||||
else:
|
else:
|
||||||
log.debug('%(classname)s - returning already existing instance'%{
|
pass
|
||||||
'classname' : cls.__name__})
|
#log.debug('%(classname)s - returning already existing instance'%{
|
||||||
|
#'classname' : cls.__name__})
|
||||||
|
|
||||||
return cls.instance
|
return cls.instance
|
|
@ -130,10 +130,22 @@ class GajimPlugin(object):
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
@log_calls('GajimPlugin')
|
@log_calls('GajimPlugin')
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
self.config.load()
|
self.config.load()
|
||||||
|
|
||||||
|
def __eq__(self, plugin):
|
||||||
|
if self.short_name == plugin.short_name:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, plugin):
|
||||||
|
if self.short_name != plugin.short_name:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
@log_calls('GajimPlugin')
|
@log_calls('GajimPlugin')
|
||||||
def local_file_path(self, file_name):
|
def local_file_path(self, file_name):
|
||||||
return os.path.join(self.__path__, file_name)
|
return os.path.join(self.__path__, file_name)
|
||||||
|
|
|
@ -96,11 +96,11 @@ class PluginManager(object):
|
||||||
for path in gajim.PLUGINS_DIRS:
|
for path in gajim.PLUGINS_DIRS:
|
||||||
self.add_plugins(PluginManager.scan_dir_for_plugins(path))
|
self.add_plugins(PluginManager.scan_dir_for_plugins(path))
|
||||||
|
|
||||||
log.debug('plugins: %s'%(self.plugins))
|
#log.debug('plugins: %s'%(self.plugins))
|
||||||
|
|
||||||
self._activate_all_plugins_from_global_config()
|
self._activate_all_plugins_from_global_config()
|
||||||
|
|
||||||
log.debug('active: %s'%(self.active_plugins))
|
#log.debug('active: %s'%(self.active_plugins))
|
||||||
|
|
||||||
@log_calls('PluginManager')
|
@log_calls('PluginManager')
|
||||||
def _plugin_has_entry_in_global_config(self, plugin):
|
def _plugin_has_entry_in_global_config(self, plugin):
|
||||||
|
@ -120,11 +120,16 @@ class PluginManager(object):
|
||||||
and adding class from reloaded module or ignoring adding plug-in?
|
and adding class from reloaded module or ignoring adding plug-in?
|
||||||
'''
|
'''
|
||||||
plugin = plugin_class()
|
plugin = plugin_class()
|
||||||
if not self._plugin_has_entry_in_global_config(plugin):
|
|
||||||
self._create_plugin_entry_in_global_config(plugin)
|
if plugin not in self.plugins:
|
||||||
|
if not self._plugin_has_entry_in_global_config(plugin):
|
||||||
self.plugins.append(plugin)
|
self._create_plugin_entry_in_global_config(plugin)
|
||||||
plugin.active = False
|
|
||||||
|
self.plugins.append(plugin)
|
||||||
|
plugin.active = False
|
||||||
|
else:
|
||||||
|
log.info('Not loading plugin %s v%s from module %s (identified by short name: %s). Plugin already loaded.'%(
|
||||||
|
plugin.name, plugin.version, plugin.__module__, plugin.short_name))
|
||||||
|
|
||||||
@log_calls('PluginManager')
|
@log_calls('PluginManager')
|
||||||
def add_plugins(self, plugin_classes):
|
def add_plugins(self, plugin_classes):
|
||||||
|
@ -134,7 +139,9 @@ class PluginManager(object):
|
||||||
@log_calls('PluginManager')
|
@log_calls('PluginManager')
|
||||||
def gui_extension_point(self, gui_extpoint_name, *args):
|
def gui_extension_point(self, gui_extpoint_name, *args):
|
||||||
'''
|
'''
|
||||||
Invokes all handlers (from plugins) for particular GUI extension point.
|
Invokes all handlers (from plugins) for particular GUI extension point
|
||||||
|
and adds it to collection for further processing (eg. by plugins not active
|
||||||
|
yet).
|
||||||
|
|
||||||
:param gui_extpoint_name: name of GUI extension point.
|
:param gui_extpoint_name: name of GUI extension point.
|
||||||
:type gui_extpoint_name: unicode
|
:type gui_extpoint_name: unicode
|
||||||
|
@ -157,10 +164,69 @@ class PluginManager(object):
|
||||||
|
|
||||||
self._add_gui_extension_point_call_to_list(gui_extpoint_name, *args)
|
self._add_gui_extension_point_call_to_list(gui_extpoint_name, *args)
|
||||||
self._execute_all_handlers_of_gui_extension_point(gui_extpoint_name, *args)
|
self._execute_all_handlers_of_gui_extension_point(gui_extpoint_name, *args)
|
||||||
|
|
||||||
|
@log_calls('PluginManager')
|
||||||
|
def remove_gui_extension_point(self, gui_extpoint_name, *args):
|
||||||
|
'''
|
||||||
|
Removes GUI extension point from collection held by `PluginManager`.
|
||||||
|
|
||||||
|
From this point this particular extension point won't be visible
|
||||||
|
to plugins (eg. it won't invoke any handlers when plugin is activated).
|
||||||
|
|
||||||
|
GUI extension point is removed completely (there is no way to recover it
|
||||||
|
from inside `PluginManager`).
|
||||||
|
|
||||||
|
Removal is needed when instance object that given extension point was
|
||||||
|
connect with is destroyed (eg. ChatControl is closed or context menu
|
||||||
|
is hidden).
|
||||||
|
|
||||||
|
Each `PluginManager.gui_extension_point` call should have a call of
|
||||||
|
`PluginManager.remove_gui_extension_point` related to it.
|
||||||
|
|
||||||
|
:note: in current implementation different arguments mean different
|
||||||
|
extension points. The same arguments and the same name mean
|
||||||
|
the same extension point.
|
||||||
|
:todo: instead of using argument to identify which extpoint should be
|
||||||
|
removed, maybe add additional 'id' argument - this would work similar
|
||||||
|
hash in Python objects. 'id' would be calculated based on arguments
|
||||||
|
passed or on anything else (even could be constant). This would give
|
||||||
|
core developers (that add new extpoints) more freedom, but is this
|
||||||
|
necessary?
|
||||||
|
|
||||||
|
:param gui_extpoint_name: name of GUI extension point.
|
||||||
|
:type gui_extpoint_name: unicode
|
||||||
|
:param args: arguments that `PluginManager.gui_extension_point` was
|
||||||
|
called with for this extension point. This is used (along with
|
||||||
|
extension point name) to identify element to be removed.
|
||||||
|
:type args: tuple
|
||||||
|
'''
|
||||||
|
log.debug('name: %s\n args: %s'%(gui_extpoint_name, args))
|
||||||
|
|
||||||
|
|
||||||
@log_calls('PluginManager')
|
@log_calls('PluginManager')
|
||||||
def _add_gui_extension_point_call_to_list(self, gui_extpoint_name, *args):
|
def _add_gui_extension_point_call_to_list(self, gui_extpoint_name, *args):
|
||||||
self.gui_extension_points.setdefault(gui_extpoint_name, []).append(args)
|
'''
|
||||||
|
Adds GUI extension point call to list of calls.
|
||||||
|
|
||||||
|
This is done only if such call hasn't been added already
|
||||||
|
(same extension point name and same arguments).
|
||||||
|
|
||||||
|
:note: This is assumption that GUI extension points are different only
|
||||||
|
if they have different name or different arguments.
|
||||||
|
|
||||||
|
:param gui_extpoint_name: GUI extension point name used to identify it
|
||||||
|
by plugins.
|
||||||
|
:type gui_extpoint_name: str
|
||||||
|
|
||||||
|
:param args: parameters to be passed to extension point handlers
|
||||||
|
(typically and object that invokes `gui_extension_point`; however,
|
||||||
|
this can be practically anything)
|
||||||
|
:type args: tuple
|
||||||
|
|
||||||
|
'''
|
||||||
|
if ((gui_extpoint_name not in self.gui_extension_points)
|
||||||
|
or (args not in self.gui_extension_points[gui_extpoint_name])):
|
||||||
|
self.gui_extension_points.setdefault(gui_extpoint_name, []).append(args)
|
||||||
|
|
||||||
@log_calls('PluginManager')
|
@log_calls('PluginManager')
|
||||||
def _execute_all_handlers_of_gui_extension_point(self, gui_extpoint_name, *args):
|
def _execute_all_handlers_of_gui_extension_point(self, gui_extpoint_name, *args):
|
||||||
|
@ -287,57 +353,62 @@ class PluginManager(object):
|
||||||
#log.debug(sys.path)
|
#log.debug(sys.path)
|
||||||
|
|
||||||
for elem_name in dir_list:
|
for elem_name in dir_list:
|
||||||
log.debug('- "%s"'%(elem_name))
|
#log.debug('- "%s"'%(elem_name))
|
||||||
file_path = os.path.join(path, elem_name)
|
file_path = os.path.join(path, elem_name)
|
||||||
log.debug(' "%s"'%(file_path))
|
#log.debug(' "%s"'%(file_path))
|
||||||
|
|
||||||
module = None
|
module = None
|
||||||
|
|
||||||
if os.path.isfile(file_path) and fnmatch.fnmatch(file_path,'*.py'):
|
if os.path.isfile(file_path) and fnmatch.fnmatch(file_path,'*.py'):
|
||||||
module_name = os.path.splitext(elem_name)[0]
|
module_name = os.path.splitext(elem_name)[0]
|
||||||
log.debug('Possible module detected.')
|
#log.debug('Possible module detected.')
|
||||||
try:
|
try:
|
||||||
module = __import__(module_name)
|
module = __import__(module_name)
|
||||||
log.debug('Module imported.')
|
#log.debug('Module imported.')
|
||||||
except ValueError, value_error:
|
except ValueError, value_error:
|
||||||
log.debug('Module not imported successfully. ValueError: %s'%(value_error))
|
pass
|
||||||
|
#log.debug('Module not imported successfully. ValueError: %s'%(value_error))
|
||||||
except ImportError, import_error:
|
except ImportError, import_error:
|
||||||
log.debug('Module not imported successfully. ImportError: %s'%(import_error))
|
pass
|
||||||
|
#log.debug('Module not imported successfully. ImportError: %s'%(import_error))
|
||||||
|
|
||||||
elif os.path.isdir(file_path):
|
elif os.path.isdir(file_path):
|
||||||
module_name = elem_name
|
module_name = elem_name
|
||||||
file_path += os.path.sep
|
file_path += os.path.sep
|
||||||
log.debug('Possible package detected.')
|
#log.debug('Possible package detected.')
|
||||||
try:
|
try:
|
||||||
module = __import__(module_name)
|
module = __import__(module_name)
|
||||||
log.debug('Package imported.')
|
#log.debug('Package imported.')
|
||||||
except ValueError, value_error:
|
except ValueError, value_error:
|
||||||
log.debug('Package not imported successfully. ValueError: %s'%(value_error))
|
pass
|
||||||
|
#log.debug('Package not imported successfully. ValueError: %s'%(value_error))
|
||||||
except ImportError, import_error:
|
except ImportError, import_error:
|
||||||
log.debug('Package not imported successfully. ImportError: %s'%(import_error))
|
pass
|
||||||
|
#log.debug('Package not imported successfully. ImportError: %s'%(import_error))
|
||||||
|
|
||||||
|
|
||||||
if module:
|
if module:
|
||||||
log.debug('Attributes processing started')
|
#log.debug('Attributes processing started')
|
||||||
for module_attr_name in [attr_name for attr_name in dir(module)
|
for module_attr_name in [attr_name for attr_name in dir(module)
|
||||||
if not (attr_name.startswith('__') or
|
if not (attr_name.startswith('__') or
|
||||||
attr_name.endswith('__'))]:
|
attr_name.endswith('__'))]:
|
||||||
module_attr = getattr(module, module_attr_name)
|
module_attr = getattr(module, module_attr_name)
|
||||||
log.debug('%s : %s'%(module_attr_name, module_attr))
|
#log.debug('%s : %s'%(module_attr_name, module_attr))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if issubclass(module_attr, GajimPlugin) and \
|
if issubclass(module_attr, GajimPlugin) and \
|
||||||
not module_attr is GajimPlugin:
|
not module_attr is GajimPlugin:
|
||||||
log.debug('is subclass of GajimPlugin')
|
#log.debug('is subclass of GajimPlugin')
|
||||||
#log.debug('file_path: %s\nabspath: %s\ndirname: %s'%(file_path, os.path.abspath(file_path), os.path.dirname(os.path.abspath(file_path))))
|
#log.debug('file_path: %s\nabspath: %s\ndirname: %s'%(file_path, os.path.abspath(file_path), os.path.dirname(os.path.abspath(file_path))))
|
||||||
#log.debug('file_path: %s\ndirname: %s\nabspath: %s'%(file_path, os.path.dirname(file_path), os.path.abspath(os.path.dirname(file_path))))
|
#log.debug('file_path: %s\ndirname: %s\nabspath: %s'%(file_path, os.path.dirname(file_path), os.path.abspath(os.path.dirname(file_path))))
|
||||||
module_attr.__path__ = os.path.abspath(os.path.dirname(file_path))
|
module_attr.__path__ = os.path.abspath(os.path.dirname(file_path))
|
||||||
plugins_found.append(module_attr)
|
plugins_found.append(module_attr)
|
||||||
except TypeError, type_error:
|
except TypeError, type_error:
|
||||||
log.debug('module_attr: %s, error : %s'%(
|
pass
|
||||||
module_name+'.'+module_attr_name,
|
#log.debug('module_attr: %s, error : %s'%(
|
||||||
type_error))
|
#module_name+'.'+module_attr_name,
|
||||||
|
#type_error))
|
||||||
|
|
||||||
log.debug(module)
|
#log.debug(module)
|
||||||
|
|
||||||
return plugins_found
|
return plugins_found
|
Loading…
Reference in New Issue