#!/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, name 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 "Undisclosed number" text = "Number: " + curnum + "\n" acn = findac(curnum) if acn is not None: text += "Area code: " + acn + "\n" else: text += "Area code: Unknown\n" if name is None: text += "Name: Looking up...\n" elif name == "": text += "Name: No hits\n" else: text += "Name: " + 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