#!/usr/bin/env python

import subprocess, os, re, gzip
import apt_pkg

archive_root = 'http://archive.ubuntu.com/ubuntu'

tempdir = 'scratchspace'

components = ('universe', 'multiverse')
archs = ['i386', 'amd64']
ports = ['armel','ia64','powerpc','sparc']

# downloaded from http://udd.debian.org/cgi-bin/ubuntu_ftbfs.cgi
current_failures = 'current_failure_list.html'

def decompress_file_from_url(url, filename):
    fetched, headers = urllib.urlretrieve(url)
    out = open(filename, 'w')
    gzip_handle = gzip.GzipFile(fetched)
    while True:
        block = gzip_handle.read(65536)
        if not block:
            break
        out.write(block)
    out.close()
    gzip_handle.close()


def main():
    apt_pkg.InitSystem()

    srcver_re = re.compile('.*\((.*)\)')
    curfail_re = re.compile('^<tr><td>([^ ]+) ')
    source = {}
    packages = {}
    curfail = []

    handle = open(current_failures, 'r')
    for line in handle:
        m = curfail_re.match(line)
        if m:
            curfail.append(m.group(1))
    handle.close()

    for component in components:
        filename = os.path.join(tempdir,"%s_Sources" % component)
        if not os.path.exists(filename):
            url = "%s/dists/lucid/%s/source/Sources.gz" % \
                  (archive_root, component)
            decompress_file_from_url(url,filename)
        s = apt_pkg.TagFile(open(filename, 'r'))
        while s.step() == 1:
            source[s.section["Package"]] = {'version': s.section["Version"],
                                            'bins': s.section['Binary'].split(', ')}

        for arch in archs:
            filename = os.path.join(tempdir,"%s_%s_Packages" % (component,arch))
            if not os.path.exists(filename):
                url = "%s/dists/lucid/%s/binary-%s/Packages.gz" % \
                      (archive_root, component, arch)
                decompress_file_from_url(url,filename)
            packages[arch] = {}
            p = apt_pkg.TagFile(open(filename, 'r'))
            while p.step() == 1:
                packages[arch][p.section["Package"]] = {'version': p.section["Version"]}
                try:
                    packages[arch][p.section["Package"]].update({
                                               'source': p.section['Source']})
                except KeyError:
                    pass

        handle = subprocess.Popen('cut -f1-2 -d\' \' nbs.* | sort -u',
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT, shell=True)
        for line in handle.stdout:
            (package,version) = line.split(' ')
            version = version.rstrip()
            try:
                cursrcver = source[package]['version']
            except KeyError:
                continue
            bins = source[package]['bins']
            for binary in bins:
                failed_archs={}
                for arch in archs:
                    if not packages[arch].has_key(binary):
                        continue
                    try:
                        m = srcver_re.match(packages[arch][binary]['source'])
                    except KeyError:
                        m = None
                    if m:
                        curver = m.group(1)
                    else:
                        curver = packages[arch][binary]['version']

                    if apt_pkg.VersionCompare(curver,version) <= 0:
                        failed_archs[arch] = curver

                if failed_archs:
                    if package not in curfail:
                        continue
                    try:
                        if failed_archs['i386'] == failed_archs['amd64']:
                            print "%s: %s %s all" % (package,binary,failed_archs['i386'])
                            continue
                    except:
                        pass
                    for arch in failed_archs:
                        print "%s: %s %s %s %s" % (package,binary,failed_archs[arch],arch,' '.join(ports))

if __name__ == '__main__':
    main()
