def _write_metadata(self): # create new Element object for RDF rdf = ElementTree.Element(utils.extend_tag_name(metadata.Namespace.rdf_terms.rdf, _XML_NS)) # iterate over archive metadata for description in self.description: desc_elem = description._rebuild_xml() desc_elem.attrib[utils.extend_tag_name(metadata.Namespace.rdf_terms.about, _XML_NS)] = self.ARCHIVE_REFERENCE[0] rdf.append(desc_elem) # iterate over all metadata for each entry for (location, entry) in self.entries.items(): if not isinstance(entry, metadata.MetaDataHolder): continue for description in entry.description: desc_elem = description._rebuild_xml() desc_elem.attrib[utils.extend_tag_name(metadata.Namespace.rdf_terms.about, _XML_NS)] = location rdf.append(desc_elem) # write xml to zip io = StringIO() ElementTree.ElementTree(rdf).write(io, xml_declaration=True) self.add_entry(io.getvalue(), _XML_CONTENT_METADATA_TYPE, location=self.METADATA_LOCATION, replace=True) io.close()
def _write_metadata(self): # create new Element object for RDF rdf = ElementTree.Element( utils.extend_tag_name(metadata.Namespace.rdf_terms.rdf, _XML_NS)) # iterate over archive metadata for description in self.description: desc_elem = description._rebuild_xml() desc_elem.attrib[utils.extend_tag_name( metadata.Namespace.rdf_terms.about, _XML_NS)] = self.ARCHIVE_REFERENCE[0] rdf.append(desc_elem) # iterate over all metadata for each entry for (location, entry) in self.entries.items(): if not isinstance(entry, metadata.MetaDataHolder): continue for description in entry.description: desc_elem = description._rebuild_xml() desc_elem.attrib[utils.extend_tag_name( metadata.Namespace.rdf_terms.about, _XML_NS)] = location rdf.append(desc_elem) # write xml to zip io = StringIO() ElementTree.ElementTree(rdf).write(io, xml_declaration=True) self.add_entry(io.getvalue(), _XML_CONTENT_METADATA_TYPE, location=self.METADATA_LOCATION, replace=True) io.close()
def _rebuild_xml(self): # TODO # builds top-level rdf:Description element elem = self._build_desc_elem() # add description if self.description and self.description != '': desc_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.dc_terms.description, combinearchive._XML_NS)) desc_elem.text = self.description # add date of creation if self.created: created_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.dc_terms.created, combinearchive._XML_NS)) w3cdtf = ElementTree.SubElement( created_elem, utils.extend_tag_name(Namespace.dc_terms.w3cdtf, combinearchive._XML_NS)) w3cdtf.text = self.created.strftime( Namespace.dc_terms.w3cdtf_dateformat) # add all modification dates for mod_date in self.modified: modified_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.dc_terms.modified, combinearchive._XML_NS)) w3cdtf = ElementTree.SubElement( modified_elem, utils.extend_tag_name(Namespace.dc_terms.w3cdtf, combinearchive._XML_NS)) w3cdtf.text = mod_date.strftime( Namespace.dc_terms.w3cdtf_dateformat) # add all VCards for vcard in self.creator: creator_elem = vcard.build_xml() elem.append(creator_elem) self._xml_element = elem return self._xml_element
def build_xml(self): # generate new xml element # (vcards are always housed in a dcterms:creator elem) elem = ElementTree.Element( utils.extend_tag_name(Namespace.dc_terms.creator, combinearchive._XML_NS)) elem.attrib[utils.extend_tag_name(Namespace.rdf_terms.parse_type, combinearchive._XML_NS)] = 'Resource' # name tag if (self.family_name and self.family_name != '') or (self.given_name and self.given_name != ''): hasname_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.vcard_terms.has_name, combinearchive._XML_NS)) hasname_elem.attrib[utils.extend_tag_name( Namespace.rdf_terms.parse_type, combinearchive._XML_NS)] = 'Resource' # add family name if self.family_name and self.family_name != '': fn_elem = ElementTree.SubElement( hasname_elem, utils.extend_tag_name(Namespace.vcard_terms.family_name, combinearchive._XML_NS)) fn_elem.text = self.family_name # add given name if self.given_name and self.given_name != '': gn_elem = ElementTree.SubElement( hasname_elem, utils.extend_tag_name(Namespace.vcard_terms.given_name, combinearchive._XML_NS)) gn_elem.text = self.given_name # add email if self.email and self.email != '': em_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.vcard_terms.email, combinearchive._XML_NS)) em_elem.text = self.email # add organization if self.organization and self.organization != '': on_elem = ElementTree.SubElement( elem, utils.extend_tag_name(Namespace.vcard_terms.organization_name, combinearchive._XML_NS)) on_elem.text = self.organization return elem
def _read_manifest(self): """ internal function. Reads the manifest file of a COMBINE Archive """ try: with self._zip.open(self.MANIFEST_LOCATION) as manifest_file: manifest = ElementTree.fromstring(manifest_file.read()) except KeyError: # manifest does not exists, probably an empty/new archive return False except ElementTree.ParseError as e: raise exceptions.CombineArchiveException( 'Cannot parse xml manifest. {}'.format(e.msg)) # check for correct root element and namespace if manifest.tag != utils.extend_tag_name(_XML_ROOT_ELEM, _XML_NS): raise exceptions.CombineArchiveException( 'manifest has no valid omex root element') # check entries for entry in manifest.findall(_XML_CONTENT_TAG, _XML_NS): try: location = utils.get_attribute(entry, _XML_CONTENT_LOCATION, _XML_NS) entry_format = utils.check_format(utils.get_attribute( entry, _XML_CONTENT_FORMAT, _XML_NS), convert=False) master = True if entry.attrib.get(_XML_CONTENT_MASTER, False) in ('True', 'true', True) else False except KeyError: raise exceptions.CombineArchiveException( 'location and format field are required. Corrupt manifest.xml' ) # clean location location = utils.clean_pathname(location) # check if file is in zip, if it's not the root element zipinfo = None if location not in self.ARCHIVE_REFERENCE: try: zipinfo = self._zip.getinfo(location) except KeyError: raise exceptions.CombineArchiveException( '{location} is specified by the manifest, but not contained by the ZIP file' .format(location=location)) archive_entry = ArchiveEntry(location, format=entry_format, master=master, archive=self, zipinfo=zipinfo) self.entries[location] = archive_entry
def _build_desc_elem(self): """ constructs the surrounding rdf:description element and returns it useful for _rebuild_xml() """ elem = ElementTree.Element( utils.extend_tag_name(Namespace.rdf_terms.description, combinearchive._XML_NS)) if isinstance(self.about, combinearchive.CombineArchive): # meta data is about the archive itself about_url = '.' elif isinstance(self.about, combinearchive.ArchiveEntry): # meta data is about a normal archive entry about_url = self.about.location # add fragment if self.fragment: about_url = urljoin(about_url, '#{}'.format(self.fragment)) elem.attrib[utils.extend_tag_name(Namespace.rdf_terms.about, combinearchive._XML_NS)] = about_url return elem
def _write_manifest(self, zip_file=None): """ internal function. Writes the manifest file of a COMBINE Archive """ if zip_file is None: zip_file = self._zip # create new DOM object manifest = ElementTree.Element( utils.extend_tag_name(_XML_ROOT_ELEM, _XML_NS)) # write first entry for archive itself content = ElementTree.SubElement( manifest, utils.extend_tag_name(_XML_CONTENT_TAG, _XML_NS)) content.attrib.update({ utils.extend_tag_name(_XML_CONTENT_LOCATION, _XML_NS): '.', utils.extend_tag_name(_XML_CONTENT_FORMAT, _XML_NS): _XML_CONTENT_ARCHIVE_TYPE, }) for (location, entry) in self.entries.items(): entry_format = utils.check_format(entry.format) content = ElementTree.SubElement( manifest, utils.extend_tag_name(_XML_CONTENT_TAG, _XML_NS)) content.attrib.update({ utils.extend_tag_name(_XML_CONTENT_LOCATION, _XML_NS): location, utils.extend_tag_name(_XML_CONTENT_FORMAT, _XML_NS): entry_format, }) if entry.master: content.attrib[utils.extend_tag_name(_XML_CONTENT_MASTER, _XML_NS)] = 'true' # write xml to zip io = StringIO() ElementTree.ElementTree(manifest).write(io, xml_declaration=True, default_namespace=_XML_ROOT_NS) try: zip_file.remove(self.MANIFEST_LOCATION) except KeyError: pass # Manifest does not exist yet, so removing it will fail zip_file.writestr(self.MANIFEST_LOCATION, io.getvalue()) io.close()
def _read_manifest(self): """ internal function. Reads the manifest file of a COMBINE Archive """ try: with self._zip.open(self.MANIFEST_LOCATION) as manifest_file: manifest = ElementTree.fromstring(manifest_file.read()) except KeyError: # manifest does not exists, probably an empty/new archive return False except ElementTree.ParseError as e: raise exceptions.CombineArchiveException('Cannot parse xml manifest. {}'.format(e.msg)) # check for correct root element and namespace if manifest.tag != utils.extend_tag_name(_XML_ROOT_ELEM, _XML_NS): raise exceptions.CombineArchiveException('manifest has no valid omex root element') # check entries for entry in manifest.findall(_XML_CONTENT_TAG, _XML_NS): try: location = utils.get_attribute(entry, _XML_CONTENT_LOCATION, _XML_NS) entry_format = utils.check_format(utils.get_attribute(entry, _XML_CONTENT_FORMAT, _XML_NS), convert=False) master = True if entry.attrib.get(_XML_CONTENT_MASTER, False) in ('True', 'true', True) else False except KeyError: raise exceptions.CombineArchiveException('location and format field are required. Corrupt manifest.xml') # clean location location = utils.clean_pathname(location) # check if file is in zip, if it's not the root element zipinfo = None if location not in self.ARCHIVE_REFERENCE: try: zipinfo = self._zip.getinfo(location) except KeyError: raise exceptions.CombineArchiveException( '{location} is specified by the manifest, but not contained by the ZIP file'.format(location=location)) archive_entry = ArchiveEntry(location, format=entry_format, master=master, archive=self, zipinfo=zipinfo) self.entries[location] = archive_entry
def _write_manifest(self, zip_file=None): """ internal function. Writes the manifest file of a COMBINE Archive """ if zip_file is None: zip_file = self._zip # create new DOM object manifest = ElementTree.Element(utils.extend_tag_name(_XML_ROOT_ELEM, _XML_NS)) # write first entry for archive itself content = ElementTree.SubElement(manifest, utils.extend_tag_name(_XML_CONTENT_TAG, _XML_NS)) content.attrib.update({ utils.extend_tag_name(_XML_CONTENT_LOCATION, _XML_NS): '.', utils.extend_tag_name(_XML_CONTENT_FORMAT, _XML_NS): _XML_CONTENT_ARCHIVE_TYPE, }) for (location, entry) in self.entries.items(): entry_format = utils.check_format(entry.format) content = ElementTree.SubElement(manifest, utils.extend_tag_name(_XML_CONTENT_TAG, _XML_NS)) content.attrib.update({ utils.extend_tag_name(_XML_CONTENT_LOCATION, _XML_NS): location, utils.extend_tag_name(_XML_CONTENT_FORMAT, _XML_NS): entry_format, }) if entry.master: content.attrib[utils.extend_tag_name(_XML_CONTENT_MASTER, _XML_NS)] = 'true' # write xml to zip io = StringIO() ElementTree.ElementTree(manifest).write(io, xml_declaration=True, default_namespace=_XML_ROOT_NS) try: zip_file.remove(self.MANIFEST_LOCATION) except KeyError: pass # Manifest does not exist yet, so removing it will fail zip_file.writestr(self.MANIFEST_LOCATION, io.getvalue()) io.close()