Compare commits
No commits in common. "fc81fa9b83da502e4ece249f3a66382f6b669f51" and "23bf0f3f8b88df0b72e3c8ccdafd81f4da4ae76e" have entirely different histories.
fc81fa9b83
...
23bf0f3f8b
2 changed files with 6 additions and 110 deletions
|
@ -1,12 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import enum
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from nexrad.db import Database
|
from nexrad.s3 import S3Bucket
|
||||||
from nexrad.s3 import S3Bucket, S3_KEY_RE
|
|
||||||
from nexrad.coord import COORD_SYSTEM
|
|
||||||
from nexrad.radar import RADAR_RANGE
|
|
||||||
|
|
||||||
class ArchiveDateError(Exception):
|
class ArchiveDateError(Exception):
|
||||||
def __init__(self, supplied: str, missing: str):
|
def __init__(self, supplied: str, missing: str):
|
||||||
|
@ -14,101 +9,7 @@ class ArchiveDateError(Exception):
|
||||||
self.missing = missing
|
self.missing = missing
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Archive {self.supplied} was supplied, but required {self.missing} is missing"
|
return "Date {self.supplied} was supplied, but required {self.missing} is missing"
|
||||||
|
|
||||||
class ArchiveProductType(enum.Enum):
|
|
||||||
DEFAULT = 1
|
|
||||||
V03 = 3
|
|
||||||
|
|
||||||
class ArchiveProduct():
|
|
||||||
__slots__ = 'typeof', 'radar', 'timestamp',
|
|
||||||
|
|
||||||
typeof: ArchiveProductType
|
|
||||||
radar: str
|
|
||||||
timestamp: datetime.datetime
|
|
||||||
|
|
||||||
def __parts__(self):
|
|
||||||
return [
|
|
||||||
"%04d" % (self.timestamp.year),
|
|
||||||
"%02d" % (self.timestamp.month),
|
|
||||||
"%02d" % (self.timestamp.day),
|
|
||||||
self.radar,
|
|
||||||
"%4s%04d%02d%02d_%02d%02d%02d" % (
|
|
||||||
self.radar,
|
|
||||||
self.timestamp.year, self.timestamp.month, self.timestamp.day,
|
|
||||||
self.timestamp.hour, self.timestamp.minute, self.timestamp.second
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
ret = '/'.join(self.__parts__())
|
|
||||||
|
|
||||||
if self.typeof == ArchiveProductType.V03:
|
|
||||||
ret += "_V03"
|
|
||||||
|
|
||||||
ret += ".gz"
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __path__(self):
|
|
||||||
parts = self.__parts__()
|
|
||||||
ret = os.path.join(*parts)
|
|
||||||
|
|
||||||
|
|
||||||
if self.typeof == ArchiveProductType.V03:
|
|
||||||
ret += "_V03"
|
|
||||||
|
|
||||||
ret += ".gz"
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_s3_key(key: str):
|
|
||||||
product = ArchiveProduct()
|
|
||||||
match = S3_KEY_RE.match(key)
|
|
||||||
|
|
||||||
product.timestamp = datetime.datetime(
|
|
||||||
year = int(match[6]),
|
|
||||||
month = int(match[7]),
|
|
||||||
day = int(match[8]),
|
|
||||||
hour = int(match[9]),
|
|
||||||
minute = int(match[10]),
|
|
||||||
second = int(match[11]),
|
|
||||||
tzinfo = datetime.UTC
|
|
||||||
)
|
|
||||||
|
|
||||||
product.radar = match[4]
|
|
||||||
product.typeof = ArchiveProductType.V03 \
|
|
||||||
if key[-7:] == '_V03.gz' else ArchiveProductType.DEFAULT
|
|
||||||
|
|
||||||
return product
|
|
||||||
|
|
||||||
def is_downloaded(self, path: str):
|
|
||||||
return os.path.isfile(os.path.join(path, self.__path__()))
|
|
||||||
|
|
||||||
def is_reported(self, db: Database):
|
|
||||||
sql = """select count((
|
|
||||||
select ST_Distance(MakeLine(report.coord_start, report.coord_end),
|
|
||||||
radar.coord,
|
|
||||||
true) as distance
|
|
||||||
from
|
|
||||||
nexrad_storm_report as report,
|
|
||||||
nexrad_radar as radar
|
|
||||||
where
|
|
||||||
distance <= :radius
|
|
||||||
and :timestamp between report.timestamp_start and report.timestamp_end
|
|
||||||
and radar.call = :call)) as num
|
|
||||||
"""
|
|
||||||
|
|
||||||
st = db.execute(sql, {
|
|
||||||
'radius': RADAR_RANGE,
|
|
||||||
'timestamp': self.timestamp,
|
|
||||||
'call': self.radar
|
|
||||||
})
|
|
||||||
|
|
||||||
result = st.fetchone()
|
|
||||||
|
|
||||||
return result['num'] == 1
|
|
||||||
|
|
||||||
class Archive():
|
class Archive():
|
||||||
path: str
|
path: str
|
||||||
|
@ -193,10 +94,3 @@ class Archive():
|
||||||
parts.pop()
|
parts.pop()
|
||||||
|
|
||||||
parts.pop()
|
parts.pop()
|
||||||
|
|
||||||
def each_downloaded_product(self,
|
|
||||||
year: int=None,
|
|
||||||
month: int=None,
|
|
||||||
day: int=None):
|
|
||||||
for key in self.each_downloaded_key(year, month, day):
|
|
||||||
yield ArchiveProduct.from_s3_key(key)
|
|
||||||
|
|
|
@ -199,12 +199,14 @@ class StormReport(DatabaseTable):
|
||||||
})
|
})
|
||||||
|
|
||||||
if timestamp is not None:
|
if timestamp is not None:
|
||||||
clauses.append(":timestamp between timestamp_start and timestamp_end")
|
clauses.append("timestamp_start >= :timestamp and timestamp_end <= :timestamp")
|
||||||
|
|
||||||
values.update({
|
values.update({
|
||||||
'timestamp': str(timestamp)
|
'timestamp': timestamp.isoformat()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
values.append(timestamp.isoformat())
|
||||||
|
|
||||||
sql = "select " + ", ".join(columns) + " from nexrad_storm_report"
|
sql = "select " + ", ".join(columns) + " from nexrad_storm_report"
|
||||||
|
|
||||||
if len(clauses) > 0:
|
if len(clauses) > 0:
|
||||||
|
|
Loading…
Add table
Reference in a new issue