0
  #   #l=J *j"T3qţ_ ?     ##!/usr/bin/python -t
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2005 Duke University 
#
# Seth Vidal <skvidal@linux.duke.edu>
# Luke Macken <lmacken@redhat.com>

"""
Update metadata (updateinfo.xml) parsing.
"""

import sys

from yum.i18n import utf8_text_wrap, to_utf8, to_unicode, _
from yum.yumRepo import YumRepository
from yum.packages import FakeRepository
from yum.misc import to_xml, decompress, repo_gen_decompress
from yum.misc import cElementTree_iterparse as iterparse 
import Errors

import logginglevels

import rpmUtils.miscutils
from rpmUtils.arch import ArchStorage


def safe_iterparse(filename, logger=None):
    """ Works like iterparse, but hides XML errors (prints a warning). """
    try:
        for event, elem in iterparse(filename):
            yield event, elem
    except SyntaxError: # Bad XML
        if logger:
            logger.critical(_("Updateinfo file is not valid XML: %s"), filename)
        else:
            print >> sys.stderr, "Updateinfo file is not valid XML:", filename

class UpdateNoticeException(Exception):
    """ An exception thrown for bad UpdateNotice data. """
    pass


class UpdateNotice(object):

    """
    A single update notice (for instance, a security fix).
    """

    def __init__(self, elem=None, repoid=None, vlogger=None):
        self._md = {
            'from'             : '',
            'type'             : '',
            'title'            : '',
            'release'          : '',
            'status'           : '',
            'version'          : '',
            'pushcount'        : '',
            'update_id'        : '',
            'issued'           : '',
            'updated'          : '',
            'description'      : '',
            'rights'           : '',
            'severity'         : '',
            'summary'          : '',
            'solution'         : '',
            'references'       : [],
            'pkglist'          : [],
            'reboot_suggested' : False
        }

        if elem:
            self._parse(elem)

        self._repoid = repoid
        self._vlogger = vlogger

    def __getitem__(self, item):
        """ Allows scriptable metadata access (ie: un['update_id']). """
        if type(item) is int:
            return sorted(self._md)[item]
        ret = self._md.get(item)
        if ret == '':
            ret = None
        return ret

    def __contains__(self, item):
        """ Allows quick tests for foo in blah. """
        return item in self._md

    def __setitem__(self, item, val):
        self._md[item] = val

    def __eq__(self, other):
        #  Tests to see if it's "the same data", which means that the
        # packages can be different (see add_notice).

        def _rid(un):
            if hasattr(un, '_repoid') and un._repoid is not None:
                return un._repoid
            else:
                return '<unknown>'

        def _log_failure(data):
            """Log the mismatched data similarly to conflict markers in git."""
            if self._vlogger is None:
                return
            msg = _('Duplicate of %s differs in some fields:\n')
            msg %= other._md['update_id']
            msg += '<<<<<<< %s:%s\n' % (_rid(other), data)
            msg += '%r\n=======\n%r\n' % (other._md[data], self._md[data])
            msg += '>>>>>>> %s:%s' % (_rid(self), 