X-Git-Url: https://yuggoth.org/gitweb?a=blobdiff_plain;f=weather.py;h=322e83db9b52ada032ea55567c7679b89122163e;hb=29f424ec50d4b0d0d2885cd9f6c6b304245e067f;hp=8df769e31157178cff69cee9a5555ad32be99145;hpb=af6955376b8cf40bb20225bf4f16c56d52bfc883;p=weather.git diff --git a/weather.py b/weather.py index 8df769e..322e83d 100644 --- a/weather.py +++ b/weather.py @@ -11,18 +11,6 @@ weather_version = "2.4.4" radian_to_km = 6372.795484 radian_to_mi = 3959.871528 -def pyversion(ref=None): - """Determine the Python version and optionally compare to a reference.""" - import platform - ver = platform.python_version() - if ref: - return [ - int(x) for x in ver.split(".")[:2] - ] >= [ - int(x) for x in ref.split(".")[:2] - ] - else: return ver - class Selections: """An object to contain selection data.""" def __init__(self): @@ -204,15 +192,7 @@ def get_uri( cachedir="." ): """Return a string containing the results of a URI GET.""" - if pyversion("3"): - import urllib, urllib.error, urllib.request - URLError = urllib.error.URLError - urlopen = urllib.request.urlopen - else: - import urllib2 as urllib - URLError = urllib.URLError - urlopen = urllib.urlopen - import os, time + import os, time, urllib, urllib.error, urllib.request if cache_data: dcachedir = os.path.join( os.path.expanduser(cachedir), "datacache" ) if not os.path.exists(dcachedir): @@ -230,8 +210,8 @@ def get_uri( dcache_fd.close() else: try: - data = urlopen(uri).read().decode("utf-8") - except URLError: + data = urllib.request.urlopen(uri).read().decode("utf-8") + except urllib.error.URLError: if ignore_fail: return "" import os, sys sys.stderr.write("%s error: failed to retrieve\n %s\n\n" % ( @@ -273,7 +253,7 @@ def get_metar( cacheage=cacheage, cachedir=cachedir ) - if pyversion("3") and type(metar) is bytes: metar = metar.decode("utf-8") + if type(metar) is bytes: metar = metar.decode("utf-8") if verbose: return metar else: import re @@ -320,7 +300,8 @@ def get_alert( quiet=False, cache_data=False, cacheage=900, - cachedir="." + cachedir=".", + delay=1 ): """Return alert notice for the specified URI.""" if not uri: @@ -332,34 +313,34 @@ def get_alert( cacheage=cacheage, cachedir=cachedir ).strip() - if pyversion("3") and type(alert) is bytes: alert = alert.decode("utf-8") + if type(alert) is bytes: alert = alert.decode("utf-8") if alert: if verbose: return alert else: - if alert.find("\nNational Weather Service") == -1: - muted = False - else: + import re + if re.search(r"\nNational Weather Service", alert): muted = True + else: + muted = False + expirycheck = re.search(r"Expires:([0-9]{12})", alert) + if expirycheck: + # only report alerts and forecasts that expired less than delay + # hours ago + import datetime, zoneinfo + expiration = datetime.datetime.fromisoformat( + "%s-%s-%sT%s:%s" % ( + expirycheck[1][:4], + expirycheck[1][4:6], + expirycheck[1][6:8], + expirycheck[1][8:10], + expirycheck[1][-2:], + )).replace(tzinfo=zoneinfo.ZoneInfo("UTC")) + now = datetime.datetime.now(tz=zoneinfo.ZoneInfo("UTC")) + if now - expiration > datetime.timedelta(hours=delay): + return "" lines = alert.split("\n") - import time - # TODO: make this offset configurable - # TODO: adjust offset relative to the difference between the user's - # local time and the zone's local time (will need to extend - # the schema in the zones file to store each tz - offset = 86400 # one day - - # report alerts and forecasts that expired less than offset ago; - # this is a cheap hack since expiration times seem to be relative - # to the zone's local time zone, and converting from the user's - # would get complicated, but also there can sometimes be a lag - # between expiration and the next update - valid_time = time.strftime( - "%Y%m%d%H%M", time.localtime(time.time() - offset)) output = [] for line in lines: - if line.startswith("Expires:") \ - and "Expires:" + valid_time > line: - return "" if muted and line.startswith("National Weather Service"): muted = False line = "" @@ -442,6 +423,15 @@ def get_options(config): default=default_cachedir, help="directory for storing cached searches and data") + # the --delay option + if config.has_option("default", "delay"): + default_delay = config.getint("default", "delay") + else: default_delay = 1 + option_parser.add_option("--delay", + dest="delay", + default=default_delay, + help="hours to delay alert and forecast expiration") + # the -f/--forecast option if config.has_option("default", "forecast"): default_forecast = config.getboolean("default", "forecast") @@ -608,10 +598,8 @@ def get_options(config): def get_config(): """Parse the aliases and configuration.""" - if pyversion("3"): import configparser - else: import ConfigParser as configparser + import configparser, os config = configparser.ConfigParser() - import os rcfiles = [ "/etc/weatherrc", "/etc/weather/weatherrc", @@ -621,10 +609,7 @@ def get_config(): ] for rcfile in rcfiles: if os.access(rcfile, os.R_OK): - if pyversion("3"): - config.read(rcfile, encoding="utf-8") - else: - config.read(rcfile) + config.read(rcfile, encoding="utf-8") for section in config.sections(): if section != section.lower(): if config.has_section(section.lower()): @@ -636,9 +621,7 @@ def get_config(): def integrate_search_cache(config, cachedir, setpath): """Add cached search results into the configuration.""" - if pyversion("3"): import configparser - else: import ConfigParser as configparser - import os, time + import configparser, os, time scache_fn = os.path.join( os.path.expanduser(cachedir), "searches" ) if not os.access(scache_fn, os.R_OK): return config scache_fd = open(scache_fn) @@ -660,10 +643,7 @@ def integrate_search_cache(config, cachedir, setpath): pass return config scache = configparser.ConfigParser() - if pyversion("3"): - scache.read(scache_fn, encoding="utf-8") - else: - scache.read(scache_fn) + scache.read(scache_fn, encoding="utf-8") for section in scache.sections(): if not config.has_section(section): config.add_section(section) @@ -719,9 +699,7 @@ def guess( quiet=False ): """Find URIs using airport, gecos, placename, station, ZCTA/ZIP, zone.""" - import codecs, datetime, time, os, re, sys - if pyversion("3"): import configparser - else: import ConfigParser as configparser + import codecs, configparser, datetime, time, os, re, sys datafiles = data_index(path) if re.match("[A-Za-z]{3}$", expression): searchtype = "airport" elif re.match("[A-Za-z0-9]{4}$", expression): searchtype = "station" @@ -756,15 +734,9 @@ def guess( datafile = datafiles[dataname][0] if datafile.endswith(".gz"): import gzip - if pyversion("3"): - stations.read_string( - gzip.open(datafile).read().decode("utf-8") ) - else: stations.read_file( gzip.open(datafile) ) + stations.read_string( gzip.open(datafile).read().decode("utf-8") ) else: - if pyversion("3"): - stations.read(datafile, encoding="utf-8") - else: - stations.read(datafile) + stations.read(datafile, encoding="utf-8") else: message = "%s error: can't find \"%s\" data file\n" % ( os.path.basename( sys.argv[0] ), @@ -778,14 +750,9 @@ def guess( datafile = datafiles[dataname][0] if datafile.endswith(".gz"): import gzip - if pyversion("3"): - zones.read_string( gzip.open(datafile).read().decode("utf-8") ) - else: zones.read_file( gzip.open(datafile) ) + zones.read_string( gzip.open(datafile).read().decode("utf-8") ) else: - if pyversion("3"): - zones.read(datafile, encoding="utf-8") - else: - zones.read(datafile) + zones.read(datafile, encoding="utf-8") else: message = "%s error: can't find \"%s\" data file\n" % ( os.path.basename( sys.argv[0] ), @@ -807,15 +774,10 @@ def guess( datafile = datafiles[dataname][0] if datafile.endswith(".gz"): import gzip - if pyversion("3"): - airports.read_string( - gzip.open(datafile).read().decode("utf-8") ) - else: airports.read_file( gzip.open(datafile) ) + airports.read_string( + gzip.open(datafile).read().decode("utf-8") ) else: - if pyversion("3"): - airports.read(datafile, encoding="utf-8") - else: - airports.read(datafile) + airports.read(datafile, encoding="utf-8") else: message = "%s error: can't find \"%s\" data file\n" % ( os.path.basename( sys.argv[0] ), @@ -899,15 +861,9 @@ def guess( datafile = datafiles[dataname][0] if datafile.endswith(".gz"): import gzip - if pyversion("3"): - zctas.read_string( - gzip.open(datafile).read().decode("utf-8") ) - else: zctas.read_file( gzip.open(datafile) ) + zctas.read_string( gzip.open(datafile).read().decode("utf-8") ) else: - if pyversion("3"): - zctas.read(datafile, encoding="utf-8") - else: - zctas.read(datafile) + zctas.read(datafile, encoding="utf-8") else: message = "%s error: can't find \"%s\" data file\n" % ( os.path.basename( sys.argv[0] ), @@ -960,15 +916,9 @@ def guess( datafile = datafiles[dataname][0] if datafile.endswith(".gz"): import gzip - if pyversion("3"): - places.read_string( - gzip.open(datafile).read().decode("utf-8") ) - else: places.read_file( gzip.open(datafile) ) + places.read_string( gzip.open(datafile).read().decode("utf-8") ) else: - if pyversion("3"): - places.read(datafile, encoding="utf-8") - else: - places.read(datafile) + places.read(datafile, encoding="utf-8") else: message = "%s error: can't find \"%s\" data file\n" % ( os.path.basename( sys.argv[0] ), @@ -1185,10 +1135,7 @@ def guess( ) try: scache_existing = configparser.ConfigParser() - if pyversion("3"): - scache_existing.read(scache_fn, encoding="utf-8") - else: - scache_existing.read(scache_fn) + scache_existing.read(scache_fn, encoding="utf-8") if not scache_existing.has_section(search[0]): scache_fd = codecs.open(scache_fn, "a", "utf-8") scache_fd.writelines(search_cache) @@ -1239,9 +1186,8 @@ def gecos(formatted): return tuple(coordinates) def correlate(): - import codecs, csv, datetime, hashlib, os, re, sys, time, zipfile, zoneinfo - if pyversion("3"): import configparser - else: import ConfigParser as configparser + import codecs, configparser, csv, datetime, hashlib, os, re, sys, time + import zipfile, zoneinfo for filename in os.listdir("."): if re.match("[0-9]{4}_Gaz_counties_national.zip$", filename): gcounties_an = filename @@ -2073,30 +2019,15 @@ def correlate(): sys.stdout.write(message) sys.stdout.flush() airports = configparser.ConfigParser() - if pyversion("3"): - airports.read(airports_fn, encoding="utf-8") - else: - airports.read(airports_fn) + airports.read(airports_fn, encoding="utf-8") places = configparser.ConfigParser() - if pyversion("3"): - places.read(places_fn, encoding="utf-8") - else: - places.read(places_fn) + places.read(places_fn, encoding="utf-8") stations = configparser.ConfigParser() - if pyversion("3"): - stations.read(stations_fn, encoding="utf-8") - else: - stations.read(stations_fn) + stations.read(stations_fn, encoding="utf-8") zctas = configparser.ConfigParser() - if pyversion("3"): - zctas.read(zctas_fn, encoding="utf-8") - else: - zctas.read(zctas_fn) + zctas.read(zctas_fn, encoding="utf-8") zones = configparser.ConfigParser() - if pyversion("3"): - zones.read(zones_fn, encoding="utf-8") - else: - zones.read(zones_fn) + zones.read(zones_fn, encoding="utf-8") qalog = [] places_nocentroid = 0 places_nodescription = 0