Specify a custom user-agent string for all default requests.
[automanga.git] / manga / lib.py
index 21edd3d..662ecc3 100644 (file)
@@ -9,6 +9,19 @@ class library(object):
         All libraries should implement this."""
         raise NotImplementedError()
 
         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.
     def byid(self, id):
         """Returns a previously known manga by its string ID, or
         raises KeyError if no such manga could be found.
@@ -136,11 +149,43 @@ class imgstream(object):
         """Close this stream."""
         raise NotImplementedError()
 
         """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()
 
         """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):
+        import urllib.request
+        req = urllib.request.Request(url, headers={"User-Agent": "automanga/1"})
+        print(req)
+        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):
 class cursor(object):
     def __init__(self, ob):
         if isinstance(ob, cursor):
@@ -175,7 +220,8 @@ class cursor(object):
 loaded = {}
 def findlib(name):
     def load(name):
 loaded = {}
 def findlib(name):
     def load(name):
-        mod = __import__(name, fromlist=["dummy"])
+        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 not hasattr(mod, "library"):
             raise ImportError("module " + name + " is not a manga library")
         return mod.library()