#!/usr/bin/env python

# Ian Wienand <ianw@ieee.org> (C) 2005

# Small python program useful for finding packages from other
# architectures when building a cross-compiler on Debian.

# Reads the Packages.gz and outputs the filename to download.  You can
# tell it about mirrors or read from a local packages file.
# --help should be illustrative.

# $ ./get-reqs.py -g -f Packages-ia64-unstable.gz libc6.1 libatomic-ops-dev
# ftp://ftp.au.debian.org/debian/pool/main/g/glibc/libc6.1_2.3.5-8_ia64.deb
# ftp://ftp.au.debian.org/debian/pool/main/liba/libatomic-ops/libatomic-ops-dev_1.1-3_ia64.deb

import re, sys, os
from optparse import OptionParser
from gzip import GzipFile

#parse a debian package description into a dictionary
class Package:
    def __init__(self, input):
        self.fields = {}
        self.fields["LongDescription"] = ""
        long_description = False
        r = re.compile('(?P<field>^.*?): (?P<val>.*$)')
        for l in input:
            if (long_description == True):
                if (l[0] == " "):
                    self.fields["LongDescription"] += l + "\n"
                else:
                    long_description = False
                
            if (long_description == False):
                m = r.match(l)
                if (m == None):
                    print l
                if (m.group("field") == "Description"):
                    long_description = True
                self.fields[m.group("field")] = m.group("val")

    def get_field(self, field):
        return self.fields[field]

#put all the available packages into this object
package_objects = {}

def parse_packages_file(fileh):
    try:
        package_lines = []
        for l in fileh.readlines():
            if (l != '\n'):
                package_lines.append(l.rstrip())
            else:
                p = Package(package_lines)
                package_objects[p.get_field("Package")] = p
                package_lines = []
    except:
        raise


usage = "get-packages.py [-m mirror] [-f file|-r] [-g] [-a arch] [-d dist] package1 package2 ... packageN"

parser = OptionParser(usage, version=".1")

parser.add_option("-m", "--mirror", dest="mirror", action="store", type="string",
                  help="Remote mirror to prefix", default="ftp://ftp.au.debian.org/debian")
parser.add_option("-f", "--file", dest="file", action="store", type="string",
                  help="Local packages file to read")
parser.add_option("-r", "--remote", dest="remote", action="store_true",
                  help="Fetch packages file from remote", default=False)
parser.add_option("-g", "--gzipped", dest="gzip", action="store_true",
                  help="Handle local packages (from -f) as gzipped", default=True)
parser.add_option("-a", "--arch", dest="arch", action="store", type="string",
                  help="Remote architecture file to grab from mirror", default="ia64")
parser.add_option("-d", "--dist", dest="dist", action="store", type="string",
                  help="Remote packages version to get", default="unstable")

(options, args) = parser.parse_args()

if (len(args) == 0):
    print usage
    sys.exit(1)

if (options.file == None and options.remote == False):
    print "Please either specify a local file or to grab from remote"
    sys.exit(1)

if (options.remote):
    filename = "/tmp/Packages-" + options.arch + "-" + options.dist
    os.system("wget " + options.mirror +
              "/" + "dists/" + options.dist +
              "/main/binary-" + options.arch +
              "/Packages.gz " +
              "-O " + filename)
    print("Packages file saved in %s" % (filename))

    fileh = GzipFile(filename, mode='r')
else:
    if (options.gzip):
        fileh = GzipFile(options.file, mode='r')
    else:
        fileh = open(options.file, mode='r')
    
parse_packages_file(fileh)

fileh.close()

for package in args:
    try:
        print options.mirror + "/" + package_objects[package].get_field("Filename")
    except:
        print "*** couldn't find package %s" % (package)
