local: Treat dots/periods as digits in destructuring directories.
[automanga.git] / automanga
index e80db3f..6e51e29 100755 (executable)
--- a/automanga
+++ b/automanga
-#!/usr/bin/python
+#!/usr/bin/python3
 
-import sys, getopt
-import manga.lib, manga.reader
-import glib, gobject, gtk
-
-gobject.threads_init()
-gtk.gdk.threads_init()
+import sys, getopt, pathlib
+import manga.lib, manga.reader, manga.profile, manga.local
+from gi.repository import Gtk, Gdk, GObject
 
 def usage(out):
-    out.write("usage: automanga [-h] [DIR]\n")
-    out.write("       automanga [-h] -l LIBRARY ID\n")
-    out.write("       automanga [-h] -s LIBRARY NAME\n")
+    out.write("usage: automanga [-h] [-p PROFILE] {DIRECTORY|-l LIBRARY ID|-a ALIAS}\n")
+    out.write("       automanga -a ALIAS=LIBRARY:ID\n")
+    out.write("       automanga -t {DIRECTORY|-l LIBRARY ID|-a ALIAS} [-]TAG...\n")
+    out.write("       automanga -{s|S} LIBRARY NAME\n")
+    out.write("       automanga -L TAG [-o ORDER]\n")
 
 libname = None
-search = False
-opts, args = getopt.getopt(sys.argv[1:], "hl:s")
+search = None
+profile = ""
+alias = None
+settags = False
+listtag = None
+listorder = None
+opts, args = getopt.getopt(sys.argv[1:], "hl:sSp:a:tL:o:")
 for o, a in opts:
     if o == "-h":
         usage(sys.stdout)
         sys.exit(0)
     elif o == "-l":
         libname = a
+    elif o == "-a":
+        alias = a
     elif o == "-s":
-        search = True
-
-if search:
-    if len(args) < 2:
-        usage(sys.stderr)
-        sys.exit(1)
-    try:
-        lib = manga.lib.libraries[args[0]]
-    except KeyError:
-        sys.stderr.write("automanga: no such library: %s\n" % args[0])
-        sys.exit(1)
-    for manga in lib.byname(args[1]):
-        sys.stdout.write("\"%s\": %s\n" % (manga.name, manga.id))
-    sys.exit(0)
-
-if libname is not None:
-    if len(args) < 1:
-        usage(sys.stderr)
-        sys.exit(1)
+        search = "name"
+    elif o == "-S":
+        search = "match"
+    elif o == "-p":
+        if a == "":
+            profile = None
+        else:
+            profile = a
+    elif o == "-t":
+        settags = True
+    elif o == "-L":
+        listtag = a
+    elif o == "-o":
+        listorder = a
+if profile == "":
     try:
-        lib = manga.lib.libraries[libname]
+        profile = manga.profile.profile.last()
     except KeyError:
-        sys.stderr.write("automanga: no such library: %s\n" % libname)
-        sys.exit(1)
-    try:
-        mng = lib.byid(args[0])
-    except KeyError:
-        sys.stderr.write("automanga: no such manga: %s\n" % args[0])
-        sys.exit(1)
-else:
-    sys.stderr.write("automanga: local manga not yet implemented\n")
-    sys.exit(1)
-
-reader = manga.reader.reader(mng)
-reader.show()
-gtk.main()
+        profile = manga.profile.profile.byname("default")
+elif profile is not None:
+    profile = manga.profile.profile.byname(profile)
+
+def main():
+    global libname
+
+    if search:
+        if len(args) < 2:
+            usage(sys.stderr)
+            sys.exit(1)
+        try:
+            lib = manga.lib.findlib(args[0])
+        except ImportError:
+            sys.stderr.write("automanga: no such library: %s\n" % args[0])
+            sys.exit(1)
+        try:
+            if search == "name":
+                results = lib.byname(args[1])
+            elif search == "match":
+                results = lib.search(args[1])
+                if hasattr(results, "__length_hint__"):
+                    sys.stderr.write("%i results:\n" % results.__length_hint__())
+        except NotImplementedError:
+            sys.stderr.write("automanga: %s does not support searching\n" % args[0])
+            sys.exit(1)
+        for mng in results:
+            sys.stdout.write("\"%s\": %s\n" % (mng.name, mng.id))
+        return
+
+    if listtag is not None:
+        if profile is not None:
+            results = []
+            for mprof in profile.bytag(listtag):
+                try:
+                    mng = mprof.open()
+                except KeyError:
+                    sys.stderr.write("%s %s: no longer found\n" % (mprof.libnm, mprof.id))
+                    continue
+                except Exception as exc:
+                    sys.stderr.write("%s %s: unexpected error: %s\n" % (mprof.libnm, mprof.id, str(exc)))
+                    continue
+                line = "%s %s: \"%s\"" % (mprof.libnm, mprof.id, mng.name)
+                if listorder is None:
+                    sys.stdout.write("%s\n" % (line,))
+                else:
+                    if listorder == "mtime":
+                        key = -mprof.mtime()
+                    else:
+                        sys.stderr.write("automanga: undefined order: %s\n" % (listorder,))
+                        sys.exit(1)
+                    results.append((line, key))
+            if len(results) > 0:
+                results.sort(key=lambda o: o[1])
+                for line, key in results:
+                    sys.stdout.write("%s\n" % (line,))
+        return
+
+    if alias and (alias.find('=') > 0):
+        tgt, nm = alias.split('=', 1)
+        if not ':' in nm:
+            usage(sys.stderr)
+            sys.exit(1)
+        libname, mid = nm.split(':', 1)
+        try:
+            lib = manga.lib.findlib(libname)
+        except ImportError:
+            sys.stderr.write("automanga: no such library: %s\n" % libname)
+            sys.exit(1)
+        try:
+            mng = lib.byid(mid)
+        except KeyError as e:
+            sys.stderr.write("automanga: no such manga: %s\n" % str(e))
+            sys.exit(1)
+        profile.setalias(tgt, libname, mng.id)
+        return
+
+    if alias:
+        try:
+            libname, mid = profile.getalias(alias)
+        except KeyError:
+            sys.stderr.write("automanga: no such alias: %s\n" % alias)
+            sys.exit(1)
+        try:
+            lib = manga.lib.findlib(libname)
+        except ImportError:
+            sys.stderr.write("automanga: no such library: %s\n" % libname)
+            sys.exit(1)
+        try:
+            mng = lib.byid(mid)
+        except KeyError:
+            sys.stderr.write("automanga: manga no longer found: %s\n" % mid)
+            sys.exit(1)
+    elif libname is not None:
+        if len(args) < 1:
+            usage(sys.stderr)
+            sys.exit(1)
+        try:
+            lib = manga.lib.findlib(libname)
+        except ImportError:
+            sys.stderr.write("automanga: no such library: %s\n" % libname)
+            sys.exit(1)
+        try:
+            mng = lib.byid(args.pop(0))
+        except KeyError as e:
+            sys.stderr.write("automanga: no such manga: %s\n" % str(e))
+            sys.exit(1)
+    else:
+        libname = "local"
+        try:
+            if len(args) < 1:
+                usage(sys.stderr)
+                sys.exit(1)
+            mdir = args.pop(0)
+            mng = manga.local.manga(pathlib.Path(mdir))
+        except TypeError:
+            sys.stderr.write("automanga: not a valid manga directory: %s\n" % mdir)
+            sys.exit(1)
+
+    mprof = None if profile is None else profile.getmanga(libname, mng.id, True)
+    if profile is not None:
+        profile.setlast()
+
+    if settags:
+        if mprof is not None:
+            ntags = [tag for tag in args if tag[:1] != "-"]
+            rtags = [tag[1:] for tag in args if tag[:1] == "-"]
+            if ntags: mprof.tags.add(*ntags)
+            if rtags: mprof.tags.remove(*rtags)
+        return
+
+    reader = manga.reader.reader(mng, mprof)
+    reader.show()
+    Gtk.main()
+
+try:
+    main()
+except KeyboardInterrupt:
+    pass