Commit 8cc708ad authored by Yann Leboulanger's avatar Yann Leboulanger

new snarl notification plugin

parent b224467c
from plugin import SnarlNotificationsPlugin
[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://sourceforge.net/projects/pysnarl/).
authors = Yann Leboulanger <asterix@lagaule.org>
homepage = http://trac-plugins.gajim.org/wiki/SnarlNotificationsPlugin
# -*- 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: Yann Leboulanger <asterix@lagaule.org>
:since: 08 April 2012
:copyright: Copyright (2012) Yann Leboulanger <asterix@lagaule.org>
:license: GPL
'''
import pySnarl
from common import gajim
from plugins import GajimPlugin
from plugins.helpers import log_calls, log
from common import ged
import os.path
class SnarlActionHandler(pySnarl.EventHandler):
def OnNotificationInvoked(self, uid):
account, jid, msg_type = uid.split()
gajim.interface.handle_event(account, jid, msg_type)
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.h = SnarlActionHandler
self.snarl_win = pySnarl.SnarlApp(
"pySnarl/Gajim", # app signature
"Gajim", # app title
os.path.abspath("..\data\pixmaps\gajim.ico"), # icon
"", # config Tool
"Gajim will use Snarl to display notifications", # hint
False, # IsDaemon
self.h, # event handler
[] # classes
)
self.events_handlers = {'notification' : (ged.PRECORE, self.notif)}
@log_calls('SnarlNotificationsPlugin')
def notif(self, obj):
if obj.do_popup:
uid = obj.conn.name + " " + obj.jid + " " + obj.popup_msg_type
self.snarl_win.notify(
[], # actions
"", # callbackScript
"", # callbackScriptType
"", # class
"", # defaultCallback
5, # duration
os.path.abspath(obj.popup_image),#r"C:\Documents and Settings\Administrateur\Mes documents\gajim\data\pixmaps\gajim.ico", # icon
"", # mergeUID
0, # priority
"", # replaceUID
obj.popup_text,
obj.popup_title,
uid, # UID
"", # sound
-1, # percent
0, # log
64, # sensitivity
)
obj.do_popup = False
# -*- coding: utf-8 -*-
# ActiveX/COM Snarl python library
# For proper functioning requires Snarl 2.5.1 or later !
# Version 0.0.2
# Changelog (in reverse chronological order):
# -------------------------------------------
# 0.0.2 by Pako 2012-01-30 14:12 UTC+1
# - base64 icon format is now supported
# 0.0.1 by Pako 2012-01-06 15:30 UTC+1
# - initial version
#-------------------------------------------------------
from win32com.client import constants, gencache, Dispatch, DispatchWithEvents
#===============================================================================
def IsRunning():
from win32gui import FindWindow
return FindWindow("w>Snarl", "Snarl")
#===============================================================================
class EventHandler:
def OnActivated(self):
self.fn("DaemonActivated")
def OnNotificationActionSelected(self, uid, command):
self.fn("ActionSelected.%s" % command, payload = uid)
def OnNotificationClosed(self, uid):
self.fn("Closed", payload = uid)
def OnNotificationExpired(self, uid):
self.fn("Expired", payload = uid)
def OnNotificationInvoked(self, uid):
self.fn("Invoked", payload = uid)
def OnQuit(self):
self.fn("AppQuit")
def OnShowAbout(self):
self.fn("ShowAbout")
def OnShowConfig(self):
self.fn("ShowConfig")
def OnSnarlLaunched(self):
self.fn("Launched")
def OnSnarlQuit(self):
self.fn("Quit")
def OnSnarlStarted(self):
self.fn("Started")
def OnSnarlStopped(self):
self.fn("Stopped")
def OnUserAway(self):
self.fn("UserAway")
def OnUserReturned(self):
self.fn("UserReturned")
#===============================================================================
class SnarlApp(object):
"""Creates an SnarlApp object"""
def __init__(
self,
signature,
title,
icon = "",
configTool = "",
hint = "",
isDaemon = False,
eventHandler = None,
classes = []
):
self.app = gencache.EnsureDispatch("libsnarl25.SnarlApp")
for d in constants.__dicts__: # we must find the right dictionary ...
if 'ERROR_NOTIFICATION_NOT_FOUND' in d: # this is it !
break
codes = d.items()
codes.sort(reverse = True)
self.statCodes = dict([[v,k] for k,v in codes[6:]])
self.statCodes[codes[2][1]] = codes[2][0] # added SUCCESS
self.classes = NotifClasses(classes)
if eventHandler:
self.SetEventHandler(eventHandler)
self.SetTo(
configTool,
hint,
icon,
isDaemon,
signature,
title
)
def SetTo(
self,
configTool,
hint,
icon,
isDaemon,
signature,
title
):
self.app.Classes = self.classes.Classes()
self.app.ConfigTool = configTool
self.app.Hint = hint
self.app.Icon = icon
self.app.IsDaemon = isDaemon
self.app.Signature = signature
self.app.Title = title
def GetStatusCode(self, code):
return self.statCodes[code]
def SetEventHandler(self, handler):
self.events = DispatchWithEvents(self.app, handler)
def register(self):
return self.GetStatusCode(self.app.Register())
def unregister(self):
return self.GetStatusCode(self.app.Unregister())
def tidyUp(self):
self.app.TidyUp()
def addClass(
self,
classId,
name,
enabled = True,
title = "",
text = "",
icon = "",
callback = "",
duration = -1,
sound = "",
):
cntOld = self.classes.count()
cntNew = self.classes.add(classId, name, enabled, title, text, icon, callback, duration, sound)
return int(not cntNew == cntOld + 1)
def remClass(self, id):
cntOld = self.classes.count()
cntNew = self.classes.remove(id)
return int(not cntNew == cntOld - 1)
def clearClasses(self):
return self.classes.makeEmpty()
def classesCount(self):
return self.classes.count()
def notify(
self,
actions,
callbackScript,
callbackScriptType,
cls,
defaultCallback,
duration,
icon,
mergeUID,
priority,
replaceUID,
text,
title,
uid,
sound = None,
percent = None,
log = None,
sensitivity = None
):
note = Notification(
actions,
callbackScript,
callbackScriptType,
cls,
defaultCallback,
duration,
"",
mergeUID,
priority,
replaceUID,
text,
title,
uid,
)
if icon:
if icon[1] == ":":
note.Add("icon", icon, True)
else:
note.Add("icon-base64", icon.replace("=","%"), True)
if sound:
note.Add("sound", sound, True)
if percent is not None and percent > -1:
note.Add("value-percent", str(percent), True)
if log is not None:
note.Add("log", str(log), True)
if sensitivity is not None:
note.Add("sensitivity", str(sensitivity), True)
return self.GetStatusCode(self.app.Show(note.Note())[0])
def hideNotification(self, uid):
return self.GetStatusCode(self.app.Hide(uid))
def isVisible(self, uid):
return self.GetStatusCode(self.app.IsVisible(uid))
def getEtcPath(self):
return self.app.GetEtcPath()
def makePath(self, pth):
return self.app.GetEtcPath(pth)
def isInstalled(self):
return self.app.IsSnarlInstalled()
def isRunning(self):
return self.app.IsSnarlRunning()
def version(self):
ver = self.app.SnarlVersion()
return ver if ver > 0 else self.GetStatusCode(-ver)
def isConnected(self):
return self.app.IsConnected
def getLibVersion(self):
return self.app.LibVersion
def getLibRevision(self):
return self.app.LibRevision
def Destroy(self):
self.app.TidyUp()
if self.events:
del self.events
del self.app
#===============================================================================
class NotifClasses(object):
def __init__(self, classes = []):
self.clss = Dispatch("libsnarl25.Classes")
for cls in classes:
self.add(*cls)
def count(self):
return self.clss.Count()
def add(self, *cls):
self.clss.Add(*cls)
return self.clss.Count()
def remove(self, cls):
self.clss.Remove(cls)
return self.clss.Count()
def makeEmpty(self):
self.clss.MakeEmpty()
return self.clss.Count()
def Classes(self):
return self.clss
#===============================================================================
class Notification(object):
def __init__(
self,
actions,
callbackScript,
callbackScriptType,
cls,
defaultCallback,
duration,
icon,
mergeUID,
priority,
replaceUID,
text,
title,
uid,
):
nt = Dispatch("libsnarl25.Notification")
nt.Actions = NotifActions(actions).Actions()
nt.CallbackScript = callbackScript
nt.CallbackScriptType = callbackScriptType
nt.Class = cls
nt.DefaultCallback = defaultCallback
nt.Duration = duration
if icon:
nt.Icon = icon
nt.MergeUID = mergeUID
nt.Priority = priority
nt.ReplaceUID = replaceUID
nt.Text = text
nt.Title = title
nt.UID = uid
self.nt = nt
def Add(self, name, value, update):
self.nt.Add(name, value, True)
def Note(self):
return self.nt
#===============================================================================
class NotifActions(object):
def __init__(self, actions=[]):
self.actns = Dispatch("libsnarl25.Actions")
self.actions = actions
for action in actions:
self.actns.Add(*action)
def add(self, actn):
self.actns.Add(*actn)
self.actions.append(actn)
return self.actns.Count()
def remove(self, actn):
if actn in self.actions:
ix = self.actions.index(actn)
self.actns.Remove(ix + 1)
self.actions.pop(ix)
return self.actns.Count()
def makeEmpty(self):
self.actns.MakeEmpty()
self.actions = []
return self.actns.Count()
def Actions(self):
return self.actns
#===============================================================================
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment