acmecert: Make error reporting more flexible.
[utils.git] / anndl
1 #!/usr/bin/python3
2
3 import sys, os, io, getopt, ann, subprocess, tempfile
4 pj = os.path.join
5
6 def opentty():
7     try:
8         return io.TextIOWrapper(io.FileIO(os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY), "r+"))
9     except OSError as exc:
10         sys.stderr.write("anndl: terminal not available for interactive input: %s\n" % (exc.strerror))
11         sys.exit(1)
12
13 def choose(opts):
14     tty.write("%d matches:\n" % (len(opts)))
15     for i, anime in enumerate(opts):
16         tty.write("%d. %s\n" % (i + 1, anime.rawname))
17     tty.write("> ")
18     tty.flush()
19     resp = tty.readline().strip()
20     if resp == "":
21         return opts[0]
22     if not resp.isdigit():
23         sys.stderr.write("anndl: %s: not a number\n" % resp)
24         sys.exit(1)
25     n = int(resp) - 1
26     if not 0 <= n < len(opts):
27         sys.stderr.write("anndl: %s: no such option\n" % resp)
28         sys.exit(1)
29     return opts[n]
30
31 def prompt(line, default=""):
32     tty.write(line)
33     if line[-1:] != " ":
34         if default != "":
35             tty.write(" [%s]" % (default))
36         tty.write(": ")
37     tty.flush()
38     resp = tty.readline().strip()
39     if resp == "":
40         return default
41     return resp
42
43 def edit(string):
44     fd, path = tempfile.mkstemp()
45     try:
46         with os.fdopen(fd, "w") as fp:
47             fp.write(string)
48         subprocess.run([os.getenv("EDITOR"), path])
49         with open(path, "r") as fp:
50             return fp.read()
51     finally:
52         os.unlink(path)
53
54 def usage(out):
55     out.write("usage: anndl [-h] SERIES\n")
56
57 def main(argv):
58     global tty
59
60     opts, args = getopt.getopt(argv[1:], "h")
61     for o, a in opts:
62         if o == "-h":
63             usage(sys.stdout)
64             sys.exit(0)
65     if len(args) < 1:
66         usage(sys.stderr)
67         sys.exit(1)
68     name = args[0]
69     tty = opentty()
70
71     match = ann.getlist(name)
72     if len(match) == 0:
73         sys.stderr.write("anndl: could not find %s\n" % (name))
74         sys.exit(1)
75     elif len(match) == 1:
76         get = match[0]
77     elif len(match) < 10:
78         get = choose(match)
79     else:
80         sys.stderr.write("anndl: %s matches %i series\n" % (name, len(match)))
81         sys.exit(1)
82
83     if get.eps is None:
84         tty.write("could not find number of eps\n")
85         if prompt("accept? ")[:1].lower() != "y":
86             sys.exit(1)
87     name = prompt("canonical name", get.name)
88     sexpr = "\"" + r"L~%s[^0-9]*0*%%i([^0-9]*(\[[^]]*\]|\([^\)]*\)|v2))*[^0-9]*\.(avi|ogm|mkv|mp4)$" + "\""
89     sexpr = sexpr % (name.lower().replace(" ", ".*"))
90     tty.write("sexpr: %s\n" % (sexpr))
91     if prompt("accept? ")[:1].lower() != "y":
92         sexpr = edit(sexpr)
93         
94     root = pj(os.getenv("HOME"), "dc/autodl/cur", name)
95     dl = pj(root, ".autodl")
96
97     try:
98         os.mkdir(root)
99     except OSError as exc:
100         sys.stderr.write("anndl: %s: %s\n" % (root, exc.strerror))
101         sys.exit(1)
102     os.mkdir(dl)
103     with open(pj(dl, "disabled"), "w") as fp:
104         pass
105     with open(pj(root, "nextep"), "w") as fp:
106         fp.write("1\n")
107     with open(pj(dl, "uarg"), "w") as fp:
108         if get.eps is None:
109             melen = 2
110         else:
111             melen = len(str(get.eps))
112         fp.write("rename:auto:%s:%i:move:../autodl/cur/%s\n" % (name, melen, name))
113     with open(pj(dl, "sexpr"), "w") as fp:
114         fp.write("%s\n" % sexpr)
115     with open(pj(dl, "curep"), "w") as fp:
116         fp.write("1\n")
117     if get.eps is not None:
118         with open(pj(dl, "maxep"), "w") as fp:
119             fp.write("%i\n" % get.eps)
120     if prompt("begin? ")[:1].lower() == "y":
121         os.unlink(pj(dl, "disabled"))
122
123 if __name__ == "__main__":
124     try:
125         main(sys.argv)
126     except KeyboardInterrupt:
127         sys.exit(1)