--- /dev/null
+#!/usr/bin/python
+
+import os, sys, signal
+from time import time
+import socket, select
+import pynotify
+
+if len(sys.argv) < 2:
+ sys.stderr.write("usage: cidnotify SERVER\n")
+ sys.exit(1)
+server = sys.argv[1]
+
+pynotify.init("cidnotify")
+
+sk = None
+notif = None
+curnum = None
+lastring = None
+t2n = None
+buf = ""
+namebuf = ""
+name = None
+actab = []
+
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+
+try:
+ acfile = open(os.getenv("HOME") + "/phone/actab")
+except IOError:
+ pass
+else:
+ for line in acfile:
+ pos = line.find(" ")
+ if pos < 0: continue
+ actab += [(line[:pos], line[pos + 1:].strip())]
+ acfile.close()
+
+for family, socktype, proto, canonname, sockaddr in socket.getaddrinfo(server, 5001, 0, socket.SOCK_STREAM):
+ try:
+ sk = socket.socket(family, socktype, proto)
+ sk.connect(sockaddr)
+ except socket.error:
+ sk = None
+ continue
+ else:
+ break
+
+if sk is None:
+ sys.stderr.write("cidnotify: could not connect to " + server + "\n");
+ sys.exit(1)
+
+def popen(*cmd):
+ rfd, wfd = os.pipe()
+ pid = os.fork()
+ if pid == 0:
+ os.dup2(wfd, 1)
+ os.close(rfd)
+ os.close(wfd)
+ os.execvp(cmd[0], cmd)
+ sys.exit(127)
+ os.close(wfd)
+ return pid, rfd
+
+def closet2n():
+ global t2n
+ if t2n is not None:
+ try:
+ os.kill(t2n[0], signal.SIGINT)
+ except:
+ pass
+ os.close(t2n[1])
+ t2n = None
+
+def close():
+ global notif, curnum, lastring
+ closet2n()
+ if notif is not None:
+ notif.close()
+ notif = None
+ curnum = None
+ lastring = None
+ name = None
+
+def findac(num):
+ for ac, acn in actab:
+ if num[:len(ac)] == ac:
+ return acn
+ return None
+
+def notiftext():
+ if curnum == "B10":
+ return "<i>Undisclosed number</i>"
+ text = "<b>Number</b>: " + curnum + "\n"
+ acn = findac(curnum)
+ if acn is not None:
+ text += "<b>Area code</b>: " + acn + "\n"
+ else:
+ text += "<b>Area code</b>: <i>Unknown</i>\n"
+ if name is None:
+ text += "<b>Name</b>: <i>Looking up...</i>\n"
+ elif name == "":
+ text += "<b>Name</b>: <i>No hits</i>\n"
+ else:
+ text += "<b>Name</b>: " + name + "\n"
+ return text.strip()
+
+def newnum(num):
+ global curnum, t2n, notif, lastring
+ close()
+ curnum = num
+ notif = pynotify.Notification("Phone call", notiftext())
+ notif.set_timeout(0)
+ notif.show()
+ lastring = time()
+ if curnum.isdigit():
+ t2n = popen("tel2name", num)
+
+try:
+ while True:
+ fds = [sk.fileno()]
+ if t2n is not None:
+ fds += [t2n[1]]
+ if lastring is not None:
+ timeout = lastring + 10 - time()
+ else:
+ timeout = None
+ fds = reduce(lambda s, l: s | set(l),
+ select.select(fds, [], fds, timeout),
+ set())
+
+ if sk.fileno() in fds:
+ ret = sk.recv(100)
+ if ret == "": sys.exit(0)
+ buf += ret
+ lines = buf.split("\n")
+ buf = lines[-1]
+ for line in lines[:-1]:
+ if line[0] == "N":
+ newnum(line[1:])
+ elif line[0] == "R":
+ if lastring is not None:
+ lastring = time()
+
+ if t2n is not None and t2n[1] in fds:
+ ret = os.read(t2n[1], 100)
+ namebuf += ret
+ if ret == "":
+ closet2n()
+ name = namebuf.strip()
+ namebuf = ""
+ if notif is not None:
+ notif.update("Phone call", notiftext())
+ notif.show()
+
+ if lastring is not None and lastring + 10 < time():
+ close()
+
+except KeyboardInterrupt:
+ pass