#!/usr/bin/env python """ rate.py - Rate Stuff Author: Sean B. Palmer, inamidst.com """ from __future__ import with_statement import sys, os, time import termios, fcntl from contextlib import contextmanager ratings = { ' ': '-2', 'g': '-1', 'u': '=0', 'k': '+1', '.': '+2' } class Unbuffered(object): def __enter__(self): self.fd = sys.stdin.fileno() self.oldterm = termios.tcgetattr(self.fd) newattr = termios.tcgetattr(self.fd) newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO termios.tcsetattr(self.fd, termios.TCSANOW, newattr) self.oldflags = fcntl.fcntl(self.fd, fcntl.F_GETFL) fcntl.fcntl(self.fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK) def __exit__(self, type, value, traceback): termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.oldterm) fcntl.fcntl(self.fd, fcntl.F_SETFL, self.oldflags) unbuffered = Unbuffered() @contextmanager def unbuffer(): """Run a function in an unbuffered terminal environment. This allows us to read byte by byte on Linux or Darwin, cf. http://www.python.org/doc/faq/library/ """ fd = sys.stdin.fileno() oldterm = termios.tcgetattr(fd) newattr = termios.tcgetattr(fd) newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO termios.tcsetattr(fd, termios.TCSANOW, newattr) oldflags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) try: yield None finally: termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags) def get(): while True: try: byte = sys.stdin.read(1) except IOError: time.sleep(0.01) continue if not byte: break yield byte def rate(input, output): stdin = get() with unbuffered: for line in input: line = line.strip(' \t\r\n') if not line: continue print line sys.stdout.write('? ') char = stdin.next() while not ratings.has_key(char): print sys.stdout.write('? ') char = stdin.next() print ratings[char] print >> output, ratings[char], line def main(): with open(sys.argv[1]) as input: with open(sys.argv[2], 'w') as output: rate(input, output) if __name__ == '__main__': main()