Skip to content

Commit b14c9a5

Browse files
add support for schema.org (#263)
* implement schema.org support (#231) * implement schema.org support (#231) * fix tests * refactor datetime generation * fix schema autodetect * fix export to schema-org (#266) * fix export to schem-org * Update __init__.py * Update __init__.py * Update __init__.py --------- Co-authored-by: Tom Kralidis <tomkralidis@gmail.com> * fix ref * fix tests * fix import/parsing * update * fix refs --------- Co-authored-by: Paul van Genuchten <genuchten@yahoo.com>
1 parent 3c8c37e commit b14c9a5

File tree

6 files changed

+628
-60
lines changed

6 files changed

+628
-60
lines changed

pygeometa/core.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ def import_metadata(schema: str, metadata: str) -> dict:
339339
:returns: MCF object
340340
"""
341341

342+
content = None
343+
error_message = None
344+
342345
if schema == 'autodetect':
343346
schemas = get_supported_schemas()
344347
else:
@@ -349,11 +352,17 @@ def import_metadata(schema: str, metadata: str) -> dict:
349352
schema_object = load_schema(s)
350353

351354
try:
352-
return schema_object.import_(metadata)
355+
content = schema_object.import_(metadata)
356+
break
353357
except NotImplementedError:
354-
raise RuntimeError(f'Import not supported for {s}')
358+
error_message = f'Import not supported for {s}'
355359
except Exception as err:
356-
raise RuntimeError(f'Import failed: {err}')
360+
error_message = f'Import failed: {err}'
361+
362+
if error_message is not None:
363+
LOGGER.warning(error_message)
364+
365+
return content
357366

358367

359368
def transform_metadata(input_schema: str, output_schema: str,
@@ -535,7 +544,7 @@ class MCFValidationError(Exception):
535544
@cli_options.ARGUMENT_METADATA_FILE
536545
@cli_options.OPTION_OUTPUT
537546
@cli_options.OPTION_VERBOSITY
538-
@click.option('--schema', required=True,
547+
@click.option('-s', '--schema', required=True,
539548
type=click.Choice(get_supported_schemas(include_autodetect=True)), # noqa
540549
default='autodetect',
541550
help='Metadata schema')

pygeometa/helpers.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,48 @@ def json_serial(obj) -> Any:
9393
msg = f'{obj} type {type(obj)} not serializable'
9494
LOGGER.error(msg)
9595
raise TypeError(msg)
96+
97+
98+
def generate_datetime(date_value: str) -> str:
99+
"""
100+
Helper function to derive RFC3339 date from MCF date type
101+
102+
:param date_value: `str` of date value
103+
104+
:returns: `str` of date-time value
105+
"""
106+
107+
value = None
108+
109+
if isinstance(date_value, str) and date_value != 'None':
110+
if len(date_value) == 10: # YYYY-MM-DD
111+
format_ = '%Y-%m-%d'
112+
elif len(date_value) == 7: # YYYY-MM
113+
format_ = '%Y-%m'
114+
elif len(date_value) == 4: # YYYY
115+
format_ = '%Y'
116+
elif len(date_value) == 19: # YYYY-MM-DDTHH:MM:SS
117+
msg = 'YYYY-MM-DDTHH:MM:SS with no timezone; converting to UTC'
118+
LOGGER.debug(msg)
119+
format_ = '%Y-%m-%dT%H:%M:%S'
120+
121+
LOGGER.debug('date type found; expanding to date-time')
122+
value = datetime.strptime(date_value, format_).strftime('%Y-%m-%dT%H:%M:%SZ') # noqa
123+
124+
elif isinstance(date_value, int) and len(str(date_value)) == 4:
125+
date_value2 = str(date_value)
126+
LOGGER.debug('date type found; expanding to date-time')
127+
format_ = '%Y'
128+
value = datetime.strptime(date_value2, format_).strftime('%Y-%m-%dT%H:%M:%SZ') # noqa
129+
130+
elif isinstance(date_value, (date, datetime)):
131+
value = date_value.strftime('%Y-%m-%dT%H:%M:%SZ')
132+
133+
elif date_value in [None, 'None']:
134+
value = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
135+
136+
else:
137+
msg = f'Unknown date string: {date_value}'
138+
raise RuntimeError(msg)
139+
140+
return value

pygeometa/schemas/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@
5353
THISDIR = os.path.dirname(os.path.realpath(__file__))
5454

5555
SCHEMAS = {
56+
'dcat': 'pygeometa.schemas.dcat.DCATOutputSchema',
5657
'iso19139': 'pygeometa.schemas.iso19139.ISO19139OutputSchema',
5758
'iso19139-2': 'pygeometa.schemas.iso19139_2.ISO19139_2OutputSchema',
5859
'iso19139-hnap': 'pygeometa.schemas.iso19139_hnap.ISO19139HNAPOutputSchema', # noqa
5960
'oarec-record': 'pygeometa.schemas.ogcapi_records.OGCAPIRecordOutputSchema', # noqa
61+
'schema-org': 'pygeometa.schemas.schema_org.SchemaOrgOutputSchema',
6062
'stac-item': 'pygeometa.schemas.stac.STACItemOutputSchema',
61-
'dcat': 'pygeometa.schemas.dcat.DCATOutputSchema',
6263
'wmo-cmp': 'pygeometa.schemas.wmo_cmp.WMOCMPOutputSchema',
6364
'wmo-wcmp2': 'pygeometa.schemas.wmo_wcmp2.WMOWCMP2OutputSchema',
6465
'wmo-wigos': 'pygeometa.schemas.wmo_wigos.WMOWIGOSOutputSchema',

pygeometa/schemas/ogcapi_records/__init__.py

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@
4343
#
4444
# =================================================================
4545

46-
from datetime import date, datetime
4746
import logging
4847
import os
4948
from typing import Union
5049

5150
from pygeometa import __version__
5251
from pygeometa.core import get_charstring
53-
from pygeometa.helpers import json_dumps
52+
from pygeometa.helpers import generate_datetime, json_dumps
5453
from pygeometa.schemas.base import BaseOutputSchema
5554

5655
THISDIR = os.path.dirname(os.path.realpath(__file__))
@@ -165,12 +164,11 @@ def write(self, mcf: dict, stringify: str = True) -> Union[dict, str]:
165164

166165
LOGGER.debug('Checking for dates')
167166

168-
if 'dates' in mcf['identification']:
169-
if 'creation' in mcf['identification']['dates']:
170-
record['properties']['created'] = self.generate_date(mcf['identification']['dates']['creation']) # noqa
171-
172-
if 'revision' in mcf['identification']['dates']:
173-
record['properties']['updated'] = self.generate_date(mcf['identification']['dates']['revision']) # noqa
167+
for key, value in mcf['identification']['dates'].items():
168+
if key == 'creation':
169+
record['properties']['created'] = generate_datetime(value)
170+
elif key == 'revision':
171+
record['properties']['updated'] = generate_datetime(value)
174172

175173
rights = get_charstring(mcf['identification'].get('rights'),
176174
self.lang1, self.lang2)
@@ -426,47 +424,3 @@ def generate_link(self, distribution: dict) -> dict:
426424
link['channel'] = distribution['channel']
427425

428426
return link
429-
430-
def generate_date(self, date_value: str) -> str:
431-
"""
432-
Helper function to derive RFC3339 date from MCF date type
433-
434-
:param date_value: `str` of date value
435-
436-
:returns: `str` of date-time value
437-
"""
438-
439-
value = None
440-
441-
if isinstance(date_value, str) and date_value != 'None':
442-
if len(date_value) == 10: # YYYY-MM-DD
443-
format_ = '%Y-%m-%d'
444-
elif len(date_value) == 7: # YYYY-MM
445-
format_ = '%Y-%m'
446-
elif len(date_value) == 4: # YYYY
447-
format_ = '%Y'
448-
elif len(date_value) == 19: # YYYY-MM-DDTHH:MM:SS
449-
msg = 'YYYY-MM-DDTHH:MM:SS with no timezone; converting to UTC'
450-
LOGGER.debug(msg)
451-
format_ = '%Y-%m-%dT%H:%M:%S'
452-
453-
LOGGER.debug('date type found; expanding to date-time')
454-
value = datetime.strptime(date_value, format_).strftime('%Y-%m-%dT%H:%M:%SZ') # noqa
455-
456-
elif isinstance(date_value, int) and len(str(date_value)) == 4:
457-
date_value2 = str(date_value)
458-
LOGGER.debug('date type found; expanding to date-time')
459-
format_ = '%Y'
460-
value = datetime.strptime(date_value2, format_).strftime('%Y-%m-%dT%H:%M:%SZ') # noqa
461-
462-
elif isinstance(date_value, (date, datetime)):
463-
value = date_value.strftime('%Y-%m-%dT%H:%M:%SZ')
464-
465-
elif date_value in [None, 'None']:
466-
value = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
467-
468-
else:
469-
msg = f'Unknown date string: {date_value}'
470-
raise RuntimeError(msg)
471-
472-
return value

0 commit comments

Comments
 (0)