Exemple #1
0
def main():

    print("""\
<?xml version="1.0" encoding="UTF-8"?>
<dfxml
  xmlns="%s"
  xmlns:delta="%s"
  version="1.1.0">
  <creator>
    <program>%s</program>
    <version>%s</version>
    <execution_environment>
      <command_line>%s</command_line>
    </execution_environment>
  </creator>
  <source>
    <image_filename>%s</image_filename>
  </source>\
""" % (dfxml.XMLNS_DFXML, dfxml.XMLNS_DELTA, sys.argv[0], __version__,
       " ".join(sys.argv), args.filename))

    ET.register_namespace("delta", dfxml.XMLNS_DELTA)

    xs = []
    for fi in dfxml.iter_dfxml(xmlfile=open(args.filename, "rb"),
                               preserve_elements=True):
        _logger.debug("Processing: %s" % str(fi))
        if args.cache:
            xs.append(fi.xml_element)
        else:
            _logger.debug("Printing without cache: %s" % str(fi))
            print(dfxml.ET_tostring(fi.xml_element, encoding="unicode"))
    if args.cache:
        for x in xs:
            _logger.debug("Printing with cache: %s" % str(fi))
            print(dfxml.ET_tostring(x, encoding="unicode"))

    print("""</dfxml>""")
Exemple #2
0
    def to_xml(self):
        import xml.etree.ElementTree as ET

        ET.register_namespace("delta", dfxml.XMLNS_DELTA)

        if not options.xmlfilename:
            sys.stderr.write("XML output filename not specified.\n")
            exit(1)

        metadict = dict()
        metadict["XMLNS_DFXML"] = dfxml.XMLNS_DFXML
        metadict["XMLNS_DELTA"] = dfxml.XMLNS_DELTA
        metadict["program"] = sys.argv[0]
        metadict["version"] = __version__
        metadict["commandline"] = " ".join(sys.argv)
        metadict["priorf"] = self.prior_fname
        metadict["currentf"] = self.current_fname

        xmlfile = open(options.xmlfilename, "w")
        xmlfile.write("""\
<?xml version="1.0" encoding="UTF-8"?>
<dfxml
  version="1.0"
  xmlns='%(XMLNS_DFXML)s'
  xmlns:dc='http://purl.org/dc/elements/1.1/'
  xmlns:delta='%(XMLNS_DELTA)s'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <metadata>
    <dc:type>Disk Image Difference Manifest</dc:type>
  </metadata>
  <creator>
    <program>%(program)s</program>
    <version>%(version)s</version>
    <execution_environment>
      <command_line>%(commandline)s</command_line>
    </execution_environment>
  </creator>
  <source>
    <image_filename>%(priorf)s</image_filename>
    <image_filename>%(currentf)s</image_filename>
  </source>
""" % metadict)

        def _annotate_changes(tmpel, ofi, fi):
            """
            Adds "delta:changed_property" attributes to elements that changed their values.
            Returns number of annotations needed.
            """
            retval = 0

            def _xpaths(xp):
                """
                Returns a list of xpaths: First, with an xmlns; second, as input.

                @param xp
                An xpath expression where all elements and attributes needing a namespace declaration are prefixed with "{0}" (for Python string formatting).
                """
                retval = []
                for nsprefix in ["{" + dfxml.XMLNS_DFXML + "}", ""]:
                    retval.append(xp.format(nsprefix))
                return retval

            # Triplets: Old value, new value, XPaths to find element to annotate
            for (oval, nval, xpaths) in [
                (ofi.filename(), fi.filename(), _xpaths("./{0}filename")),
                (ofi.sha1(), fi.sha1(),
                 _xpaths("./{0}hashdigest[@type='sha1']")),
                (ofi.md5(), fi.md5(), _xpaths("./{0}hashdigest[@type='md5']")),
                (ofi.mtime(), fi.mtime(), _xpaths("./{0}mtime")),
                (ofi.atime(), fi.atime(), _xpaths("./{0}atime")),
                (ofi.ctime(), fi.ctime(), _xpaths("./{0}ctime")),
                (ofi.crtime(), fi.crtime(), _xpaths("./{0}crtime")),
                (ofi.filesize(), fi.filesize(), _xpaths("./{0}filesize"))
            ]:
                #Find and flag the changed properties

                #Skip null-null comparisons
                if oval is None and nval is None:
                    continue

                if oval != nval:
                    retval += 1
                    #Find first namespace match for the property element
                    for xp in xpaths:
                        propertyel = tmpel.find(xp)
                        if not propertyel is None:
                            break
                    if propertyel is None:
                        comment = ET.Comment(
                            "Warning: Tried to note a changed property with the XPath queries %r; however, could not find the element."
                            % xpaths)
                        tmpel.insert(0, comment)
                    else:
                        propertyel.attrib["delta:changed_property"] = "1"
            return retval

        #List new files
        for fi in self.new_files:
            #xmlfile.write("  <!-- + %s -->\n" % fi.filename())
            xmlfile.write("  ")
            tmpel = copy.copy(fi.xml_element)
            tmpel.attrib["delta:new_file"] = "1"
            xmlfile.write(dfxml.ET_tostring(tmpel, encoding="unicode"))
            xmlfile.write("\n")
        #List deleted files
        for fi in self.fnames.values():
            #xmlfile.write("<!-- - %s -->\n" % fi.filename())
            xmlfile.write("  ")
            tmpel = ET.Element("fileobject")
            tmpel.attrib["delta:deleted_file"] = "1"
            tmpchild = copy.copy(fi.xml_element)
            tmpchild.tag = "delta:original_fileobject"
            tmpel.insert(-1, tmpchild)
            xmlfile.write(dfxml.ET_tostring(tmpel, encoding="unicode"))
            xmlfile.write("\n")
        #List renamed files
        for (ofi, fi) in self.renamed_files:
            #xmlfile.write("<!-- ! %s -> %s -->\n" % (ofi.filename(), fi.filename()))
            tmpel = copy.copy(fi.xml_element)
            annos = _annotate_changes(tmpel, ofi, fi)
            tmpoldel = copy.copy(ofi.xml_element)
            tmpoldel.tag = "delta:original_fileobject"
            tmpel.append(tmpoldel)
            tmpel.attrib["delta:renamed_file"] = "1"
            if annos > 1:
                tmpel.attrib["delta:changed_file"] = "1"
            xmlfile.write(dfxml.ET_tostring(tmpel, encoding="unicode"))
            xmlfile.write("\n")
        #List files with with modified data or metadata
        changed_files = set.union(set(self.changed_content),
                                  set(self.changed_properties))
        for (ofi, fi) in changed_files:
            #xmlfile.write("<!-- ~ %s -->\n" % fi.filename())
            xmlfile.write("  ")
            tmpel = copy.copy(fi.xml_element)
            _annotate_changes(tmpel, ofi, fi)
            tmpoldel = copy.copy(ofi.xml_element)
            tmpoldel.tag = "delta:original_fileobject"
            tmpel.append(tmpoldel)
            tmpel.attrib["delta:changed_file"] = "1"
            xmlfile.write(dfxml.ET_tostring(tmpel, encoding="unicode"))
            xmlfile.write("\n")
        xmlfile.write("</dfxml>\n")
        xmlfile.close()