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:
authorMateusz Biliński <mateusz.bilinski@gmail.com>2008-08-17 00:30:37 +0400
committerMateusz Biliński <mateusz.bilinski@gmail.com>2008-08-17 00:30:37 +0400
commit94f27ecffcbe61b3723f6d77a101e6ee6c21ee2f (patch)
tree3feb26e79aef5e2e8a08c527c86d47d5883c18e1 /plugins
parent2ee4c7ee5e008038607f72ed8f39d4abede291b1 (diff)
Snarl Notifications plugin initial version added. New events (from current core) go also through GED.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/events_dump/plugin.py34
-rwxr-xr-xplugins/snarl_notifications/PySnarl.py772
-rw-r--r--plugins/snarl_notifications/__init__.py1
-rw-r--r--plugins/snarl_notifications/plugin.py88
4 files changed, 893 insertions, 2 deletions
diff --git a/plugins/events_dump/plugin.py b/plugins/events_dump/plugin.py
index 44cf46348..055af8772 100644
--- a/plugins/events_dump/plugin.py
+++ b/plugins/events_dump/plugin.py
@@ -51,7 +51,37 @@ class EventsDumpPlugin(GajimPlugin):
'Subscribe', 'Subscribed', 'Unsubscribed',
'NewAccount', 'VcardInfo', 'LastStatusTime',
'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo',
- 'NewGmail']
+ 'NewGmail','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']
self.events_handlers = {}
self._set_handling_methods()
@@ -75,6 +105,6 @@ class EventsDumpPlugin(GajimPlugin):
def _generate_handling_method(self, event_name):
def handler(self, *args):
- print "Event '%s' occured. Arguments: %s"%(event_name, pformat(*args))
+ print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(*args))
return handler \ No newline at end of file
diff --git a/plugins/snarl_notifications/PySnarl.py b/plugins/snarl_notifications/PySnarl.py
new file mode 100755
index 000000000..f75ccd5c1
--- /dev/null
+++ b/plugins/snarl_notifications/PySnarl.py
@@ -0,0 +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)
diff --git a/plugins/snarl_notifications/__init__.py b/plugins/snarl_notifications/__init__.py
new file mode 100644
index 000000000..ad9c96aaa
--- /dev/null
+++ b/plugins/snarl_notifications/__init__.py
@@ -0,0 +1 @@
+from plugin import SnarlNotificationsPlugin \ No newline at end of file
diff --git a/plugins/snarl_notifications/plugin.py b/plugins/snarl_notifications/plugin.py
new file mode 100644
index 000000000..e6ef5ae18
--- /dev/null
+++ b/plugins/snarl_notifications/plugin.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+##
+## This file is part of Gajim.
+##
+## Gajim is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 3 only.
+##
+## Gajim is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
+##
+'''
+Events notifications using Snarl
+
+Fancy events notifications under Windows using Snarl infrastructure.
+
+:note: plugin is at proof-of-concept state.
+
+:author: Mateusz Biliński <mateusz@bilinski.it>
+:since: 15th August 2008
+:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
+:license: GPL
+'''
+
+import new
+from pprint import pformat
+
+import PySnarl
+
+from common import gajim
+from plugins import GajimPlugin
+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.
+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)}
+
+ def activate(self):
+ pass
+
+ def deactivate(self):
+ pass
+
+ def newMessage(self, args):
+ event_name = "NewMessage"
+ data = args[0]
+ 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