All libraries should implement this."""
raise NotImplementedError()
+ def search(self, string):
+ """Returns an iterable object of mangas in this library that
+ matches the search string in a library-dependent manner. While
+ each library is at liberty to define its own matching
+ criteria, it is probably likely to involve something akin to
+ searching for keywords in the titles of the library.
+
+ Searching may return very many results and may be slow to
+ iterate.
+
+ Not all libraries need implement this."""
+ raise NotImplementedError()
+
def byid(self, id):
"""Returns a previously known manga by its string ID, or
raises KeyError if no such manga could be found.
"""Close this stream."""
raise NotImplementedError()
- def read(self, sz = None):
+ def read(self, sz=None):
"""Read SZ bytes from the stream, or the entire rest of the
stream of SZ is not given."""
raise NotImplementedError()
+class stdimgstream(imgstream):
+ """A standard implementation of imgstream, for libraries which
+ have no particular implementation requirements."""
+
+ def __init__(self, url, referer=None):
+ import urllib.request
+ headers = {"User-Agent": "automanga/1"}
+ if referer:
+ headers["Referer"] = referer
+ req = urllib.request.Request(url, headers=headers)
+ self.bk = urllib.request.urlopen(req)
+ ok = False
+ try:
+ if self.bk.getcode() != 200:
+ raise IOError("Server error: " + str(self.bk.getcode()))
+ self.ctype = self.bk.info()["Content-Type"]
+ self.clen = int(self.bk.info()["Content-Length"])
+ ok = True
+ finally:
+ if not ok:
+ self.bk.close()
+
+ def fileno(self):
+ return self.bk.fileno()
+
+ def close(self):
+ self.bk.close()
+
+ def read(self, sz=None):
+ if sz is None:
+ return self.bk.read()
+ else:
+ return self.bk.read(sz)
+
class cursor(object):
def __init__(self, ob):
if isinstance(ob, cursor):
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
def prev(self):
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()
+ def iterator():
+ yield self.cur
+ while True:
+ try:
+ yield self.next()
+ except StopIteration:
+ break
+ return iterator()
+
+loaded = {}
+def findlib(name):
+ def load(name):
+ import importlib
+ mod = importlib.import_module(name)
+ if not hasattr(mod, "library"):
+ raise ImportError("module " + name + " is not a manga library")
+ return mod.library()
+ if name not in loaded:
+ try:
+ loaded[name] = load("manga." + name)
+ except ImportError:
+ loaded[name] = load(name)
+ return loaded[name]