Source code for pyiem.nws.products.scp

"""Parsing NESDIS Satellite Cloud Product (SCP)."""

import re
from collections import namedtuple
from datetime import timedelta

from pyiem.nws.product import TextProduct

SCP = namedtuple(
    "SCP", ["station", "valid", "mid", "high", "cldtop1", "cldtop2", "eca"]
)
LINEFMT = re.compile(r"^([A-Z0-9]){3,5}\s+[0-3][0-9]/[0-2][0-9][0-5][0-9]\s")


def _to_str(val):
    """Safe conversion."""
    if val.strip() == "":
        return None
    return val.strip()


def _to_int(val, multi=100):
    """Safe conversion."""
    if val.strip() == "":
        return None
    try:
        return int(val) * multi
    except ValueError:
        return None


def _processor(textprod):
    """Parse out what we can find in the text product."""
    res = []
    for line in textprod.unixtext.split("\n"):
        if not LINEFMT.match(line):
            continue
        if line[9] != "/":
            continue
        station = line[:5].strip()
        da = int(line[7:9])
        hr = int(line[10:12])
        mi = int(line[12:14])
        valid = textprod.valid
        if da != textprod.valid.day:
            # Yesterday
            valid = textprod.valid - timedelta(days=1)
        valid = valid.replace(day=da, hour=hr, minute=mi)
        mid = _to_str(line[17:20])
        high = _to_str(line[23:26])
        cldtop1 = _to_int(line[28:31])
        cldtop2 = _to_int(line[32:35])
        eca = _to_int(line[37:40], 1)
        res.append(
            SCP._make([station, valid, mid, high, cldtop1, cldtop2, eca])
        )

    return res


[docs] class SCPProduct(TextProduct): """Class representing a SCP Product""" def __init__( self, text, utcnow=None, ugc_provider=None, nwsli_provider=None ): """Constructor Args: text (str): text to parse """ super().__init__( text, utcnow=utcnow, ugc_provider=ugc_provider, nwsli_provider=nwsli_provider, ) self.data = _processor(self)
[docs] def sql(self, txn): """Do the necessary database work Args: (psycopg.transaction): a database transaction """ inserts = 0 for ob in self.data: inserts += 1 txn.execute( "INSERT into scp_alldata(station, valid, mid, high, cldtop1, " "cldtop2, eca, source) " "VALUES (%s, %s, %s, %s, %s, %s, %s, %s)", ( ob.station, ob.valid, ob.mid, ob.high, ob.cldtop1, ob.cldtop2, ob.eca, self.afos[-1], ), ) return inserts
[docs] def parser(text, utcnow=None, ugc_provider=None, nwsli_provider=None): """parser of raw SCP Text. Args: text (str): the raw text to parse utcnow (datetime): the current datetime with timezone set! Returns: SCPProduct instance """ return SCPProduct(text, utcnow, ugc_provider, nwsli_provider)