#!/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 "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