webapp.py: fuse two sql queries in get_details
[~helmut/debian-dedup.git] / dedup / utils.py
1 import contextlib
2 import errno
3 import urllib.error
4 import urllib.request
5
6 import debian.deb822
7
8 from dedup.compression import decompress
9
10 def fetchiter(cursor):
11     rows = cursor.fetchmany()
12     while rows:
13         yield from rows
14         rows = cursor.fetchmany()
15
16 def open_compressed_mirror_url(url, extensions=(".xz", ".gz", "")):
17     """Fetch the given url. Try appending each of the given compression
18     schemes and move on in case it doesn't exist. Decompress the resulting
19     stream on the fly.
20     @returns: a file-like with the decompressed contents
21     """
22     for ext in extensions:
23         try:
24             handle = urllib.request.urlopen(url + ext)
25         except urllib.error.HTTPError as error:
26             if error.code != 404:
27                 raise
28         except urllib.error.URLError as error:
29             if not hasattr(error.reason, "errno"):
30                 raise
31             if error.reason.errno != errno.ENOENT:
32                 raise
33         else:
34             return decompress(handle, ext)
35     raise OSError(errno.ENOENT, "No such file or directory")
36
37 def iterate_packages(mirror, architecture, distribution="sid", section="main"):
38     """Download the relevant binary package list and generate
39     debian.deb822.Packages objects per listed package."""
40     url = "%s/dists/%s/%s/binary-%s/Packages" % \
41             (mirror, distribution, section, architecture)
42     with contextlib.closing(open_compressed_mirror_url(url)) as pkglist:
43         yield from debian.deb822.Packages.iter_paragraphs(pkglist)