diff --git a/arcpy_metadata/elements.py b/arcpy_metadata/elements.py index 4db67f2..d00db7b 100644 --- a/arcpy_metadata/elements.py +++ b/arcpy_metadata/elements.py @@ -227,7 +227,7 @@ "last_update": { "path": "dataIdInfo/idCitation/date/reviseDate", - "type": "date"}, + "type": "datetime"}, "license": { "path": "dataIdInfo/resConst/LegConsts/useLimit", @@ -259,6 +259,38 @@ ("french", "fre")] }, + "meta_style": { + "path": "Esri/ArcGISstyle", + "type": "string"}, + + "meta_create_date": { + "path": "Esri/CreaDate", + "type": "date"}, + + "meta_create_time": { + "path": "Esri/CreaTime", + "type": "time"}, + + "meta_modification_date": { + "path": "Esri/ModDate", + "type": "date"}, + + "meta_modification_time": { + "path": "Esri/ModTime", + "type": "time"}, + + "meta_format": { + "path": "Esri/ArcGISFormat", + "type": "string"}, + + "meta_profile": { + "path": "Esri/ArcGISProfile", + "type": "string"}, + + "meta_publish_status": { + "path": "Esri/PublishStatus", + "type": "string"}, + "min_scale": { "path": "Esri/scaleRange/minScale", "type": "integer"}, @@ -316,15 +348,15 @@ "temporal_extent_end": { "path": "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Period/tmEnd", - "type": "date"}, + "type": "datetime"}, "temporal_extent_instance": { "path": "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Instant/tmPosition", - "type": "date"}, + "type": "datetime"}, "temporal_extent_start": { "path": "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Period/tmBegin", - "type": "date"}, + "type": "datetime"}, "update_frequency": { "path": "dataIdInfo/resMaint/maintFreq/MaintFreqCd", @@ -340,7 +372,4 @@ "path": "dataIdInfo/resMaint/usrDefFreq/duration", "type": "string"} -} - - - +} \ No newline at end of file diff --git a/arcpy_metadata/metadata_editor.py b/arcpy_metadata/metadata_editor.py index 417ff82..e1e94fe 100644 --- a/arcpy_metadata/metadata_editor.py +++ b/arcpy_metadata/metadata_editor.py @@ -6,6 +6,8 @@ import traceback import logging from datetime import datetime +from datetime import date +from datetime import time from arcpy_metadata.metadata_constructors import MetadataItem from arcpy_metadata.metadata_constructors import MetadataValueList @@ -156,7 +158,7 @@ def __init__(self, dataset=None, metadata_file=None, items=None, setattr(self, "_{0!s}".format(name), None) - if elements[name]['type'] in ["string", "date", "integer", "float"]: + if elements[name]['type'] in ["string", "datetime", "date", "time", "integer", "float"]: setattr(self, "_{0}".format(name), MetadataItem(elements[name]['path'], name, self, sync)) if self.__dict__["_{0}".format(name)].value is not None: setattr(self, name, self.__dict__["_{0}".format(name)].value.strip()) @@ -232,16 +234,26 @@ def __setattr__(self, n, v): else: raise RuntimeWarning("Input value must be of type String") - elif elements[n]['type'] == "date": + elif elements[n]['type'] == "datetime": + if isinstance(v, datetime): self.__dict__["_{0}".format(n)].value = datetime.strftime(v, "%Y-%m-%dT%H:%M:%S") elif isinstance(v, (str, six.text_type)): + + # remove all whitespaces for easier handling + v = "".join(v.split()) + try: if len(v) == 8: # try first to convert to datetime to check if format is correct # then write string to file new_value = datetime.strptime(v, "%Y%m%d") self.__dict__["_{0}".format(n)].value = new_value.isoformat() + elif len(v) == 10: + # try first to convert to datetime to check if format is correct + # then write string to file + new_value = datetime.strptime(v, "%Y-%m-%d") + self.__dict__["_{0}".format(n)].value = new_value.isoformat() else: # try first to convert to datetime to check if format is correct @@ -250,12 +262,77 @@ def __setattr__(self, n, v): self.__dict__["_{0}".format(n)].value = new_value.isoformat() except ValueError: - RuntimeWarning("Input value must be of type a Datetime or a String ('%Y%m%d' or '%Y-%m-%dT%H:%M:%S')") + RuntimeWarning( + "Input value must be of type a Datetime or a String ('%Y%m%d', '%Y-%m-%d' or '%Y-%m-%dT%H:%M:%S')") + elif v is None: + self.__dict__["_{0}".format(n)].value = "" + else: + raise RuntimeWarning("Input value must be of type a Date or a String ('yyyymmdd')") + + elif elements[n]['type'] == "date": + if isinstance(v, date): + self.__dict__["_{0}".format(n)].value = datetime.strftime(v, "%Y-%m-%d") + elif isinstance(v, (str, six.text_type)): + + # remove all whitespaces for easier handling + v = "".join(v.split()) + + try: + if len(v) == 8: + # try first to convert to datetime to check if format is correct + # then write string to file + new_value = datetime.strptime(v, "%Y%m%d") + self.__dict__["_{0}".format(n)].value = new_value.date().isoformat() + elif len(v) == 10: + # try first to convert to datetime to check if format is correct + # then write string to file + new_value = datetime.strptime(v, "%Y-%m-%d") + self.__dict__["_{0}".format(n)].value = new_value.date().isoformat() + + else: + # try first to convert to datetime to check if format is correct + # then write string to fil + new_value = datetime.date().strptime(v, "%Y-%m-%d") + self.__dict__["_{0}".format(n)].value = new_value.date().isoformat() + + except ValueError: + RuntimeWarning("Input value must be of type a Datetime.date or a String ('%Y%m%d' or '%Y-%m-%d'") elif v is None: self.__dict__["_{0}".format(n)].value = "" else: raise RuntimeWarning("Input value must be of type a Date or a String ('yyyymmdd')") + elif elements[n]['type'] == "time": + if isinstance(v, time): + self.__dict__["_{0}".format(n)].value = datetime.strftime(v, "%H:%M:%S") + elif isinstance(v, (str, six.text_type)): + + # remove all whitespaces for easier handling + v = "".join(v.split()) + + try: + if len(v) == 8 and v.find(":") == -1: + new_value = datetime.strptime(v, "%H%M%S%f") + self.__dict__["_{0}".format(n)].value = new_value.time().isoformat() + elif len(v) <= 8: + # try first to convert to datetime to check if format is correct + # then write string to file + new_value = datetime.strptime(v, "%H:%M:%S") + self.__dict__["_{0}".format(n)].value = new_value.time().isoformat() + else: + # try first to convert to datetime to check if format is correct + # then write string to file + new_value = datetime.strptime(v, "%I:%M:%S%p") + self.__dict__["_{0}".format(n)].value = new_value.time().isoformat() + + except ValueError: + RuntimeWarning( + "Input value must be of type a Datetime.time or a String ('%H:%M:%S' or '%I:%M:%S%p')") + elif v is None: + self.__dict__["_{0}".format(n)].value = "" + else: + raise RuntimeWarning("Input value must be of type a tatetime.time or a String ('HH:MM:SS')") + elif elements[n]['type'] == "integer": if isinstance(v, int): self.__dict__["_{0}".format(n)].value = str(v) @@ -348,17 +425,33 @@ def __getattr__(self, n): if "deprecated" in elements[n].keys(): warnings.warn("Call to deprecated property {0}. {1}".format(n, elements[n]["deprecated"]), category=DeprecationWarning) - if self.__dict__["_{0}".format(n)].value == "" and elements[n]['type'] in ["integer", "float", "date"]: + if self.__dict__["_{0}".format(n)].value == "" and elements[n]['type'] in ["integer", "float", "datetime", "date", "time"]: return None elif elements[n]['type'] == "integer": return int(self.__dict__["_{0}".format(n)].value) elif elements[n]['type'] == "float": return float(self.__dict__["_{0}".format(n)].value) - elif elements[n]['type'] == "date": + + elif elements[n]['type'] == "datetime": if len(self.__dict__["_{0}".format(n)].value) == 8: return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%Y%m%d") + elif len(self.__dict__["_{0}".format(n)].value) == 10: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%Y-%m-%d") else: return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%Y-%m-%dT%H:%M:%S") + elif elements[n]['type'] == "date": + if len(self.__dict__["_{0}".format(n)].value) == 8: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%Y%m%d").date() + else: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%Y-%m-%d").date() + elif elements[n]['type'] == "time": + if len(self.__dict__["_{0}".format(n)].value) == 8 and self.__dict__["_{0}".format(n)].value.find(":") == -1: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%H%M%S%f").time() + elif len(self.__dict__["_{0}".format(n)].value) <= 8: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%H:%M:%S").time() + else: + return datetime.strptime(self.__dict__["_{0}".format(n)].value, "%I:%M:%S%p") + elif elements[n]['type'] == "parent_item": return self.__dict__["_{0}".format(n)] elif elements[n]['type'] == "language": @@ -457,6 +550,18 @@ def save(self, Enable_automatic_updates=False): """ self.logger.info("Saving metadata") + # Write meta-metadata + self.meta_style = "ISO 19139 Metadata Implementation Specification" + if not self.meta_create_date: + self.meta_create_date = datetime.now().date().isoformat() + if not self.meta_create_time: + self.meta_create_time = datetime.now().time().isoformat() + self.meta_modification_date = datetime.now().date().isoformat() + self.meta_modification_time = datetime.now().time().isoformat() + self.meta_format = "1.0" + self.meta_profile = "ISO19139" + self.meta_publish_status = "editor:arcpy_metadata" + for item in self.items: # TODO: What's going on here? try: self.logger.debug(item.value) @@ -481,7 +586,7 @@ def cleanup(self): :return: """ try: - log.debug("cleaning up from metadata operation") + self.logger.debug("cleaning up from metadata operation") if self._workspace_type != 'FileSystem': if os.path.exists(self.metadata_file): os.remove(self.metadata_file) diff --git a/arcpy_metadata/version.py b/arcpy_metadata/version.py index bbf41b5..adb333c 100644 --- a/arcpy_metadata/version.py +++ b/arcpy_metadata/version.py @@ -1,2 +1,2 @@ -__version__ = '0.5.1' +__version__ = '0.5.2' __author__ = 'nickrsan, thomas.maschler'