Fixed cursor bug.
[automanga.git] / manga / lib.py
index 52f75ea..3c83ab1 100644 (file)
@@ -36,14 +36,18 @@ class pagetree(object):
     `id', which should be a string that can be passed to the `byid'
     function of its parent node to recover the node. Such string ID
     should be more persistent than the node's numeric index in the
-    parent."""
+    parent.
+
+    All pagetree objects should contain an attribute `name',
+    containing some human-readable Unicode representation of the
+    pagelist."""
     
     def idlist(self):
         """Returns a list of the IDs necessary to resolve this node
         from the root node."""
         if len(self.stack) == 0:
-            raise Exception("Cannot get ID list on root node.")
-        return [n.id for n, i in self.stack[1:]] + [self.id]
+            return []
+        return self.stack[-1][0].idlist() + [self.id]
 
     def byidlist(self, idlist):
         if len(idlist) == 0:
@@ -52,10 +56,7 @@ class pagetree(object):
 
 class pagelist(pagetree):
     """Class representing a list of either pages, or nested
-    pagelists. Might be, for instance, a volume or a chapter.
-
-    All pagelists should contain an attribute `name', containing some
-    human-readable Unicode representation of the pagelist."""
+    pagelists. Might be, for instance, a volume or a chapter."""
 
     def __len__(self):
         """Return the number of (direct) sub-nodes in this pagelist.
@@ -115,7 +116,9 @@ class imgstream(object):
     when exiting the with-scope.
 
     All imgstreams should contain an attribute `ctype', being the
-    Content-Type of the image being read by the stream."""
+    Content-Type of the image being read by the stream, and `clen`,
+    being either an int describing the total number of bytes in the
+    stream, or None if the value is not known in advance."""
 
     def __enter__(self):
         return self
@@ -123,6 +126,12 @@ class imgstream(object):
     def __exit__(self, *exc_info):
         self.close()
 
+    def fileno(self):
+        """If reading the imgstream may block, fileno() should return
+        a file descriptor that can be polled. If fileno() returns
+        None, that should mean that reading will not block."""
+        return None
+
     def close(self):
         """Close this stream."""
         raise NotImplementedError()
@@ -134,11 +143,14 @@ class imgstream(object):
 
 class cursor(object):
     def __init__(self, ob):
-        self.cur = self.descend(ob)
+        if isinstance(ob, cursor):
+            self.cur = ob.cur
+        else:
+            self.cur = self.descend(ob)
 
-    def descend(self, ob):
+    def descend(self, ob, last=False):
         while isinstance(ob, pagelist):
-            ob = ob[0]
+            ob = ob[len(ob) - 1 if last else 0]
         if not isinstance(ob, page):
             raise TypeError("object in page tree was unexpectedly not a pagetree")
         return ob
@@ -151,11 +163,26 @@ class cursor(object):
         raise StopIteration()
 
     def prev(self):
-        for n, i in reversed(self.cur,stack):
+        for n, i in reversed(self.cur.stack):
             if i > 0:
-                self.cur = self.descend(n[i - 1])
+                self.cur = self.descend(n[i - 1], True)
                 return self.cur
         raise StopIteration()
 
     def __iter__(self):
         return self
+
+def _lazymod(name):
+    return __import__(name, fromlist=["dummy"])
+class _lazydict(object):
+    def __init__(self):
+        self.bk = {}
+    def __setitem__(self, key, val):
+        self.bk[key] = "u", val
+    def __getitem__(self, key):
+        st, v = self.bk[key]
+        if st == "u":
+            v = self.bk[key] = v()
+        return v
+libraries = _lazydict()
+libraries["mf"] = lambda: _lazymod("manga.mangafox").library()