view treepkg/info/status.py @ 433:9926ced5d477 treepkg-status

fixed typo
author Bjoern Ricks <bricks@intevation.de>
date Thu, 29 Jul 2010 14:52:42 +0000
parents acf97c1a06e0
children c6d88d70bc43
line wrap: on
line source
# Copyright (C) 2010 by Intevation GmbH
# Authors:
# Bjoern Ricks <bjoern.ricks@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.

"""Build treepkg status information"""

import os.path
import xml.dom.minidom

from treepkg.report import get_packager_group
from treepkg.util import md5sum
from treepkg.info.package import BinaryPackage

TREEPKG_NAMESPACE_URI = "http://wald.intevation.org/projects/treepkg/"
TREEPKG_NAMESPACE_PREFIX = "tpkg"

def createTpkgElement(doc, name):
    return doc.createElementNS(TREEPKG_NAMESPACE_URI, name)

def createTpkgRoot(name):
    domimpl = xml.dom.minidom.getDOMImplementation()
    doc = domimpl.createDocument(TREEPKG_NAMESPACE_URI, name, None)
    root = doc.documentElement
    return (doc, root)

def getTextFromNode(node):
    if not node:
        return None
    textnode = node.firstChild
    if not textnode or textnode.nodeType != node.TEXT_NODE:
        return None
    return textnode.data

def getChild(node, name, required=False):
    childs = getChilds(node, name, required)
    if not childs or len(childs) == 0:
        return None
    else:
        return childs[0]

def getChilds(node, name, required=False):
    if not node:
        if required:
            raise TreepkgInfoException("Element %s is required as child. But"
                                    "parent element is not available.")
        return None
    childs = node.getElementsByTagName(name)
    if not childs:
        if required:
            raise TreepkgInfoException("Element %s is required as child for %s."
                        "The XML file must be invalid." % (name, node.nodeName))
        return None
    return childs


class TreepkgInfoException(Exception):
    """ Exception class for TreepkgInfo  """

class TreepkgInfo:

    def __init__(self, config, numnewestrev=-1, success=False):
        self.numnewestrev = numnewestrev
        self.success = success
        group = get_packager_group(config)
        treepkgrootinfo = TreepkgRootInfo(group.name, group.treepkg_dir, 
                                        group.tracks_dir)
        version = "1.0"
        self.tpkgroot = TreepkgRoot(version, treepkgrootinfo)
        tracks = group.get_package_tracks()

        for track in tracks:
            trackinfo = TreepkgTrackInfo(track.name)
            self.tpkgroot.add_track(trackinfo)
            self.add_revisions(track, trackinfo)

    def toxml(self):
        return self.tpkgroot.toxml()

    @staticmethod
    def fromxml(xmlstr):
        doc = xml.dom.minidom.parseString(xmlstr)
        root = doc.documentElement
        if not root.tagName == "treepkg":
            raise TreepkgInfoException("XML is not valid for treepkginfo")
        return TreepkgRoot.fromxml(root)

    def add_revisions(self, track, trackinfo):
        revisions = track.get_revisions()
        revisions = sorted(revisions, key=lambda r: r.status.start,
                           reverse=True)
        canidates = revisions
        if self.success: # skip not successful builds
            candidates = [rev for rev in revisions
                          if rev.status.status.finished 
                            and not rev.status.status.error]

        if self.numnewestrev > 0:
            canditates = candidates[:self.numnewestrev]

        arch = None

        for rev in candidates:
            revision = rev.revision
            rules_revision = rev.rules_revision
            status  = rev.status.status.description  # extend status
            
            sources = rev.list_source_files()
            binaries = rev.list_binary_files()

            revinfo = TreepkgTrackRevisionInfo(revision, rules_revision,
                                               status)
            logs = rev.get_log_files()
            for (title, filename) in logs:
                loginfo = TreepkgLogInfo(title, filename)
                revinfo.add_log(loginfo)
            for source in sources:
                self.add_package(revinfo, source, "source")
            for binary in binaries:
                binpackage =  BinaryPackage(binary)
                arch = binpackage.get_architecture()
                self.add_package(revinfo, binary, "binary", arch)

            trackinfo.add_revision(revinfo)

    def add_package(self, revision, file, type, arch=None):
        name = os.path.basename(file)
        checksum = md5sum(file)
        checksuminfo = TreepkgChecksumInfo(checksum, "md5")
        pkginfo = TreepkgPackageInfo(name, file, type, arch)
        pkginfo.add_checksum(checksuminfo)
        revision.add_package(pkginfo)

class TreepkgRoot:
    
    def __init__(self, version, info):
        self.version = version
        self.info = info
        self.tracks = []

    def add_track(self, track):
        self.tracks.append(track)

    def toxml(self):
        (doc, root) = createTpkgRoot("treepkg")
        root.setAttributeNS(TREEPKG_NAMESPACE_URI, "version", self.version)
        if len(self.tracks) > 0:
            tracksele = createTpkgElement(doc, "tracks")
            for track in self.tracks:
                tracksele.appendChild(track.toxml())
            root.appendChild(tracksele)
        root.appendChild(self.info.toxml())
        return root

    @staticmethod
    def fromxml(node):
        version = node.getAttribute("version")
        tracksele = getChild(node, "tracks")
        trackeles = getChilds(tracksele, "track")
        infoele = getChild(node, "info")
        treepkgrootinfo = TreepkgRootInfo.fromxml(infoele)
        treepkgroot = TreepkgRoot(version, treepkgrootinfo)
        tracks = []
        for trackele in trackeles:
            tracks.append(TreepkgTrackInfo.fromxml(trackele))
        treepkgroot.tracks = tracks
        return treepkgroot
 
class TreepkgRootInfo:

    def __init__(self, name, treepkgpath=None, trackspath=None, version=None):
        self.name = name
        self.treepkgpath = treepkgpath
        self.trackspath = trackspath
        self.version = version

    def toxml(self):
        (doc, root) = createTpkgRoot("info")
        # add <name>
        nameele = createTpkgElement(doc, "name")
        text = doc.createTextNode(self.name)
        nameele.appendChild(text)
        root.appendChild(nameele)
        # add <treepkgpath>
        if self.treepkgpath:
            treepkgpathele = createTpkgElement(doc, "treepkgpath")
            text = doc.createTextNode(self.treepkgpath)
            treepkgpathele.appendChild(text)
            root.appendChild(treepkgpathele)
        # add <trackspath>
        if self.trackspath:
            trackspathele = createTpkgElement(doc, "trackspath")
            text = doc.createTextNode(self.trackspath)
            trackspathele.appendChild(text)
            root.appendChild(trackspathele)
        # add <version>
        if self.version:
            versionele = createTpkgElement(doc, "version")
            text = doc.createTextNode(self.version)
            versionele.appendChild(text)
            root.appendChild(versionele)
        return root
    
    @staticmethod
    def fromxml(node):
        version = node.getAttribute("version")
        nameele = getChild(node, "name", True)
        name = getTextFromNode(nameele)
        treepkgpathele = getChild(node, "treepkgpath")
        treepkgpath = getTextFromNode(treepkgpathele)
        trackspathele = getChild(node, "trackspath")
        trackspath = getTextFromNode(trackspathele)
        return TreepkgRootInfo(name, treepkgpath, trackspath, version)

class TreepkgTrackInfo:
    
    def __init__(self, name, os=None):
        self.name = name
        self.os = os
        self.revisions = []

    def add_revision(self, revision):
        self.revisions.append(revision)

    def toxml(self):
        (doc, root) = createTpkgRoot("track")
        nameele = createTpkgElement(doc, "name")
        text = doc.createTextNode(self.name)
        nameele.appendChild(text)
        root.appendChild(nameele)
        for rev in self.revisions:
            root.appendChild(rev.toxml())
        if not self.os is None:
            osele = createTpkgElement(doc, "os")
            text = doc.createTextNode(self.os)
            osele.appendChild(text)
            root.appendChild(osele)
        return root

    @staticmethod
    def fromxml(node):
        nameele = getChild(node, "name", True)
        name = getTextFromNode(nameele)
        osele = getChild(node, "os")
        os = getTextFromNode(osele)
        treepkgtrackinfo = TreepkgTrackInfo(name, os)
        treepkgtrackinfo.revisions = []
        revisioneles = node.getElementsByTagName("revision")
        for revele in revisioneles:
            treepkgrevision = TreepkgTrackRevisionInfo.fromxml(revele)
            treepkgtrackinfo.revisions.append(treepkgrevision)
        return treepkgtrackinfo


class TreepkgTrackRevisionInfo:

    def __init__(self, number, rules, status):
        self.number = number
        self.rules = rules
        self.status = status
        self.packages = []
        self.logs = []

    def add_package(self, package):
        self.packages.append(package)

    def add_log(self, log):
        self.logs.append(log)

    def toxml(self):
        (doc, root) = createTpkgRoot("revision")
        # add <number>
        numberele = createTpkgElement(doc, "number")
        text = doc.createTextNode(self.number)
        numberele.appendChild(text)
        root.appendChild(numberele)
        # add <rules>
        rulesele = createTpkgElement(doc, "rules")
        text = doc.createTextNode(self.rules)
        rulesele.appendChild(text)
        root.appendChild(rulesele)
        # add <status><message></message></status>
        statusele = createTpkgElement(doc, "status")
        messageele = createTpkgElement(doc, "message")
        text = doc.createTextNode(self.status)
        messageele.appendChild(text)
        statusele.appendChild(messageele)
        root.appendChild(statusele)
        # add <packages>
        packagesele = createTpkgElement(doc, "packages")
        for package in self.packages:
            packagesele.appendChild(package.toxml())
        root.appendChild(packagesele)
        # add <logs>
        logsele = createTpkgElement(doc, "logs")
        for log in self.logs:
            logsele.appendChild(log.toxml())
        root.appendChild(logsele)
        return root

    @staticmethod
    def fromxml(node):
        numberele = getChild(node, "number", True)
        number = getTextFromNode(numberele)
        rulesele = getChild(node, "rules", True)
        rules = getTextFromNode(rulesele)
        statusele = getChild(node, "status", True)
        messageele = getChild(statusele, "message")
        message = getTextFromNode(messageele)
        treepkgrevisioninfo = TreepkgTrackRevisionInfo(number, rules, message)
        treepkgrevisioninfo.packages = []
        treepkgrevisioninfo.logs = []
        packagesele = getChild(node, "packages")
        packageeles = getChilds(packagesele, "package")
        for packageele in packageeles:
            treepkgrevisioninfo.packages.append(
                TreepkgPackageInfo.fromxml(packageele))
        logsele = getChild(node, "logs")
        logeles = getChilds(logsele, "log")
        for logele in logeles:
            treepkgrevisioninfo.logs.append(
                TreepkgLogInfo.fromxml(logele))
        return treepkgrevisioninfo

class TreepkgLogInfo:

    def __init__(self, name, path):
        self.name = name
        self.path = path

    def toxml(self):
        (doc, root) = createTpkgRoot("log")
        # add <name>
        nameele = createTpkgElement(doc, "name")
        text = doc.createTextNode(self.name)
        nameele.appendChild(text)
        root.appendChild(nameele)
        # add path
        pathele = createTpkgElement(doc, "path")
        text = doc.createTextNode(self.path)
        pathele.appendChild(text)
        root.appendChild(pathele)
        return root

    @staticmethod
    def fromxml(node):
        nameele = getChild(node, "name", True)
        name = getTextFromNode(nameele)
        pathele = getChild(node, "path", True)
        path = getTextFromNode(pathele)
        return TreepkgLogInfo(name, path)

class TreepkgPackageInfo:
        
    def __init__(self, name, path, type, arch):
        self.name = name
        self.path = path
        self.type = type
        self.arch = arch
        self.checksums = [] 

    def toxml(self):
        (doc, root) = createTpkgRoot("package")
        # add <name>
        nameele = createTpkgElement(doc, "name")
        text = doc.createTextNode(self.name)
        nameele.appendChild(text)
        root.appendChild(nameele)
        # add <path>
        pathele = createTpkgElement(doc, "path")
        text = doc.createTextNode(self.path)
        pathele.appendChild(text)
        root.appendChild(pathele)
        # add <checksum>
        for checksum in self.checksums:
            root.appendChild(checksum.toxml())
        # add <type>
        root.setAttributeNS(TREEPKG_NAMESPACE_URI, "type", self.type)
        if not self.arch is None:
            root.setAttributeNS(TREEPKG_NAMESPACE_URI, "arch", self.arch)
        return root

    def add_checksum(self, checksum):
        self.checksums.append(checksum)

    @staticmethod
    def fromxml(node):
        nameele = getChild(node, "name", True)
        name = getTextFromNode(nameele)
        pathele = getChild(node, "path", True)
        path = getTextFromNode(pathele)
        ptype = node.getAttribute("type")
        arch = node.getAttribute("arch")
        if len(arch) == 0:
            arch = None
        packageinfo = TreepkgPackageInfo(name, path, ptype, arch)
        checksumeles = node.getElementsByTagName("checksum")
        for checksumele in checksumeles:
            packageinfo.checksums.append(TreepkgChecksumInfo.fromxml(checksumele))
        return packageinfo

class TreepkgChecksumInfo:
    
    def __init__(self, checksum, type="md5"):
        self.checksum = checksum
        self.type = type

    def toxml(self):
        (doc, root) = createTpkgRoot("checksum")
        text = doc.createTextNode(self.checksum)
        root.appendChild(text)
        # add attribute type
        if type:
            root.setAttributeNS(TREEPKG_NAMESPACE_URI, "type", self.type)
        return root

    @staticmethod
    def fromxml(node):
        checksum = getTextFromNode(node)
        ctype = node.getAttribute("type")
        if len(ctype) == 0:
            return TreepkgChecksumInfo(checksum)
        return TreepkgChecksumInfo(checksum, ctype)
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)