Newer
Older
Wernle, Alexandra Nicole
committed
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 7 11:05:19 2022
@author: awernle
"""
import json
Wernle, Alexandra Nicole
committed
from datetime import date, datetime, time, timedelta
from typing import List, Optional
from pathlib import Path
Wernle, Alexandra Nicole
committed
import typer
Wernle, Alexandra Nicole
committed
from enum import Enum
Wernle, Alexandra Nicole
committed
from obspy import UTCDateTime
Wernle, Alexandra Nicole
committed
from ..metadata import Metadata, MetadataFactory, MetadataCategory
from ..residual import Reading, WebAbsolutesFactory, SpreadsheetAbsolutesFactory
Wernle, Alexandra Nicole
committed
TODAY = datetime.combine(date.today(), time(0, 0, 0))
class ResidualFactory(str, Enum):
SPREADSHEET = "spreadsheet"
WEB_ABSOLUTES = "webabsolutes"
Wernle, Alexandra Nicole
committed
Wernle, Alexandra Nicole
committed
def copy_absolutes(
observatory: str = typer.Option(..., help="Observatory code"),
starttime: datetime = typer.Option(
default=TODAY - timedelta(days=1), help="Search start time, default "
),
endtime: datetime = typer.Option(default=TODAY),
metadata_token: str = typer.Option(
default=os.getenv("GITLAB_API_TOKEN"),
help="Token for metadata web service.",
metavar="TOKEN",
show_default="environment variable GITLAB_API_TOKEN",
),
metadata_url: str = typer.Option(
Wernle, Alexandra Nicole
committed
default="https://geomag.usgs.gov/ws/secure",
Wernle, Alexandra Nicole
committed
help="URL to metadata web service",
metavar="URL",
),
web_absolutes_url: str = typer.Option(
default="https://geomag.usgs.gov/baselines/observation.json.php",
help="URL to web absolutes service",
metavar="URL",
),
directory: Optional[Path] = typer.Option(
None,
exists=True,
file_okay=False,
dir_okay=True,
writable=False,
readable=False,
resolve_path=True,
help="Residual spreadsheet directory",
Wernle, Alexandra Nicole
committed
),
factory: ResidualFactory = ResidualFactory.WEB_ABSOLUTES,
force: bool = typer.Option(
default=False,
help="Force skip the check to copy absolutes",
),
Wernle, Alexandra Nicole
committed
):
Wernle, Alexandra Nicole
committed
"""Copy absolutes from the web absolutes service OR residual spreadsheets into the metadata service."""
if factory.value == ResidualFactory.WEB_ABSOLUTES:
Wernle, Alexandra Nicole
committed
factory = WebAbsolutesFactory(url=web_absolutes_url)
else:
factory = SpreadsheetAbsolutesFactory(base_directory=directory)
Wernle, Alexandra Nicole
committed
Wernle, Alexandra Nicole
committed
readings = get_readings(
Wernle, Alexandra Nicole
committed
factory=factory,
Wernle, Alexandra Nicole
committed
observatory=observatory,
starttime=UTCDateTime(starttime),
endtime=UTCDateTime(endtime),
)
# confirm whether or not to copy absolutes
if not force:
typer.confirm(
f"Are you sure you want to copy {len(readings)} absolutes?", abort=True
)
print("Copying over absolutes")
Wernle, Alexandra Nicole
committed
# write readings to metadata service
metadata_factory = MetadataFactory(token=metadata_token, url=metadata_url)
with typer.progressbar(
iterable=readings, label="Uploading to metadata service"
) as progressbar:
for reading in progressbar:
upload_reading(factory=metadata_factory, reading=reading)
def create_reading_metadata(reading: Reading) -> Metadata:
"""Create reading metadata object.
Parameters
----------
reading:
reading to convert to metadata.
Returns
-------
metadata object for reading
"""
measurement_times = [m.time for m in reading.measurements if m.time]
Wernle, Alexandra Nicole
committed
metadata = Metadata(
category=MetadataCategory.READING,
created_by=reading.metadata.get("observer", "copy_absolutes"),
endtime=max(measurement_times),
metadata=json.loads(reading.json()),
Wernle, Alexandra Nicole
committed
network="NT",
Wernle, Alexandra Nicole
committed
station=reading.metadata["station"],
status="reviewed" if reading.metadata.get("reviewed") else "new",
updated_by=reading.metadata.get("reviewer"),
Wernle, Alexandra Nicole
committed
)
return metadata
Wernle, Alexandra Nicole
committed
Wernle, Alexandra Nicole
committed
def get_readings(
factory: ResidualFactory,
observatory: str,
starttime: UTCDateTime,
endtime: UTCDateTime,
Wernle, Alexandra Nicole
committed
) -> List[Reading]:
Wernle, Alexandra Nicole
committed
"""Get readings from web absolutes or residual spreadsheets.
Wernle, Alexandra Nicole
committed
Parameters
----------
factory
Wernle, Alexandra Nicole
committed
configured WebAbsolutesFactory or SpreadsheetAbsolutesFactory
Wernle, Alexandra Nicole
committed
observatory
search observatory
starttime
search start time
endtime
search end time
Returns
-------
list of found readings
"""
readings = factory.get_readings(
observatory=observatory,
starttime=UTCDateTime(starttime),
endtime=UTCDateTime(endtime),
include_measurements=True,
)
return readings
Wernle, Alexandra Nicole
committed
def main() -> None:
"""Entrypoint for copy absolutes method."""
# for one command, can use typer.run
typer.run(copy_absolutes)
Wernle, Alexandra Nicole
committed
def upload_reading(factory: MetadataFactory, reading: Reading) -> Metadata:
"""Upload reading to metadata service
Parameters
----------
factory
factory configured for metadata service
reading
reading to upload
Returns
-------
created metadata object
"""
metadata = create_reading_metadata(reading=reading)
# TODO: should this check if metadata was already uploaded?
# TODO: should that check occur before calling this method?
Wernle, Alexandra Nicole
committed
return factory.create_metadata(metadata=metadata)
Wernle, Alexandra Nicole
committed
if __name__ == "__main__":
main()