Skip to content
Snippets Groups Projects
copy_absolutes.py 5.06 KiB
Newer Older
# -*- coding: utf-8 -*-
"""
Created on Thu Jul  7 11:05:19 2022

@author: awernle
"""
import json
Jeremy M Fee's avatar
Jeremy M Fee committed
import os
from datetime import date, datetime, time, timedelta
from typing import List, Optional
from pathlib import Path
from ..metadata import Metadata, MetadataFactory, MetadataCategory
from ..residual import Reading, WebAbsolutesFactory, SpreadsheetAbsolutesFactory
class ResidualFactory(str, Enum):
    SPREADSHEET = "spreadsheet"
    WEB_ABSOLUTES = "webabsolutes"
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(
        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",
    factory: ResidualFactory = ResidualFactory.WEB_ABSOLUTES,
    force: bool = typer.Option(
        default=False,
        help="Force skip the check to copy absolutes",
    ),
    """Copy absolutes from the web absolutes service OR residual spreadsheets into the metadata service."""
    if factory.value == ResidualFactory.WEB_ABSOLUTES:
        factory = WebAbsolutesFactory(url=web_absolutes_url)
    else:
        factory = SpreadsheetAbsolutesFactory(base_directory=directory)
        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")
    # 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
    """
Jeremy M Fee's avatar
Jeremy M Fee committed
    measurement_times = [m.time for m in reading.measurements if m.time]
    metadata = Metadata(
        category=MetadataCategory.READING,
        created_by=reading.metadata.get("observer", "copy_absolutes"),
Jeremy M Fee's avatar
Jeremy M Fee committed
        endtime=max(measurement_times),
        metadata=json.loads(reading.json()),
Jeremy M Fee's avatar
Jeremy M Fee committed
        starttime=min(measurement_times),
Jeremy M Fee's avatar
Jeremy M Fee committed
        status="reviewed" if reading.metadata.get("reviewed") else "new",
        updated_by=reading.metadata.get("reviewer"),
    factory: ResidualFactory,
    observatory: str,
    starttime: UTCDateTime,
    endtime: UTCDateTime,
    """Get readings from web absolutes or residual spreadsheets.
        configured WebAbsolutesFactory or SpreadsheetAbsolutesFactory
    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


def main() -> None:
    """Entrypoint for copy absolutes method."""
    # for one command, can use typer.run
    typer.run(copy_absolutes)


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?