Select Git revision
not2osd 7.31 KiB
#!/usr/bin/env python2
#
# not2osd - Bridge from DBus notifications to osd
#
# Copyright (c) 2009 by Henrik Hallberg (halhen@k2h.se) [program statnot]
# http://code.k2h.se
# Copyright (c) 2021 by Jiří Kalvoda (jirikalvoda@kam.mff.cuni.cz)
#
# This program 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; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
import dbus
import dbus.service
import dbus.mainloop.glib
import gobject
import os
import subprocess
import sys
import thread
import time
from htmlentitydefs import name2codepoint as n2cp
import re
def strip_tags(value):
"Return the given HTML with all tags stripped."
return re.sub(r'<[^>]*?>', '', value)
# from http://snipplr.com/view/19472/decode-html-entities/
# also on http://snippets.dzone.com/posts/show/4569
def substitute_entity(match):
ent = match.group(3)
if match.group(1) == "#":
if match.group(2) == '':
return unichr(int(ent))
elif match.group(2) == 'x':
return unichr(int('0x'+ent, 16))
else:
cp = n2cp.get(ent)
if cp:
return unichr(cp)
else:
return match.group()
def decode_htmlentities(string):
entity_re = re.compile(r'&(#?)(x?)(\w+);')
return entity_re.subn(substitute_entity, string)[0]
class NotificationFetcher(dbus.service.Object):
_id = 0
@dbus.service.method("org.freedesktop.Notifications",
in_signature='susssasa{ss}i',
out_signature='u')
def Notify(self, app_name, notification_id, app_icon,
summary, body, actions, hints, expire_timeout):
print "app_name", app_name
print "notification_id", notification_id
print "app_icon", app_icon
print "summary", summary
print "body", body
print "actions", actions
print "expire_timeout", expire_timeout
su = strip_tags(unicode(summary)).split("\n")
bo = strip_tags(unicode(body)).split("\n")
for i in range(len(su)):
if su[i]!="" and su[i][0]=='-':
su[i] = ' '+su[i];
for i in range(len(bo)):
if bo[i]!="" and bo[i][0]=='-':
bo[i] = ' '+bo[i];
if (expire_timeout <= 0) or (expire_timeout > 20000):
expire_timeout = 5000
cmd = ["osdc","--duration="+str(expire_timeout),"--min-duration=1000","--color=blue","--outline-color=red"] + su + ["--outline-color=black"] + bo
subprocess.call(cmd)
if not notification_id:
self._id += 1
notification_id = self._id
text = ("%s %s" % (summary, body)).strip()
add_notification( [notification_id,
text[:NOTIFICATION_MAX_LENGTH],
int(expire_timeout) / 1000.0] )
return notification_id
@dbus.service.method("org.freedesktop.Notifications", in_signature='', out_signature='as')
def GetCapabilities(self):
return ('actions', 'body', 'body-hyperlinks', 'body-markup')
@dbus.service.signal('org.freedesktop.Notifications', signature='uu')
def NotificationClosed(self, id_in, reason_in):
pass
@dbus.service.method("org.freedesktop.Notifications", in_signature='u', out_signature='')
def CloseNotification(self, id):
pass
@dbus.service.method("org.freedesktop.Notifications", in_signature='', out_signature='ssss')
def GetServerInformation(self):
return ("statnot", "http://code.k2h.se", "0.0.2", "1")
if __name__ == '__main__':
for curarg in sys.argv[1:]:
if curarg in ('-v', '--version'):
#print "%s CURVERSION" % sys.argv[0]
sys.exit(1)
elif curarg in ('-h', '--help'):
#print " Usage: %s [-h] [--help] [-v] [--version] [configuration file]" % sys.argv[0]
#print " -h, --help: Print this help and exit"
#print " -v, --version: Print version and exit"
#print ""
#print " Configuration:"
#print " A file can be read to set the configuration."
#print " This configuration file must be written in valid python,"
#print " which will be read if the filename is given on the command line."
#print " You do only need to set the variables you want to change, and can"
#print " leave the rest out."
#print ""
##print " Below is an example of a configuration which sets the defaults."
#print ""
#print " # Default time a notification is show, unless specified in notification"
#print " DEFAULT_NOTIFY_TIMEOUT = 3000 # milliseconds"
#print " "
#print " # Maximum time a notification is allowed to show"
###print " MAX_NOTIFY_TIMEOUT = 5000 # milliseconds"
#print " "
#print " # Maximum number of characters in a notification. "
#print " NOTIFICATION_MAX_LENGTH = 100 # number of characters"
#print " "
#print " # Time between regular status updates"
#print " STATUS_UPDATE_INTERVAL = 2.0 # seconds"
#print " "
##print " # Command to fetch status text from. We read from stdout."
#print " # Each argument must be an element in the array"
##print " # os must be imported to use os.getenv"
##print " import os"
#print " STATUS_COMMAND = ['/bin/sh', '%s/.statusline.sh' % os.getenv('HOME')] "
##print ""
#print " # Always show text from STATUS_COMMAND? If false, only show notifications"
#print " USE_STATUSTEXT=True"
#print " "
#print " # Put incoming notifications in a queue, so each one is shown."
#print " # If false, the most recent notification is shown directly."
#print " QUEUE_NOTIFICATIONS=True"
#print " "
#print " # update_text(text) is called when the status text should be updated"
#print " # If there is a pending notification to be formatted, it is appended as"
#print " # the final argument to the STATUS_COMMAND, e.g. as $1 in default shellscript"
##print ""
#print " # dwm statusbar update"
#print " import subprocess"
#print " def update_text(text):"
#print " subprocess.call(['xsetroot', '-name', text])"
sys.exit(1)
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
session_bus = dbus.SessionBus()
name = dbus.service.BusName("org.freedesktop.Notifications", session_bus)
nf = NotificationFetcher(session_bus, '/org/freedesktop/Notifications')
context = gobject.MainLoop().get_context()
while 1:
context.iteration(True)