From 8a274cc5f24386139e6a5dd65c79e0dded875e31 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 18 Oct 2023 13:13:13 -0500 Subject: [PATCH 1/3] fix: sday selection when crossing 1 jan --- htdocs/plotting/auto/scripts100/p107.py | 2 +- htdocs/plotting/auto/scripts100/p140.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/plotting/auto/scripts100/p107.py b/htdocs/plotting/auto/scripts100/p107.py index 5d4ec66be2..9432f90d92 100644 --- a/htdocs/plotting/auto/scripts100/p107.py +++ b/htdocs/plotting/auto/scripts100/p107.py @@ -177,7 +177,7 @@ def plotter(fdict): doff = "year" if ctx["eday"] < ctx["sday"]: dtlimiter = "(sday >= :sday or sday <= :eday)" - doff = "case when sday < :eday then year - 1 else year end" + doff = "case when sday <= :eday then year - 1 else year end" if stop is not None: dtlimiter = "sday >= :sday" doff = "year" diff --git a/htdocs/plotting/auto/scripts100/p140.py b/htdocs/plotting/auto/scripts100/p140.py index 430564832b..e947711210 100644 --- a/htdocs/plotting/auto/scripts100/p140.py +++ b/htdocs/plotting/auto/scripts100/p140.py @@ -156,11 +156,11 @@ def plotter(fdict): doff = "extract(year from day)" if ctx["eday"] < ctx["sday"]: dtlimiter = ( - "(to_char(day, 'mmdd') >= :eday or " - "to_char(day, 'mmdd') <= :sday)" + "(to_char(day, 'mmdd') >= :sday or " + "to_char(day, 'mmdd') <= :eday)" ) doff = ( - "case when to_char(day, 'mmdd') < :sday then " + "case when to_char(day, 'mmdd') <= :eday then " "(extract(year from day)::int - 1) else extract(year from day) end" ) threshold = ctx["thres"] From cbed1563f9eecc60730f4800b49cbda3d8720db3 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 18 Oct 2023 20:41:13 -0500 Subject: [PATCH 2/3] feat: add two website stat bars to homepage --- include/generators.php | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/include/generators.php b/include/generators.php index 9b56b4bdfe..4afd2a484b 100644 --- a/include/generators.php +++ b/include/generators.php @@ -67,11 +67,23 @@ function get_website_stats() } $bcolor = "success"; $rcolor = "success"; + $ocolor = "success"; + $acolor = "success"; $bandwidth = 0; $req = 0; + $ok = 0; + $apirate = 0; if ($val) { $jobj = json_decode($val); + $ok = $jobj->stats->telemetry_ok; + if ($ok < 90) $ocolor = "warning"; + if ($ok < 80) $ocolor = "danger"; + + $apirate = $jobj->stats->telemetry_rate; + if ($apirate < 10) $acolor = "warning"; + if ($apirate < 5) $acolor = "danger"; + $bandwidth = $jobj->stats->bandwidth / 1000000.0; // grading of the bandwidth (MB/s) if ($bandwidth > 35) $bcolor = "warning"; @@ -83,8 +95,12 @@ function get_website_stats() } $label = sprintf("%.1f MB/s", $bandwidth); $bpercent = intval($bandwidth / 124.0 * 100.0); - $rlabel = number_format($req); + $rlabel = sprintf("%s req/s", number_format($req)); $rpercent = intval($req / 15000.0 * 100.0); + $olabel = sprintf("%.0f%%", $ok); + $opercent = intval($ok); + $alabel = sprintf("%.1f req/s", $apirate); + $apercent = intval($apirate / 100.0 * 100.0); $s = << @@ -97,12 +113,26 @@ function get_website_stats() - Requests/Second: {$rlabel} +Total Website: {$rlabel}
- + +API/Data Services: {$alabel} +
+
+
+
+ +API Success: {$olabel} +
+
+
+
+ EOF; From d1f4e55201081602b628dba22d5c283bb2c84610 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 18 Oct 2023 20:46:17 -0500 Subject: [PATCH 3/3] mnt: use ensure_list helper --- cgi-bin/request/asos1min.py | 15 +++++---------- cgi-bin/request/daily.py | 14 ++++---------- cgi-bin/request/gis/lsr.py | 10 +++------- cgi-bin/request/gis/watchwarn.py | 14 ++++---------- cgi-bin/request/talltowers.py | 12 +++--------- 5 files changed, 19 insertions(+), 46 deletions(-) diff --git a/cgi-bin/request/asos1min.py b/cgi-bin/request/asos1min.py index 0b180c49de..2639f61ff4 100644 --- a/cgi-bin/request/asos1min.py +++ b/cgi-bin/request/asos1min.py @@ -3,7 +3,7 @@ from pyiem.exceptions import IncompleteWebRequest from pyiem.util import get_dbconnc -from pyiem.webutil import iemapp +from pyiem.webutil import ensure_list, iemapp SAMPLING = { "1min": 1, @@ -74,23 +74,18 @@ def compute_prefixes(sio, form, delim, stations, tz) -> dict: @iemapp() def application(environ, start_response): """Handle mod_wsgi request.""" - stations = environ.get("station", []) + stations = ensure_list(environ, "station") if not stations: # legacy php - stations = environ.get("station[]", []) - # Ensure stations is a list - if isinstance(stations, str): - stations = [stations] + stations = ensure_list(environ, "station[]") if not stations: raise IncompleteWebRequest("No station= was specified in request.") delim = DELIM[environ.get("delim", "comma")] sample = SAMPLING[environ.get("sample", "1min")] what = environ.get("what", "dl") tz = environ.get("tz", "UTC") - varnames = environ.get("vars", []) + varnames = ensure_list(environ, "vars") if not varnames: # legacy php - varnames = environ.get("vars[]", []) - if isinstance(varnames, str): - varnames = [varnames] + varnames = ensure_list(environ, "vars[]") if not varnames: raise IncompleteWebRequest("No vars= was specified in request.") pgconn, cursor = get_dbconnc("asos1min") diff --git a/cgi-bin/request/daily.py b/cgi-bin/request/daily.py index 06efa7f05d..f7f2517924 100644 --- a/cgi-bin/request/daily.py +++ b/cgi-bin/request/daily.py @@ -6,7 +6,7 @@ from pyiem.exceptions import IncompleteWebRequest from pyiem.network import Table as NetworkTable from pyiem.util import get_dbconn, get_sqlalchemy_conn -from pyiem.webutil import iemapp +from pyiem.webutil import ensure_list, iemapp from sqlalchemy import text EXL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" @@ -138,20 +138,14 @@ def application(environ, start_response): return [b"ERROR: server over capacity, please try later"] fmt = environ.get("format", "csv") - stations = environ.get("stations", []) - if isinstance(stations, str): - stations = [stations] + stations = ensure_list(environ, "stations") if not stations: - stations = environ.get("station", []) - if isinstance(stations, str): - stations = [stations] + stations = ensure_list(environ, "station") if not stations: start_response("200 OK", [("Content-type", "text/plain")]) return [b"ERROR: No stations specified for request"] network = environ.get("network")[:12] - cols = environ.get("var", []) - if isinstance(cols, str): - cols = [cols] + cols = ensure_list(environ, "var") na = environ.get("na", "None") if na not in ["M", "None", "blank"]: start_response("200 OK", [("Content-type", "text/plain")]) diff --git a/cgi-bin/request/gis/lsr.py b/cgi-bin/request/gis/lsr.py index f6635a1e11..1c781afcc6 100644 --- a/cgi-bin/request/gis/lsr.py +++ b/cgi-bin/request/gis/lsr.py @@ -9,7 +9,7 @@ import shapefile from pyiem.exceptions import IncompleteWebRequest from pyiem.util import get_dbconn, get_sqlalchemy_conn, utc -from pyiem.webutil import iemapp +from pyiem.webutil import ensure_list, iemapp fiona.supported_drivers["KML"] = "rw" EXL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" @@ -114,17 +114,13 @@ def application(environ, start_response): statelimiter = "" for opt in ["state", "states", "states[]"]: if opt in environ: - aStates = environ.get(opt, []) - if isinstance(aStates, str): - aStates = [aStates] + aStates = ensure_list(environ, opt) aStates.append("XX") if "_ALL" not in aStates: statelimiter = f" and l.state in {tuple(aStates)} " wfoLimiter = "" if "wfo[]" in environ: - aWFO = environ.get("wfo[]", []) - if isinstance(aWFO, str): - aWFO = [aWFO] + aWFO = ensure_list(environ, "wfo[]") aWFO.append("XXX") # Hack to make next section work if "ALL" not in aWFO: wfoLimiter = f" and l.wfo in {tuple(aWFO)} " diff --git a/cgi-bin/request/gis/watchwarn.py b/cgi-bin/request/gis/watchwarn.py index ba3d9e8579..ab03f1d881 100644 --- a/cgi-bin/request/gis/watchwarn.py +++ b/cgi-bin/request/gis/watchwarn.py @@ -8,7 +8,7 @@ import pandas as pd from pyiem.exceptions import IncompleteWebRequest from pyiem.util import get_dbconnc, get_sqlalchemy_conn, utc -from pyiem.webutil import iemapp +from pyiem.webutil import ensure_list, iemapp from shapely.geometry import mapping from shapely.wkb import loads @@ -34,17 +34,13 @@ def parse_wfo_location_group(form): """Parse wfoLimiter""" limiter = "" if "wfo[]" in form: - wfos = form.get("wfo[]", []) - if not isinstance(wfos, list): - wfos = [wfos] + wfos = ensure_list(form, "wfo[]") wfos.append("XXX") # Hack to make next section work if "ALL" not in wfos: limiter = f" and w.wfo in {tuple(char3(wfos))} " if "wfos[]" in form: - wfos = form.get("wfos[]", []) - if not isinstance(wfos, list): - wfos = [wfos] + wfos = ensure_list(form, "wfos[]") wfos.append("XXX") # Hack to make next section work if "ALL" not in wfos: limiter = f" and w.wfo in {tuple(char3(wfos))} " @@ -59,9 +55,7 @@ def build_sql(environ): location_group = environ.get("location_group", "wfo") if location_group == "states": if "states[]" in environ: - arstates = environ.get("states[]", []) - if not isinstance(arstates, list): - arstates = [arstates] + arstates = ensure_list(environ, "states[]") states = [x[:2].upper() for x in arstates] states.append("XX") # Hack for 1 length wfo_limiter = ( diff --git a/cgi-bin/request/talltowers.py b/cgi-bin/request/talltowers.py index d53b539b90..6fe31bba0b 100644 --- a/cgi-bin/request/talltowers.py +++ b/cgi-bin/request/talltowers.py @@ -70,15 +70,9 @@ def application(environ, start_response): fmt = environ.get("format") # Build out our variable list tokens = [] - zz = environ.get("z", []) - if isinstance(zz, str): - zz = [zz] - varnames = environ.get("var", []) - if isinstance(varnames, str): - varnames = [varnames] - aggs = environ.get("agg", []) - if isinstance(aggs, str): - aggs = [aggs] + zz = ensure_list(environ, "z") + varnames = ensure_list(environ, "var") + aggs = ensure_list(environ, "agg") for z in zz: for v in varnames: v1 = v