2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2005-2009 Alexander Bernauer <alex@copton.net>
4 # Copyright (C) 2005-2009 Rico Schiekel <fire@downgra.de>
5 # Copyright (C) 2005-2009 Ulrich Dangel <uli@spamt.net>
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation version 2
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA.
23 example of ~/.notifyd.conf:
24 ---------------------------
30 logfile = os.path.expanduser("~/.event.log")
31 osdparams = "-p bottom --color=red --delay=4 --age=4 " \
32 "--font=\-\*\-helvetica\-medium\-r\-\*\-\*\-34\-\*\-\*\-\*\-\*\-\*\-\*\-15 " \ # noqa: W605,E501
33 "--offset=100 --shadow=0 --lines=5 --align=right --indent=100"
36 ("IRC:&bitlbee:bitlbee", [], False),
37 (".*shutdown.*", [command('sudo shutdown -h now %(msg)s')], False),
38 (".*", [libnotify], False),
52 default_hostname = "localhost"
54 default_osd_params = osdparams = (
55 "-p bottom --color=red --delay=4 --age=4 "
56 "--font=\-\*\-helvetica\-medium\-r\-\*\-\*\-34\-\*\-\*\-\*\-\*\-\*\-\*\-15 " # noqa: W605,E501
57 "--offset=100 --shadow=0 --lines=5 --align=right --indent=100"
59 default_logfile = None
63 def play_wrapper(msg):
64 with open(os.devnull, "w") as devnull:
65 subprocess.Popen(["/usr/bin/aplay", sound_file], stderr=devnull)
71 def command_wrapper(msg):
72 subprocess.call(command % dict(msg=msg))
74 return command_wrapper
78 osdcmd = "/usr/bin/osd_cat"
79 osdpipe = os.popen("%s %s" % (osdcmd, osdparams), "w")
88 sys.stderr.write("Please install python-dbus\n")
91 bus = dbus.SessionBus()
92 notifyService = bus.get_object(
93 "org.freedesktop.Notifications", "/org/freedesktop/Notifications"
95 interface = dbus.Interface(notifyService, "org.freedesktop.Notifications")
97 message, title = (":" + msg).split(":")[::-1][0:2]
99 title, message = message, title
103 "notification-message-im",
107 {"x-canonical-append": "allowed"},
118 print("osd_server.py [options]")
120 print(" -h --help print this message")
121 print(" -H --host host of the osd server (def: " + default_hostname + ")")
123 " -P --port port of the osd server (def: " + str(default_port) + ")"
125 print(" -l --log log file ('-' logs to stdout)")
132 "libnotify": libnotify,
134 "host": default_hostname,
135 "port": default_port,
136 "logfile": default_logfile,
141 (".*", [libnotify], False),
145 default_bind = (default_hostname, default_port)
150 open(os.path.expanduser("~/.notifyd.conf"), "rb").read(),
151 os.path.expanduser("~/.notifyd.conf"),
161 opts, args = getopt.getopt(
162 sys.argv[1:], "hH:P:l:", ["help", "host=", "port=", "log="]
164 except getopt.GetoptError:
168 for opt, arg in opts:
169 if opt in ("-h", "--help"):
172 elif opt in ("-H", "--host"):
174 elif opt in ("-P", "--port"):
175 env["port"] = int(arg)
176 elif opt in ("-l", "--log"):
180 actions = env.get("actions", default_actions)
181 logfile_name = env.get("logfile")
182 logfile_format = env.get("logformat", "%(asctime)s %(message)s")
183 bind_address = (env["host"], env["port"])
184 osd_params = env.get("osdparams", default_osd_params)
187 logger = logging.getLogger("notify_server")
188 lformatter = logging.Formatter(logfile_format)
189 if logfile_name not in ("", "-"):
190 lfh = logging.FileHandler(logfile_name)
191 lfh.setFormatter(lformatter)
192 logger.addHandler(lfh)
194 lout = logging.StreamHandler(sys.stdout)
195 lout.setFormatter(lformatter)
196 logger.addHandler(lout)
197 logger.setLevel(logging.INFO)
201 listen = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
202 listen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
203 listen.bind(bind_address)
208 return c in string.printable + "äöüßÄÖÜ" and c or "_"
213 (con, addr) = listen.accept()
216 data = con.recv(50).strip()
219 log = "".join(filter_char(c) for c in data)
221 for pattern, handlers, cont in actions:
222 if re.match(pattern, log):
223 for handler in handlers: