<commit_before>"""Auxilary functions for the API controllers."""


def set_timestamp():
    """Format POSIX UTC time for metadata."""
    from time import gmtime

    t = gmtime()
    return '{0:4d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d} UTC'.format(
        t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)


def set_db_special(db):
    """Add custom payload additions unique to a specific db."""
    if db == 'pbdb':
        return {'show': 'full'}
    # Add another database specific case here
    else:
        return {}


def set_taxon(taxon, subtax, db):
    """
    Return a database specific key-val pair for taxon paramaterization.

    :arg db: database name
    :type db: str
    :arg taxon: user input taxon name
    :type taxon: str
    :arg subtax: include lower taxonomy switch
    :type subtax: bool

    """
    taxon = taxon.capitalize()

    if len(taxon.split()) == 2:
        genus_species = True
    elif len(taxon.split()) == 1:
        genus_species = False
    else:
        msg = 'Taxon argument contains too many parameters'
        raise ValueError(400, msg)

    if db == 'neotoma':
        if subtax and not genus_species:
            wildcard = '{0:s}%'.format(taxon)
            return {'taxonname': wildcard}
        else:
            return {'taxonname': taxon}
    elif db == 'pbdb':
        if subtax and not genus_species:
            return {'base_name': taxon}
        else:
            return {'taxon_name': taxon}
    # Add another databse specific case here
    else:
        return {}


def set_age(age_range, options, db):
    """Return key-val ages for identified database subquery payload."""
    from ..elc import aux

    try:
        early_age, late_age = aux.get_age(age_range=age_range,
                                          options=options)
    except ValueError as err:
        raise ValueError(err.args[0], err.args[1])

    factor = aux.set_age_scaler(options, db)

    if db == 'neotoma':
        return {'ageyounger': early_age * factor,
                'ageolder': late_age * factor}
    elif db == 'pbdb':
        return {'max_ma': early_age * factor,
                'min_ma': late_age * factor}
    # Add another databse specific case here
    else:
        return {}


def get_age(age_range, options):
    """
    Parse age range parameters.

    :arg age_range: one or two comma separated numerical or text geoage bounds
    :type age_range: str
    :arg age_units: dimension of age parameter
    :type age_units: str ['yr', 'ka' or 'ma']

    """
    from ..elc import aux

    bound = age_range.split(',')
    if '' in bound:
        msg = 'Incorrectly formatted parameter pair: agerange'
        raise ValueError(400, msg)

    factor = aux.set_age_scaler(options, 'pbdb')

    if len(bound) == 1:

        if bound[0].isalpha():
            ea1, la1 = [x / factor for x in aux.resolve_age(bound[0])]
        elif float(bound[0]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            msg = 'Incorrect number of parameters: agerange'
            raise ValueError(400, msg)

        return round(ea1, 2), round(la1, 2)

    if len(bound) == 2:

        if bound[0].isalpha():
            ea1, la1 = [x / factor for x in aux.resolve_age(bound[0])]
        elif float(bound[0]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            ea1 = la1 = float(bound[0])

        if bound[1].isalpha():
            ea2, la2 = [x / factor for x in aux.resolve_age(bound[1])]
        elif float(bound[1]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            ea2 = la2 = float(bound[1])

        if ea1 < ea2:
            ea1, ea2, la1, la2 = ea2, ea1, la2, la1

        return round(ea1, 2), round(la2, 2)

    else:
        msg = 'Incorrect number of parameters: agerange'
        raise ValueError(400, msg)


def resolve_age(geologic_age):
    """Query PBDB for find early and late bounds for a geologic age."""
    import requests

    url = 'https://paleobiodb.org/data1.2/intervals/single.json'
    payload = {'name': geologic_age}

    try:
        r = requests.get(url, payload)
        r.raise_for_status()

    except requests.exceptions.HTTPError as e:
        msg = '{0:s}: {1:s}'.format(r.json().get('errors')[0], geologic_age)
        raise ValueError(r.status_code, msg)

    data = r.json().get('records')[0]

    return data.get('eag'), data.get('lag')


def get_subtaxa(taxon, inc_syn=True):
    """
    Query PBDB for all lower order relatives of a specified taxa.

    :arg taxon: Taxonmic name to query
    :type taxon: str
    :arg inc_syn: Include recognized synonyms in the return
    :type inc_syn: bool

    """
    import requests
    from .elc import config

    subtaxa = set()
    base_url = config.get('resource_api', 'pbdb') + 'taxa/list.json'

    payload = dict()
    payload.update(rel='all_children', name=taxon)

    resp = requests.get(base_url, params=payload, timeout=None)

    if resp.status_code == 200:
        resp_json = resp.json()

        if 'warnings' in resp_json:
            raise ValueError(400, str(resp_json['warnings'][0]))<commit_msg>added gplates call function for paleocoordinate conversion<commit_after>"""Auxilary functions for the API controllers."""


def set_timestamp():
    """Format POSIX UTC time for metadata."""
    from time import gmtime

    t = gmtime()
    return '{0:4d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d} UTC'.format(
        t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)


def set_db_special(db):
    """Add custom payload additions unique to a specific db."""
    if db == 'pbdb':
        return {'show': 'full'}
    # Add another database specific case here
    else:
        return {}


def set_taxon(taxon, subtax, db):
    """
    Return a database specific key-val pair for taxon paramaterization.

    :arg db: database name
    :type db: str
    :arg taxon: user input taxon name
    :type taxon: str
    :arg subtax: include lower taxonomy switch
    :type subtax: bool

    """
    taxon = taxon.capitalize()

    if len(taxon.split()) == 2:
        genus_species = True
    elif len(taxon.split()) == 1:
        genus_species = False
    else:
        msg = 'Taxon argument contains too many parameters'
        raise ValueError(400, msg)

    if db == 'neotoma':
        if subtax and not genus_species:
            wildcard = '{0:s}%'.format(taxon)
            return {'taxonname': wildcard}
        else:
            return {'taxonname': taxon}
    elif db == 'pbdb':
        if subtax and not genus_species:
            return {'base_name': taxon}
        else:
            return {'taxon_name': taxon}
    # Add another databse specific case here
    else:
        return {}


def set_age(age_range, options, db):
    """Return key-val ages for identified database subquery payload."""
    from ..elc import aux

    try:
        early_age, late_age = aux.get_age(age_range=age_range,
                                          options=options)
    except ValueError as err:
        raise ValueError(err.args[0], err.args[1])

    factor = aux.set_age_scaler(options, db)

    if db == 'neotoma':
        return {'ageyounger': early_age * factor,
                'ageolder': late_age * factor}
    elif db == 'pbdb':
        return {'max_ma': early_age * factor,
                'min_ma': late_age * factor}
    # Add another databse specific case here
    else:
        return {}


def get_age(age_range, options):
    """
    Parse age range parameters.

    :arg age_range: one or two comma separated numerical or text geoage bounds
    :type age_range: str
    :arg age_units: dimension of age parameter
    :type age_units: str ['yr', 'ka' or 'ma']

    """
    from ..elc import aux

    bound = age_range.split(',')
    if '' in bound:
        msg = 'Incorrectly formatted parameter pair: agerange'
        raise ValueError(400, msg)

    factor = aux.set_age_scaler(options, 'pbdb')

    if len(bound) == 1:

        if bound[0].isalpha():
            ea1, la1 = [x / factor for x in aux.resolve_age(bound[0])]
        elif float(bound[0]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            msg = 'Incorrect number of parameters: agerange'
            raise ValueError(400, msg)

        return round(ea1, 2), round(la1, 2)

    if len(bound) == 2:

        if bound[0].isalpha():
            ea1, la1 = [x / factor for x in aux.resolve_age(bound[0])]
        elif float(bound[0]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            ea1 = la1 = float(bound[0])

        if bound[1].isalpha():
            ea2, la2 = [x / factor for x in aux.resolve_age(bound[1])]
        elif float(bound[1]) < 0:
            msg = 'Parameter out of bounds: agerange'
            raise ValueError(400, msg)
        else:
            ea2 = la2 = float(bound[1])

        if ea1 < ea2:
            ea1, ea2, la1, la2 = ea2, ea1, la2, la1

        return round(ea1, 2), round(la2, 2)

    else:
        msg = 'Incorrect number of parameters: agerange'
        raise ValueError(400, msg)


def resolve_age(geologic_age):
    """Query PBDB for find early and late bounds for a geologic age."""
    import requests

    url = 'https://paleobiodb.org/data1.2/intervals/single.json'
    payload = {'name': geologic_age}

    try:
        r = requests.get(url, payload)
        r.raise_for_status()

    except requests.exceptions.HTTPError as e:
        msg = '{0:s}: {1:s}'.format(r.json().get('errors')[0], geologic_age)
        raise ValueError(r.status_code, msg)

    data = r.json().get('records')[0]

    return data.get('eag'), data.get('lag')


def resolve_geog(lat, lon, mean_age):
    """Query GPlates model (hosted by MacroStrat) for paleocoordinates."""
    import requests

    url = 'https://macrostrat.org/gplates/reconstruct'
    payload = {'lat': lat, 'lng': lon, 'age': mean_age}

    try:
        r = requests.get(url, payload)
        r.raise_for_status()

    except requests.exceptions.HTTPError as e:
        msg = '{0:s}'.format(r.json().get('error'))
        raise ValueError(r.status_code, msg)

    if r.json().get('features')[0]['geometry']:
        return r.json().get('features')[0]['geometry']['coordinates']
    else:
        msg = 'Coordinates must range from -180 to 180 decimal degrees'
        raise ValueError(400, msg)


def get_subtaxa(taxon, inc_syn=True):
    """
    Query PBDB for all lower order relatives of a specified taxa.

    :arg taxon: Taxonmic name to query
    :type taxon: str
    :arg inc_syn: Include recognized synonyms in the return
    :type inc_syn: bool

    """
    import requests
    from .elc import config

    subtaxa = set()
    base_url = config.get('resource_api', 'pbdb') + 'taxa/list.json'

    payload = dict()
    payload.update(rel='all_children', name=taxon)

    resp = requests.get(base_url, params=payload, timeout=None)

    if resp.status_code == 200:
        resp_json = resp.json()

        if 'warnings' in resp_json:
            raise ValueError(400, str(resp_json['warnings'][0]))
{'fraction_non_alphanumeric': 0.12266406872730494, 'fraction_numerical': 0.01877601629616509, 'mean_word_length': 2.350741839762611, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '741833', 'n_tokens_mistral': 3788, 'n_tokens_neox': 3603, 'n_words': 1060}