Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉric Araujo <merwok@netwok.org>2010-04-08 03:20:17 +0400
committerÉric Araujo <merwok@netwok.org>2010-04-08 03:20:17 +0400
commit9b5ee1e13b3a3e9f31aeec48e62fa69271c35e1e (patch)
treec5adfc610d64e6b8428f3fb2e780021b81c4e374 /plugins
parent57cd53aea13ecd05fdd1782534b9921901e1ec62 (diff)
convert tabs to spaces in source code thanks to reindent.py
Also use sed to remove now unneeded Vim lines, 2to3 -f ws_comma to fix some whitespace, and fix some other madness manually.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/acronyms_expander.py123
-rw-r--r--plugins/banner_tweaks/__init__.py2
-rw-r--r--plugins/banner_tweaks/plugin.py316
-rw-r--r--plugins/dbus_plugin/__init__.py2
-rw-r--r--plugins/dbus_plugin/plugin.py1371
-rw-r--r--plugins/events_dump/__init__.py2
-rw-r--r--plugins/events_dump/plugin.py190
-rw-r--r--plugins/google_translation/__init__.py2
-rw-r--r--plugins/google_translation/plugin.py151
-rw-r--r--plugins/length_notifier/__init__.py2
-rw-r--r--plugins/length_notifier/length_notifier.py249
-rw-r--r--plugins/new_events_example/__init__.py2
-rw-r--r--plugins/new_events_example/plugin.py206
-rw-r--r--plugins/roster_buttons/plugin.py101
-rwxr-xr-xplugins/snarl_notifications/PySnarl.py1544
-rw-r--r--plugins/snarl_notifications/__init__.py2
-rw-r--r--plugins/snarl_notifications/plugin.py97
17 files changed, 2178 insertions, 2184 deletions
diff --git a/plugins/acronyms_expander.py b/plugins/acronyms_expander.py
index 69e2448e5..12ad677b0 100644
--- a/plugins/acronyms_expander.py
+++ b/plugins/acronyms_expander.py
@@ -33,69 +33,70 @@ from plugins import GajimPlugin
from plugins.helpers import log, log_calls
class AcronymsExpanderPlugin(GajimPlugin):
- name = u'Acronyms Expander'
- short_name = u'acronyms_expander'
- version = u'0.1'
- description = u'''Replaces acronyms (or other strings) with given expansions/substitutes.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('AcronymsExpanderPlugin')
- def init(self):
- self.config_dialog = None
-
- self.gui_extension_points = {
- 'chat_control_base' : (self.connect_with_chat_control_base,
- self.disconnect_from_chat_control_base)
- }
+ name = u'Acronyms Expander'
+ short_name = u'acronyms_expander'
+ version = u'0.1'
+ description = u'''Replaces acronyms (or other strings) with given expansions/substitutes.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
- self.config_default_values = {'INVOKER' : (' ', _('')),
- 'ACRONYMS' : ({'RTFM' : 'Read The Friendly Manual',
- '/slap' : '/me slaps',
- 'PS-' : 'plug-in system',
- 'G-' : 'Gajim',
- 'GNT-' : 'http://trac.gajim.org/newticket',
- 'GW-' : 'http://trac.gajim.org/',
- 'GTS-' : 'http://trac.gajim.org/report'
- }, _('')),
- }
+ @log_calls('AcronymsExpanderPlugin')
+ def init(self):
+ self.config_dialog = None
- @log_calls('AcronymsExpanderPlugin')
- def textbuffer_live_acronym_expander(self, tb):
- """
- @param tb gtk.TextBuffer
- """
- #assert isinstance(tb,gtk.TextBuffer)
- ACRONYMS = self.config['ACRONYMS']
- INVOKER = self.config['INVOKER']
- t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
- #log.debug('%s %d'%(t, len(t)))
- if t and t[-1] == INVOKER:
- #log.debug('changing msg text')
- base,sep,head=t[:-1].rpartition(INVOKER)
- log.debug('%s | %s | %s'%(base, sep, head))
- if head in ACRONYMS:
- head = ACRONYMS[head]
- #log.debug('head: %s'%(head))
- t = ''.join((base, sep, head, INVOKER))
- #log.debug("setting text: '%s'"%(t))
- gobject.idle_add(tb.set_text, t)
-
- @log_calls('AcronymsExpanderPlugin')
- def connect_with_chat_control_base(self, chat_control):
- d = {}
- tv = chat_control.msg_textview
- tb = tv.get_buffer()
- h_id = tb.connect('changed', self.textbuffer_live_acronym_expander)
- d['h_id'] = h_id
+ self.gui_extension_points = {
+ 'chat_control_base': (self.connect_with_chat_control_base,
+ self.disconnect_from_chat_control_base)
+ }
- chat_control.acronyms_expander_plugin_data = d
+ self.config_default_values = {
+ 'INVOKER': (' ', _('')),
+ 'ACRONYMS': ({'RTFM': 'Read The Friendly Manual',
+ '/slap': '/me slaps',
+ 'PS-': 'plug-in system',
+ 'G-': 'Gajim',
+ 'GNT-': 'http://trac.gajim.org/newticket',
+ 'GW-': 'http://trac.gajim.org/',
+ 'GTS-': 'http://trac.gajim.org/report',
+ },
+ _('')),
+ }
- return True
+ @log_calls('AcronymsExpanderPlugin')
+ def textbuffer_live_acronym_expander(self, tb):
+ """
+ @param tb gtk.TextBuffer
+ """
+ #assert isinstance(tb,gtk.TextBuffer)
+ ACRONYMS = self.config['ACRONYMS']
+ INVOKER = self.config['INVOKER']
+ t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
+ #log.debug('%s %d'%(t, len(t)))
+ if t and t[-1] == INVOKER:
+ #log.debug('changing msg text')
+ base, sep, head=t[:-1].rpartition(INVOKER)
+ log.debug('%s | %s | %s'%(base, sep, head))
+ if head in ACRONYMS:
+ head = ACRONYMS[head]
+ #log.debug('head: %s'%(head))
+ t = ''.join((base, sep, head, INVOKER))
+ #log.debug("setting text: '%s'"%(t))
+ gobject.idle_add(tb.set_text, t)
- @log_calls('AcronymsExpanderPlugin')
- def disconnect_from_chat_control_base(self, chat_control):
- d = chat_control.acronyms_expander_plugin_data
- tv = chat_control.msg_textview
- tv.get_buffer().disconnect(d['h_id'])
-
+ @log_calls('AcronymsExpanderPlugin')
+ def connect_with_chat_control_base(self, chat_control):
+ d = {}
+ tv = chat_control.msg_textview
+ tb = tv.get_buffer()
+ h_id = tb.connect('changed', self.textbuffer_live_acronym_expander)
+ d['h_id'] = h_id
+
+ chat_control.acronyms_expander_plugin_data = d
+
+ return True
+
+ @log_calls('AcronymsExpanderPlugin')
+ def disconnect_from_chat_control_base(self, chat_control):
+ d = chat_control.acronyms_expander_plugin_data
+ tv = chat_control.msg_textview
+ tv.get_buffer().disconnect(d['h_id'])
diff --git a/plugins/banner_tweaks/__init__.py b/plugins/banner_tweaks/__init__.py
index f8266d228..a328f68ee 100644
--- a/plugins/banner_tweaks/__init__.py
+++ b/plugins/banner_tweaks/__init__.py
@@ -1,2 +1,2 @@
-from plugin import BannerTweaksPlugin \ No newline at end of file
+from plugin import BannerTweaksPlugin
diff --git a/plugins/banner_tweaks/plugin.py b/plugins/banner_tweaks/plugin.py
index ad03765db..121606aa4 100644
--- a/plugins/banner_tweaks/plugin.py
+++ b/plugins/banner_tweaks/plugin.py
@@ -43,163 +43,163 @@ from plugins.helpers import log, log_calls
from plugins.gui import GajimPluginConfigDialog
class BannerTweaksPlugin(GajimPlugin):
- name = u'Banner Tweaks'
- short_name = u'banner_tweaks'
- version = u'0.1'
- description = u'''Allows user to tweak chat window banner appearance (eg. make it compact).
-
-Based on patch by pb in ticket #4133:
+ name = u'Banner Tweaks'
+ short_name = u'banner_tweaks'
+ version = u'0.1'
+ description = u'''Allows user to tweak chat window banner appearance (eg. make it compact).
+
+Based on patch by pb in ticket #4133:
http://trac.gajim.org/attachment/ticket/4133'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('BannerTweaksPlugin')
- def init(self):
- self.config_dialog = BannerTweaksPluginConfigDialog(self)
-
- self.gui_extension_points = {
- 'chat_control_base_draw_banner' : (self.chat_control_base_draw_banner_called,
- self.chat_control_base_draw_banner_deactivation)
- }
-
- self.config_default_values = {'show_banner_image': (True, _('If True, Gajim will display a status icon in the banner of chat windows.')),
- 'show_banner_online_msg': (True, _('If True, Gajim will display the status message of the contact in the banner of chat windows.')),
- 'show_banner_resource': (False, _('If True, Gajim will display the resource name of the contact in the banner of chat windows.')),
- 'banner_small_fonts': (False, _('If True, Gajim will use small fonts for contact name and resource name in the banner of chat windows.')),
- 'old_chat_avatar_height' : (52, _('chat_avatar_height value before plugin was activated')),
- }
-
- @log_calls('BannerTweaksPlugin')
- def activate(self):
- self.config['old_chat_avatar_height'] = gajim.config.get('chat_avatar_height')
- #gajim.config.set('chat_avatar_height', 28)
-
- @log_calls('BannerTweaksPlugin')
- def deactivate(self):
- gajim.config.set('chat_avatar_height', self.config['old_chat_avatar_height'])
-
- @log_calls('BannerTweaksPlugin')
- def chat_control_base_draw_banner_called(self, chat_control):
- if not self.config['show_banner_online_msg']:
- chat_control.banner_status_label.hide()
- chat_control.banner_status_label.set_no_show_all(True)
- status_text = ''
- chat_control.banner_status_label.set_markup(status_text)
-
- if not self.config['show_banner_image']:
- banner_status_img = chat_control.xml.get_object('banner_status_image')
- banner_status_img.clear()
-
- # TODO: part below repeats a lot of code from ChatControl.draw_banner_text()
- # This could be rewritten using re module: getting markup text from
- # banner_name_label and replacing some elements based on plugin config.
- # Would it be faster?
- if self.config['show_banner_resource'] or self.config['banner_small_fonts']:
- banner_name_label = chat_control.xml.get_object('banner_name_label')
- label_text = banner_name_label.get_label()
-
- contact = chat_control.contact
- jid = contact.jid
-
- name = contact.get_shown_name()
- if chat_control.resource:
- name += '/' + chat_control.resource
- elif contact.resource and self.config['show_banner_resource']:
- name += '/' + contact.resource
-
- if chat_control.TYPE_ID == message_control.TYPE_PM:
- name = _('%(nickname)s from group chat %(room_name)s') %\
- {'nickname': name, 'room_name': chat_control.room_name}
- name = gobject.markup_escape_text(name)
-
- # We know our contacts nick, but if another contact has the same nick
- # in another account we need to also display the account.
- # except if we are talking to two different resources of the same contact
- acct_info = ''
- for account in gajim.contacts.get_accounts():
- if account == chat_control.account:
- continue
- if acct_info: # We already found a contact with same nick
- break
- for jid in gajim.contacts.get_jid_list(account):
- other_contact_ = \
- gajim.contacts.get_first_contact_from_jid(account, jid)
- if other_contact_.get_shown_name() == chat_control.contact.get_shown_name():
- acct_info = ' (%s)' % \
- gobject.markup_escape_text(chat_control.account)
- break
-
- font_attrs, font_attrs_small = chat_control.get_font_attrs()
- if self.config['banner_small_fonts']:
- font_attrs = font_attrs_small
-
- st = gajim.config.get('displayed_chat_state_notifications')
- cs = contact.chatstate
- if cs and st in ('composing_only', 'all'):
- if contact.show == 'offline':
- chatstate = ''
- elif contact.composing_xep == 'XEP-0085':
- if st == 'all' or cs == 'composing':
- chatstate = helpers.get_uf_chatstate(cs)
- else:
- chatstate = ''
- elif contact.composing_xep == 'XEP-0022':
- if cs in ('composing', 'paused'):
- # only print composing, paused
- chatstate = helpers.get_uf_chatstate(cs)
- else:
- chatstate = ''
- else:
- # When does that happen ? See [7797] and [7804]
- chatstate = helpers.get_uf_chatstate(cs)
-
- label_text = '<span %s>%s</span><span %s>%s %s</span>' % \
- (font_attrs, name, font_attrs_small, acct_info, chatstate)
- else:
- # weight="heavy" size="x-large"
- label_text = '<span %s>%s</span><span %s>%s</span>' % \
- (font_attrs, name, font_attrs_small, acct_info)
-
- banner_name_label.set_markup(label_text)
-
- @log_calls('BannerTweaksPlugin')
- def chat_control_base_draw_banner_deactivation(self, chat_control):
- pass
- #chat_control.draw_banner()
-
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('BannerTweaksPlugin')
+ def init(self):
+ self.config_dialog = BannerTweaksPluginConfigDialog(self)
+
+ self.gui_extension_points = {
+ 'chat_control_base_draw_banner': (self.chat_control_base_draw_banner_called,
+ self.chat_control_base_draw_banner_deactivation)
+ }
+
+ self.config_default_values = {
+ 'show_banner_image': (True, _('If True, Gajim will display a status icon in the banner of chat windows.')),
+ 'show_banner_online_msg': (True, _('If True, Gajim will display the status message of the contact in the banner of chat windows.')),
+ 'show_banner_resource': (False, _('If True, Gajim will display the resource name of the contact in the banner of chat windows.')),
+ 'banner_small_fonts': (False, _('If True, Gajim will use small fonts for contact name and resource name in the banner of chat windows.')),
+ 'old_chat_avatar_height': (52, _('chat_avatar_height value before plugin was activated')),
+ }
+
+ @log_calls('BannerTweaksPlugin')
+ def activate(self):
+ self.config['old_chat_avatar_height'] = gajim.config.get('chat_avatar_height')
+ #gajim.config.set('chat_avatar_height', 28)
+
+ @log_calls('BannerTweaksPlugin')
+ def deactivate(self):
+ gajim.config.set('chat_avatar_height', self.config['old_chat_avatar_height'])
+
+ @log_calls('BannerTweaksPlugin')
+ def chat_control_base_draw_banner_called(self, chat_control):
+ if not self.config['show_banner_online_msg']:
+ chat_control.banner_status_label.hide()
+ chat_control.banner_status_label.set_no_show_all(True)
+ status_text = ''
+ chat_control.banner_status_label.set_markup(status_text)
+
+ if not self.config['show_banner_image']:
+ banner_status_img = chat_control.xml.get_object('banner_status_image')
+ banner_status_img.clear()
+
+ # TODO: part below repeats a lot of code from ChatControl.draw_banner_text()
+ # This could be rewritten using re module: getting markup text from
+ # banner_name_label and replacing some elements based on plugin config.
+ # Would it be faster?
+ if self.config['show_banner_resource'] or self.config['banner_small_fonts']:
+ banner_name_label = chat_control.xml.get_object('banner_name_label')
+ label_text = banner_name_label.get_label()
+
+ contact = chat_control.contact
+ jid = contact.jid
+
+ name = contact.get_shown_name()
+ if chat_control.resource:
+ name += '/' + chat_control.resource
+ elif contact.resource and self.config['show_banner_resource']:
+ name += '/' + contact.resource
+
+ if chat_control.TYPE_ID == message_control.TYPE_PM:
+ name = _('%(nickname)s from group chat %(room_name)s') %\
+ {'nickname': name, 'room_name': chat_control.room_name}
+ name = gobject.markup_escape_text(name)
+
+ # We know our contacts nick, but if another contact has the same nick
+ # in another account we need to also display the account.
+ # except if we are talking to two different resources of the same contact
+ acct_info = ''
+ for account in gajim.contacts.get_accounts():
+ if account == chat_control.account:
+ continue
+ if acct_info: # We already found a contact with same nick
+ break
+ for jid in gajim.contacts.get_jid_list(account):
+ other_contact_ = \
+ gajim.contacts.get_first_contact_from_jid(account, jid)
+ if other_contact_.get_shown_name() == chat_control.contact.get_shown_name():
+ acct_info = ' (%s)' % \
+ gobject.markup_escape_text(chat_control.account)
+ break
+
+ font_attrs, font_attrs_small = chat_control.get_font_attrs()
+ if self.config['banner_small_fonts']:
+ font_attrs = font_attrs_small
+
+ st = gajim.config.get('displayed_chat_state_notifications')
+ cs = contact.chatstate
+ if cs and st in ('composing_only', 'all'):
+ if contact.show == 'offline':
+ chatstate = ''
+ elif contact.composing_xep == 'XEP-0085':
+ if st == 'all' or cs == 'composing':
+ chatstate = helpers.get_uf_chatstate(cs)
+ else:
+ chatstate = ''
+ elif contact.composing_xep == 'XEP-0022':
+ if cs in ('composing', 'paused'):
+ # only print composing, paused
+ chatstate = helpers.get_uf_chatstate(cs)
+ else:
+ chatstate = ''
+ else:
+ # When does that happen ? See [7797] and [7804]
+ chatstate = helpers.get_uf_chatstate(cs)
+
+ label_text = '<span %s>%s</span><span %s>%s %s</span>' % \
+ (font_attrs, name, font_attrs_small, acct_info, chatstate)
+ else:
+ # weight="heavy" size="x-large"
+ label_text = '<span %s>%s</span><span %s>%s</span>' % \
+ (font_attrs, name, font_attrs_small, acct_info)
+
+ banner_name_label.set_markup(label_text)
+
+ @log_calls('BannerTweaksPlugin')
+ def chat_control_base_draw_banner_deactivation(self, chat_control):
+ pass
+ #chat_control.draw_banner()
+
class BannerTweaksPluginConfigDialog(GajimPluginConfigDialog):
- def init(self):
- self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
- 'config_dialog.ui')
- self.xml = gtk.Builder()
- self.xml.set_translation_domain(i18n.APP)
- self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
- ['banner_tweaks_config_vbox'])
- self.config_vbox = self.xml.get_object('banner_tweaks_config_vbox')
- self.child.pack_start(self.config_vbox)
-
- self.show_banner_image_checkbutton = self.xml.get_object('show_banner_image_checkbutton')
- self.show_banner_online_msg_checkbutton = self.xml.get_object('show_banner_online_msg_checkbutton')
- self.show_banner_resource_checkbutton = self.xml.get_object('show_banner_resource_checkbutton')
- self.banner_small_fonts_checkbutton = self.xml.get_object('banner_small_fonts_checkbutton')
-
- self.xml.connect_signals(self)
-
- def on_run(self):
- self.show_banner_image_checkbutton.set_active(self.plugin.config['show_banner_image'])
- self.show_banner_online_msg_checkbutton.set_active(self.plugin.config['show_banner_online_msg'])
- self.show_banner_resource_checkbutton.set_active(self.plugin.config['show_banner_resource'])
- self.banner_small_fonts_checkbutton.set_active(self.plugin.config['banner_small_fonts'])
-
- def on_show_banner_image_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_image'] = button.get_active()
-
- def on_show_banner_online_msg_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_online_msg'] = button.get_active()
-
- def on_show_banner_resource_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_resource'] = button.get_active()
-
- def on_banner_small_fonts_checkbutton_toggled(self, button):
- self.plugin.config['banner_small_fonts'] = button.get_active()
-
+ def init(self):
+ self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
+ 'config_dialog.ui')
+ self.xml = gtk.Builder()
+ self.xml.set_translation_domain(i18n.APP)
+ self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
+ ['banner_tweaks_config_vbox'])
+ self.config_vbox = self.xml.get_object('banner_tweaks_config_vbox')
+ self.child.pack_start(self.config_vbox)
+
+ self.show_banner_image_checkbutton = self.xml.get_object('show_banner_image_checkbutton')
+ self.show_banner_online_msg_checkbutton = self.xml.get_object('show_banner_online_msg_checkbutton')
+ self.show_banner_resource_checkbutton = self.xml.get_object('show_banner_resource_checkbutton')
+ self.banner_small_fonts_checkbutton = self.xml.get_object('banner_small_fonts_checkbutton')
+
+ self.xml.connect_signals(self)
+
+ def on_run(self):
+ self.show_banner_image_checkbutton.set_active(self.plugin.config['show_banner_image'])
+ self.show_banner_online_msg_checkbutton.set_active(self.plugin.config['show_banner_online_msg'])
+ self.show_banner_resource_checkbutton.set_active(self.plugin.config['show_banner_resource'])
+ self.banner_small_fonts_checkbutton.set_active(self.plugin.config['banner_small_fonts'])
+
+ def on_show_banner_image_checkbutton_toggled(self, button):
+ self.plugin.config['show_banner_image'] = button.get_active()
+
+ def on_show_banner_online_msg_checkbutton_toggled(self, button):
+ self.plugin.config['show_banner_online_msg'] = button.get_active()
+
+ def on_show_banner_resource_checkbutton_toggled(self, button):
+ self.plugin.config['show_banner_resource'] = button.get_active()
+
+ def on_banner_small_fonts_checkbutton_toggled(self, button):
+ self.plugin.config['banner_small_fonts'] = button.get_active()
diff --git a/plugins/dbus_plugin/__init__.py b/plugins/dbus_plugin/__init__.py
index c5c296ad7..3851c6bb9 100644
--- a/plugins/dbus_plugin/__init__.py
+++ b/plugins/dbus_plugin/__init__.py
@@ -1 +1 @@
-from plugin import DBusPlugin \ No newline at end of file
+from plugin import DBusPlugin
diff --git a/plugins/dbus_plugin/plugin.py b/plugins/dbus_plugin/plugin.py
index ac26c3b1d..c34e0ad0c 100644
--- a/plugins/dbus_plugin/plugin.py
+++ b/plugins/dbus_plugin/plugin.py
@@ -6,7 +6,7 @@
## Copyright (C) 2005-2006 Andrew Sayman <lorien420@myrealbox.com>
## Copyright (C) 2007 Lukas Petrovicky <lukas@petrovicky.net>
## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
-## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
+## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
## Copyright (C) 2008 Mateusz Biliński <mateusz@bilinski.it>
##
## This file is part of Gajim.
@@ -41,634 +41,634 @@ import gobject
from common import dbus_support
if dbus_support.supported:
- import dbus
- if dbus_support:
- INTERFACE = 'org.gajim.dbusplugin.RemoteInterface'
- OBJ_PATH = '/org/gajim/dbusplugin/RemoteObject'
- SERVICE = 'org.gajim.dbusplugin'
-
- import dbus.service
- import dbus.glib
- # type mapping
-
- # in most cases it is a utf-8 string
- DBUS_STRING = dbus.String
-
- # general type (for use in dicts, where all values should have the same type)
- DBUS_BOOLEAN = dbus.Boolean
- DBUS_DOUBLE = dbus.Double
- DBUS_INT32 = dbus.Int32
- # dictionary with string key and binary value
- DBUS_DICT_SV = lambda : dbus.Dictionary({}, signature="sv")
- # dictionary with string key and value
- DBUS_DICT_SS = lambda : dbus.Dictionary({}, signature="ss")
- # empty type (there is no equivalent of None on D-Bus, but historically gajim
- # used 0 instead)
- DBUS_NONE = lambda : dbus.Int32(0)
-
- def get_dbus_struct(obj):
- ''' recursively go through all the items and replace
- them with their casted dbus equivalents
- '''
- if obj is None:
- return DBUS_NONE()
- if isinstance(obj, (unicode, str)):
- return DBUS_STRING(obj)
- if isinstance(obj, int):
- return DBUS_INT32(obj)
- if isinstance(obj, float):
- return DBUS_DOUBLE(obj)
- if isinstance(obj, bool):
- return DBUS_BOOLEAN(obj)
- if isinstance(obj, (list, tuple)):
- result = dbus.Array([get_dbus_struct(i) for i in obj],
- signature='v')
- if result == []:
- return DBUS_NONE()
- return result
- if isinstance(obj, dict):
- result = DBUS_DICT_SV()
- for key, value in obj.items():
- result[DBUS_STRING(key)] = get_dbus_struct(value)
- if result == {}:
- return DBUS_NONE()
- return result
- # unknown type
- return DBUS_NONE()
-
- class SignalObject(dbus.service.Object):
- ''' Local object definition for /org/gajim/dbus/RemoteObject.
- (This docstring is not be visible, because the clients can access only the remote object.)'''
-
- def __init__(self, bus_name):
- self.first_show = True
- self.vcard_account = None
-
- # register our dbus API
- dbus.service.Object.__init__(self, bus_name, OBJ_PATH)
-
- @dbus.service.signal(INTERFACE, signature='av')
- def Roster(self, account_and_data):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def AccountPresence(self, status_and_account):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def ContactPresence(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def ContactAbsence(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def ContactStatus(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def NewMessage(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def Subscribe(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def Subscribed(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def Unsubscribed(self, account_and_jid):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def NewAccount(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def VcardInfo(self, account_and_vcard):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def LastStatusTime(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def OsInfo(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def GCPresence(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def GCMessage(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def RosterInfo(self, account_and_array):
- pass
-
- @dbus.service.signal(INTERFACE, signature='av')
- def NewGmail(self, account_and_array):
- pass
-
- def raise_signal(self, signal, arg):
- '''raise a signal, with a single argument of unspecified type
- Instead of obj.raise_signal("Foo", bar), use obj.Foo(bar).'''
- getattr(self, signal)(arg)
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
- def get_status(self, account):
- '''Returns status (show to be exact) which is the global one
- unless account is given'''
- if not account:
- # If user did not ask for account, returns the global status
- return DBUS_STRING(helpers.get_global_show())
- # return show for the given account
- index = gajim.connections[account].connected
- return DBUS_STRING(gajim.SHOW_LIST[index])
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
- def get_status_message(self, account):
- '''Returns status which is the global one
- unless account is given'''
- if not account:
- # If user did not ask for account, returns the global status
- return DBUS_STRING(str(helpers.get_global_status()))
- # return show for the given account
- status = gajim.connections[account].status
- return DBUS_STRING(status)
-
- def _get_account_and_contact(self, account, jid):
- '''get the account (if not given) and contact instance from jid'''
- connected_account = None
- contact = None
- accounts = gajim.contacts.get_accounts()
- # if there is only one account in roster, take it as default
- # if user did not ask for account
- if not account and len(accounts) == 1:
- account = accounts[0]
- if account:
- if gajim.connections[account].connected > 1: # account is connected
- connected_account = account
- contact = gajim.contacts.get_contact_with_highest_priority(account,
- jid)
- else:
- for account in accounts:
- contact = gajim.contacts.get_contact_with_highest_priority(account,
- jid)
- if contact and gajim.connections[account].connected > 1:
- # account is connected
- connected_account = account
- break
- if not contact:
- contact = jid
-
- return connected_account, contact
-
- def _get_account_for_groupchat(self, account, room_jid):
- '''get the account which is connected to groupchat (if not given)
- or check if the given account is connected to the groupchat'''
- connected_account = None
- accounts = gajim.contacts.get_accounts()
- # if there is only one account in roster, take it as default
- # if user did not ask for account
- if not account and len(accounts) == 1:
- account = accounts[0]
- if account:
- if gajim.connections[account].connected > 1 and \
- room_jid in gajim.gc_connected[account] and \
- gajim.gc_connected[account][room_jid]:
- # account and groupchat are connected
- connected_account = account
- else:
- for account in accounts:
- if gajim.connections[account].connected > 1 and \
- room_jid in gajim.gc_connected[account] and \
- gajim.gc_connected[account][room_jid]:
- # account and groupchat are connected
- connected_account = account
- break
- return connected_account
-
- @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
- def send_file(self, file_path, jid, account):
- '''send file, located at 'file_path' to 'jid', using account
- (optional) 'account' '''
- jid = self._get_real_jid(jid, account)
- connected_account, contact = self._get_account_and_contact(account, jid)
-
- if connected_account:
- if file_path[:7] == 'file://':
- file_path=file_path[7:]
- if os.path.isfile(file_path): # is it file?
- gajim.interface.instances['file_transfers'].send_file(
- connected_account, contact, file_path)
- return DBUS_BOOLEAN(True)
- return DBUS_BOOLEAN(False)
-
- def _send_message(self, jid, message, keyID, account, type = 'chat',
- subject = None):
- '''can be called from send_chat_message (default when send_message)
- or send_single_message'''
- if not jid or not message:
- return DBUS_BOOLEAN(False)
- if not keyID:
- keyID = ''
-
- connected_account, contact = self._get_account_and_contact(account, jid)
- if connected_account:
- connection = gajim.connections[connected_account]
- connection.send_message(jid, message, keyID, type, subject)
- return DBUS_BOOLEAN(True)
- return DBUS_BOOLEAN(False)
-
- @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='b')
- def send_chat_message(self, jid, message, keyID, account):
- '''Send chat 'message' to 'jid', using account (optional) 'account'.
- if keyID is specified, encrypt the message with the pgp key '''
- jid = self._get_real_jid(jid, account)
- return self._send_message(jid, message, keyID, account)
-
- @dbus.service.method(INTERFACE, in_signature='sssss', out_signature='b')
- def send_single_message(self, jid, subject, message, keyID, account):
- '''Send single 'message' to 'jid', using account (optional) 'account'.
- if keyID is specified, encrypt the message with the pgp key '''
- jid = self._get_real_jid(jid, account)
- return self._send_message(jid, message, keyID, account, type, subject)
-
- @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
- def send_groupchat_message(self, room_jid, message, account):
- '''Send 'message' to groupchat 'room_jid',
- using account (optional) 'account'.'''
- if not room_jid or not message:
- return DBUS_BOOLEAN(False)
- connected_account = self._get_account_for_groupchat(account, room_jid)
- if connected_account:
- connection = gajim.connections[connected_account]
- connection.send_gc_message(room_jid, message)
- return DBUS_BOOLEAN(True)
- return DBUS_BOOLEAN(False)
-
- @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
- def open_chat(self, jid, account):
- '''Shows the tabbed window for new message to 'jid', using account
- (optional) 'account' '''
- if not jid:
- raise MissingArgument
- return DBUS_BOOLEAN(False)
- jid = self._get_real_jid(jid, account)
- try:
- jid = helpers.parse_jid(jid)
- except:
- # Jid is not conform, ignore it
- return DBUS_BOOLEAN(False)
-
- if account:
- accounts = [account]
- else:
- accounts = gajim.connections.keys()
- if len(accounts) == 1:
- account = accounts[0]
- connected_account = None
- first_connected_acct = None
- for acct in accounts:
- if gajim.connections[acct].connected > 1: # account is online
- contact = gajim.contacts.get_first_contact_from_jid(acct, jid)
- if gajim.interface.msg_win_mgr.has_window(jid, acct):
- connected_account = acct
- break
- # jid is in roster
- elif contact:
- connected_account = acct
- break
- # we send the message to jid not in roster, because account is
- # specified, or there is only one account
- elif account:
- connected_account = acct
- elif first_connected_acct is None:
- first_connected_acct = acct
-
- # if jid is not a conntact, open-chat with first connected account
- if connected_account is None and first_connected_acct:
- connected_account = first_connected_acct
-
- if connected_account:
- gajim.interface.new_chat_from_jid(connected_account, jid)
- # preserve the 'steal focus preservation'
- win = gajim.interface.msg_win_mgr.get_window(jid,
- connected_account).window
- if win.get_property('visible'):
- win.window.focus()
- return DBUS_BOOLEAN(True)
- return DBUS_BOOLEAN(False)
-
- @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
- def change_status(self, status, message, account):
- ''' change_status(status, message, account). account is optional -
- if not specified status is changed for all accounts. '''
- if status not in ('offline', 'online', 'chat',
- 'away', 'xa', 'dnd', 'invisible'):
- return DBUS_BOOLEAN(False)
- if account:
- gobject.idle_add(gajim.interface.roster.send_status, account,
- status, message)
- else:
- # account not specified, so change the status of all accounts
- for acc in gajim.contacts.get_accounts():
- if not gajim.config.get_per('accounts', acc,
- 'sync_with_global_status'):
- continue
- gobject.idle_add(gajim.interface.roster.send_status, acc,
- status, message)
- return DBUS_BOOLEAN(False)
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='')
- def show_next_pending_event(self):
- '''Show the window(s) with next pending event in tabbed/group chats.'''
- if gajim.events.get_nb_events():
- gajim.interface.systray.handle_first_event()
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{sv}')
- def contact_info(self, jid):
- '''get vcard info for a contact. Return cached value of the vcard.
- '''
- if not isinstance(jid, unicode):
- jid = unicode(jid)
- if not jid:
- raise MissingArgument
- return DBUS_DICT_SV()
- jid = self._get_real_jid(jid)
-
- cached_vcard = gajim.connections.values()[0].get_cached_vcard(jid)
- if cached_vcard:
- return get_dbus_struct(cached_vcard)
-
- # return empty dict
- return DBUS_DICT_SV()
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='as')
- def list_accounts(self):
- '''list register accounts'''
- result = gajim.contacts.get_accounts()
- result_array = dbus.Array([], signature='s')
- if result and len(result) > 0:
- for account in result:
- result_array.append(DBUS_STRING(account))
- return result_array
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{ss}')
- def account_info(self, account):
- '''show info on account: resource, jid, nick, prio, message'''
- result = DBUS_DICT_SS()
- if gajim.connections.has_key(account):
- # account is valid
- con = gajim.connections[account]
- index = con.connected
- result['status'] = DBUS_STRING(gajim.SHOW_LIST[index])
- result['name'] = DBUS_STRING(con.name)
- result['jid'] = DBUS_STRING(gajim.get_jid_from_account(con.name))
- result['message'] = DBUS_STRING(con.status)
- result['priority'] = DBUS_STRING(unicode(con.priority))
- result['resource'] = DBUS_STRING(unicode(gajim.config.get_per(
- 'accounts', con.name, 'resource')))
- return result
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='aa{sv}')
- def list_contacts(self, account):
- '''list all contacts in the roster. If the first argument is specified,
- then return the contacts for the specified account'''
- result = dbus.Array([], signature='aa{sv}')
- accounts = gajim.contacts.get_accounts()
- if len(accounts) == 0:
- return result
- if account:
- accounts_to_search = [account]
- else:
- accounts_to_search = accounts
- for acct in accounts_to_search:
- if acct in accounts:
- for jid in gajim.contacts.get_jid_list(acct):
- item = self._contacts_as_dbus_structure(
- gajim.contacts.get_contacts(acct, jid))
- if item:
- result.append(item)
- return result
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='')
- def toggle_roster_appearance(self):
- ''' shows/hides the roster window '''
- win = gajim.interface.roster.window
- if win.get_property('visible'):
- gobject.idle_add(win.hide)
- else:
- win.present()
- # preserve the 'steal focus preservation'
- if self._is_first():
- win.window.focus()
- else:
- win.window.focus(long(time()))
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='')
- def toggle_ipython(self):
- ''' shows/hides the ipython window '''
- win = gajim.ipython_window
- if win:
- if win.window.is_visible():
- gobject.idle_add(win.hide)
- else:
- win.show_all()
- win.present()
- else:
- gajim.interface.create_ipython_window()
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='a{ss}')
- def prefs_list(self):
- prefs_dict = DBUS_DICT_SS()
- def get_prefs(data, name, path, value):
- if value is None:
- return
- key = ''
- if path is not None:
- for node in path:
- key += node + '#'
- key += name
- prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value[1])
- gajim.config.foreach(get_prefs)
- return prefs_dict
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='b')
- def prefs_store(self):
- try:
- gajim.interface.save_config()
- except Exception, e:
- return DBUS_BOOLEAN(False)
- return DBUS_BOOLEAN(True)
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
- def prefs_del(self, key):
- if not key:
- return DBUS_BOOLEAN(False)
- key_path = key.split('#', 2)
- if len(key_path) != 3:
- return DBUS_BOOLEAN(False)
- if key_path[2] == '*':
- gajim.config.del_per(key_path[0], key_path[1])
- else:
- gajim.config.del_per(key_path[0], key_path[1], key_path[2])
- return DBUS_BOOLEAN(True)
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
- def prefs_put(self, key):
- if not key:
- return DBUS_BOOLEAN(False)
- key_path = key.split('#', 2)
- if len(key_path) < 3:
- subname, value = key.split('=', 1)
- gajim.config.set(subname, value)
- return DBUS_BOOLEAN(True)
- subname, value = key_path[2].split('=', 1)
- gajim.config.set_per(key_path[0], key_path[1], subname, value)
- return DBUS_BOOLEAN(True)
-
- @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
- def add_contact(self, jid, account):
- if account:
- if account in gajim.connections and \
- gajim.connections[account].connected > 1:
- # if given account is active, use it
- AddNewContactWindow(account = account, jid = jid)
- else:
- # wrong account
- return DBUS_BOOLEAN(False)
- else:
- # if account is not given, show account combobox
- AddNewContactWindow(account = None, jid = jid)
- return DBUS_BOOLEAN(True)
-
- @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
- def remove_contact(self, jid, account):
- jid = self._get_real_jid(jid, account)
- accounts = gajim.contacts.get_accounts()
-
- # if there is only one account in roster, take it as default
- if account:
- accounts = [account]
- contact_exists = False
- for account in accounts:
- contacts = gajim.contacts.get_contacts(account, jid)
- if contacts:
- gajim.connections[account].unsubscribe(jid)
- for contact in contacts:
- gajim.interface.roster.remove_contact(contact, account)
- gajim.contacts.remove_jid(account, jid)
- contact_exists = True
- return DBUS_BOOLEAN(contact_exists)
-
- def _is_first(self):
- if self.first_show:
- self.first_show = False
- return True
- return False
-
- def _get_real_jid(self, jid, account = None):
- '''get the real jid from the given one: removes xmpp: or get jid from nick
- if account is specified, search only in this account
- '''
- if account:
- accounts = [account]
- else:
- accounts = gajim.connections.keys()
- if jid.startswith('xmpp:'):
- return jid[5:] # len('xmpp:') = 5
- nick_in_roster = None # Is jid a nick ?
- for account in accounts:
- # Does jid exists in roster of one account ?
- if gajim.contacts.get_contacts(account, jid):
- return jid
- if not nick_in_roster:
- # look in all contact if one has jid as nick
- for jid_ in gajim.contacts.get_jid_list(account):
- c = gajim.contacts.get_contacts(account, jid_)
- if c[0].name == jid:
- nick_in_roster = jid_
- break
- if nick_in_roster:
- # We have not found jid in roster, but we found is as a nick
- return nick_in_roster
- # We have not found it as jid nor as nick, probably a not in roster jid
- return jid
-
- def _contacts_as_dbus_structure(self, contacts):
- ''' get info from list of Contact objects and create dbus dict '''
- if not contacts:
- return None
- prim_contact = None # primary contact
- for contact in contacts:
- if prim_contact is None or contact.priority > prim_contact.priority:
- prim_contact = contact
- contact_dict = DBUS_DICT_SV()
- contact_dict['name'] = DBUS_STRING(prim_contact.name)
- contact_dict['show'] = DBUS_STRING(prim_contact.show)
- contact_dict['jid'] = DBUS_STRING(prim_contact.jid)
- if prim_contact.keyID:
- keyID = None
- if len(prim_contact.keyID) == 8:
- keyID = prim_contact.keyID
- elif len(prim_contact.keyID) == 16:
- keyID = prim_contact.keyID[8:]
- if keyID:
- contact_dict['openpgp'] = keyID
- contact_dict['resources'] = dbus.Array([], signature='(sis)')
- for contact in contacts:
- resource_props = dbus.Struct((DBUS_STRING(contact.resource),
- dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
- contact_dict['resources'].append(resource_props)
- contact_dict['groups'] = dbus.Array([], signature='(s)')
- for group in prim_contact.groups:
- contact_dict['groups'].append((DBUS_STRING(group),))
- return contact_dict
-
- @dbus.service.method(INTERFACE, in_signature='', out_signature='s')
- def get_unread_msgs_number(self):
- return DBUS_STRING(str(gajim.events.get_nb_events()))
-
- @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
- def start_chat(self, account):
- if not account:
- # error is shown in gajim-remote check_arguments(..)
- return DBUS_BOOLEAN(False)
- NewChatDialog(account)
- return DBUS_BOOLEAN(True)
-
- @dbus.service.method(INTERFACE, in_signature='ss', out_signature='')
- def send_xml(self, xml, account):
- if account:
- gajim.connections[account].send_stanza(xml)
- else:
- for acc in gajim.contacts.get_accounts():
- gajim.connections[acc].send_stanza(xml)
-
- @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='')
- def join_room(self, room_jid, nick, password, account):
- if not account:
- # get the first connected account
- accounts = gajim.connections.keys()
- for acct in accounts:
- if gajim.account_is_connected(acct):
- account = acct
- break
- if not account:
- return
- if not nick:
- nick = ''
- gajim.interface.instances[account]['join_gc'] = \
- JoinGroupchatWindow(account, room_jid, nick)
- else:
- gajim.interface.join_gc_room(account, room_jid, nick, password)
+ import dbus
+ if dbus_support:
+ INTERFACE = 'org.gajim.dbusplugin.RemoteInterface'
+ OBJ_PATH = '/org/gajim/dbusplugin/RemoteObject'
+ SERVICE = 'org.gajim.dbusplugin'
+
+ import dbus.service
+ import dbus.glib
+ # type mapping
+
+ # in most cases it is a utf-8 string
+ DBUS_STRING = dbus.String
+
+ # general type (for use in dicts, where all values should have the same type)
+ DBUS_BOOLEAN = dbus.Boolean
+ DBUS_DOUBLE = dbus.Double
+ DBUS_INT32 = dbus.Int32
+ # dictionary with string key and binary value
+ DBUS_DICT_SV = lambda : dbus.Dictionary({}, signature="sv")
+ # dictionary with string key and value
+ DBUS_DICT_SS = lambda : dbus.Dictionary({}, signature="ss")
+ # empty type (there is no equivalent of None on D-Bus, but historically gajim
+ # used 0 instead)
+ DBUS_NONE = lambda : dbus.Int32(0)
+
+ def get_dbus_struct(obj):
+ ''' recursively go through all the items and replace
+ them with their casted dbus equivalents
+ '''
+ if obj is None:
+ return DBUS_NONE()
+ if isinstance(obj, (unicode, str)):
+ return DBUS_STRING(obj)
+ if isinstance(obj, int):
+ return DBUS_INT32(obj)
+ if isinstance(obj, float):
+ return DBUS_DOUBLE(obj)
+ if isinstance(obj, bool):
+ return DBUS_BOOLEAN(obj)
+ if isinstance(obj, (list, tuple)):
+ result = dbus.Array([get_dbus_struct(i) for i in obj],
+ signature='v')
+ if result == []:
+ return DBUS_NONE()
+ return result
+ if isinstance(obj, dict):
+ result = DBUS_DICT_SV()
+ for key, value in obj.items():
+ result[DBUS_STRING(key)] = get_dbus_struct(value)
+ if result == {}:
+ return DBUS_NONE()
+ return result
+ # unknown type
+ return DBUS_NONE()
+
+ class SignalObject(dbus.service.Object):
+ ''' Local object definition for /org/gajim/dbus/RemoteObject.
+ (This docstring is not be visible, because the clients can access only the remote object.)'''
+
+ def __init__(self, bus_name):
+ self.first_show = True
+ self.vcard_account = None
+
+ # register our dbus API
+ dbus.service.Object.__init__(self, bus_name, OBJ_PATH)
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def Roster(self, account_and_data):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def AccountPresence(self, status_and_account):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def ContactPresence(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def ContactAbsence(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def ContactStatus(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def NewMessage(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def Subscribe(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def Subscribed(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def Unsubscribed(self, account_and_jid):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def NewAccount(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def VcardInfo(self, account_and_vcard):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def LastStatusTime(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def OsInfo(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def GCPresence(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def GCMessage(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def RosterInfo(self, account_and_array):
+ pass
+
+ @dbus.service.signal(INTERFACE, signature='av')
+ def NewGmail(self, account_and_array):
+ pass
+
+ def raise_signal(self, signal, arg):
+ '''raise a signal, with a single argument of unspecified type
+ Instead of obj.raise_signal("Foo", bar), use obj.Foo(bar).'''
+ getattr(self, signal)(arg)
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
+ def get_status(self, account):
+ '''Returns status (show to be exact) which is the global one
+ unless account is given'''
+ if not account:
+ # If user did not ask for account, returns the global status
+ return DBUS_STRING(helpers.get_global_show())
+ # return show for the given account
+ index = gajim.connections[account].connected
+ return DBUS_STRING(gajim.SHOW_LIST[index])
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
+ def get_status_message(self, account):
+ '''Returns status which is the global one
+ unless account is given'''
+ if not account:
+ # If user did not ask for account, returns the global status
+ return DBUS_STRING(str(helpers.get_global_status()))
+ # return show for the given account
+ status = gajim.connections[account].status
+ return DBUS_STRING(status)
+
+ def _get_account_and_contact(self, account, jid):
+ '''get the account (if not given) and contact instance from jid'''
+ connected_account = None
+ contact = None
+ accounts = gajim.contacts.get_accounts()
+ # if there is only one account in roster, take it as default
+ # if user did not ask for account
+ if not account and len(accounts) == 1:
+ account = accounts[0]
+ if account:
+ if gajim.connections[account].connected > 1: # account is connected
+ connected_account = account
+ contact = gajim.contacts.get_contact_with_highest_priority(account,
+ jid)
+ else:
+ for account in accounts:
+ contact = gajim.contacts.get_contact_with_highest_priority(account,
+ jid)
+ if contact and gajim.connections[account].connected > 1:
+ # account is connected
+ connected_account = account
+ break
+ if not contact:
+ contact = jid
+
+ return connected_account, contact
+
+ def _get_account_for_groupchat(self, account, room_jid):
+ '''get the account which is connected to groupchat (if not given)
+ or check if the given account is connected to the groupchat'''
+ connected_account = None
+ accounts = gajim.contacts.get_accounts()
+ # if there is only one account in roster, take it as default
+ # if user did not ask for account
+ if not account and len(accounts) == 1:
+ account = accounts[0]
+ if account:
+ if gajim.connections[account].connected > 1 and \
+ room_jid in gajim.gc_connected[account] and \
+ gajim.gc_connected[account][room_jid]:
+ # account and groupchat are connected
+ connected_account = account
+ else:
+ for account in accounts:
+ if gajim.connections[account].connected > 1 and \
+ room_jid in gajim.gc_connected[account] and \
+ gajim.gc_connected[account][room_jid]:
+ # account and groupchat are connected
+ connected_account = account
+ break
+ return connected_account
+
+ @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
+ def send_file(self, file_path, jid, account):
+ '''send file, located at 'file_path' to 'jid', using account
+ (optional) 'account' '''
+ jid = self._get_real_jid(jid, account)
+ connected_account, contact = self._get_account_and_contact(account, jid)
+
+ if connected_account:
+ if file_path[:7] == 'file://':
+ file_path=file_path[7:]
+ if os.path.isfile(file_path): # is it file?
+ gajim.interface.instances['file_transfers'].send_file(
+ connected_account, contact, file_path)
+ return DBUS_BOOLEAN(True)
+ return DBUS_BOOLEAN(False)
+
+ def _send_message(self, jid, message, keyID, account, type = 'chat',
+ subject = None):
+ '''can be called from send_chat_message (default when send_message)
+ or send_single_message'''
+ if not jid or not message:
+ return DBUS_BOOLEAN(False)
+ if not keyID:
+ keyID = ''
+
+ connected_account, contact = self._get_account_and_contact(account, jid)
+ if connected_account:
+ connection = gajim.connections[connected_account]
+ connection.send_message(jid, message, keyID, type, subject)
+ return DBUS_BOOLEAN(True)
+ return DBUS_BOOLEAN(False)
+
+ @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='b')
+ def send_chat_message(self, jid, message, keyID, account):
+ '''Send chat 'message' to 'jid', using account (optional) 'account'.
+ if keyID is specified, encrypt the message with the pgp key '''
+ jid = self._get_real_jid(jid, account)
+ return self._send_message(jid, message, keyID, account)
+
+ @dbus.service.method(INTERFACE, in_signature='sssss', out_signature='b')
+ def send_single_message(self, jid, subject, message, keyID, account):
+ '''Send single 'message' to 'jid', using account (optional) 'account'.
+ if keyID is specified, encrypt the message with the pgp key '''
+ jid = self._get_real_jid(jid, account)
+ return self._send_message(jid, message, keyID, account, type, subject)
+
+ @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
+ def send_groupchat_message(self, room_jid, message, account):
+ '''Send 'message' to groupchat 'room_jid',
+ using account (optional) 'account'.'''
+ if not room_jid or not message:
+ return DBUS_BOOLEAN(False)
+ connected_account = self._get_account_for_groupchat(account, room_jid)
+ if connected_account:
+ connection = gajim.connections[connected_account]
+ connection.send_gc_message(room_jid, message)
+ return DBUS_BOOLEAN(True)
+ return DBUS_BOOLEAN(False)
+
+ @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
+ def open_chat(self, jid, account):
+ '''Shows the tabbed window for new message to 'jid', using account
+ (optional) 'account' '''
+ if not jid:
+ raise MissingArgument
+ return DBUS_BOOLEAN(False)
+ jid = self._get_real_jid(jid, account)
+ try:
+ jid = helpers.parse_jid(jid)
+ except:
+ # Jid is not conform, ignore it
+ return DBUS_BOOLEAN(False)
+
+ if account:
+ accounts = [account]
+ else:
+ accounts = gajim.connections.keys()
+ if len(accounts) == 1:
+ account = accounts[0]
+ connected_account = None
+ first_connected_acct = None
+ for acct in accounts:
+ if gajim.connections[acct].connected > 1: # account is online
+ contact = gajim.contacts.get_first_contact_from_jid(acct, jid)
+ if gajim.interface.msg_win_mgr.has_window(jid, acct):
+ connected_account = acct
+ break
+ # jid is in roster
+ elif contact:
+ connected_account = acct
+ break
+ # we send the message to jid not in roster, because account is
+ # specified, or there is only one account
+ elif account:
+ connected_account = acct
+ elif first_connected_acct is None:
+ first_connected_acct = acct
+
+ # if jid is not a conntact, open-chat with first connected account
+ if connected_account is None and first_connected_acct:
+ connected_account = first_connected_acct
+
+ if connected_account:
+ gajim.interface.new_chat_from_jid(connected_account, jid)
+ # preserve the 'steal focus preservation'
+ win = gajim.interface.msg_win_mgr.get_window(jid,
+ connected_account).window
+ if win.get_property('visible'):
+ win.window.focus()
+ return DBUS_BOOLEAN(True)
+ return DBUS_BOOLEAN(False)
+
+ @dbus.service.method(INTERFACE, in_signature='sss', out_signature='b')
+ def change_status(self, status, message, account):
+ ''' change_status(status, message, account). account is optional -
+ if not specified status is changed for all accounts. '''
+ if status not in ('offline', 'online', 'chat',
+ 'away', 'xa', 'dnd', 'invisible'):
+ return DBUS_BOOLEAN(False)
+ if account:
+ gobject.idle_add(gajim.interface.roster.send_status, account,
+ status, message)
+ else:
+ # account not specified, so change the status of all accounts
+ for acc in gajim.contacts.get_accounts():
+ if not gajim.config.get_per('accounts', acc,
+ 'sync_with_global_status'):
+ continue
+ gobject.idle_add(gajim.interface.roster.send_status, acc,
+ status, message)
+ return DBUS_BOOLEAN(False)
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='')
+ def show_next_pending_event(self):
+ '''Show the window(s) with next pending event in tabbed/group chats.'''
+ if gajim.events.get_nb_events():
+ gajim.interface.systray.handle_first_event()
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{sv}')
+ def contact_info(self, jid):
+ '''get vcard info for a contact. Return cached value of the vcard.
+ '''
+ if not isinstance(jid, unicode):
+ jid = unicode(jid)
+ if not jid:
+ raise MissingArgument
+ return DBUS_DICT_SV()
+ jid = self._get_real_jid(jid)
+
+ cached_vcard = gajim.connections.values()[0].get_cached_vcard(jid)
+ if cached_vcard:
+ return get_dbus_struct(cached_vcard)
+
+ # return empty dict
+ return DBUS_DICT_SV()
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='as')
+ def list_accounts(self):
+ '''list register accounts'''
+ result = gajim.contacts.get_accounts()
+ result_array = dbus.Array([], signature='s')
+ if result and len(result) > 0:
+ for account in result:
+ result_array.append(DBUS_STRING(account))
+ return result_array
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{ss}')
+ def account_info(self, account):
+ '''show info on account: resource, jid, nick, prio, message'''
+ result = DBUS_DICT_SS()
+ if gajim.connections.has_key(account):
+ # account is valid
+ con = gajim.connections[account]
+ index = con.connected
+ result['status'] = DBUS_STRING(gajim.SHOW_LIST[index])
+ result['name'] = DBUS_STRING(con.name)
+ result['jid'] = DBUS_STRING(gajim.get_jid_from_account(con.name))
+ result['message'] = DBUS_STRING(con.status)
+ result['priority'] = DBUS_STRING(unicode(con.priority))
+ result['resource'] = DBUS_STRING(unicode(gajim.config.get_per(
+ 'accounts', con.name, 'resource')))
+ return result
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='aa{sv}')
+ def list_contacts(self, account):
+ '''list all contacts in the roster. If the first argument is specified,
+ then return the contacts for the specified account'''
+ result = dbus.Array([], signature='aa{sv}')
+ accounts = gajim.contacts.get_accounts()
+ if len(accounts) == 0:
+ return result
+ if account:
+ accounts_to_search = [account]
+ else:
+ accounts_to_search = accounts
+ for acct in accounts_to_search:
+ if acct in accounts:
+ for jid in gajim.contacts.get_jid_list(acct):
+ item = self._contacts_as_dbus_structure(
+ gajim.contacts.get_contacts(acct, jid))
+ if item:
+ result.append(item)
+ return result
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='')
+ def toggle_roster_appearance(self):
+ ''' shows/hides the roster window '''
+ win = gajim.interface.roster.window
+ if win.get_property('visible'):
+ gobject.idle_add(win.hide)
+ else:
+ win.present()
+ # preserve the 'steal focus preservation'
+ if self._is_first():
+ win.window.focus()
+ else:
+ win.window.focus(long(time()))
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='')
+ def toggle_ipython(self):
+ ''' shows/hides the ipython window '''
+ win = gajim.ipython_window
+ if win:
+ if win.window.is_visible():
+ gobject.idle_add(win.hide)
+ else:
+ win.show_all()
+ win.present()
+ else:
+ gajim.interface.create_ipython_window()
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='a{ss}')
+ def prefs_list(self):
+ prefs_dict = DBUS_DICT_SS()
+ def get_prefs(data, name, path, value):
+ if value is None:
+ return
+ key = ''
+ if path is not None:
+ for node in path:
+ key += node + '#'
+ key += name
+ prefs_dict[DBUS_STRING(key)] = DBUS_STRING(value[1])
+ gajim.config.foreach(get_prefs)
+ return prefs_dict
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='b')
+ def prefs_store(self):
+ try:
+ gajim.interface.save_config()
+ except Exception, e:
+ return DBUS_BOOLEAN(False)
+ return DBUS_BOOLEAN(True)
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
+ def prefs_del(self, key):
+ if not key:
+ return DBUS_BOOLEAN(False)
+ key_path = key.split('#', 2)
+ if len(key_path) != 3:
+ return DBUS_BOOLEAN(False)
+ if key_path[2] == '*':
+ gajim.config.del_per(key_path[0], key_path[1])
+ else:
+ gajim.config.del_per(key_path[0], key_path[1], key_path[2])
+ return DBUS_BOOLEAN(True)
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
+ def prefs_put(self, key):
+ if not key:
+ return DBUS_BOOLEAN(False)
+ key_path = key.split('#', 2)
+ if len(key_path) < 3:
+ subname, value = key.split('=', 1)
+ gajim.config.set(subname, value)
+ return DBUS_BOOLEAN(True)
+ subname, value = key_path[2].split('=', 1)
+ gajim.config.set_per(key_path[0], key_path[1], subname, value)
+ return DBUS_BOOLEAN(True)
+
+ @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
+ def add_contact(self, jid, account):
+ if account:
+ if account in gajim.connections and \
+ gajim.connections[account].connected > 1:
+ # if given account is active, use it
+ AddNewContactWindow(account = account, jid = jid)
+ else:
+ # wrong account
+ return DBUS_BOOLEAN(False)
+ else:
+ # if account is not given, show account combobox
+ AddNewContactWindow(account = None, jid = jid)
+ return DBUS_BOOLEAN(True)
+
+ @dbus.service.method(INTERFACE, in_signature='ss', out_signature='b')
+ def remove_contact(self, jid, account):
+ jid = self._get_real_jid(jid, account)
+ accounts = gajim.contacts.get_accounts()
+
+ # if there is only one account in roster, take it as default
+ if account:
+ accounts = [account]
+ contact_exists = False
+ for account in accounts:
+ contacts = gajim.contacts.get_contacts(account, jid)
+ if contacts:
+ gajim.connections[account].unsubscribe(jid)
+ for contact in contacts:
+ gajim.interface.roster.remove_contact(contact, account)
+ gajim.contacts.remove_jid(account, jid)
+ contact_exists = True
+ return DBUS_BOOLEAN(contact_exists)
+
+ def _is_first(self):
+ if self.first_show:
+ self.first_show = False
+ return True
+ return False
+
+ def _get_real_jid(self, jid, account = None):
+ '''get the real jid from the given one: removes xmpp: or get jid from nick
+ if account is specified, search only in this account
+ '''
+ if account:
+ accounts = [account]
+ else:
+ accounts = gajim.connections.keys()
+ if jid.startswith('xmpp:'):
+ return jid[5:] # len('xmpp:') = 5
+ nick_in_roster = None # Is jid a nick ?
+ for account in accounts:
+ # Does jid exists in roster of one account ?
+ if gajim.contacts.get_contacts(account, jid):
+ return jid
+ if not nick_in_roster:
+ # look in all contact if one has jid as nick
+ for jid_ in gajim.contacts.get_jid_list(account):
+ c = gajim.contacts.get_contacts(account, jid_)
+ if c[0].name == jid:
+ nick_in_roster = jid_
+ break
+ if nick_in_roster:
+ # We have not found jid in roster, but we found is as a nick
+ return nick_in_roster
+ # We have not found it as jid nor as nick, probably a not in roster jid
+ return jid
+
+ def _contacts_as_dbus_structure(self, contacts):
+ ''' get info from list of Contact objects and create dbus dict '''
+ if not contacts:
+ return None
+ prim_contact = None # primary contact
+ for contact in contacts:
+ if prim_contact is None or contact.priority > prim_contact.priority:
+ prim_contact = contact
+ contact_dict = DBUS_DICT_SV()
+ contact_dict['name'] = DBUS_STRING(prim_contact.name)
+ contact_dict['show'] = DBUS_STRING(prim_contact.show)
+ contact_dict['jid'] = DBUS_STRING(prim_contact.jid)
+ if prim_contact.keyID:
+ keyID = None
+ if len(prim_contact.keyID) == 8:
+ keyID = prim_contact.keyID
+ elif len(prim_contact.keyID) == 16:
+ keyID = prim_contact.keyID[8:]
+ if keyID:
+ contact_dict['openpgp'] = keyID
+ contact_dict['resources'] = dbus.Array([], signature='(sis)')
+ for contact in contacts:
+ resource_props = dbus.Struct((DBUS_STRING(contact.resource),
+ dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
+ contact_dict['resources'].append(resource_props)
+ contact_dict['groups'] = dbus.Array([], signature='(s)')
+ for group in prim_contact.groups:
+ contact_dict['groups'].append((DBUS_STRING(group),))
+ return contact_dict
+
+ @dbus.service.method(INTERFACE, in_signature='', out_signature='s')
+ def get_unread_msgs_number(self):
+ return DBUS_STRING(str(gajim.events.get_nb_events()))
+
+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='b')
+ def start_chat(self, account):
+ if not account:
+ # error is shown in gajim-remote check_arguments(..)
+ return DBUS_BOOLEAN(False)
+ NewChatDialog(account)
+ return DBUS_BOOLEAN(True)
+
+ @dbus.service.method(INTERFACE, in_signature='ss', out_signature='')
+ def send_xml(self, xml, account):
+ if account:
+ gajim.connections[account].send_stanza(xml)
+ else:
+ for acc in gajim.contacts.get_accounts():
+ gajim.connections[acc].send_stanza(xml)
+
+ @dbus.service.method(INTERFACE, in_signature='ssss', out_signature='')
+ def join_room(self, room_jid, nick, password, account):
+ if not account:
+ # get the first connected account
+ accounts = gajim.connections.keys()
+ for acct in accounts:
+ if gajim.account_is_connected(acct):
+ account = acct
+ break
+ if not account:
+ return
+ if not nick:
+ nick = ''
+ gajim.interface.instances[account]['join_gc'] = \
+ JoinGroupchatWindow(account, room_jid, nick)
+ else:
+ gajim.interface.join_gc_room(account, room_jid, nick, password)
from common import gajim
from common import helpers
@@ -680,62 +680,59 @@ from plugins.helpers import log_calls, log
from common import ged
class DBusPlugin(GajimPlugin):
- name = u'D-Bus Support'
- short_name = u'dbus'
- version = u'0.1'
- description = u'''D-Bus support. Based on remote_control module from
+ name = u'D-Bus Support'
+ short_name = u'dbus'
+ version = u'0.1'
+ description = u'''D-Bus support. Based on remote_control module from
Gajim core but uses new events handling system.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('DBusPlugin')
- def init(self):
- self.config_dialog = None
- #self.gui_extension_points = {}
- #self.config_default_values = {}
-
- self.events_names = ['Roster', 'AccountPresence', 'ContactPresence',
- 'ContactAbsence', 'ContactStatus', 'NewMessage',
- 'Subscribe', 'Subscribed', 'Unsubscribed',
- 'NewAccount', 'VcardInfo', 'LastStatusTime',
- 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
- 'NewGmail']
-
- self.signal_object = None
-
- self.events_handlers = {}
- self._set_handling_methods()
-
- @log_calls('DBusPlugin')
- def activate(self):
- session_bus = dbus_support.session_bus.SessionBus()
-
- bus_name = dbus.service.BusName(SERVICE, bus=session_bus)
- self.signal_object = SignalObject(bus_name)
-
- @log_calls('DBusPlugin')
- def deactivate(self):
- self.signal_object.remove_from_connection()
- self.signal_object = None
-
- @log_calls('DBusPlugin')
- def _set_handling_methods(self):
- for event_name in self.events_names:
- setattr(self, event_name,
- new.instancemethod(
- self._generate_handling_method(event_name),
- self,
- DBusPlugin))
- self.events_handlers[event_name] = (ged.POSTCORE,
- getattr(self, event_name))
-
- def _generate_handling_method(self, event_name):
- def handler(self, arg):
- #print "Handler of event %s called"%(event_name)
- if self.signal_object:
- getattr(self.signal_object, event_name)(get_dbus_struct(arg))
-
- return handler
-
-
- \ No newline at end of file
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('DBusPlugin')
+ def init(self):
+ self.config_dialog = None
+ #self.gui_extension_points = {}
+ #self.config_default_values = {}
+
+ self.events_names = ['Roster', 'AccountPresence', 'ContactPresence',
+ 'ContactAbsence', 'ContactStatus', 'NewMessage',
+ 'Subscribe', 'Subscribed', 'Unsubscribed',
+ 'NewAccount', 'VcardInfo', 'LastStatusTime',
+ 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
+ 'NewGmail']
+
+ self.signal_object = None
+
+ self.events_handlers = {}
+ self._set_handling_methods()
+
+ @log_calls('DBusPlugin')
+ def activate(self):
+ session_bus = dbus_support.session_bus.SessionBus()
+
+ bus_name = dbus.service.BusName(SERVICE, bus=session_bus)
+ self.signal_object = SignalObject(bus_name)
+
+ @log_calls('DBusPlugin')
+ def deactivate(self):
+ self.signal_object.remove_from_connection()
+ self.signal_object = None
+
+ @log_calls('DBusPlugin')
+ def _set_handling_methods(self):
+ for event_name in self.events_names:
+ setattr(self, event_name,
+ new.instancemethod(
+ self._generate_handling_method(event_name),
+ self,
+ DBusPlugin))
+ self.events_handlers[event_name] = (ged.POSTCORE,
+ getattr(self, event_name))
+
+ def _generate_handling_method(self, event_name):
+ def handler(self, arg):
+ #print "Handler of event %s called"%(event_name)
+ if self.signal_object:
+ getattr(self.signal_object, event_name)(get_dbus_struct(arg))
+
+ return handler
diff --git a/plugins/events_dump/__init__.py b/plugins/events_dump/__init__.py
index fc198d87d..de174c1b9 100644
--- a/plugins/events_dump/__init__.py
+++ b/plugins/events_dump/__init__.py
@@ -1 +1 @@
-from plugin import EventsDumpPlugin \ No newline at end of file
+from plugin import EventsDumpPlugin
diff --git a/plugins/events_dump/plugin.py b/plugins/events_dump/plugin.py
index 9aa4565b1..3e816ae3a 100644
--- a/plugins/events_dump/plugin.py
+++ b/plugins/events_dump/plugin.py
@@ -17,7 +17,7 @@
'''
Events Dump plugin.
-Dumps info about selected events to console.
+Dumps info about selected events to console.
:author: Mateusz Biliński <mateusz@bilinski.it>
:since: 10th August 2008
@@ -33,97 +33,97 @@ from plugins.helpers import log_calls, log
from common import ged
class EventsDumpPlugin(GajimPlugin):
- name = u'Events Dump'
- short_name = u'events_dump'
- version = u'0.1'
- description = u'''Dumps info about selected events to console.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('EventsDumpPlugin')
- def init(self):
- self.config_dialog = None
- #self.gui_extension_points = {}
- #self.config_default_values = {}
- events_from_old_dbus_support = [
- 'Roster', 'AccountPresence', 'ContactPresence',
- 'ContactAbsence', 'ContactStatus', 'NewMessage',
- 'Subscribe', 'Subscribed', 'Unsubscribed',
- 'NewAccount', 'VcardInfo', 'LastStatusTime',
- 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
- 'NewGmail']
-
- events_from_src_gajim = [
- 'ROSTER', 'WARNING', 'ERROR',
- 'INFORMATION', 'ERROR_ANSWER', 'STATUS',
- 'NOTIFY', 'MSGERROR', 'MSGSENT', 'MSGNOTSENT',
- 'SUBSCRIBED', 'UNSUBSCRIBED', 'SUBSCRIBE',
- 'AGENT_ERROR_INFO', 'AGENT_ERROR_ITEMS',
- 'AGENT_REMOVED', 'REGISTER_AGENT_INFO',
- 'AGENT_INFO_ITEMS', 'AGENT_INFO_INFO',
- 'QUIT', 'NEW_ACC_CONNECTED',
- 'NEW_ACC_NOT_CONNECTED', 'ACC_OK', 'ACC_NOT_OK',
- 'MYVCARD', 'VCARD', 'LAST_STATUS_TIME', 'OS_INFO',
- 'GC_NOTIFY', 'GC_MSG', 'GC_SUBJECT', 'GC_CONFIG',
- 'GC_CONFIG_CHANGE', 'GC_INVITATION',
- 'GC_AFFILIATION', 'GC_PASSWORD_REQUIRED',
- 'BAD_PASSPHRASE', 'ROSTER_INFO', 'BOOKMARKS',
- 'CON_TYPE', 'CONNECTION_LOST', 'FILE_REQUEST',
- 'GMAIL_NOTIFY', 'FILE_REQUEST_ERROR',
- 'FILE_SEND_ERROR', 'STANZA_ARRIVED', 'STANZA_SENT',
- 'HTTP_AUTH', 'VCARD_PUBLISHED',
- 'VCARD_NOT_PUBLISHED', 'ASK_NEW_NICK', 'SIGNED_IN',
- 'METACONTACTS', 'ATOM_ENTRY', 'FAILED_DECRYPT',
- 'PRIVACY_LISTS_RECEIVED', 'PRIVACY_LIST_RECEIVED',
- 'PRIVACY_LISTS_ACTIVE_DEFAULT',
- 'PRIVACY_LIST_REMOVED', 'ZC_NAME_CONFLICT',
- 'PING_SENT', 'PING_REPLY', 'PING_ERROR',
- 'SEARCH_FORM', 'SEARCH_RESULT',
- 'RESOURCE_CONFLICT', 'PEP_CONFIG',
- 'UNIQUE_ROOM_ID_UNSUPPORTED',
- 'UNIQUE_ROOM_ID_SUPPORTED', 'SESSION_NEG',
- 'GPG_PASSWORD_REQUIRED', 'SSL_ERROR',
- 'FINGERPRINT_ERROR', 'PLAIN_CONNECTION',
- 'PUBSUB_NODE_REMOVED', 'PUBSUB_NODE_NOT_REMOVED']
-
- network_events_from_core = ['raw-message-received',
- 'raw-iq-received',
- 'raw-pres-received']
-
- network_events_generated_in_nec = [
- 'customized-message-received',
- 'more-customized-message-received',
- 'modify-only-message-received',
- 'enriched-chat-message-received']
-
- self.events_names = []
- self.events_names += network_events_from_core
- self.events_names += network_events_generated_in_nec
-
- self.events_handlers = {}
- self._set_handling_methods()
-
- @log_calls('EventsDumpPlugin')
- def activate(self):
- pass
-
- @log_calls('EventsDumpPlugin')
- def deactivate(self):
- pass
-
- @log_calls('EventsDumpPlugin')
- def _set_handling_methods(self):
- for event_name in self.events_names:
- setattr(self, event_name,
- new.instancemethod(
- self._generate_handling_method(event_name),
- self,
- EventsDumpPlugin))
- self.events_handlers[event_name] = (ged.POSTCORE,
- getattr(self, event_name))
-
- def _generate_handling_method(self, event_name):
- def handler(self, *args):
- print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args))
-
- return handler \ No newline at end of file
+ name = u'Events Dump'
+ short_name = u'events_dump'
+ version = u'0.1'
+ description = u'''Dumps info about selected events to console.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('EventsDumpPlugin')
+ def init(self):
+ self.config_dialog = None
+ #self.gui_extension_points = {}
+ #self.config_default_values = {}
+ events_from_old_dbus_support = [
+ 'Roster', 'AccountPresence', 'ContactPresence',
+ 'ContactAbsence', 'ContactStatus', 'NewMessage',
+ 'Subscribe', 'Subscribed', 'Unsubscribed',
+ 'NewAccount', 'VcardInfo', 'LastStatusTime',
+ 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
+ 'NewGmail']
+
+ events_from_src_gajim = [
+ 'ROSTER', 'WARNING', 'ERROR',
+ 'INFORMATION', 'ERROR_ANSWER', 'STATUS',
+ 'NOTIFY', 'MSGERROR', 'MSGSENT', 'MSGNOTSENT',
+ 'SUBSCRIBED', 'UNSUBSCRIBED', 'SUBSCRIBE',
+ 'AGENT_ERROR_INFO', 'AGENT_ERROR_ITEMS',
+ 'AGENT_REMOVED', 'REGISTER_AGENT_INFO',
+ 'AGENT_INFO_ITEMS', 'AGENT_INFO_INFO',
+ 'QUIT', 'NEW_ACC_CONNECTED',
+ 'NEW_ACC_NOT_CONNECTED', 'ACC_OK', 'ACC_NOT_OK',
+ 'MYVCARD', 'VCARD', 'LAST_STATUS_TIME', 'OS_INFO',
+ 'GC_NOTIFY', 'GC_MSG', 'GC_SUBJECT', 'GC_CONFIG',
+ 'GC_CONFIG_CHANGE', 'GC_INVITATION',
+ 'GC_AFFILIATION', 'GC_PASSWORD_REQUIRED',
+ 'BAD_PASSPHRASE', 'ROSTER_INFO', 'BOOKMARKS',
+ 'CON_TYPE', 'CONNECTION_LOST', 'FILE_REQUEST',
+ 'GMAIL_NOTIFY', 'FILE_REQUEST_ERROR',
+ 'FILE_SEND_ERROR', 'STANZA_ARRIVED', 'STANZA_SENT',
+ 'HTTP_AUTH', 'VCARD_PUBLISHED',
+ 'VCARD_NOT_PUBLISHED', 'ASK_NEW_NICK', 'SIGNED_IN',
+ 'METACONTACTS', 'ATOM_ENTRY', 'FAILED_DECRYPT',
+ 'PRIVACY_LISTS_RECEIVED', 'PRIVACY_LIST_RECEIVED',
+ 'PRIVACY_LISTS_ACTIVE_DEFAULT',
+ 'PRIVACY_LIST_REMOVED', 'ZC_NAME_CONFLICT',
+ 'PING_SENT', 'PING_REPLY', 'PING_ERROR',
+ 'SEARCH_FORM', 'SEARCH_RESULT',
+ 'RESOURCE_CONFLICT', 'PEP_CONFIG',
+ 'UNIQUE_ROOM_ID_UNSUPPORTED',
+ 'UNIQUE_ROOM_ID_SUPPORTED', 'SESSION_NEG',
+ 'GPG_PASSWORD_REQUIRED', 'SSL_ERROR',
+ 'FINGERPRINT_ERROR', 'PLAIN_CONNECTION',
+ 'PUBSUB_NODE_REMOVED', 'PUBSUB_NODE_NOT_REMOVED']
+
+ network_events_from_core = ['raw-message-received',
+ 'raw-iq-received',
+ 'raw-pres-received']
+
+ network_events_generated_in_nec = [
+ 'customized-message-received',
+ 'more-customized-message-received',
+ 'modify-only-message-received',
+ 'enriched-chat-message-received']
+
+ self.events_names = []
+ self.events_names += network_events_from_core
+ self.events_names += network_events_generated_in_nec
+
+ self.events_handlers = {}
+ self._set_handling_methods()
+
+ @log_calls('EventsDumpPlugin')
+ def activate(self):
+ pass
+
+ @log_calls('EventsDumpPlugin')
+ def deactivate(self):
+ pass
+
+ @log_calls('EventsDumpPlugin')
+ def _set_handling_methods(self):
+ for event_name in self.events_names:
+ setattr(self, event_name,
+ new.instancemethod(
+ self._generate_handling_method(event_name),
+ self,
+ EventsDumpPlugin))
+ self.events_handlers[event_name] = (ged.POSTCORE,
+ getattr(self, event_name))
+
+ def _generate_handling_method(self, event_name):
+ def handler(self, *args):
+ print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args))
+
+ return handler
diff --git a/plugins/google_translation/__init__.py b/plugins/google_translation/__init__.py
index 33fb27f0f..dc2c3bc36 100644
--- a/plugins/google_translation/__init__.py
+++ b/plugins/google_translation/__init__.py
@@ -1 +1 @@
-from plugin import GoogleTranslationPlugin \ No newline at end of file
+from plugin import GoogleTranslationPlugin
diff --git a/plugins/google_translation/plugin.py b/plugins/google_translation/plugin.py
index b2f920e37..a20664060 100644
--- a/plugins/google_translation/plugin.py
+++ b/plugins/google_translation/plugin.py
@@ -40,80 +40,79 @@ from common import ged
from common import nec
class GoogleTranslationPlugin(GajimPlugin):
- name = u'Google Translation'
- short_name = u'google_translation'
- version = u'0.1'
- description = u'''Translates (currently only incoming) messages using Google Translate.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('GoogleTranslationPlugin')
- def init(self):
- self.config_dialog = None
- #self.gui_extension_points = {}
- self.config_default_values = {'from_lang' : (u'en', _(u'Language of text to be translated')),
- 'to_lang' : (u'fr', _(u'Language to which translation will be made')),
- 'user_agent' : (u'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080213 Firefox/2.0.0.11',
- _(u'User Agent data to be used with urllib2 when connecting to Google Translate service'))}
-
- #self.events_handlers = {}
-
- self.events = [GoogleTranslateMessageReceivedEvent]
-
- self.translated_text_re = \
- re.compile(r'google.language.callbacks.id100\(\'22\',{"translatedText":"(?P<text>[^"]*)"}, 200, null, 200\)')
-
- @log_calls('GoogleTranslationPlugin')
- def translate_text(self, text, from_lang, to_lang):
- text = self.prepare_text_for_url(text)
- headers = { 'User-Agent' : self.config['user_agent'] }
- translation_url = u'http://www.google.com/uds/Gtranslate?callback=google.language.callbacks.id100&context=22&q=%(text)s&langpair=%(from_lang)s%%7C%(to_lang)s&key=notsupplied&v=1.0'%locals()
-
- request = urllib2.Request(translation_url, headers=headers)
- response = urllib2.urlopen(request)
- results = response.read()
-
- translated_text = self.translated_text_re.search(results).group('text')
-
- return translated_text
-
- @log_calls('GoogleTranslationPlugin')
- def prepare_text_for_url(self, text):
- '''
- Converts text so it can be used within URL as query to Google Translate.
- '''
-
- # There should be more replacements for plugin to work in any case:
- char_replacements = { ' ' : '%20',
- '+' : '%2B'}
-
- for char, replacement in char_replacements.iteritems():
- text = text.replace(char, replacement)
-
- return text
-
- @log_calls('GoogleTranslationPlugin')
- def activate(self):
- pass
-
- @log_calls('GoogleTranslationPlugin')
- def deactivate(self):
- pass
-
+ name = u'Google Translation'
+ short_name = u'google_translation'
+ version = u'0.1'
+ description = u'''Translates (currently only incoming) messages using Google Translate.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('GoogleTranslationPlugin')
+ def init(self):
+ self.config_dialog = None
+ #self.gui_extension_points = {}
+ self.config_default_values = {'from_lang' : (u'en', _(u'Language of text to be translated')),
+ 'to_lang' : (u'fr', _(u'Language to which translation will be made')),
+ 'user_agent' : (u'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080213 Firefox/2.0.0.11',
+ _(u'User Agent data to be used with urllib2 when connecting to Google Translate service'))}
+
+ #self.events_handlers = {}
+
+ self.events = [GoogleTranslateMessageReceivedEvent]
+
+ self.translated_text_re = \
+ re.compile(r'google.language.callbacks.id100\(\'22\',{"translatedText":"(?P<text>[^"]*)"}, 200, null, 200\)')
+
+ @log_calls('GoogleTranslationPlugin')
+ def translate_text(self, text, from_lang, to_lang):
+ text = self.prepare_text_for_url(text)
+ headers = { 'User-Agent' : self.config['user_agent'] }
+ translation_url = u'http://www.google.com/uds/Gtranslate?callback=google.language.callbacks.id100&context=22&q=%(text)s&langpair=%(from_lang)s%%7C%(to_lang)s&key=notsupplied&v=1.0'%locals()
+
+ request = urllib2.Request(translation_url, headers=headers)
+ response = urllib2.urlopen(request)
+ results = response.read()
+
+ translated_text = self.translated_text_re.search(results).group('text')
+
+ return translated_text
+
+ @log_calls('GoogleTranslationPlugin')
+ def prepare_text_for_url(self, text):
+ '''
+ Converts text so it can be used within URL as query to Google Translate.
+ '''
+
+ # There should be more replacements for plugin to work in any case:
+ char_replacements = { ' ' : '%20',
+ '+' : '%2B'}
+
+ for char, replacement in char_replacements.iteritems():
+ text = text.replace(char, replacement)
+
+ return text
+
+ @log_calls('GoogleTranslationPlugin')
+ def activate(self):
+ pass
+
+ @log_calls('GoogleTranslationPlugin')
+ def deactivate(self):
+ pass
+
class GoogleTranslateMessageReceivedEvent(nec.NetworkIncomingEvent):
- name = 'google-translate-message-received'
- base_network_events = ['raw-message-received']
-
- def generate(self):
- msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
- if msg_type == u'chat':
- msg_text = "".join(self.base_event.xmpp_msg.kids[0].data)
- if msg_text:
- from_lang = self.plugin.config['from_lang']
- to_lang = self.plugin.config['to_lang']
- self.base_event.xmpp_msg.kids[0].setData(
- self.plugin.translate_text(msg_text, from_lang, to_lang))
-
- return False # We only want to modify old event, not emit another,
- # so we return False here.
-
+ name = 'google-translate-message-received'
+ base_network_events = ['raw-message-received']
+
+ def generate(self):
+ msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
+ if msg_type == u'chat':
+ msg_text = "".join(self.base_event.xmpp_msg.kids[0].data)
+ if msg_text:
+ from_lang = self.plugin.config['from_lang']
+ to_lang = self.plugin.config['to_lang']
+ self.base_event.xmpp_msg.kids[0].setData(
+ self.plugin.translate_text(msg_text, from_lang, to_lang))
+
+ return False # We only want to modify old event, not emit another,
+ # so we return False here.
diff --git a/plugins/length_notifier/__init__.py b/plugins/length_notifier/__init__.py
index fc433a0af..67c8c614a 100644
--- a/plugins/length_notifier/__init__.py
+++ b/plugins/length_notifier/__init__.py
@@ -1,2 +1,2 @@
-from length_notifier import LengthNotifierPlugin \ No newline at end of file
+from length_notifier import LengthNotifierPlugin
diff --git a/plugins/length_notifier/length_notifier.py b/plugins/length_notifier/length_notifier.py
index 86413ba13..cde132208 100644
--- a/plugins/length_notifier/length_notifier.py
+++ b/plugins/length_notifier/length_notifier.py
@@ -34,129 +34,128 @@ from plugins.helpers import log, log_calls
from plugins.gui import GajimPluginConfigDialog
class LengthNotifierPlugin(GajimPlugin):
- name = u'Message Length Notifier'
- short_name = u'length_notifier'
- version = u'0.1'
- description = u'''Highlights message entry field in chat window when given length of message is exceeded.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('LengthNotifierPlugin')
- def init(self):
- self.config_dialog = LengthNotifierPluginConfigDialog(self)
-
- self.gui_extension_points = {
- 'chat_control' : (self.connect_with_chat_control,
- self.disconnect_from_chat_control)
- }
-
- self.config_default_values = {'MESSAGE_WARNING_LENGTH' : (140, _('Message length at which notification is invoked.')),
- 'WARNING_COLOR' : ('#F0DB3E', _('Background color of text entry field in chat window when notification is invoked.')),
- 'JIDS' : ([], _('JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]'))
- }
-
- @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.config['MESSAGE_WARNING_LENGTH']:
- if not d['prev_color']:
- d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
- tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['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
- tb = tv.get_buffer()
- h_id = tb.connect('changed', self.textview_length_warning, chat_control)
- d['h_id'] = h_id
-
- t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
- if t:
- len_t = len(t)
- if len_t>self.config['MESSAGE_WARNING_LENGTH']:
- d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
- tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['WARNING_COLOR']))
-
- chat_control.length_notifier_plugin_data = d
-
- return True
-
- return False
-
- @log_calls('LengthNotifierPlugin')
- def disconnect_from_chat_control(self, chat_control):
- try:
- d = chat_control.length_notifier_plugin_data
- tv = chat_control.msg_textview
- tv.get_buffer().disconnect(d['h_id'])
- if d['prev_color']:
- tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
- except AttributeError, error:
- pass
- #log.debug('Length Notifier Plugin was (probably) never connected with this chat window.\n Error: %s' % (error))
-
- @log_calls('LengthNotifierPlugin')
- def jid_is_ok(self, jid):
- if jid in self.config['JIDS'] or not self.config['JIDS']:
- return True
-
- return False
-
+ name = u'Message Length Notifier'
+ short_name = u'length_notifier'
+ version = u'0.1'
+ description = u'''Highlights message entry field in chat window when given length of message is exceeded.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('LengthNotifierPlugin')
+ def init(self):
+ self.config_dialog = LengthNotifierPluginConfigDialog(self)
+
+ self.gui_extension_points = {
+ 'chat_control' : (self.connect_with_chat_control,
+ self.disconnect_from_chat_control)
+ }
+
+ self.config_default_values = {'MESSAGE_WARNING_LENGTH' : (140, _('Message length at which notification is invoked.')),
+ 'WARNING_COLOR' : ('#F0DB3E', _('Background color of text entry field in chat window when notification is invoked.')),
+ 'JIDS' : ([], _('JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]'))
+ }
+
+ @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.config['MESSAGE_WARNING_LENGTH']:
+ if not d['prev_color']:
+ d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
+ tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['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
+ tb = tv.get_buffer()
+ h_id = tb.connect('changed', self.textview_length_warning, chat_control)
+ d['h_id'] = h_id
+
+ t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
+ if t:
+ len_t = len(t)
+ if len_t>self.config['MESSAGE_WARNING_LENGTH']:
+ d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
+ tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['WARNING_COLOR']))
+
+ chat_control.length_notifier_plugin_data = d
+
+ return True
+
+ return False
+
+ @log_calls('LengthNotifierPlugin')
+ def disconnect_from_chat_control(self, chat_control):
+ try:
+ d = chat_control.length_notifier_plugin_data
+ tv = chat_control.msg_textview
+ tv.get_buffer().disconnect(d['h_id'])
+ if d['prev_color']:
+ tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
+ except AttributeError, error:
+ pass
+ #log.debug('Length Notifier Plugin was (probably) never connected with this chat window.\n Error: %s' % (error))
+
+ @log_calls('LengthNotifierPlugin')
+ def jid_is_ok(self, jid):
+ if jid in self.config['JIDS'] or not self.config['JIDS']:
+ return True
+
+ return False
+
class LengthNotifierPluginConfigDialog(GajimPluginConfigDialog):
- def init(self):
- self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
- 'config_dialog.ui')
- self.xml = gtk.Builder()
- self.xml.set_translation_domain(i18n.APP)
- self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
- ['length_notifier_config_table'])
- self.config_table = self.xml.get_object('length_notifier_config_table')
- self.child.pack_start(self.config_table)
-
- self.message_length_spinbutton = self.xml.get_object(
- 'message_length_spinbutton')
- self.message_length_spinbutton.get_adjustment().set_all(140, 0, 500, 1,
- 10, 0)
- self.notification_colorbutton = self.xml.get_object(
- 'notification_colorbutton')
- self.jids_entry = self.xml.get_object('jids_entry')
-
- self.xml.connect_signals(self)
-
- def on_run(self):
- self.message_length_spinbutton.set_value(self.plugin.config['MESSAGE_WARNING_LENGTH'])
- self.notification_colorbutton.set_color(gtk.gdk.color_parse(self.plugin.config['WARNING_COLOR']))
- #self.jids_entry.set_text(self.plugin.config['JIDS'])
- self.jids_entry.set_text(','.join(self.plugin.config['JIDS']))
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_message_length_spinbutton_value_changed(self, spinbutton):
- self.plugin.config['MESSAGE_WARNING_LENGTH'] = spinbutton.get_value()
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_notification_colorbutton_color_set(self, colorbutton):
- self.plugin.config['WARNING_COLOR'] = colorbutton.get_color().to_string()
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_jids_entry_changed(self, entry):
- text = entry.get_text()
- if len(text)>0:
- self.plugin.config['JIDS'] = entry.get_text().split(',')
- else:
- self.plugin.config['JIDS'] = []
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_jids_entry_editing_done(self, entry):
- pass
-
+ def init(self):
+ self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
+ 'config_dialog.ui')
+ self.xml = gtk.Builder()
+ self.xml.set_translation_domain(i18n.APP)
+ self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
+ ['length_notifier_config_table'])
+ self.config_table = self.xml.get_object('length_notifier_config_table')
+ self.child.pack_start(self.config_table)
+
+ self.message_length_spinbutton = self.xml.get_object(
+ 'message_length_spinbutton')
+ self.message_length_spinbutton.get_adjustment().set_all(140, 0, 500, 1,
+ 10, 0)
+ self.notification_colorbutton = self.xml.get_object(
+ 'notification_colorbutton')
+ self.jids_entry = self.xml.get_object('jids_entry')
+
+ self.xml.connect_signals(self)
+
+ def on_run(self):
+ self.message_length_spinbutton.set_value(self.plugin.config['MESSAGE_WARNING_LENGTH'])
+ self.notification_colorbutton.set_color(gtk.gdk.color_parse(self.plugin.config['WARNING_COLOR']))
+ #self.jids_entry.set_text(self.plugin.config['JIDS'])
+ self.jids_entry.set_text(','.join(self.plugin.config['JIDS']))
+
+ @log_calls('LengthNotifierPluginConfigDialog')
+ def on_message_length_spinbutton_value_changed(self, spinbutton):
+ self.plugin.config['MESSAGE_WARNING_LENGTH'] = spinbutton.get_value()
+
+ @log_calls('LengthNotifierPluginConfigDialog')
+ def on_notification_colorbutton_color_set(self, colorbutton):
+ self.plugin.config['WARNING_COLOR'] = colorbutton.get_color().to_string()
+
+ @log_calls('LengthNotifierPluginConfigDialog')
+ def on_jids_entry_changed(self, entry):
+ text = entry.get_text()
+ if len(text)>0:
+ self.plugin.config['JIDS'] = entry.get_text().split(',')
+ else:
+ self.plugin.config['JIDS'] = []
+
+ @log_calls('LengthNotifierPluginConfigDialog')
+ def on_jids_entry_editing_done(self, entry):
+ pass
diff --git a/plugins/new_events_example/__init__.py b/plugins/new_events_example/__init__.py
index a0eca896c..523d43e14 100644
--- a/plugins/new_events_example/__init__.py
+++ b/plugins/new_events_example/__init__.py
@@ -1 +1 @@
-from plugin import NewEventsExamplePlugin \ No newline at end of file
+from plugin import NewEventsExamplePlugin
diff --git a/plugins/new_events_example/plugin.py b/plugins/new_events_example/plugin.py
index 29740d1a4..ff40dd56f 100644
--- a/plugins/new_events_example/plugin.py
+++ b/plugins/new_events_example/plugin.py
@@ -38,110 +38,110 @@ from common import ged
from common import nec
class NewEventsExamplePlugin(GajimPlugin):
- name = u'New Events Example'
- short_name = u'new_events_example'
- version = u'0.1'
- description = u'''Shows how to generate new network events based on existing one using Network Events Controller.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('NewEventsExamplePlugin')
- def init(self):
- self.config_dialog = None
- #self.gui_extension_points = {}
- #self.config_default_values = {}
-
- self.events_handlers = {'raw-message-received' :
- (ged.POSTCORE,
- self.raw_message_received),
- 'customized-message-received' :
- (ged.POSTCORE,
- self.customized_message_received),
- 'enriched-chat-message-received' :
- (ged.POSTCORE,
- self.enriched_chat_message_received)}
-
- self.events = [CustomizedMessageReceivedEvent,
- MoreCustomizedMessageReceivedEvent,
- ModifyOnlyMessageReceivedEvent,
- EnrichedChatMessageReceivedEvent]
-
- def enriched_chat_message_received(self, event_object):
- pass
- #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
- #event_object)
-
- def raw_message_received(self, event_object):
- pass
- #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
- #event_object)
-
- def customized_message_received(self, event_object):
- pass
- #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
- #event_object
-
- @log_calls('NewEventsExamplePlugin')
- def activate(self):
- pass
-
- @log_calls('NewEventsExamplePlugin')
- def deactivate(self):
- pass
-
+ name = u'New Events Example'
+ short_name = u'new_events_example'
+ version = u'0.1'
+ description = u'''Shows how to generate new network events based on existing one using Network Events Controller.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('NewEventsExamplePlugin')
+ def init(self):
+ self.config_dialog = None
+ #self.gui_extension_points = {}
+ #self.config_default_values = {}
+
+ self.events_handlers = {'raw-message-received' :
+ (ged.POSTCORE,
+ self.raw_message_received),
+ 'customized-message-received' :
+ (ged.POSTCORE,
+ self.customized_message_received),
+ 'enriched-chat-message-received' :
+ (ged.POSTCORE,
+ self.enriched_chat_message_received)}
+
+ self.events = [CustomizedMessageReceivedEvent,
+ MoreCustomizedMessageReceivedEvent,
+ ModifyOnlyMessageReceivedEvent,
+ EnrichedChatMessageReceivedEvent]
+
+ def enriched_chat_message_received(self, event_object):
+ pass
+ #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
+ #event_object)
+
+ def raw_message_received(self, event_object):
+ pass
+ #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
+ #event_object)
+
+ def customized_message_received(self, event_object):
+ pass
+ #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name,
+ #event_object
+
+ @log_calls('NewEventsExamplePlugin')
+ def activate(self):
+ pass
+
+ @log_calls('NewEventsExamplePlugin')
+ def deactivate(self):
+ pass
+
class CustomizedMessageReceivedEvent(nec.NetworkIncomingEvent):
- name = 'customized-message-received'
- base_network_events = ['raw-message-received']
-
- def generate(self):
- return True
-
+ name = 'customized-message-received'
+ base_network_events = ['raw-message-received']
+
+ def generate(self):
+ return True
+
class MoreCustomizedMessageReceivedEvent(nec.NetworkIncomingEvent):
- '''
- Shows chain of custom created events.
-
- This one is based on custom 'customized-messsage-received'.
- '''
- name = 'more-customized-message-received'
- base_network_events = ['customized-message-received']
-
- def generate(self):
- return True
-
+ '''
+ Shows chain of custom created events.
+
+ This one is based on custom 'customized-messsage-received'.
+ '''
+ name = 'more-customized-message-received'
+ base_network_events = ['customized-message-received']
+
+ def generate(self):
+ return True
+
class ModifyOnlyMessageReceivedEvent(nec.NetworkIncomingEvent):
- name = 'modify-only-message-received'
- base_network_events = ['raw-message-received']
-
- def generate(self):
- msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
- if msg_type == u'chat':
- msg_text = "".join(self.base_event.xmpp_msg.kids[0].data)
- self.base_event.xmpp_msg.kids[0].setData(
- u'%s [MODIFIED BY CUSTOM NETWORK EVENT]'%(msg_text))
-
- return False
-
+ name = 'modify-only-message-received'
+ base_network_events = ['raw-message-received']
+
+ def generate(self):
+ msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
+ if msg_type == u'chat':
+ msg_text = "".join(self.base_event.xmpp_msg.kids[0].data)
+ self.base_event.xmpp_msg.kids[0].setData(
+ u'%s [MODIFIED BY CUSTOM NETWORK EVENT]'%(msg_text))
+
+ return False
+
class EnrichedChatMessageReceivedEvent(nec.NetworkIncomingEvent):
- '''
- Generates more friendly (in use by handlers) network event for
- received chat message.
- '''
- name = 'enriched-chat-message-received'
- base_network_events = ['raw-message-received']
-
- def generate(self):
- msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
- if msg_type == u'chat':
- self.xmpp_msg = self.base_event.xmpp_msg
- self.conn = self.base_event.conn
- self.from_jid = helpers.get_full_jid_from_iq(self.xmpp_msg)
- self.from_jid_without_resource = gajim.get_jid_without_resource(self.from_jid)
- self.account = self.base_event.account
- self.from_nickname = gajim.get_contact_name_from_jid(
- self.account,
- self.from_jid_without_resource)
- self.msg_text = "".join(self.xmpp_msg.kids[0].data)
-
- return True
-
- return False
+ '''
+ Generates more friendly (in use by handlers) network event for
+ received chat message.
+ '''
+ name = 'enriched-chat-message-received'
+ base_network_events = ['raw-message-received']
+
+ def generate(self):
+ msg_type = self.base_event.xmpp_msg.attrs.get('type', None)
+ if msg_type == u'chat':
+ self.xmpp_msg = self.base_event.xmpp_msg
+ self.conn = self.base_event.conn
+ self.from_jid = helpers.get_full_jid_from_iq(self.xmpp_msg)
+ self.from_jid_without_resource = gajim.get_jid_without_resource(self.from_jid)
+ self.account = self.base_event.account
+ self.from_nickname = gajim.get_contact_name_from_jid(
+ self.account,
+ self.from_jid_without_resource)
+ self.msg_text = "".join(self.xmpp_msg.kids[0].data)
+
+ return True
+
+ return False
diff --git a/plugins/roster_buttons/plugin.py b/plugins/roster_buttons/plugin.py
index 90a636ce5..a75fd8c6c 100644
--- a/plugins/roster_buttons/plugin.py
+++ b/plugins/roster_buttons/plugin.py
@@ -34,54 +34,53 @@ from plugins import GajimPlugin
from plugins.helpers import log, log_calls
class RosterButtonsPlugin(GajimPlugin):
- name = u'Roster Buttons'
- short_name = u'roster_buttons'
- version = u'0.1'
- description = u'''Adds quick action buttons to roster window.'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('RosterButtonsPlugin')
- def init(self):
- self.GTK_BUILDER_FILE_PATH = self.local_file_path('roster_buttons.ui')
- self.roster_vbox = gajim.interface.roster.xml.get_object('roster_vbox2')
- self.show_offline_contacts_menuitem = gajim.interface.roster.xml.get_object('show_offline_contacts_menuitem')
-
- self.config_dialog = None
-
- @log_calls('RosterButtonsPlugin')
- def activate(self):
- self.xml = gtk.Builder()
- self.xml.set_translation_domain(i18n.APP)
- self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
- ['roster_buttons_buttonbox'])
- self.buttonbox = self.xml.get_object('roster_buttons_buttonbox')
-
- self.roster_vbox.pack_start(self.buttonbox, expand=False)
- self.roster_vbox.reorder_child(self.buttonbox, 0)
- self.xml.connect_signals(self)
-
- @log_calls('RosterButtonsPlugin')
- def deactivate(self):
- self.roster_vbox.remove(self.buttonbox)
-
- self.buttonbox = None
- self.xml = None
-
- @log_calls('RosterButtonsPlugin')
- def on_roster_button_1_clicked(self, button):
- #gajim.interface.roster.on_show_offline_contacts_menuitem_activate(None)
- self.show_offline_contacts_menuitem.set_active(not self.show_offline_contacts_menuitem.get_active())
-
- @log_calls('RosterButtonsPlugin')
- def on_roster_button_2_clicked(self, button):
- pass
-
- @log_calls('RosterButtonsPlugin')
- def on_roster_button_3_clicked(self, button):
- pass
-
- @log_calls('RosterButtonsPlugin')
- def on_roster_button_4_clicked(self, button):
- pass
-
+ name = u'Roster Buttons'
+ short_name = u'roster_buttons'
+ version = u'0.1'
+ description = u'''Adds quick action buttons to roster window.'''
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
+
+ @log_calls('RosterButtonsPlugin')
+ def init(self):
+ self.GTK_BUILDER_FILE_PATH = self.local_file_path('roster_buttons.ui')
+ self.roster_vbox = gajim.interface.roster.xml.get_object('roster_vbox2')
+ self.show_offline_contacts_menuitem = gajim.interface.roster.xml.get_object('show_offline_contacts_menuitem')
+
+ self.config_dialog = None
+
+ @log_calls('RosterButtonsPlugin')
+ def activate(self):
+ self.xml = gtk.Builder()
+ self.xml.set_translation_domain(i18n.APP)
+ self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
+ ['roster_buttons_buttonbox'])
+ self.buttonbox = self.xml.get_object('roster_buttons_buttonbox')
+
+ self.roster_vbox.pack_start(self.buttonbox, expand=False)
+ self.roster_vbox.reorder_child(self.buttonbox, 0)
+ self.xml.connect_signals(self)
+
+ @log_calls('RosterButtonsPlugin')
+ def deactivate(self):
+ self.roster_vbox.remove(self.buttonbox)
+
+ self.buttonbox = None
+ self.xml = None
+
+ @log_calls('RosterButtonsPlugin')
+ def on_roster_button_1_clicked(self, button):
+ #gajim.interface.roster.on_show_offline_contacts_menuitem_activate(None)
+ self.show_offline_contacts_menuitem.set_active(not self.show_offline_contacts_menuitem.get_active())
+
+ @log_calls('RosterButtonsPlugin')
+ def on_roster_button_2_clicked(self, button):
+ pass
+
+ @log_calls('RosterButtonsPlugin')
+ def on_roster_button_3_clicked(self, button):
+ pass
+
+ @log_calls('RosterButtonsPlugin')
+ def on_roster_button_4_clicked(self, button):
+ pass
diff --git a/plugins/snarl_notifications/PySnarl.py b/plugins/snarl_notifications/PySnarl.py
index 118a7b25c..c3c657e56 100755
--- a/plugins/snarl_notifications/PySnarl.py
+++ b/plugins/snarl_notifications/PySnarl.py
@@ -1,772 +1,772 @@
-"""
-A python version of the main functions to use Snarl
-(http://www.fullphat.net/snarl)
-
-Version 1.0
-
-This module can be used in two ways. One is the normal way
-the other snarl interfaces work. This means you can call snShowMessage
-and get an ID back for manipulations.
-
-The other way is there is a class this module exposes called SnarlMessage.
-This allows you to keep track of the message as a python object. If you
-use the send without specifying False as the argument it will set the ID
-to what the return of the last SendMessage was. This is of course only
-useful for the SHOW message.
-
-Requires one of:
- pywin32 extensions from http://pywin32.sourceforge.net
- ctypes (included in Python 2.5, downloadable for earlier versions)
-
-Creator: Sam Listopad II (samlii@users.sourceforge.net)
-
-Copyright 2006-2008 Samuel Listopad II
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not
-use this file except in compliance with the License. You may obtain a copy
-of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-by applicable law or agreed to in writing, software distributed under the
-License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-OF ANY KIND, either express or implied. See the License for the specific
-language governing permissions and limitations under the License.
-"""
-
-import array, struct
-
-def LOWORD(dword):
- """Return the low WORD of the passed in integer"""
- return dword & 0x0000ffff
-#get the hi word
-def HIWORD(dword):
- """Return the high WORD of the passed in integer"""
- return dword >> 16
-
-class Win32FuncException(Exception):
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return repr(self.value)
-
-class Win32Funcs:
- """Just a little class to hide the details of finding and using the
-correct win32 functions. The functions may throw a UnicodeEncodeError if
-there is not a unicode version and it is sent a unicode string that cannot
-be converted to ASCII."""
- WM_USER = 0x400
- WM_COPYDATA = 0x4a
- #Type of String the functions are expecting.
- #Used like function(myWin32Funcs.strType(param)).
- __strType = str
- #FindWindow function to use
- __FindWindow = None
- #FindWindow function to use
- __FindWindowEx = None
- #SendMessage function to use
- __SendMessage = None
- #SendMessageTimeout function to use
- __SendMessageTimeout = None
- #IsWindow function to use
- __IsWindow = None
- #RegisterWindowMessage to use
- __RegisterWindowMessage = None
- #GetWindowText to use
- __GetWindowText = None
-
- def FindWindow(self, lpClassName, lpWindowName):
- """Wraps the windows API call of FindWindow"""
- if lpClassName is not None:
- lpClassName = self.__strType(lpClassName)
- if lpWindowName is not None:
- lpWindowName = self.__strType(lpWindowName)
- return self.__FindWindow(lpClassName, lpWindowName)
-
- def FindWindowEx(self, hwndParent, hwndChildAfter, lpClassName, lpWindowName):
- """Wraps the windows API call of FindWindow"""
- if lpClassName is not None:
- lpClassName = self.__strType(lpClassName)
- if lpWindowName is not None:
- lpWindowName = self.__strType(lpWindowName)
- return self.__FindWindowEx(hwndParent, hwndChildAfter, lpClassName, lpWindowName)
-
- def SendMessage(self, hWnd, Msg, wParam, lParam):
- """Wraps the windows API call of SendMessage"""
- return self.__SendMessage(hWnd, Msg, wParam, lParam)
-
- def SendMessageTimeout(self, hWnd, Msg,
- wParam, lParam, fuFlags,
- uTimeout, lpdwResult = None):
- """Wraps the windows API call of SendMessageTimeout"""
- idToRet = None
- try:
- idFromMsg = array.array('I', [0])
- result = idFromMsg.buffer_info()[0]
- response = self.__SendMessageTimeout(hWnd, Msg, wParam,
- lParam, fuFlags,
- uTimeout, result)
- if response == 0:
- raise Win32FuncException, "SendMessageTimeout TimedOut"
-
- idToRet = idFromMsg[0]
- except TypeError:
- idToRet = self.__SendMessageTimeout(hWnd, Msg, wParam,
- lParam, fuFlags,
- uTimeout)
-
- if lpdwResult is not None and lpdwResult.typecode == 'I':
- lpdwResult[0] = idToRet
-
- return idToRet
-
- def IsWindow(self, hWnd):
- """Wraps the windows API call of IsWindow"""
- return self.__IsWindow(hWnd)
-
- def RegisterWindowMessage(self, lpString):
- """Wraps the windows API call of RegisterWindowMessage"""
- return self.__RegisterWindowMessage(self.__strType(lpString))
-
- def GetWindowText(self, hWnd, lpString = None, nMaxCount = None):
- """Wraps the windows API call of SendMessageTimeout"""
- text = ''
- if hWnd == 0:
- return text
-
- if nMaxCount is None:
- nMaxCount = 1025
-
- try:
- arrayType = 'c'
- if self.__strType == unicode:
- arrayType = 'u'
- path_string = array.array(arrayType, self.__strType('\x00') * nMaxCount)
- path_buffer = path_string.buffer_info()[0]
- result = self.__GetWindowText(hWnd,
- path_buffer,
- nMaxCount)
- if result > 0:
- if self.__strType == unicode:
- text = path_string[0:result].tounicode()
- else:
- text = path_string[0:result].tostring()
- except TypeError:
- text = self.__GetWindowText(hWnd)
-
- if lpString is not None and lpString.typecode == 'c':
- lpdwResult[0:len(text)] = array.array('c',str(text));
-
- if lpString is not None and lpString.typecode == 'u':
- lpdwResult[0:len(text)] = array.array('u',unicode(text));
-
- return text
-
- def __init__(self):
- """Load up my needed functions"""
- # First see if they already have win32gui imported. If so use it.
- # This has to be checked first since the auto check looks for ctypes
- # first.
- try:
- self.__FindWindow = win32gui.FindWindow
- self.__FindWindowEx = win32gui.FindWindowEx
- self.__GetWindowText = win32gui.GetWindowText
- self.__IsWindow = win32gui.IsWindow
- self.__SendMessage = win32gui.SendMessage
- self.__SendMessageTimeout = win32gui.SendMessageTimeout
- self.__RegisterWindowMessage = win32gui.RegisterWindowMessage
- self.__strType = unicode
-
- #Something threw a NameError, most likely the win32gui lines
- #so do auto check
- except NameError:
- try:
- from ctypes import windll
- self.__FindWindow = windll.user32.FindWindowW
- self.__FindWindowEx = windll.user32.FindWindowExW
- self.__GetWindowText = windll.user32.GetWindowTextW
- self.__IsWindow = windll.user32.IsWindow
- self.__SendMessage = windll.user32.SendMessageW
- self.__SendMessageTimeout = windll.user32.SendMessageTimeoutW
- self.__RegisterWindowMessage = windll.user32.RegisterWindowMessageW
- self.__strType = unicode
-
- #FindWindowW wasn't found, look for FindWindowA
- except AttributeError:
- try:
- self.__FindWindow = windll.user32.FindWindowA
- self.__FindWindowEx = windll.user32.FindWindowExA
- self.__GetWindowText = windll.user32.GetWindowTextA
- self.__IsWindow = windll.user32.IsWindow
- self.__SendMessage = windll.user32.SendMessageA
- self.__SendMessageTimeout = windll.user32.SendMessageTimeoutA
- self.__RegisterWindowMessage = windll.user32.RegisterWindowMessageA
- # Couldn't find either so Die and tell user why.
- except AttributeError:
- import sys
- sys.stderr.write("Your Windows TM setup seems to be corrupt."+
- " No FindWindow found in user32.\n")
- sys.stderr.flush()
- sys.exit(3)
-
- except ImportError:
- try:
- import win32gui
- self.__FindWindow = win32gui.FindWindow
- self.__FindWindowEx = win32gui.FindWindowEx
- self.__GetWindowText = win32gui.GetWindowText
- self.__IsWindow = win32gui.IsWindow
- self.__SendMessage = win32gui.SendMessage
- self.__SendMessageTimeout = win32gui.SendMessageTimeout
- self.__RegisterWindowMessage = win32gui.RegisterWindowMessage
- self.__strType = unicode
-
- except ImportError:
- import sys
- sys.stderr.write("You need to have either"+
- " ctypes or pywin32 installed.\n")
- sys.stderr.flush()
- #sys.exit(2)
-
-
-myWin32Funcs = Win32Funcs()
-
-
-SHOW = 1
-HIDE = 2
-UPDATE = 3
-IS_VISIBLE = 4
-GET_VERSION = 5
-REGISTER_CONFIG_WINDOW = 6
-REVOKE_CONFIG_WINDOW = 7
-REGISTER_ALERT = 8
-REVOKE_ALERT = 9
-REGISTER_CONFIG_WINDOW_2 = 10
-GET_VERSION_EX = 11
-SET_TIMEOUT = 12
-
-EX_SHOW = 32
-
-GLOBAL_MESSAGE = "SnarlGlobalMessage"
-GLOBAL_MSG = "SnarlGlobalEvent"
-
-#Messages That may be received from Snarl
-SNARL_LAUNCHED = 1
-SNARL_QUIT = 2
-SNARL_ASK_APPLET_VER = 3
-SNARL_SHOW_APP_UI = 4
-
-SNARL_NOTIFICATION_CLICKED = 32 #notification was right-clicked by user
-SNARL_NOTIFICATION_CANCELLED = SNARL_NOTIFICATION_CLICKED #Name clarified
-SNARL_NOTIFICATION_TIMED_OUT = 33
-SNARL_NOTIFICATION_ACK = 34 #notification was left-clicked by user
-
-#Snarl Test Message
-WM_SNARLTEST = myWin32Funcs.WM_USER + 237
-
-M_ABORTED = 0x80000007L
-M_ACCESS_DENIED = 0x80000009L
-M_ALREADY_EXISTS = 0x8000000CL
-M_BAD_HANDLE = 0x80000006L
-M_BAD_POINTER = 0x80000005L
-M_FAILED = 0x80000008L
-M_INVALID_ARGS = 0x80000003L
-M_NO_INTERFACE = 0x80000004L
-M_NOT_FOUND = 0x8000000BL
-M_NOT_IMPLEMENTED = 0x80000001L
-M_OK = 0x00000000L
-M_OUT_OF_MEMORY = 0x80000002L
-M_TIMED_OUT = 0x8000000AL
-
-ErrorCodeRev = {
- 0x80000007L : "M_ABORTED",
- 0x80000009L : "M_ACCESS_DENIED",
- 0x8000000CL : "M_ALREADY_EXISTS",
- 0x80000006L : "M_BAD_HANDLE",
- 0x80000005L : "M_BAD_POINTER",
- 0x80000008L : "M_FAILED",
- 0x80000003L : "M_INVALID_ARGS",
- 0x80000004L : "M_NO_INTERFACE",
- 0x8000000BL : "M_NOT_FOUND",
- 0x80000001L : "M_NOT_IMPLEMENTED",
- 0x00000000L : "M_OK",
- 0x80000002L : "M_OUT_OF_MEMORY",
- 0x8000000AL : "M_TIMED_OUT"
- }
-
-class SnarlMessage(object):
- """The main Snarl interface object.
-
- ID = Snarl Message ID for most operations. See SDK for more info
- as to other values to put here.
- type = Snarl Message Type. Valid values are : SHOW, HIDE, UPDATE,
- IS_VISIBLE, GET_VERSION, REGISTER_CONFIG_WINDOW, REVOKE_CONFIG_WINDOW
- all which are constants in the PySnarl module.
- timeout = Timeout in seconds for the Snarl Message
- data = Snarl Message data. This is dependant upon message type. See SDK
- title = Snarl Message title.
- text = Snarl Message text.
- icon = Path to the icon to display in the Snarl Message.
- """
- __msgType = 0
- __msgID = 0
- __msgTimeout = 0
- __msgData = 0
- __msgTitle = ""
- __msgText = ""
- __msgIcon = ""
- __msgClass = ""
- __msgExtra = ""
- __msgExtra2 = ""
- __msgRsvd1 = 0
- __msgRsvd2 = 0
- __msgHWnd = 0
-
- lastKnownHWnd = 0
-
- def getType(self):
- """Type Attribute getter."""
- return self.__msgType
- def setType(self, value):
- """Type Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgType = value
- type = property(getType, setType, doc="The Snarl Message Type")
-
- def getID(self):
- """ID Attribute getter."""
- return self.__msgID
- def setID(self, value):
- """ID Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgID = value
- ID = property(getID, setID, doc="The Snarl Message ID")
-
- def getTimeout(self):
- """Timeout Attribute getter."""
- return self.__msgTimeout
- def updateTimeout(self, value):
- """Timeout Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgTimeout = value
- timeout = property(getTimeout, updateTimeout,
- doc="The Snarl Message Timeout")
-
- def getData(self):
- """Data Attribute getter."""
- return self.__msgData
- def setData(self, value):
- """Data Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgData = value
- data = property(getData, setData, doc="The Snarl Message Data")
-
- def getTitle(self):
- """Title Attribute getter."""
- return self.__msgTitle
- def setTitle(self, value):
- """Title Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgTitle = value
- title = property(getTitle, setTitle, doc="The Snarl Message Title")
-
- def getText(self):
- """Text Attribute getter."""
- return self.__msgText
- def setText(self, value):
- """Text Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgText = value
- text = property(getText, setText, doc="The Snarl Message Text")
-
- def getIcon(self):
- """Icon Attribute getter."""
- return self.__msgIcon
- def setIcon(self, value):
- """Icon Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgIcon = value
- icon = property(getIcon, setIcon, doc="The Snarl Message Icon")
-
- def getClass(self):
- """Class Attribute getter."""
- return self.__msgClass
- def setClass(self, value):
- """Class Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgClass = value
- msgclass = property(getClass, setClass, doc="The Snarl Message Class")
-
- def getExtra(self):
- """Extra Attribute getter."""
- return self.__msgExtra
- def setExtra(self, value):
- """Extra Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgExtra = value
- extra = property(getExtra, setExtra, doc="Extra Info for the Snarl Message")
-
- def getExtra2(self):
- """Extra2 Attribute getter."""
- return self.__msgExtra2
- def setExtra2(self, value):
- """Extra2 Attribute setter."""
- if( isinstance(value, basestring) ):
- self.__msgExtra2 = value
- extra2 = property(getExtra2, setExtra2,
- doc="More Extra Info for the Snarl Message")
-
- def getRsvd1(self):
- """Rsvd1 Attribute getter."""
- return self.__msgRsvd1
- def setRsvd1(self, value):
- """Rsvd1 Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgRsvd1 = value
- rsvd1 = property(getRsvd1, setRsvd1, doc="The Snarl Message Field Rsvd1")
-
- def getRsvd2(self):
- """Rsvd2 Attribute getter."""
- return self.__msgRsvd2
- def setRsvd2(self, value):
- """Rsvd2 Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgRsvd2 = value
- rsvd2 = property(getRsvd2, setRsvd2, doc="The Snarl Message Field Rsvd2")
-
- def getHwnd(self):
- """hWnd Attribute getter."""
- return self.__msgHWnd
- def setHwnd(self, value):
- """hWnd Attribute setter."""
- if( isinstance(value, (int, long)) ):
- self.__msgHWnd = value
-
- hWnd = property(getHwnd, setHwnd, doc="The hWnd of the window this message is being sent from")
-
-
- def __init__(self, title="", text="", icon="", msg_type=1, msg_id=0):
- self.__msgTimeout = 0
- self.__msgData = 0
- self.__msgClass = ""
- self.__msgExtra = ""
- self.__msgExtra2 = ""
- self.__msgRsvd1 = 0
- self.__msgRsvd2 = 0
- self.__msgType = msg_type
- self.__msgText = text
- self.__msgTitle = title
- self.__msgIcon = icon
- self.__msgID = msg_id
-
- def createCopyStruct(self):
- """Creates the struct to send as the copyData in the message."""
- return struct.pack("ILLL1024s1024s1024s1024s1024s1024sLL",
- self.__msgType,
- self.__msgID,
- self.__msgTimeout,
- self.__msgData,
- self.__msgTitle.encode('utf-8'),
- self.__msgText.encode('utf-8'),
- self.__msgIcon.encode('utf-8'),
- self.__msgClass.encode('utf-8'),
- self.__msgExtra.encode('utf-8'),
- self.__msgExtra2.encode('utf-8'),
- self.__msgRsvd1,
- self.__msgRsvd2
- )
- __lpData = None
- __cds = None
-
- def packData(self, dwData):
- """This packs the data in the necessary format for a
-WM_COPYDATA message."""
- self.__lpData = None
- self.__cds = None
- item = self.createCopyStruct()
- self.__lpData = array.array('c', item)
- lpData_ad = self.__lpData.buffer_info()[0]
- cbData = self.__lpData.buffer_info()[1]
- self.__cds = array.array('c',
- struct.pack("IIP",
- dwData,
- cbData,
- lpData_ad)
- )
- cds_ad = self.__cds.buffer_info()[0]
- return cds_ad
-
- def reset(self):
- """Reset this SnarlMessage to the default state."""
- self.__msgType = 0
- self.__msgID = 0
- self.__msgTimeout = 0
- self.__msgData = 0
- self.__msgTitle = ""
- self.__msgText = ""
- self.__msgIcon = ""
- self.__msgClass = ""
- self.__msgExtra = ""
- self.__msgExtra2 = ""
- self.__msgRsvd1 = 0
- self.__msgRsvd2 = 0
-
-
- def send(self, setid=True):
- """Send this SnarlMessage to the Snarl window.
-Args:
- setid - Boolean defining whether or not to set the ID
- of this SnarlMessage to the return value of
- the SendMessage call. Default is True to
- make simple case of SHOW easy.
- """
- hwnd = myWin32Funcs.FindWindow(None, "Snarl")
- if myWin32Funcs.IsWindow(hwnd):
- if self.type == REGISTER_CONFIG_WINDOW or self.type == REGISTER_CONFIG_WINDOW_2:
- self.hWnd = self.data
- try:
- response = myWin32Funcs.SendMessageTimeout(hwnd,
- myWin32Funcs.WM_COPYDATA,
- self.hWnd, self.packData(2),
- 2, 500)
- except Win32FuncException:
- return False
-
- idFromMsg = response
- if setid:
- self.ID = idFromMsg
- return True
- else:
- return idFromMsg
- print "No snarl window found"
- return False
-
- def hide(self):
- """Hide this message. Type will revert to type before calling hide
-to allow for better reuse of object."""
- oldType = self.__msgType
- self.__msgType = HIDE
- retVal = bool(self.send(False))
- self.__msgType = oldType
- return retVal
-
- def isVisible(self):
- """Is this message visible. Type will revert to type before calling
-hide to allow for better reuse of object."""
- oldType = self.__msgType
- self.__msgType = IS_VISIBLE
- retVal = bool(self.send(False))
- self.__msgType = oldType
- return retVal
-
- def update(self, title=None, text=None, icon=None):
- """Update this message with given title and text. Type will revert
-to type before calling hide to allow for better reuse of object."""
- oldType = self.__msgType
- self.__msgType = UPDATE
- if text:
- self.__msgText = text
- if title:
- self.__msgTitle = title
- if icon:
- self.__msgIcon = icon
- retVal = self.send(False)
- self.__msgType = oldType
- return retVal
-
- def setTimeout(self, timeout):
- """Set the timeout in seconds of the message"""
- oldType = self.__msgType
- oldData = self.__msgData
- self.__msgType = SET_TIMEOUT
- #self.timeout = timeout
- #self.__msgData = self.__msgTimeout
- self.__msgData = timeout
- retVal = self.send(False)
- self.__msgType = oldType
- self.__msgData = oldData
- return retVal
-
- def show(self, timeout=None, title=None,
- text=None, icon=None,
- replyWindow=None, replyMsg=None, msgclass=None, soundPath=None):
- """Show a message"""
- oldType = self.__msgType
- oldTimeout = self.__msgTimeout
- self.__msgType = SHOW
- if text:
- self.__msgText = text
- if title:
- self.__msgTitle = title
- if timeout:
- self.__msgTimeout = timeout
- if icon:
- self.__msgIcon = icon
- if replyWindow:
- self.__msgID = replyMsg
- if replyMsg:
- self.__msgData = replyWindow
- if soundPath:
- self.__msgExtra = soundPath
- if msgclass:
- self.__msgClass = msgclass
-
- if ((self.__msgClass and self.__msgClass != "") or
- (self.__msgExtra and self.__msgExtra != "")):
- self.__msgType = EX_SHOW
-
-
- retVal = bool(self.send())
- self.__msgType = oldType
- self.__msgTimeout = oldTimeout
- return retVal
-
-
-def snGetVersion():
- """ Get the version of Snarl that is running as a tuple. (Major, Minor)
-
-If Snarl is not running or there was an error it will
-return False."""
- msg = SnarlMessage(msg_type=GET_VERSION)
- version = msg.send(False)
- if not version:
- return False
- return (HIWORD(version), LOWORD(version))
-
-def snGetVersionEx():
- """ Get the internal version of Snarl that is running.
-
-If Snarl is not running or there was an error it will
-return False."""
- sm = SnarlMessage(msg_type=GET_VERSION_EX)
- verNum = sm.send(False)
- if not verNum:
- return False
- return verNum
-
-def snGetGlobalMessage():
- """Get the Snarl global message id from windows."""
- return myWin32Funcs.RegisterWindowMessage(GLOBAL_MSG)
-
-def snShowMessage(title, text, timeout=0, iconPath="",
- replyWindow=0, replyMsg=0):
- """Show a message using Snarl and return its ID. See SDK for arguments."""
- sm = SnarlMessage( title, text, iconPath, msg_id=replyMsg)
- sm.data = replyWindow
- if sm.show(timeout):
- return sm.ID
- else:
- return False
-
-def snShowMessageEx(msgClass, title, text, timeout=0, iconPath="",
- replyWindow=0, replyMsg=0, soundFile=None, hWndFrom=None):
- """Show a message using Snarl and return its ID. See SDK for arguments.
- One added argument is hWndFrom that allows one to make the messages appear
- to come from a specific window. This window should be the one you registered
- earlier with RegisterConfig"""
- sm = SnarlMessage( title, text, iconPath, msg_id=replyMsg)
- sm.data = replyWindow
- if hWndFrom is not None:
- sm.hWnd = hWndFrom
- else:
- sm.hWnd = SnarlMessage.lastKnownHWnd
- if sm.show(timeout, msgclass=msgClass, soundPath=soundFile):
- return sm.ID
- else:
- return False
-
-def snUpdateMessage(msgId, msgTitle, msgText, icon=None):
- """Update a message"""
- sm = SnarlMessage(msg_id=msgId)
- if icon:
- sm.icon = icon
- return sm.update(msgTitle, msgText)
-
-def snHideMessage(msgId):
- """Hide a message"""
- return SnarlMessage(msg_id=msgId).hide()
-
-def snSetTimeout(msgId, timeout):
- """Update the timeout of a message already shown."""
- sm = SnarlMessage(msg_id=msgId)
- return sm.setTimeout(timeout)
-
-def snIsMessageVisible(msgId):
- """Returns True if the message is visible False otherwise."""
- return SnarlMessage(msg_id=msgId).isVisible()
-
-def snRegisterConfig(replyWnd, appName, replyMsg):
- """Register a config window. See SDK for more info."""
- global lastRegisteredSnarlMsg
- sm = SnarlMessage(msg_type=REGISTER_CONFIG_WINDOW,
- title=appName,
- msg_id=replyMsg)
- sm.data = replyWnd
- SnarlMessage.lastKnownHWnd = replyWnd
-
- return sm.send(False)
-
-def snRegisterConfig2(replyWnd, appName, replyMsg, icon):
- """Register a config window. See SDK for more info."""
- global lastRegisteredSnarlMsg
- sm = SnarlMessage(msg_type=REGISTER_CONFIG_WINDOW_2,
- title=appName,
- msg_id=replyMsg,
- icon=icon)
- sm.data = replyWnd
- SnarlMessage.lastKnownHWnd = replyWnd
- return sm.send(False)
-
-def snRegisterAlert(appName, classStr) :
- """Register an alert for an already registered config. See SDK for more info."""
- sm = SnarlMessage(msg_type=REGISTER_ALERT,
- title=appName,
- text=classStr)
- return sm.send(False)
-
-def snRevokeConfig(replyWnd):
- """Revoke a config window"""
- sm = SnarlMessage(msg_type=REVOKE_CONFIG_WINDOW)
- sm.data = replyWnd
- if replyWnd == SnarlMessage.lastKnownHWnd:
- SnarlMessage.lastKnownHWnd = 0
- return sm.send(False)
-
-def snGetSnarlWindow():
- """Returns the hWnd of the snarl window"""
- return myWin32Funcs.FindWindow(None, "Snarl")
-
-def snGetAppPath():
- """Returns the application path of the currently running snarl window"""
- app_path = None
- snarl_handle = snGetSnarlWindow()
- if snarl_handle != 0:
- pathwin_handle = myWin32Funcs.FindWindowEx(snarl_handle,
- 0,
- "static",
- None)
- if pathwin_handle != 0:
- try:
- result = myWin32Funcs.GetWindowText(pathwin_handle)
- app_path = result
- except Win32FuncException:
- pass
-
-
- return app_path
-
-def snGetIconsPath():
- """Returns the path to the icons of the program"""
- s = snGetAppPath()
- if s is None:
- return ""
- else:
- return s + "etc\\icons\\"
-
-def snSendTestMessage(data=None):
- """Sends a test message to Snarl. Used to make sure the
-api is connecting"""
- param = 0
- command = 0
- if data:
- param = struct.pack("I", data)
- command = 1
- myWin32Funcs.SendMessage(snGetSnarlWindow(), WM_SNARLTEST, command, param)
+"""
+A python version of the main functions to use Snarl
+(http://www.fullphat.net/snarl)
+
+Version 1.0
+
+This module can be used in two ways. One is the normal way
+the other snarl interfaces work. This means you can call snShowMessage
+and get an ID back for manipulations.
+
+The other way is there is a class this module exposes called SnarlMessage.
+This allows you to keep track of the message as a python object. If you
+use the send without specifying False as the argument it will set the ID
+to what the return of the last SendMessage was. This is of course only
+useful for the SHOW message.
+
+Requires one of:
+ pywin32 extensions from http://pywin32.sourceforge.net
+ ctypes (included in Python 2.5, downloadable for earlier versions)
+
+Creator: Sam Listopad II (samlii@users.sourceforge.net)
+
+Copyright 2006-2008 Samuel Listopad II
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy
+of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
+by applicable law or agreed to in writing, software distributed under the
+License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+"""
+
+import array, struct
+
+def LOWORD(dword):
+ """Return the low WORD of the passed in integer"""
+ return dword & 0x0000ffff
+#get the hi word
+def HIWORD(dword):
+ """Return the high WORD of the passed in integer"""
+ return dword >> 16
+
+class Win32FuncException(Exception):
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
+
+class Win32Funcs:
+ """Just a little class to hide the details of finding and using the
+correct win32 functions. The functions may throw a UnicodeEncodeError if
+there is not a unicode version and it is sent a unicode string that cannot
+be converted to ASCII."""
+ WM_USER = 0x400
+ WM_COPYDATA = 0x4a
+ #Type of String the functions are expecting.
+ #Used like function(myWin32Funcs.strType(param)).
+ __strType = str
+ #FindWindow function to use
+ __FindWindow = None
+ #FindWindow function to use
+ __FindWindowEx = None
+ #SendMessage function to use
+ __SendMessage = None
+ #SendMessageTimeout function to use
+ __SendMessageTimeout = None
+ #IsWindow function to use
+ __IsWindow = None
+ #RegisterWindowMessage to use
+ __RegisterWindowMessage = None
+ #GetWindowText to use
+ __GetWindowText = None
+
+ def FindWindow(self, lpClassName, lpWindowName):
+ """Wraps the windows API call of FindWindow"""
+ if lpClassName is not None:
+ lpClassName = self.__strType(lpClassName)
+ if lpWindowName is not None:
+ lpWindowName = self.__strType(lpWindowName)
+ return self.__FindWindow(lpClassName, lpWindowName)
+
+ def FindWindowEx(self, hwndParent, hwndChildAfter, lpClassName, lpWindowName):
+ """Wraps the windows API call of FindWindow"""
+ if lpClassName is not None:
+ lpClassName = self.__strType(lpClassName)
+ if lpWindowName is not None:
+ lpWindowName = self.__strType(lpWindowName)
+ return self.__FindWindowEx(hwndParent, hwndChildAfter, lpClassName, lpWindowName)
+
+ def SendMessage(self, hWnd, Msg, wParam, lParam):
+ """Wraps the windows API call of SendMessage"""
+ return self.__SendMessage(hWnd, Msg, wParam, lParam)
+
+ def SendMessageTimeout(self, hWnd, Msg,
+ wParam, lParam, fuFlags,
+ uTimeout, lpdwResult = None):
+ """Wraps the windows API call of SendMessageTimeout"""
+ idToRet = None
+ try:
+ idFromMsg = array.array('I', [0])
+ result = idFromMsg.buffer_info()[0]
+ response = self.__SendMessageTimeout(hWnd, Msg, wParam,
+ lParam, fuFlags,
+ uTimeout, result)
+ if response == 0:
+ raise Win32FuncException, "SendMessageTimeout TimedOut"
+
+ idToRet = idFromMsg[0]
+ except TypeError:
+ idToRet = self.__SendMessageTimeout(hWnd, Msg, wParam,
+ lParam, fuFlags,
+ uTimeout)
+
+ if lpdwResult is not None and lpdwResult.typecode == 'I':
+ lpdwResult[0] = idToRet
+
+ return idToRet
+
+ def IsWindow(self, hWnd):
+ """Wraps the windows API call of IsWindow"""
+ return self.__IsWindow(hWnd)
+
+ def RegisterWindowMessage(self, lpString):
+ """Wraps the windows API call of RegisterWindowMessage"""
+ return self.__RegisterWindowMessage(self.__strType(lpString))
+
+ def GetWindowText(self, hWnd, lpString = None, nMaxCount = None):
+ """Wraps the windows API call of SendMessageTimeout"""
+ text = ''
+ if hWnd == 0:
+ return text
+
+ if nMaxCount is None:
+ nMaxCount = 1025
+
+ try:
+ arrayType = 'c'
+ if self.__strType == unicode:
+ arrayType = 'u'
+ path_string = array.array(arrayType, self.__strType('\x00') * nMaxCount)
+ path_buffer = path_string.buffer_info()[0]
+ result = self.__GetWindowText(hWnd,
+ path_buffer,
+ nMaxCount)
+ if result > 0:
+ if self.__strType == unicode:
+ text = path_string[0:result].tounicode()
+ else:
+ text = path_string[0:result].tostring()
+ except TypeError:
+ text = self.__GetWindowText(hWnd)
+
+ if lpString is not None and lpString.typecode == 'c':
+ lpdwResult[0:len(text)] = array.array('c', str(text));
+
+ if lpString is not None and lpString.typecode == 'u':
+ lpdwResult[0:len(text)] = array.array('u', unicode(text));
+
+ return text
+
+ def __init__(self):
+ """Load up my needed functions"""
+ # First see if they already have win32gui imported. If so use it.
+ # This has to be checked first since the auto check looks for ctypes
+ # first.
+ try:
+ self.__FindWindow = win32gui.FindWindow
+ self.__FindWindowEx = win32gui.FindWindowEx
+ self.__GetWindowText = win32gui.GetWindowText
+ self.__IsWindow = win32gui.IsWindow
+ self.__SendMessage = win32gui.SendMessage
+ self.__SendMessageTimeout = win32gui.SendMessageTimeout
+ self.__RegisterWindowMessage = win32gui.RegisterWindowMessage
+ self.__strType = unicode
+
+ #Something threw a NameError, most likely the win32gui lines
+ #so do auto check
+ except NameError:
+ try:
+ from ctypes import windll
+ self.__FindWindow = windll.user32.FindWindowW
+ self.__FindWindowEx = windll.user32.FindWindowExW
+ self.__GetWindowText = windll.user32.GetWindowTextW
+ self.__IsWindow = windll.user32.IsWindow
+ self.__SendMessage = windll.user32.SendMessageW
+ self.__SendMessageTimeout = windll.user32.SendMessageTimeoutW
+ self.__RegisterWindowMessage = windll.user32.RegisterWindowMessageW
+ self.__strType = unicode
+
+ #FindWindowW wasn't found, look for FindWindowA
+ except AttributeError:
+ try:
+ self.__FindWindow = windll.user32.FindWindowA
+ self.__FindWindowEx = windll.user32.FindWindowExA
+ self.__GetWindowText = windll.user32.GetWindowTextA
+ self.__IsWindow = windll.user32.IsWindow
+ self.__SendMessage = windll.user32.SendMessageA
+ self.__SendMessageTimeout = windll.user32.SendMessageTimeoutA
+ self.__RegisterWindowMessage = windll.user32.RegisterWindowMessageA
+ # Couldn't find either so Die and tell user why.
+ except AttributeError:
+ import sys
+ sys.stderr.write("Your Windows TM setup seems to be corrupt."+
+ " No FindWindow found in user32.\n")
+ sys.stderr.flush()
+ sys.exit(3)
+
+ except ImportError:
+ try:
+ import win32gui
+ self.__FindWindow = win32gui.FindWindow
+ self.__FindWindowEx = win32gui.FindWindowEx
+ self.__GetWindowText = win32gui.GetWindowText
+ self.__IsWindow = win32gui.IsWindow
+ self.__SendMessage = win32gui.SendMessage
+ self.__SendMessageTimeout = win32gui.SendMessageTimeout
+ self.__RegisterWindowMessage = win32gui.RegisterWindowMessage
+ self.__strType = unicode
+
+ except ImportError:
+ import sys
+ sys.stderr.write("You need to have either"+
+ " ctypes or pywin32 installed.\n")
+ sys.stderr.flush()
+ #sys.exit(2)
+
+
+myWin32Funcs = Win32Funcs()
+
+
+SHOW = 1
+HIDE = 2
+UPDATE = 3
+IS_VISIBLE = 4
+GET_VERSION = 5
+REGISTER_CONFIG_WINDOW = 6
+REVOKE_CONFIG_WINDOW = 7
+REGISTER_ALERT = 8
+REVOKE_ALERT = 9
+REGISTER_CONFIG_WINDOW_2 = 10
+GET_VERSION_EX = 11
+SET_TIMEOUT = 12
+
+EX_SHOW = 32
+
+GLOBAL_MESSAGE = "SnarlGlobalMessage"
+GLOBAL_MSG = "SnarlGlobalEvent"
+
+#Messages That may be received from Snarl
+SNARL_LAUNCHED = 1
+SNARL_QUIT = 2
+SNARL_ASK_APPLET_VER = 3
+SNARL_SHOW_APP_UI = 4
+
+SNARL_NOTIFICATION_CLICKED = 32 #notification was right-clicked by user
+SNARL_NOTIFICATION_CANCELLED = SNARL_NOTIFICATION_CLICKED #Name clarified
+SNARL_NOTIFICATION_TIMED_OUT = 33
+SNARL_NOTIFICATION_ACK = 34 #notification was left-clicked by user
+
+#Snarl Test Message
+WM_SNARLTEST = myWin32Funcs.WM_USER + 237
+
+M_ABORTED = 0x80000007L
+M_ACCESS_DENIED = 0x80000009L
+M_ALREADY_EXISTS = 0x8000000CL
+M_BAD_HANDLE = 0x80000006L
+M_BAD_POINTER = 0x80000005L
+M_FAILED = 0x80000008L
+M_INVALID_ARGS = 0x80000003L
+M_NO_INTERFACE = 0x80000004L
+M_NOT_FOUND = 0x8000000BL
+M_NOT_IMPLEMENTED = 0x80000001L
+M_OK = 0x00000000L
+M_OUT_OF_MEMORY = 0x80000002L
+M_TIMED_OUT = 0x8000000AL
+
+ErrorCodeRev = {
+ 0x80000007L : "M_ABORTED",
+ 0x80000009L : "M_ACCESS_DENIED",
+ 0x8000000CL : "M_ALREADY_EXISTS",
+ 0x80000006L : "M_BAD_HANDLE",
+ 0x80000005L : "M_BAD_POINTER",
+ 0x80000008L : "M_FAILED",
+ 0x80000003L : "M_INVALID_ARGS",
+ 0x80000004L : "M_NO_INTERFACE",
+ 0x8000000BL : "M_NOT_FOUND",
+ 0x80000001L : "M_NOT_IMPLEMENTED",
+ 0x00000000L : "M_OK",
+ 0x80000002L : "M_OUT_OF_MEMORY",
+ 0x8000000AL : "M_TIMED_OUT"
+ }
+
+class SnarlMessage(object):
+ """The main Snarl interface object.
+
+ ID = Snarl Message ID for most operations. See SDK for more info
+ as to other values to put here.
+ type = Snarl Message Type. Valid values are : SHOW, HIDE, UPDATE,
+ IS_VISIBLE, GET_VERSION, REGISTER_CONFIG_WINDOW, REVOKE_CONFIG_WINDOW
+ all which are constants in the PySnarl module.
+ timeout = Timeout in seconds for the Snarl Message
+ data = Snarl Message data. This is dependant upon message type. See SDK
+ title = Snarl Message title.
+ text = Snarl Message text.
+ icon = Path to the icon to display in the Snarl Message.
+ """
+ __msgType = 0
+ __msgID = 0
+ __msgTimeout = 0
+ __msgData = 0
+ __msgTitle = ""
+ __msgText = ""
+ __msgIcon = ""
+ __msgClass = ""
+ __msgExtra = ""
+ __msgExtra2 = ""
+ __msgRsvd1 = 0
+ __msgRsvd2 = 0
+ __msgHWnd = 0
+
+ lastKnownHWnd = 0
+
+ def getType(self):
+ """Type Attribute getter."""
+ return self.__msgType
+ def setType(self, value):
+ """Type Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgType = value
+ type = property(getType, setType, doc="The Snarl Message Type")
+
+ def getID(self):
+ """ID Attribute getter."""
+ return self.__msgID
+ def setID(self, value):
+ """ID Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgID = value
+ ID = property(getID, setID, doc="The Snarl Message ID")
+
+ def getTimeout(self):
+ """Timeout Attribute getter."""
+ return self.__msgTimeout
+ def updateTimeout(self, value):
+ """Timeout Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgTimeout = value
+ timeout = property(getTimeout, updateTimeout,
+ doc="The Snarl Message Timeout")
+
+ def getData(self):
+ """Data Attribute getter."""
+ return self.__msgData
+ def setData(self, value):
+ """Data Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgData = value
+ data = property(getData, setData, doc="The Snarl Message Data")
+
+ def getTitle(self):
+ """Title Attribute getter."""
+ return self.__msgTitle
+ def setTitle(self, value):
+ """Title Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgTitle = value
+ title = property(getTitle, setTitle, doc="The Snarl Message Title")
+
+ def getText(self):
+ """Text Attribute getter."""
+ return self.__msgText
+ def setText(self, value):
+ """Text Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgText = value
+ text = property(getText, setText, doc="The Snarl Message Text")
+
+ def getIcon(self):
+ """Icon Attribute getter."""
+ return self.__msgIcon
+ def setIcon(self, value):
+ """Icon Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgIcon = value
+ icon = property(getIcon, setIcon, doc="The Snarl Message Icon")
+
+ def getClass(self):
+ """Class Attribute getter."""
+ return self.__msgClass
+ def setClass(self, value):
+ """Class Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgClass = value
+ msgclass = property(getClass, setClass, doc="The Snarl Message Class")
+
+ def getExtra(self):
+ """Extra Attribute getter."""
+ return self.__msgExtra
+ def setExtra(self, value):
+ """Extra Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgExtra = value
+ extra = property(getExtra, setExtra, doc="Extra Info for the Snarl Message")
+
+ def getExtra2(self):
+ """Extra2 Attribute getter."""
+ return self.__msgExtra2
+ def setExtra2(self, value):
+ """Extra2 Attribute setter."""
+ if( isinstance(value, basestring) ):
+ self.__msgExtra2 = value
+ extra2 = property(getExtra2, setExtra2,
+ doc="More Extra Info for the Snarl Message")
+
+ def getRsvd1(self):
+ """Rsvd1 Attribute getter."""
+ return self.__msgRsvd1
+ def setRsvd1(self, value):
+ """Rsvd1 Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgRsvd1 = value
+ rsvd1 = property(getRsvd1, setRsvd1, doc="The Snarl Message Field Rsvd1")
+
+ def getRsvd2(self):
+ """Rsvd2 Attribute getter."""
+ return self.__msgRsvd2
+ def setRsvd2(self, value):
+ """Rsvd2 Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgRsvd2 = value
+ rsvd2 = property(getRsvd2, setRsvd2, doc="The Snarl Message Field Rsvd2")
+
+ def getHwnd(self):
+ """hWnd Attribute getter."""
+ return self.__msgHWnd
+ def setHwnd(self, value):
+ """hWnd Attribute setter."""
+ if( isinstance(value, (int, long)) ):
+ self.__msgHWnd = value
+
+ hWnd = property(getHwnd, setHwnd, doc="The hWnd of the window this message is being sent from")
+
+
+ def __init__(self, title="", text="", icon="", msg_type=1, msg_id=0):
+ self.__msgTimeout = 0
+ self.__msgData = 0
+ self.__msgClass = ""
+ self.__msgExtra = ""
+ self.__msgExtra2 = ""
+ self.__msgRsvd1 = 0
+ self.__msgRsvd2 = 0
+ self.__msgType = msg_type
+ self.__msgText = text
+ self.__msgTitle = title
+ self.__msgIcon = icon
+ self.__msgID = msg_id
+
+ def createCopyStruct(self):
+ """Creates the struct to send as the copyData in the message."""
+ return struct.pack("ILLL1024s1024s1024s1024s1024s1024sLL",
+ self.__msgType,
+ self.__msgID,
+ self.__msgTimeout,
+ self.__msgData,
+ self.__msgTitle.encode('utf-8'),
+ self.__msgText.encode('utf-8'),
+ self.__msgIcon.encode('utf-8'),
+ self.__msgClass.encode('utf-8'),
+ self.__msgExtra.encode('utf-8'),
+ self.__msgExtra2.encode('utf-8'),
+ self.__msgRsvd1,
+ self.__msgRsvd2
+ )
+ __lpData = None
+ __cds = None
+
+ def packData(self, dwData):
+ """This packs the data in the necessary format for a
+WM_COPYDATA message."""
+ self.__lpData = None
+ self.__cds = None
+ item = self.createCopyStruct()
+ self.__lpData = array.array('c', item)
+ lpData_ad = self.__lpData.buffer_info()[0]
+ cbData = self.__lpData.buffer_info()[1]
+ self.__cds = array.array('c',
+ struct.pack("IIP",
+ dwData,
+ cbData,
+ lpData_ad)
+ )
+ cds_ad = self.__cds.buffer_info()[0]
+ return cds_ad
+
+ def reset(self):
+ """Reset this SnarlMessage to the default state."""
+ self.__msgType = 0
+ self.__msgID = 0
+ self.__msgTimeout = 0
+ self.__msgData = 0
+ self.__msgTitle = ""
+ self.__msgText = ""
+ self.__msgIcon = ""
+ self.__msgClass = ""
+ self.__msgExtra = ""
+ self.__msgExtra2 = ""
+ self.__msgRsvd1 = 0
+ self.__msgRsvd2 = 0
+
+
+ def send(self, setid=True):
+ """Send this SnarlMessage to the Snarl window.
+Args:
+ setid - Boolean defining whether or not to set the ID
+ of this SnarlMessage to the return value of
+ the SendMessage call. Default is True to
+ make simple case of SHOW easy.
+ """
+ hwnd = myWin32Funcs.FindWindow(None, "Snarl")
+ if myWin32Funcs.IsWindow(hwnd):
+ if self.type == REGISTER_CONFIG_WINDOW or self.type == REGISTER_CONFIG_WINDOW_2:
+ self.hWnd = self.data
+ try:
+ response = myWin32Funcs.SendMessageTimeout(hwnd,
+ myWin32Funcs.WM_COPYDATA,
+ self.hWnd, self.packData(2),
+ 2, 500)
+ except Win32FuncException:
+ return False
+
+ idFromMsg = response
+ if setid:
+ self.ID = idFromMsg
+ return True
+ else:
+ return idFromMsg
+ print "No snarl window found"
+ return False
+
+ def hide(self):
+ """Hide this message. Type will revert to type before calling hide
+to allow for better reuse of object."""
+ oldType = self.__msgType
+ self.__msgType = HIDE
+ retVal = bool(self.send(False))
+ self.__msgType = oldType
+ return retVal
+
+ def isVisible(self):
+ """Is this message visible. Type will revert to type before calling
+hide to allow for better reuse of object."""
+ oldType = self.__msgType
+ self.__msgType = IS_VISIBLE
+ retVal = bool(self.send(False))
+ self.__msgType = oldType
+ return retVal
+
+ def update(self, title=None, text=None, icon=None):
+ """Update this message with given title and text. Type will revert
+to type before calling hide to allow for better reuse of object."""
+ oldType = self.__msgType
+ self.__msgType = UPDATE
+ if text:
+ self.__msgText = text
+ if title:
+ self.__msgTitle = title
+ if icon:
+ self.__msgIcon = icon
+ retVal = self.send(False)
+ self.__msgType = oldType
+ return retVal
+
+ def setTimeout(self, timeout):
+ """Set the timeout in seconds of the message"""
+ oldType = self.__msgType
+ oldData = self.__msgData
+ self.__msgType = SET_TIMEOUT
+ #self.timeout = timeout
+ #self.__msgData = self.__msgTimeout
+ self.__msgData = timeout
+ retVal = self.send(False)
+ self.__msgType = oldType
+ self.__msgData = oldData
+ return retVal
+
+ def show(self, timeout=None, title=None,
+ text=None, icon=None,
+ replyWindow=None, replyMsg=None, msgclass=None, soundPath=None):
+ """Show a message"""
+ oldType = self.__msgType
+ oldTimeout = self.__msgTimeout
+ self.__msgType = SHOW
+ if text:
+ self.__msgText = text
+ if title:
+ self.__msgTitle = title
+ if timeout:
+ self.__msgTimeout = timeout
+ if icon:
+ self.__msgIcon = icon
+ if replyWindow:
+ self.__msgID = replyMsg
+ if replyMsg:
+ self.__msgData = replyWindow
+ if soundPath:
+ self.__msgExtra = soundPath
+ if msgclass:
+ self.__msgClass = msgclass
+
+ if ((self.__msgClass and self.__msgClass != "") or
+ (self.__msgExtra and self.__msgExtra != "")):
+ self.__msgType = EX_SHOW
+
+
+ retVal = bool(self.send())
+ self.__msgType = oldType
+ self.__msgTimeout = oldTimeout
+ return retVal
+
+
+def snGetVersion():
+ """ Get the version of Snarl that is running as a tuple. (Major, Minor)
+
+If Snarl is not running or there was an error it will
+return False."""
+ msg = SnarlMessage(msg_type=GET_VERSION)
+ version = msg.send(False)
+ if not version:
+ return False
+ return (HIWORD(version), LOWORD(version))
+
+def snGetVersionEx():
+ """ Get the internal version of Snarl that is running.
+
+If Snarl is not running or there was an error it will
+return False."""
+ sm = SnarlMessage(msg_type=GET_VERSION_EX)
+ verNum = sm.send(False)
+ if not verNum:
+ return False
+ return verNum
+
+def snGetGlobalMessage():
+ """Get the Snarl global message id from windows."""
+ return myWin32Funcs.RegisterWindowMessage(GLOBAL_MSG)
+
+def snShowMessage(title, text, timeout=0, iconPath="",
+ replyWindow=0, replyMsg=0):
+ """Show a message using Snarl and return its ID. See SDK for arguments."""
+ sm = SnarlMessage( title, text, iconPath, msg_id=replyMsg)
+ sm.data = replyWindow
+ if sm.show(timeout):
+ return sm.ID
+ else:
+ return False
+
+def snShowMessageEx(msgClass, title, text, timeout=0, iconPath="",
+ replyWindow=0, replyMsg=0, soundFile=None, hWndFrom=None):
+ """Show a message using Snarl and return its ID. See SDK for arguments.
+ One added argument is hWndFrom that allows one to make the messages appear
+ to come from a specific window. This window should be the one you registered
+ earlier with RegisterConfig"""
+ sm = SnarlMessage( title, text, iconPath, msg_id=replyMsg)
+ sm.data = replyWindow
+ if hWndFrom is not None:
+ sm.hWnd = hWndFrom
+ else:
+ sm.hWnd = SnarlMessage.lastKnownHWnd
+ if sm.show(timeout, msgclass=msgClass, soundPath=soundFile):
+ return sm.ID
+ else:
+ return False
+
+def snUpdateMessage(msgId, msgTitle, msgText, icon=None):
+ """Update a message"""
+ sm = SnarlMessage(msg_id=msgId)
+ if icon:
+ sm.icon = icon
+ return sm.update(msgTitle, msgText)
+
+def snHideMessage(msgId):
+ """Hide a message"""
+ return SnarlMessage(msg_id=msgId).hide()
+
+def snSetTimeout(msgId, timeout):
+ """Update the timeout of a message already shown."""
+ sm = SnarlMessage(msg_id=msgId)
+ return sm.setTimeout(timeout)
+
+def snIsMessageVisible(msgId):
+ """Returns True if the message is visible False otherwise."""
+ return SnarlMessage(msg_id=msgId).isVisible()
+
+def snRegisterConfig(replyWnd, appName, replyMsg):
+ """Register a config window. See SDK for more info."""
+ global lastRegisteredSnarlMsg
+ sm = SnarlMessage(msg_type=REGISTER_CONFIG_WINDOW,
+ title=appName,
+ msg_id=replyMsg)
+ sm.data = replyWnd
+ SnarlMessage.lastKnownHWnd = replyWnd
+
+ return sm.send(False)
+
+def snRegisterConfig2(replyWnd, appName, replyMsg, icon):
+ """Register a config window. See SDK for more info."""
+ global lastRegisteredSnarlMsg
+ sm = SnarlMessage(msg_type=REGISTER_CONFIG_WINDOW_2,
+ title=appName,
+ msg_id=replyMsg,
+ icon=icon)
+ sm.data = replyWnd
+ SnarlMessage.lastKnownHWnd = replyWnd
+ return sm.send(False)
+
+def snRegisterAlert(appName, classStr) :
+ """Register an alert for an already registered config. See SDK for more info."""
+ sm = SnarlMessage(msg_type=REGISTER_ALERT,
+ title=appName,
+ text=classStr)
+ return sm.send(False)
+
+def snRevokeConfig(replyWnd):
+ """Revoke a config window"""
+ sm = SnarlMessage(msg_type=REVOKE_CONFIG_WINDOW)
+ sm.data = replyWnd
+ if replyWnd == SnarlMessage.lastKnownHWnd:
+ SnarlMessage.lastKnownHWnd = 0
+ return sm.send(False)
+
+def snGetSnarlWindow():
+ """Returns the hWnd of the snarl window"""
+ return myWin32Funcs.FindWindow(None, "Snarl")
+
+def snGetAppPath():
+ """Returns the application path of the currently running snarl window"""
+ app_path = None
+ snarl_handle = snGetSnarlWindow()
+ if snarl_handle != 0:
+ pathwin_handle = myWin32Funcs.FindWindowEx(snarl_handle,
+ 0,
+ "static",
+ None)
+ if pathwin_handle != 0:
+ try:
+ result = myWin32Funcs.GetWindowText(pathwin_handle)
+ app_path = result
+ except Win32FuncException:
+ pass
+
+
+ return app_path
+
+def snGetIconsPath():
+ """Returns the path to the icons of the program"""
+ s = snGetAppPath()
+ if s is None:
+ return ""
+ else:
+ return s + "etc\\icons\\"
+
+def snSendTestMessage(data=None):
+ """Sends a test message to Snarl. Used to make sure the
+api is connecting"""
+ param = 0
+ command = 0
+ if data:
+ param = struct.pack("I", data)
+ command = 1
+ myWin32Funcs.SendMessage(snGetSnarlWindow(), WM_SNARLTEST, command, param)
diff --git a/plugins/snarl_notifications/__init__.py b/plugins/snarl_notifications/__init__.py
index ad9c96aaa..b504dfd50 100644
--- a/plugins/snarl_notifications/__init__.py
+++ b/plugins/snarl_notifications/__init__.py
@@ -1 +1 @@
-from plugin import SnarlNotificationsPlugin \ No newline at end of file
+from plugin import SnarlNotificationsPlugin
diff --git a/plugins/snarl_notifications/plugin.py b/plugins/snarl_notifications/plugin.py
index 4d831ee39..3e21acb77 100644
--- a/plugins/snarl_notifications/plugin.py
+++ b/plugins/snarl_notifications/plugin.py
@@ -38,54 +38,53 @@ from plugins.helpers import log_calls, log
from common import ged
class SnarlNotificationsPlugin(GajimPlugin):
- name = u'Snarl Notifications'
- short_name = u'snarl_notifications'
- version = u'0.1'
- description = u'''Shows events notification using Snarl (http://www.fullphat.net/) under Windows. Snarl needs to be installed in system.
+ name = u'Snarl Notifications'
+ short_name = u'snarl_notifications'
+ version = u'0.1'
+ description = u'''Shows events notification using Snarl (http://www.fullphat.net/) under Windows. Snarl needs to be installed in system.
PySnarl bindings are used (http://code.google.com/p/pysnarl/).'''
- authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
- homepage = u'http://blog.bilinski.it'
-
- @log_calls('SnarlNotificationsPlugin')
- def init(self):
- self.config_dialog = None
- #self.gui_extension_points = {}
- #self.config_default_values = {}
-
- self.events_handlers = {'NewMessage' : (ged.POSTCORE, self.newMessage)}
+ authors = [u'Mateusz Biliński <mateusz@bilinski.it>']
+ homepage = u'http://blog.bilinski.it'
- @log_calls('SnarlNotificationsPlugin')
- def activate(self):
- pass
-
- @log_calls('SnarlNotificationsPlugin')
- def deactivate(self):
- pass
-
- @log_calls('SnarlNotificationsPlugin')
- def newMessage(self, args):
- event_name = "NewMessage"
- data = args
- account = data[0]
- jid = data[1][0]
- jid_without_resource = gajim.get_jid_without_resource(jid)
- msg = data[1][1]
- msg_type = data[1][4]
- if msg_type == 'chat':
- nickname = gajim.get_contact_name_from_jid(account,
- jid_without_resource)
- elif msg_type == 'pm':
- nickname = gajim.get_resource_from_jid(jid)
-
- print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args))
- print "Event '%s' occured. Arguments: \naccount = %s\njid = %s\nmsg = %s\nnickname = %s"%(
- event_name, account, jid, msg, nickname)
-
-
- #if PySnarl.snGetVersion() != False:
- #(major, minor) = PySnarl.snGetVersion()
- #print "Found Snarl version",str(major)+"."+str(minor),"running."
- #PySnarl.snShowMessage(nickname, msg[:20]+'...')
- #else:
- #print "Sorry Snarl does not appear to be running"
- \ No newline at end of file
+ @log_calls('SnarlNotificationsPlugin')
+ def init(self):
+ self.config_dialog = None
+ #self.gui_extension_points = {}
+ #self.config_default_values = {}
+
+ self.events_handlers = {'NewMessage' : (ged.POSTCORE, self.newMessage)}
+
+ @log_calls('SnarlNotificationsPlugin')
+ def activate(self):
+ pass
+
+ @log_calls('SnarlNotificationsPlugin')
+ def deactivate(self):
+ pass
+
+ @log_calls('SnarlNotificationsPlugin')
+ def newMessage(self, args):
+ event_name = "NewMessage"
+ data = args
+ account = data[0]
+ jid = data[1][0]
+ jid_without_resource = gajim.get_jid_without_resource(jid)
+ msg = data[1][1]
+ msg_type = data[1][4]
+ if msg_type == 'chat':
+ nickname = gajim.get_contact_name_from_jid(account,
+ jid_without_resource)
+ elif msg_type == 'pm':
+ nickname = gajim.get_resource_from_jid(jid)
+
+ print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args))
+ print "Event '%s' occured. Arguments: \naccount = %s\njid = %s\nmsg = %s\nnickname = %s"%(
+ event_name, account, jid, msg, nickname)
+
+
+ #if PySnarl.snGetVersion() != False:
+ #(major, minor) = PySnarl.snGetVersion()
+ #print "Found Snarl version",str(major)+"."+str(minor),"running."
+ #PySnarl.snShowMessage(nickname, msg[:20]+'...')
+ #else:
+ #print "Sorry Snarl does not appear to be running"