Make session saving and lookup more reusable.
[fulbank.git] / fulbank / auth.py
1 import sys, os, io, termios, tempfile, subprocess
2
3 class autherror(Exception):
4     pass
5
6 class conv(object):
7     msg_notice = 0
8     msg_info = 1
9     msg_debug = 2
10
11     def error(self, msg):
12         pass
13     def message(self, msg, level=0):
14         pass
15     def prompt(self, prompt, echo, default=None):
16         return default
17     def image(self, image):
18         pass
19
20 class termconv(conv):
21     def __init__(self, ifp, ofp):
22         self.ifp = ifp
23         self.ofp = ofp
24
25     def error(self, msg):
26         self.ofp.write("%s\n" % (msg,))
27         self.ofp.flush()
28     def message(self, msg, level=0):
29         if level <= self.msg_info:
30             self.ofp.write("%s\n" % (msg,))
31             self.ofp.flush()
32     def prompt(self, prompt, echo, default=None):
33         if echo:
34             self.ofp.write(prompt)
35             self.ofp.flush()
36             ret = self.ifp.readline()
37             assert ret[-1] == '\n'
38             return ret[:-1]
39         else:
40             attr = termios.tcgetattr(self.ifp.fileno())
41             bka = list(attr)
42             try:
43                 attr[3] &= ~termios.ECHO
44                 termios.tcflush(self.ifp.fileno(), termios.TCIOFLUSH)
45                 termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, attr)
46                 self.ofp.write(prompt)
47                 self.ofp.flush()
48                 ret = self.ifp.readline()
49                 self.ofp.write("\n")
50                 assert ret[-1] == '\n'
51                 return ret[:-1]
52             finally:
53                 termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, bka)
54     def image(self, image):
55         fd, fn = tempfile.mkstemp()
56         try:
57             with os.fdopen(fd, "wb") as fp:
58                 image.save(fp, "PNG")
59             subprocess.call(["sxiv", fn])
60         finally:
61             os.unlink(fn)
62
63 class ctermconv(termconv):
64     def __init__(self, fp):
65         super().__init__(fp, fp)
66         self.cfp = fp
67
68     def close(self):
69         self.cfp.close()
70     def __enter__(self):
71         return self
72     def __exit__(self, *excinfo):
73         self.close()
74         return False
75
76 null = conv()
77 stdioconv = termconv(sys.stdin, sys.stdout)
78
79 def ttyconv():
80     return ctermconv(io.TextIOWrapper(io.FileIO(os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY), "r+")))
81
82 def default():
83     return null