#!/usr/bin/python

# This script generates a report on the packaging status of X.org
# releases in Buildroot. It does so by downloading the list of
# tarballs that are part of a given X.org release, and compare that
# with the packages that are available in Buildroot.

import BeautifulSoup
import re
import os
import urllib
from distutils.version import LooseVersion

# This can be customized
XORG_VERSION = "X11R7.7"

# Key names in dictionaries
XORG_VERSION_KEY = "xorg-version"
BR_VERSION_KEY = "br-version"
BR_NAME_KEY = "br-name"

# Packages part of X.org releases that we do not want to package in
# Buildroot (old drivers for hardware unlikely to be used in embedded
# contexts).
XORG_EXCEPTIONS = [
    'xf86-video-suncg6',
    'xf86-video-sunffb',
]

# Get the list of tarballs of a X.org release, parse it, and return a
# dictionary of dictionaries, of the form:
#
#   { <name_of_package> : { XORG_VERSION_KEY: <version_of_package> },
#     <name_of_package2> : { XORG_VERSION_KEY: <version_of_package2> }}
#
def get_xorg_release_pkgs():
    u = urllib.URLopener().open("http://www.x.org/releases/%s/src/everything/" % XORG_VERSION)
    b = BeautifulSoup.BeautifulSoup()
    b.feed(u.read())
    links = b.findAll("a")
    packages = {}
    r = re.compile("(.*)-([0-9\.]*).tar.bz2")
    # We now have a list of all links.
    for link in links:
        href = link.get("href")
        # Skip everything but tarballs
        if not href.endswith(".tar.bz2"):
            continue
        # Separate the name and the version
        groups = r.match(href)
        if not groups:
            continue
        name = groups.group(1)
        version = groups.group(2)
        # Skip packages we don't want to hear about
        if name in XORG_EXCEPTIONS:
            continue
        packages[name] = { XORG_VERSION_KEY : version }
    return packages

# Files and directories in package/x11r7/ that should be ignored in
# our processing.
BUILDROOT_EXCEPTIONS = [
    "mcookie", # Code is directly in package directory
    "x11r7.mk",
    "Config.in",
    "xdriver_xf86-input-tslib", # From Pengutronix, not part of X.org releases
]

# Prefixes of directories in package/x11r7/ that must be stripped
# before trying to match Buildroot package names with X.org tarball
# names.
BUILDROOT_PREFIXES = [
    "xapp",
    "xdriver",
    "xfont",
    "xlib",
    "xserver",
    "xutil",
    "xproto",
]

# From a Buildroot package name, try to see if a prefix should be
# stripped from it. For example, passing "xapp_xlsfonts" as argument
# to this function will return "xlsfonts".
def buildroot_strip_prefix(dirname):
    for prefix in BUILDROOT_PREFIXES:
        if dirname.startswith(prefix + "_"):
            return dirname[len(prefix) + 1:]
    return dirname

# From a Buildroot package name, parse its .mk file to find the
# Buildroot version of the package by looking at the <foo>_VERSION
# line.
def buildroot_get_version(dirname):
    f = open(os.path.join("package", "x11r7", dirname, dirname + ".mk"))
    r = re.compile("^([A-Z0-9_]*)_VERSION = ([0-9\.]*)$")
    for l in f.readlines():
        m = r.match(l)
        if m:
            return m.group(2)
    return None

# Augment the informations of the X.org list of packages (given as
# argument) by details about their packaging in Buildroot. Those
# details are found by looking at the contents of package/x11r7/.
def get_buildroot_pkgs(packages):
    dirs = os.listdir(os.path.join(os.getcwd(), "package", "x11r7"))
    for d in dirs:
        # Skip exceptions
        if d in BUILDROOT_EXCEPTIONS:
            continue
        pkgname = buildroot_strip_prefix(d)
        version = buildroot_get_version(d)
        if packages.has_key(pkgname):
            # There is a X.org package of the same name, so we just
            # add informations to the existing dict entry.
            packages[pkgname]['br-version'] = version
            packages[pkgname]['br-name'] = d
        else:
            # There is no X.org package with this name, so we add a
            # new dict entry.
            packages[pkgname] = { BR_VERSION_KEY: version,
                                  BR_NAME_KEY : d }
    return packages

def show_summary(packages):
    FORMAT_STRING = "%40s | %15s | %15s | %-30s"
    print FORMAT_STRING % ("Package name", "Vers in BR", "Vers in X.org", "Action")
    print FORMAT_STRING % ("-" * 40, "-" * 15, "-" * 15, "-" * 30)
    pkgs = packages.keys()
    pkgs.sort()
    total_pkgs = 0
    upgrade_pkgs = 0
    add_pkgs = 0
    remove_pkgs = 0
    nothing_todo_pkgs = 0
    for pkgname in pkgs:
        pkg = packages[pkgname]
        total_pkgs += 1
        if pkg.has_key(XORG_VERSION_KEY) and not pkg.has_key(BR_VERSION_KEY):
            xorg_version = pkg[XORG_VERSION_KEY]
            br_version = "N/A"
            action = "Add to Buildroot"
            add_pkgs += 1
        elif not pkg.has_key(XORG_VERSION_KEY) and pkg.has_key(BR_VERSION_KEY):
            br_version = pkg[BR_VERSION_KEY]
            xorg_version = "N/A"
            action = "Remove from Buildroot"
            remove_pkgs += 1
        elif LooseVersion(pkg[XORG_VERSION_KEY]) > LooseVersion(pkg[BR_VERSION_KEY]):
            br_version = pkg[BR_VERSION_KEY]
            xorg_version = pkg[XORG_VERSION_KEY]
            action = "Upgrade"
            upgrade_pkgs += 1
        elif LooseVersion(pkg[XORG_VERSION_KEY]) < LooseVersion(pkg[BR_VERSION_KEY]):
            br_version = pkg[BR_VERSION_KEY]
            xorg_version = pkg[XORG_VERSION_KEY]
            action = "More recent"
            nothing_todo_pkgs += 1
        else:
            br_version = pkg[BR_VERSION_KEY]
            xorg_version = pkg[XORG_VERSION_KEY]
            action = ""
            nothing_todo_pkgs += 1

        print FORMAT_STRING % (pkgname, br_version.center(15), xorg_version.center(15), action)
    print FORMAT_STRING % ("-" * 40, "-" * 15, "-" * 15, "-" * 30)
    STAT_FORMAT_STRING = "%40s : %3d"
    print STAT_FORMAT_STRING % ("Total number of packages", total_pkgs)
    print STAT_FORMAT_STRING % ("Packages to upgrade", upgrade_pkgs)
    print STAT_FORMAT_STRING % ("Packages to add", add_pkgs)
    print STAT_FORMAT_STRING % ("Packages to remove", remove_pkgs)
    print STAT_FORMAT_STRING % ("Packages with nothing to do", nothing_todo_pkgs)

packages = get_xorg_release_pkgs()
packages = get_buildroot_pkgs(packages)
# print packages
show_summary(packages)

