[Yum-devel] [PATCH] new dump_xml methods for repodata and repomd and related changes

Mike Bonnet mikeb at redhat.com
Wed Apr 14 20:36:40 UTC 2010


On 04/14/2010 04:11 PM, Seth Vidal wrote:
> - add dump_xml methods to RepoData and RepoMD so we can write them back out
> 
> - also make them more object-y by allowing us to create the objects without having
>   anything to put in them so we populate them by hand, if need be.
> ---
>  yum/repoMDObject.py |   92 +++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 85 insertions(+), 7 deletions(-)
> 
> diff --git a/yum/repoMDObject.py b/yum/repoMDObject.py
> index 0021d94..eab351a 100755
> --- a/yum/repoMDObject.py
> +++ b/yum/repoMDObject.py
> @@ -23,7 +23,7 @@ from Errors import RepoMDError
>  
>  import sys
>  import types
> -from misc import AutoFileChecksums
> +from misc import AutoFileChecksums, to_xml
>  
>  def ns_cleanup(qn):
>      if qn.find('}') == -1: return qn 
> @@ -32,7 +32,9 @@ def ns_cleanup(qn):
>  class RepoData:
>      """represents anything beneath a <data> tag"""
>      def __init__(self, elem):
> -        self.type = elem.attrib.get('type')
> +        self.type = None
> +        if elem:
> +            self.type = elem.attrib.get('type')
>          self.location = (None, None)
>          self.checksum = (None,None) # type,value
>          self.openchecksum = (None,None) # type,value
> @@ -40,8 +42,9 @@ class RepoData:
>          self.dbversion = None
>          self.size      = None
>          self.opensize  = None
> -    
> -        self.parse(elem)
> +
> +        if elem:
> +            self.parse(elem)
>  
>      def parse(self, elem):
>          
> @@ -70,11 +73,47 @@ class RepoData:
>                  self.size = child.text
>              elif child_name == 'open-size':
>                  self.opensize = child.text
> +
> +    def dump_xml(self):
> +        msg = ""
> +        top = """<data type="%s">\n""" % to_xml(self.type, attrib=True)
> +        msg += top
> +        
> +        for (data, xmlname) in [('checksum', 'checksum'),('openchecksum', 'open-checksum')]:
> +            if hasattr(self, data):
> +                val = getattr(self, data)
> +                if val[0]:
> +                    d_xml = """  <%s type="%s">%s</%s>\n""" % (xmlname,
> +                                       to_xml(val[0], attrib=True), 
> +                                       to_xml(val[1]), xmlname)
> +                    msg += d_xml
> +
> +        if hasattr(self, 'location'):
> +            val = getattr(self, 'location')
> +            if val[1]:
> +                loc = """  <location href="%s"/>\n""" % to_xml(val[1], attrib=True)
> +                if val[0]:
> +                    loc = """  <location xml:base="%s" href="%s"/>\n""" % (
> +                       to_xml(val[0], attrib=True), to_xml(val[1], attrib=True))
> +                msg += loc
> +            
> +        for (data,xmlname) in [('timestamp', 'timestamp'),
> +                               ('dbversion', 'database_version'),
> +                               ('size','size'), ('opensize', 'open-size')]:
> +            val = getattr(self, data)
> +            if val:
> +                d_xml = """  <%s>%s</%s>\n""" % (xmlname, to_xml(val), 
> +                                                 xmlname)
> +                msg += d_xml
> +
> +        bottom = """</data>\n"""
> +        msg += bottom
> +        return msg
>          
>  class RepoMD:
>      """represents the repomd xml file"""
>      
> -    def __init__(self, repoid, srcfile):
> +    def __init__(self, repoid, srcfile=None):
>          """takes a repoid and a filename for the repomd.xml"""
>          
>          self.timestamp = 0
> @@ -83,8 +122,12 @@ class RepoMD:
>          self.checksums = {}
>          self.length    = 0
>          self.revision  = None
> -        self.tags      = {'content' : set(), 'distro' : {}}
> -        
> +        self.tags      = {'content' : set(), 'distro' : {}, 'repo': set()}
> +    
> +        if srcfile:
> +            self.parse(srcfile)
> +    
> +    def parse(self, srcfile):
>          if type(srcfile) in types.StringTypes:
>              # srcfile is a filename string
>              try:
> @@ -168,6 +211,41 @@ class RepoMD:
>              print '    open checksum: %s - %s' %  thisdata.openchecksum
>              print '    dbversion    : %s' % thisdata.dbversion
>              print ''
> +    def dump_xml(self):
> +        msg = ""
> +        
> +        top = """<?xml version="1.0" encoding="UTF-8"?>
> +<repomd xmlns="http://linux.duke.edu/metadata/repo" xmlns:rpm="http://linux.duke.edu/metadata/rpm">\n"""
> +        msg += top
> +        if self.revision:
> +            rev = """ <revision>%s</revision>\n""" % self.revision
> +            msg += rev

We're sure self.revision will never be a unicode object?  Maybe it needs
a to_xml() also?  Unexpected coercions to unicode were a major source of
problems with mergerepos in Koji, so I'm a little paranoid about this.

> +        
> +        if self.tags['content'] or self.tags['distro'] or self.tags['repo']:
> +            tags = """ <tags>\n"""
> +            for item in self.tags['content']:
> +                tag = """   <content>%s</content>\n""" % (to_xml(item))
> +                tags += tag
> +            for item in self.tags['repo']:
> +                tag = """   <repo>%s</repo>\n""" % (to_xml(item))
> +                tags += tag
> +            for (cpeid, item) in self.tags['distro'].items():
> +                itemlist = list(item) # frellingsets.
> +                if cpeid:
> +                    tag = """   <distro cpeid="%s">%s</distro>\n""" % (
> +                                to_xml(cpeid, attrib=True), to_xml(itemlist[0]))
> +                else:
> +                    tag = """   <distro>%s</distro>\n""" % (to_xml(itemlist[0]))
> +                tags += tag
> +            tags += """ </tags>\n"""
> +            msg += tags
> +        
> +        for md in self.repoData.values():
> +            msg += md.dump_xml()
> +        
> +        msg += """</repomd>\n"""
> +
> +        return msg
>  
>  def main():
>  



More information about the Yum-devel mailing list