diff --git a/main.py b/main.py index 1d3de91..16c1c9c 100644 --- a/main.py +++ b/main.py @@ -27,7 +27,7 @@ COUNTDOWN_HTML = os.path.join(app_folder, "countdown.html") GONOGO_HTML = os.path.join(app_folder, "gonogo.html") SHEET_LINK = "" session = requests.Session() -appVersion = "0.6.1" +appVersion = "0.7.0" SETTINGS_FILE = os.path.join(app_folder, "settings.json") # Default settings @@ -53,6 +53,8 @@ DEFAULT_SETTINGS.setdefault("gn_bg_color", "#111111") DEFAULT_SETTINGS.setdefault("gn_border_color", "#FFFFFF") DEFAULT_SETTINGS.setdefault("gn_go_color", "#00FF00") DEFAULT_SETTINGS.setdefault("gn_nogo_color", "#FF0000") +DEFAULT_SETTINGS.setdefault("gn_caution_color", "#FFA500") # orange +DEFAULT_SETTINGS.setdefault("html_gn_caution_color", "#FFA500") DEFAULT_SETTINGS.setdefault("gn_font_px", 20) DEFAULT_SETTINGS.setdefault("appearance_mode", "dark") @@ -133,16 +135,28 @@ def fetch_gonogo(): mode = settings.get("mode", "spreadsheet") # If manual mode, read values from a runtime stash (set by the GUI buttons) if mode == "buttons": - # stored values will be on the app class; fallback to N/A + # stored values will be on the function object (set by the GUI dialog/buttons) try: - return [ - getattr(fetch_gonogo, "manual_range", "N/A"), - getattr(fetch_gonogo, "manual_weather", "N/A"), - getattr(fetch_gonogo, "manual_vehicle", "N/A"), - ] + range_val = getattr(fetch_gonogo, "manual_range", "N/A") + weather_val = getattr(fetch_gonogo, "manual_weather", "N/A") + vehicle_val = getattr(fetch_gonogo, "manual_vehicle", "N/A") + + # If values are numeric strings or numbers, we keep them numeric (so formatting + coloring works) + # convert empty strings -> "N/A" + def normv(v): + if v is None: + return "N/A" + s = str(v).strip() + if s == "": + return "N/A" + return s + + return [normv(range_val), normv(weather_val), normv(vehicle_val)] except Exception: return ["N/A", "N/A", "N/A"] + + # spreadsheet mode link = settings.get("sheet_link", SHEET_LINK) col = max(1, int(settings.get("column", 12))) - 1 @@ -172,34 +186,81 @@ def fetch_gonogo(): # Helper for color # ------------------------- def get_status_color(status): - """Return color name for a Go/No-Go status string.""" + """ + Accepts status which may be: + - a percentage string/number (e.g. '82', '82.0', 82) + - 'GO', 'NO-GO', 'CAUTION' or variants + - anything else -> white + Returns CSS color names / hex strings. + """ try: - s = str(status or "").strip().upper() - # normalize to letters only so variants like 'NO GO', 'NO-GO', 'NOGO' match - norm = re.sub(r"[^A-Z]", "", s) + if status is None: + return "white" + s = str(status).strip() + # Try numeric percentage first + try: + pct = float(s.replace("%", "")) + + # Bound it to 0..100 + pct = max(0.0, min(100.0, pct)) + if pct >= 75.0: + return "green" + if pct >= 50.0: + return "orange" + return "red" + except Exception: + pass + + # Non-numeric: interpret standard words + norm = re.sub(r"[^A-Z]", "", s.upper()) if norm == "GO": return "green" - if norm == "NOGO": + if norm == "NOGO" or norm == "NOGO" or norm == "NOGO": return "red" - # fallback: treat unknown/empty as white + if norm == "CAUTION" or norm == "CAUT": + return "orange" return "white" except Exception: return "white" def format_status_display(status): + """ + Formats the status for display: + - numeric -> 'NN%' (rounded as needed) + - 'NO-GO'/'GO' -> canonical formatting + - otherwise return original string + """ try: - s = str(status or "").strip().upper() - norm = re.sub(r"[^A-Z]", "", s) + if status is None: + return "N/A" + s = str(status).strip() + # numeric + try: + pct = float(s) + # bound and show as integer if whole, else one decimal + pct = max(0.0, min(100.0, pct)) + if abs(pct - round(pct)) < 0.001: + return f"{int(round(pct))}%" + return f"{pct:.1f}%" + except Exception: + pass + + # canonical text forms + norm = re.sub(r"[^A-Z]", "", s.upper()) if norm == "GO": return "GO" if norm == "NOGO": return "NO-GO" + if norm == "CAUTION": + return "CAUTION" + # fallback to raw return s except Exception: return str(status or "") + # ------------------------- # Write Countdown HTML # ------------------------- @@ -251,30 +312,28 @@ body {{ f.write(html) -# ------------------------- -# Write Go/No-Go HTML -# ------------------------- def write_gonogo_html(gonogo_values=None): if gonogo_values is None: gonogo_values = ["N/A", "N/A", "N/A"] s = load_settings() - # Prefer HTML-specific settings; fall back to GUI appearance settings for backwards compatibility bg = s.get("html_bg_color", s.get("bg_color", "#000000")) text = s.get("html_text_color", s.get("text_color", "#FFFFFF")) font = s.get("html_font_family", s.get("font_family", "Consolas, monospace")) gn_bg = s.get("html_gn_bg_color", s.get("gn_bg_color", "#111111")) gn_border = s.get("html_gn_border_color", s.get("gn_border_color", "#FFFFFF")) - gn_go = s.get("html_gn_go_color", s.get("gn_go_color", "#00FF00")) - gn_nogo = s.get("html_gn_nogo_color", s.get("gn_nogo_color", "#FF0000")) gn_px = int(s.get("html_gn_font_px", s.get("gn_font_px", 28))) - # normalize and format display values so variants like 'NO GO' become 'NO-GO' - disp0 = format_status_display(gonogo_values[0]) - disp1 = format_status_display(gonogo_values[1]) - disp2 = format_status_display(gonogo_values[2]) - n0 = re.sub(r"[^A-Z]", "", (str(gonogo_values[0] or "")).strip().upper()) - n1 = re.sub(r"[^A-Z]", "", (str(gonogo_values[1] or "")).strip().upper()) - n2 = re.sub(r"[^A-Z]", "", (str(gonogo_values[2] or "")).strip().upper()) + # Prepare display text and color for each item + disp = [format_status_display(v) for v in gonogo_values] + + def pick_css_color(v): + return get_status_color(v) + + c0 = pick_css_color(gonogo_values[0]) + c1 = pick_css_color(gonogo_values[1]) + c2 = pick_css_color(gonogo_values[2]) + + # Inline style approach per box to ensure color picks up numeric/word cases html = f"""
@@ -301,8 +360,6 @@ body {{ text-align: center; background-color: {gn_bg}; }} -.go {{ color: {gn_go}; }} -.nogo {{ color: {gn_nogo}; }}