#!/usr/bin/env python # ph.py - a simple ph module # # dan sandler # # run from the command line, implements a mutt-compatible address search tool import sys, os, re, socket, time __all__ = ["PhServer", "ph_mutt_query"] # see http://www.ietf.org/rfc/rfc2378.txt class PhServer: def __init__(self, host, port=105): self._host = host self._port = port self._socket = None def connect(self): if self._socket: try: self._socket.fileno() except socket.error: self._socket = None if not self._socket: self._socket = socket.socket() self._socket.connect( (self._host, self._port) ) self._socket.setblocking(2.0) # seconds return self._socket def disconnect(self): if self._socket: self._socket.send('quit\r\n') self._socket.close() self._socket = None def query(self, term, fields=('all',)): sock = self.connect() results = [] if fields: query_fmt = "query %%s return %s\r\n" % ' '.join(fields) else: query_fmt = "query %%s\r\n" if sock: fp = sock.makefile('rw') fp.write(query_fmt % term) fp.flush() current_row = None current = {} while 1: try: line = fp.readline() except socket.error, e: #break continue if not line: break line.strip() dissect = re.match(r'^([-0-9]+):(.*)$', line) if not dissect: continue # weird line code = int(dissect.group(1)) if code >= 200: break # end of output elif code != -200: continue # some error data = dissect.group(2) m = re.match(r'(\d+):\s*([^:]+): (.*)$', data) if m: row = m.group(1) if row != current_row: if current: results.append(current) current = {} current_row = row current[m.group(2)] = m.group(3) fp = None if current: results.append(current) return results def ph_mutt_query(): ph = PhServer('riceinfo.rice.edu') if len(sys.argv) == 1: print "usage: ph.py 'query'" sys.exit(2) term = sys.argv[1] results = ph.query(term) num = len(results) print "%d match%s for '%s'" % (num, ('es','')[(num==1)], term) for person in results: if person.has_key('email') and person.has_key('name'): row="%s\t%s\t" % (person['email'],person['name']) if person.has_key('class'): row += person['class'] if person.has_key('major'): row += " (%s)" % person['major'] elif person.has_key('department'): row += " (%s)" % person['department'] print row if num == 0: sys.exit(1) if __name__ == '__main__': ph_mutt_query()