remove snarl test plugin. It is now in plugins repos
This commit is contained in:
parent
134d55b285
commit
8ac4782b68
|
@ -1,772 +0,0 @@
|
||||||
"""
|
|
||||||
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)
|
|
|
@ -1 +0,0 @@
|
||||||
from plugin import SnarlNotificationsPlugin
|
|
|
@ -1,11 +0,0 @@
|
||||||
[info]
|
|
||||||
name: Snarl Notifications
|
|
||||||
short_name: snarl_notifications
|
|
||||||
version: 0.1
|
|
||||||
description: 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 = Mateusz Biliński <mateusz@bilinski.it>
|
|
||||||
homepage = http://blog.bilinski.it
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
# -*- 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):
|
|
||||||
|
|
||||||
@log_calls('SnarlNotificationsPlugin')
|
|
||||||
def init(self):
|
|
||||||
self.description = _('Shows events notification using Snarl '
|
|
||||||
'(http://www.fullphat.net/) under Windows. '
|
|
||||||
'Snarl needs to be installed in system.\n'
|
|
||||||
'PySnarl bindings are used (http://code.google.com/p/pysnarl/).')
|
|
||||||
self.config_dialog = None
|
|
||||||
#self.gui_extension_points = {}
|
|
||||||
#self.config_default_values = {}
|
|
||||||
|
|
||||||
self.events_handlers = {'notification' : (ged.POSTCORE, self.notif)}
|
|
||||||
|
|
||||||
@log_calls('SnarlNotificationsPlugin')
|
|
||||||
def activate(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@log_calls('SnarlNotificationsPlugin')
|
|
||||||
def deactivate(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@log_calls('SnarlNotificationsPlugin')
|
|
||||||
def notif(self, obj):
|
|
||||||
print "Event '%s' occured.\n\n===\n" % obj.popup_event_type
|
|
||||||
|
|
||||||
#if PySnarl.snGetVersion() != False:
|
|
||||||
#(major, minor) = PySnarl.snGetVersion()
|
|
||||||
#print "Found Snarl version",str(major)+"."+str(minor),"running."
|
|
||||||
#PySnarl.snShowMessage(obj.popup_title, obj.popup_text)
|
|
||||||
#else:
|
|
||||||
#print "Sorry Snarl does not appear to be running"
|
|
Loading…
Reference in New Issue