netbank: Changed login syntax.
[fulbank.git] / netbank
1 #!/usr/bin/python3
2
3 import sys, os, getopt, pwd
4 from fulbank import auth, data, util
5
6 sessname = data.defaultsess()
7 sess = None
8
9 def usage(out):
10     out.write("usage: netbank [-h] [-s SESSION-ID] COMMAND [ARGS...]\n")
11
12 def requiresess(fn):
13     def wrap(cmd, args):
14         if sess is None:
15             sys.stderr.write("netbank: %s: no current session\n" % (cmd))
16             sys.exit(1)
17         return fn(cmd, args)
18     return wrap
19
20 commands = {}
21
22 def cmd_login(cmd, args):
23     global sess
24     if len(args) < 2:
25         sys.stderr.write("usage: login BANK-ID TYPE [ARGS...]\n")
26         sys.exit(1)
27     sess = data.getsessnam(args[0]).create()
28     if args[1] == "bankid":
29         authfun = sess.auth_bankid
30     elif args[1] == "token":
31         authfun = sess.auth_token
32     else:
33         sys.stderr.write("netbank: %s: unknown authentication type\n" % (args[1]))
34         sys.exit(1)
35     if len(args) < 3:
36         sys.stderr.write("usage: login bankid USER-ID\n")
37         sys.exit(1)
38     with auth.ttyconv() as conv:
39         try:
40             authfun(args[2], conv)
41         except auth.autherror as err:
42             sys.stderr.write("netbank: authentication failed: %s\n" % err)
43             sys.exit(1)
44 commands["login"] = cmd_login
45
46 @requiresess
47 def cmd_logout(cmd, args):
48     global sess
49     if sess is not None:
50         sess.close()
51         sess = None
52 commands["logout"] = cmd_logout
53
54 @requiresess
55 def cmd_ping(cmd, args):
56     sess.keepalive()
57 commands["ping"] = cmd_ping
58
59 @requiresess
60 def cmd_lsacct(cmd, args):
61     for acct in sess.accounts:
62         sys.stdout.write("%s (%s): %s\n" % (acct.number, acct.name, acct.balance))
63 commands["lsacct"] = cmd_lsacct
64
65 @requiresess
66 def cmd_lstxn(cmd, args):
67     opts, args = getopt.getopt(args, "n:")
68     num = 10
69     for o, a in opts:
70         if o == "-n":
71             num = int(a)
72     if len(args) < 1:
73         sys.stderr.write("usage: lstxn [-n NUM] ACCOUNT\n")
74         sys.exit(1)
75     try:
76         acct = util.find(sess.accounts, item=args[0], key=lambda acct: acct.number, test=util.pfxmatch)
77     except util.ambiguous as exc:
78         sys.stderr.write("netbank: %s: ambiguous match between %s and %s\n" % (args[0], exc.a, exc.b))
79         sys.exit(1)
80     except LookupError:
81         sys.stderr.write("netbank: %s: no such account\n" % (args[0]))
82         sys.exit(1)
83     for i, txn in zip(range(num), acct.transactions()):
84         sys.stdout.write("%s %s: %s\n" % (txn.date.isoformat(), txn.value, txn.message))
85 commands["lstxn"] = cmd_lstxn
86
87 def main():
88     global sess, sessname
89
90     opts, args = getopt.getopt(sys.argv[1:], "hs:")
91     for o, a in opts:
92         if o == "-h":
93             usage(sys.stdout)
94             sys.exit(0)
95         if o == "-s":
96             sessname = a
97     if len(args) < 1:
98         usage(sys.stderr)
99         sys.exit(1)
100
101     cmd = args[0]
102     args = args[1:]
103
104     sess = data.loadsess(sessname, None)
105     if cmd in commands:
106         commands[cmd](cmd, args)
107     else:
108         sys.stderr.write("netbank: %s: unknown command\n" % (cmd))
109         sys.exit(1)
110     data.savesess(sess, sessname)
111
112 try:
113     if __name__ == "__main__":
114         main()
115 except KeyboardInterrupt:
116     sys.exit(1)