class _BaseMessage(_BaseCerp): '''Common message elements''' local_id = xmlmap.IntegerField('xm:LocalId') message_id = xmlmap.StringField('xm:MessageId') message_id_supplied = xmlmap.SimpleBooleanField('xm:MessageId/@Supplied', true='1', false=None) mime_version = xmlmap.StringField('xm:MimeVersion') orig_date_list = xmlmap.StringListField('xm:OrigDate') # FIXME: really datetime # NOTE: eulxml.xmlmap.DateTimeField supports specifying format, # but we might need additional work since %z only works with # strftime, not strptime from_list = xmlmap.StringListField('xm:From') sender_list = xmlmap.StringListField('xm:Sender') to_list = xmlmap.StringListField('xm:To') cc_list = xmlmap.StringListField('xm:Cc') bcc_list = xmlmap.StringListField('xm:Bcc') in_reply_to_list = xmlmap.StringListField('xm:InReplyTo') references_list = xmlmap.StringListField('xm:References') subject_list = xmlmap.StringListField('xm:Subject') comments_list = xmlmap.StringListField('xm:Comments') keywords_list = xmlmap.StringListField('xm:Keywords') headers = xmlmap.NodeListField('xm:Header', Header) single_body = xmlmap.NodeField('xm:SingleBody', SingleBody) multi_body = xmlmap.NodeField('xm:MultiBody', MultiBody) @property def body(self): return self.single_body or self.multi_body incomplete_list = xmlmap.NodeField('xm:Incomplete', Incomplete) def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.message_id or self.local_id or '(no id)')
class PremisEnvironment(premis.BasePremis): ROOT_NAME = 'environment' note = xmlmap.StringField('p:environmentNote') # NOTE: both hardware and software could be repeated; # for simplicity, onyl mapping one for disk images, for now software = xmlmap.NodeField('p:software', PremisSoftwareEnvironment) hardware = xmlmap.NodeField('p:hardware', PremisHardwareEnvironment)
class Report(xmlmap.XmlObject): """ Windows Error Report """ ROOT_NAME = 'WERREPORT' machine = xmlmap.NodeField('MACHINEINFO', MachineInfo) """ Machine informations :type :class:`wer.schema.MachineInfo` """ user = xmlmap.StringField('USERINFO/@username') """ User informations :type :class:`wer.schema.UserInfo` """ application = xmlmap.NodeField('APPLICATIONINFO', ApplicationInfo, required=False) """ Application informations :type :class:`wer.schema.ApplicationInfo` """ event = xmlmap.NodeField('EVENTINFO', EventInfo) """ Event informations :type :class:`wer.schema.EventInfo` """ parameters = xmlmap.NodeListField('SIGNATURE/PARAMETER', Parameter) """ Event parameters :type list of :class:`wer.schema.Parameter` """ secondary_parameters = xmlmap.NodeListField('SIGNATURE/SECONDARYPARAMETER', SecondaryParameter) """ Event secondary parameters :type list of :class:`wer.schema.SecondaryParameter` """ files = xmlmap.NodeListField('FILES/FILE', File) """ Event attached files :type list of :class:`wer.schema.File` """ @classmethod def from_file(cls, file_path): """ Creates a Report from a XML file """ return xmlmap.load_xmlobject_from_file(file_path, xmlclass=cls) @classmethod def from_string(cls, xml_string): """ Creates a Report from a XML string """ return xmlmap.load_xmlobject_from_string(xml_string, xmlclass=cls)
class Section(_EadBase): """Generic EAD section. Currently only has mappings for head, paragraph, and note.""" head = xmlmap.NodeField("e:head", xmlmap.XmlObject) "heading - `head`" content = xmlmap.NodeListField( "e:p", xmlmap.XmlObject) # ?? (to allow formatting) "list of paragraphs - `p`" note = xmlmap.NodeField("e:note", Note) ":class:`Note`"
class IndexEntry(_EadBase): "Index entry in an archival description index." ROOT_NAME = 'indexentry' name = xmlmap.NodeField( "e:corpname|e:famname|e:function|e:genreform|e:geogname|e:name|e:namegrp|e:occupation|e:persname|e:title|e:subject", xmlmap.XmlObject) "access element, e.g. name or subject" ptrgroup = xmlmap.NodeField("e:ptrgrp", PointerGroup) ":class:`PointerGroup` - group of references for this index entry"
class MultiBody(_BaseCerp): ROOT_NAME = 'MultiBody' preamble = xmlmap.StringField('xm:Preamble') epilogue = xmlmap.StringField('xm:Epilogue') single_body = xmlmap.NodeField('xm:SingleBody', SingleBody) multi_body = xmlmap.NodeField('xm:MultiBody', 'self') @property def body(self): return self.single_body or self.multi_body
class ProcessInformation(XmlObject): ROOT_NAME = 'ProcessInformation' pid = xmlmap.IntegerField('Pid') image = xmlmap.StringField('ImageName') # Must generate more samples : bytes, string or integer ? cmd_line_signature = xmlmap.StringField('CmdLineSignature') uptime = xmlmap.IntegerField('Uptime') vm = xmlmap.NodeField('ProcessVmInformation', ProcessVmInformation) parent = xmlmap.NodeField('ParentProcess/ProcessInformation', 'self', required=False)
class PublicationStatement(_EadBase): """Publication information for an EAD document. Expected node element passed to constructor: `ead/eadheader/filedesc/publicationstmt`. """ ROOT_NAME = 'publicationstmt' date = xmlmap.NodeField("e:date", DateField) ":class:`DateField` - `date`" publisher = xmlmap.StringField("e:publisher") "publisher - `publisher`" address = xmlmap.NodeField("e:address", Address) "address of publication/publisher - `address`"
class VideoDigitalTech(_BaseDigitalTech): ":class:`~eulxml.xmlmap.XmlObject` for Digital Technical Metadata." ROOT_NAME = 'digitaltech' date_captured = xmlmap.StringField( 'dt:dateCaptured[@encoding="w3cdtf"]', help_text='Date digital capture was made', required=True) 'date digital capture was made (string)' codec_quality = xmlmap.StringField( 'dt:codecQuality', required=False, help_text='Whether the data compression method was lossless or lossy', choices=('lossless', 'compressed')) 'codec quality - lossless or lossy' duration = xmlmap.IntegerField( 'dt:duration/dt:measure[@type="time"][@unit="seconds"][@aspect="duration of playing time"]', help_text='Duration of video playing time', required=True) 'duration of the video file' # FIXME/TODO: note and digitization purpose could be plural note = xmlmap.StringField( 'dt:note[@type="general"]', required=False, help_text= 'Additional information that may be helpful in describing the surrogate' ) 'general note' note_list = xmlmap.StringListField('dt:note[@type="general"]') digitization_purpose = xmlmap.StringField( 'dt:note[@type="purpose of digitization"]', required=False, help_text= 'The reason why the digital surrogate was created (e.g., exhibit, patron request, preservation)' ) 'reason the item was digitized' digitization_purpose_list = xmlmap.StringListField( 'dt:note[@type="purpose of digitization"]') transfer_engineer = xmlmap.NodeField( 'dt:transferEngineer', TransferEngineer, required=False, help_text= 'The person who performed the digitization or conversion that produced the file' ) ':class:`TransferEngineer` - person who digitized the item' codec_creator = xmlmap.NodeField( 'dt:codecCreator[@type="moving image"]', VideoCodecCreator, help_text= 'Hardware, software, and software version used to create the digital file' ) ':class:`VideoCodecCreator` - hardware & software used to digitize the item'
class TestObject(xmlmap.XmlObject): ROOT_NAME = 'foo' id = xmlmap.StringField('@id', verbose_name='My Id', help_text='enter an id') int = xmlmap.IntegerField('bar[2]/baz') bool = xmlmap.SimpleBooleanField('boolean', 'yes', 'no') longtext = xmlmap.StringField('longtext', normalize=True, required=False) date = xmlmap.DateField('date') child = xmlmap.NodeField('bar[1]', TestSubobject, verbose_name='Child bar1') children = xmlmap.NodeListField('bar', TestSubobject) other_child = xmlmap.NodeField('plugh', OtherTestSubobject) my_opt = xmlmap.StringField('opt', choices=['a', 'b', 'c']) text = xmlmap.StringListField('text') numbers = xmlmap.IntegerListField('number')
class SingleBody(_BaseBody): ROOT_NAME = 'SingleBody' body_content = xmlmap.NodeField('xm:BodyContent', BodyContent) ext_body_content = xmlmap.NodeField('xm:ExtBodyContent', ExtBodyContent) child_message = xmlmap.NodeField('xm:ChildMessage', None) # this will be fixed below @property def content(self): return self.body_content or \ self.ext_body_content or \ self.child_message phantom_body = xmlmap.StringField('xm:PhantomBody')
class ReportMetadata(LoaderMixin, XmlObject): ROOT_NAME = 'WERReportMetadata' XSD_SCHEMA = path.join(path.dirname(__file__), 'wer-metadata.xsd') os = xmlmap.NodeField('OSVersionInformation', OSVersionInformation) process = xmlmap.NodeField('ProcessInformation', ProcessInformation) system = xmlmap.NodeField('SystemInformation', SystemInformation) secure_boot = xmlmap.NodeField('SecureBootState', SecureBootState, required=False) parameters = xmlmap.NodeListField( 'ProblemSignatures/*[starts-with(name(), "Parameter")]', MetaParameter) dynamic_parameters = xmlmap.NodeListField( 'DynamicSignatures/*[starts-with(name(), "Parameter")]', MetaParameter) id = xmlmap.StringField('ReportInformation/Guid') created_on = xmlmap.StringField('ReportInformation/CreationTime')
class _BaseExternal(_BaseCerp): '''Common external entity reference elements''' EOL_CHOICES = [ 'CR', 'LF', 'CRLF' ] rel_path = xmlmap.StringField('xm:RelPath') eol = xmlmap.StringField('xm:Eol', choices=EOL_CHOICES) hash = xmlmap.NodeField('xm:Hash', Hash)
class Tei(_TeiBase): """xmlmap object for a TEI (Text Encoding Initiative) XML document """ id = xmlmap.StringField('@xml:id') title = xmlmap.StringField( 'tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title') author = xmlmap.StringField( 'tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:author/tei:name/tei:choice/tei:sic' ) editor = xmlmap.StringField( 'tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:editor/tei:name/tei:choice/tei:sic' ) header = xmlmap.NodeField('tei:teiHeader', TeiHeader) front = xmlmap.NodeField('tei:text/tei:front', TeiSection) body = xmlmap.NodeField('tei:text/tei:body', TeiSection) back = xmlmap.NodeField('tei:text/tei:back', TeiSection)
class ArrangementPremis(premis.Premis): # adapdet from diskimage premis XSD_SCHEMA = premis.PREMIS_SCHEMA object = xmlmap.NodeField('p:object', PremisObject) events = xmlmap.NodeListField('p:event', PremisEvent)
class Facsimile(TeiBase): '''Extension of :class:`eulxml.xmlmap.teimap.TEI` to provide access to TEI facsimile elements''' #: local xsd schema XSD_SCHEMA = 'file://%s' % os.path.join( os.path.abspath(os.path.dirname(__file__)), 'schema', 'TEIPageView.xsd') # NOTE: using absolute path for schema to avoid path issues when # building documentation on readthedocs.org ROOT_NAME = 'TEI' xmlschema = etree.XMLSchema(etree.parse(XSD_SCHEMA)) # NOTE: not using xmlmap.loadSchema because it doesn't correctly load # referenced files in the same directory #: surface with type page, as :class:`Zone` page = xmlmap.NodeField('tei:facsimile/tei:surface[@type="page"]', Zone) #: list of pages (surface with type page) page_list = xmlmap.NodeListField('tei:facsimile/tei:surface[@type="page"]', Zone) # NOTE: tei facsimile could include illustrations, but ignoring those for now #: list of zones with type textLine or line as :class:`Zone` lines = xmlmap.NodeListField( 'tei:facsimile//tei:zone[@type="textLine" or @type="line"]', Zone) #: list of word zones (type string) as :class:`Zone` word_zones = xmlmap.NodeListField( 'tei:facsimile//tei:zone[@type="string"]', Zone) #: publication statment distributor distributor = xmlmap.StringField( 'tei:teiHeader/tei:fileDesc/tei:publicationStmt/tei:distributor') #: publication statmnt as :class:`PublicationStatement` pubstmt = xmlmap.NodeField( 'tei:teiHeader/tei:fileDesc/tei:publicationStmt', PublicationStatement) #: encoding description encoding_desc = xmlmap.NodeField('tei:teiHeader/tei:encodingDesc', xmlmap.XmlObject) #: source description for the original volume original_source = xmlmap.NodeField( 'tei:teiHeader/tei:fileDesc/tei:sourceDesc/tei:bibl[@type="original"]', Bibl) #: source description for the readux digital edition digital_source = xmlmap.NodeField( 'tei:teiHeader/tei:fileDesc/tei:sourceDesc/tei:bibl[@type="digital"]', Bibl)
class FileDescription(_EadBase): """Bibliographic information about this EAD document. Expected node element passed to constructor: `ead/eadheader/filedesc`. """ ROOT_NAME = 'filedesc' publication = xmlmap.NodeField("e:publicationstmt", PublicationStatement) "publication information - `publicationstmt`"
class DiskImagePremis(premis.Premis): XSD_SCHEMA = premis.PREMIS_SCHEMA object = xmlmap.NodeField('p:object', PremisObject) fixity_checks = xmlmap.NodeListField('p:event[p:eventType="fixity check"]', premis.Event) '''list of PREMIS fixity check events (where event type is "fixity check"),
class BaseMods(Common): ''':class:`~eulxml.xmlmap.XmlObject` with common field declarations for all top-level MODS elements; base class for :class:`MODS` and :class:`RelatedItem`.''' schema_validate = True id = xmlmap.StringField("@ID") title = xmlmap.StringField("mods:titleInfo/mods:title") title_info = xmlmap.NodeField('mods:titleInfo', TitleInfo) title_info_list = xmlmap.NodeListField('mods:titleInfo', TitleInfo) resource_type = xmlmap.SchemaField("mods:typeOfResource", "resourceTypeDefinition") name = xmlmap.NodeField('mods:name', Name) # DEPRECATED: use names instead names = xmlmap.NodeListField('mods:name', Name) note = xmlmap.NodeField('mods:note', Note) notes = xmlmap.NodeListField('mods:note', Note) origin_info = xmlmap.NodeField('mods:originInfo', OriginInfo) record_info = xmlmap.NodeField('mods:recordInfo', RecordInfo) identifiers = xmlmap.NodeListField('mods:identifier', Identifier) access_conditions = xmlmap.NodeListField('mods:accessCondition', AccessCondition) genres = xmlmap.NodeListField('mods:genre', Genre) languages = xmlmap.NodeListField('mods:language', Language) location = xmlmap.StringField('mods:location/mods:physicalLocation', required=False) locations = xmlmap.NodeListField('mods:location', Location) subjects = xmlmap.NodeListField('mods:subject', Subject) physical_description = xmlmap.NodeField('mods:physicalDescription', PhysicalDescription) abstract = xmlmap.NodeField('mods:abstract', Abstract) parts = xmlmap.NodeListField('mods:part', Part)
class FoxmlDigitalObject(_FedoraBase): '''Minimal :class:`~eulxml.xmlmap.XmlObject` for Foxml DigitalObject as returned by :meth:`REST_API.getObjectXML`, to provide access to the Fedora audit trail. ''' audit_trail = xmlmap.NodeField( 'foxml:datastream[@ID="AUDIT"]/foxml:datastreamVersion/foxml:xmlContent/audit:auditTrail', AuditTrail) 'Fedora audit trail, as instance of :class:`AuditTrail`'
class AudioMods(LocalMODS): '''Customized MODS for :class:`AudioObject`, based on :class:`~keep.common.fedora.LocalMODS`.''' # possibly map identifier type uri as well ? general_note = xmlmap.NodeField('mods:note[@type="general"]', mods.TypedNote, required=False) ':class:`~eulxml.xmlmap.mods.TypedNote` with `type="general"`' part_note = xmlmap.NodeField('mods:note[@type="part number"]', mods.TypedNote) ':class:`~eulxml.xmlmap.mods.TypedNote` with `type="part number"`' dm1_id = xmlmap.StringField('mods:identifier[@type="dm1_id"]', required=False, verbose_name='Record ID/Filename') dm1_other_id = xmlmap.StringField('mods:identifier[@type="dm1_other"]', required=False, verbose_name='Other ID')
class Subject(Common): ROOT_NAME = 'subject' authority = xmlmap.StringField('@authority') id = xmlmap.StringField('@ID') # and one of the following: geographic = xmlmap.StringField('mods:geographic') name = xmlmap.NodeField('mods:name', Name) topic = xmlmap.StringField('mods:topic') title = xmlmap.StringField('mods:titleInfo/mods:title')
class QueryTestModel(xmlmap.XmlObject): ROOT_NAMESPACES = {'ex': 'http://example.com/'} id = xmlmap.StringField('@id') name = xmlmap.StringField('name') description = xmlmap.StringField('description') wnn = xmlmap.IntegerField('wacky_node_name') sub = xmlmap.NodeField("sub", QuerySubModel) or_field = xmlmap.StringField('name|description|@id') substring = xmlmap.StringField('substring(name, 1, 1)') nsfield = xmlmap.StringField('ex:field') years = xmlmap.StringListField('year')
class Series(XmlModel, eadmap.Component): """ Top-level (c01) series. Customized version of :class:`eulcore.xmlmap.eadmap.Component` """ ROOT_NAMESPACES = { 'e': eadmap.EAD_NAMESPACE, 'exist': 'http://exist.sourceforge.net/NS/exist' } eadid = xmlmap.NodeField('ancestor::e:ead/e:eadheader/e:eadid', eadmap.EadId) objects = Manager('//e:c01[@level="series"]') """:class:`eulcore.django.existdb.manager.Manager` - similar to an object manager for django db objects, used for finding and retrieving series objects in eXist. Configured to use *//c01[@level='series']* as base search path. """ subseries = xmlmap.NodeListField('child::e:c02[@level="subseries"]', SubSeries) _short_id = None @property def short_id(self): "Short-form id (without eadid prefix) for use in external urls." if self._short_id is None: # get eadid, if available if hasattr(self, 'eadid') and self.eadid.value: eadid = self.eadid.value else: eadid = None self._short_id = shortform_id(self.id, eadid) return self._short_id _title = None @property def title(self): "Title of series without the date." if self._title is None: if hasattr(self, 'did') and hasattr(self.did, 'unittitle'): self._title = unicode(self.did.unittitle) comma_pos = self._title.rfind(", ") if (comma_pos != -1): self._title = self._title[:comma_pos] else: self._title = None return self._title
class Index(Section): """Index (index element); list of key terms and reference information. Expected node element passed to constructor: `ead/archdesc/index`. """ ROOT_NAME = 'index' entry = xmlmap.NodeListField("e:indexentry", IndexEntry) "list of :class:`IndexEntry` - `indexentry`; entry in the index" id = xmlmap.StringField("@id") note = xmlmap.NodeField("e:note", Note) ":class:`Note`"
class ProfileDescription(_EadBase): """Profile Descriptor for an EAD document. Expected node element passed to constructor: 'ead/eadheader/profiledesc'. """ ROOT_NAME = 'profiledesc' date = xmlmap.NodeField("e:creation/e:date", DateField) ":class:`DateField` - `creation/date`" languages = xmlmap.StringListField("e:langusage/e:language") "language information - `langusage/language`" language_codes = xmlmap.StringListField("e:langusage/e:language/@langcode") "language codes - `langusage/language/@langcode`"
class Report(LoaderMixin, XmlObject): """ Windows Error Report """ ROOT_NAME = 'WERREPORT' XSD_SCHEMA = path.join(path.dirname(__file__), 'ms-cer2.xsd') machine = xmlmap.NodeField('MACHINEINFO', MachineInfo) """ Machine informations :type :class:`wer.schema.MachineInfo` """ user = xmlmap.StringField('USERINFO/@username') """ User informations :type :class:`wer.schema.UserInfo` """ application = xmlmap.NodeField('APPLICATIONINFO', ApplicationInfo, required=False) """ Application informations :type :class:`wer.schema.ApplicationInfo` """ event = xmlmap.NodeField('EVENTINFO', EventInfo) """ Event informations :type :class:`wer.schema.EventInfo` """ parameters = xmlmap.NodeListField('SIGNATURE/PARAMETER', Parameter) """ Event parameters :type list of :class:`wer.schema.Parameter` """ secondary_parameters = xmlmap.NodeListField('SIGNATURE/SECONDARYPARAMETER', SecondaryParameter) """ Event secondary parameters :type list of :class:`wer.schema.SecondaryParameter` """ files = xmlmap.NodeListField('FILES/FILE', File) """ Event attached files :type list of :class:`wer.schema.File` """ @property def id(self): """ Computes the signature of the record, a SHA-512 of significant values :return: SHa-512 Hex string """ h = hashlib.new('sha512') for value in (self.machine.name, self.machine.os, self.user, self.application.name, self.application.path, self.event.report_type, self.event.type, self.event.time.isoformat()): h.update(str(value).encode('utf-8')) for parameter in sorted(self.parameters, key=lambda k: getattr(k, 'id')): h.update(parameter.value.encode('utf-8')) return h.hexdigest()
class Part(Common): ROOT_NAME = 'part' type = xmlmap.StringField('@type') details = xmlmap.NodeListField('mods:detail', PartDetail) extent = xmlmap.NodeField('mods:extent', PartExtent) def is_empty(self): '''Returns True if details, extent, and type are not set or return True for ``is_empty``; returns False if any of the fields are not empty.''' return all(field.is_empty() for field in [self.details, self.extent] if field is not None) \ and not self.type
class RepositoryDescription(_FedoraBase): """:class:`~eulxml.xmlmap.XmlObject` for a repository description as returned by :meth:`API_A_LITE.describeRepository` """ # default namespace is fedora access name = xmlmap.StringField('a:repositoryName') "repository name" base_url = xmlmap.StringField('a:repositoryBaseURL') "base url" version = xmlmap.StringField('a:repositoryVersion') "version of Fedora being run" pid_info = xmlmap.NodeField('a:repositoryPID', RepositoryDescriptionPid) ":class:`RepositoryDescriptionPid` - configuration info for pids" oai_info = xmlmap.NodeField('a:repositoryPID', RepositoryDescriptionOAI) ":class:`RepositoryDescriptionOAI` - configuration info for OAI" search_url = xmlmap.StringField('a:sampleSearch-URL') "sample search url" access_url = xmlmap.StringField('a:sampleAccess-URL') "sample access url" oai_url = xmlmap.StringField('a:sampleOAI-URL') "sample OAI url" admin_email = xmlmap.StringListField("a:adminEmail") "administrator emails"
class PremisObject(premis.Object): composition_level = xmlmap.IntegerField( 'p:objectCharacteristics/p:compositionLevel') checksums = xmlmap.NodeListField('p:objectCharacteristics/p:fixity', PremisFixity) format = xmlmap.NodeField('p:objectCharacteristics/p:format', PremisObjectFormat) latest_format = xmlmap.NodeField( 'p:objectCharacteristics[position() = last()]/p:format', PremisObjectFormat) creating_application = xmlmap.NodeField( 'p:objectCharacteristics/p:creatingApplication', PremisCreatingApplication) original_environment = xmlmap.NodeField( 'p:environment[p:environmentNote="Original environment"]', PremisEnvironment) characteristics = xmlmap.NodeListField('p:objectCharacteristics', PremisObjectCharacteristics) relationships = xmlmap.NodeListField('p:relationship', PremisRelationship)