From 7f7cbfe65ef83ceec605c05fed3be56cdd56457c Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Fri, 21 Feb 2025 17:00:44 -0500
Subject: [PATCH] feat: add logging to control output based on TTY context

- Replaced print() with logging.info() and logging.error()
- Added logging configuration to output INFO messages only in TTY
- Ensured ERROR messages are always logged to stdout, including cron runs
- Used sys.stdout.isatty() to detect terminal context
- Maintained existing functionality with updated config and SMTP setup
---
 check.py | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/check.py b/check.py
index 2eba7ea..7dd2d34 100755
--- a/check.py
+++ b/check.py
@@ -2,7 +2,9 @@
 
 import configparser
 import json
+import logging
 import smtplib
+import sys
 from datetime import date
 from email.mime.text import MIMEText
 from pathlib import Path
@@ -33,6 +35,22 @@ DATA_DIR = Path.home() / "lib" / "data"
 DATA_FILE = DATA_DIR / "ferrocarril_dates.json"
 URL = "https://ferrocarrilcentral.com.pe/appfcca/"
 
+# Configure logging
+logger = logging.getLogger("FerrocarrilMonitor")
+logger.setLevel(logging.INFO)
+
+# Handler for stdout
+handler = logging.StreamHandler(sys.stdout)
+formatter = logging.Formatter("%(levelname)s: %(message)s")
+handler.setFormatter(formatter)
+
+# Only log INFO when in TTY, always log ERROR
+if sys.stdout.isatty():
+    logger.addHandler(handler)
+else:
+    handler.setLevel(logging.ERROR)
+    logger.addHandler(handler)
+
 
 def parse_dates(html_content: str) -> list[date]:
     doc = lxml.html.fromstring(html_content)
@@ -57,7 +75,7 @@ def parse_dates(html_content: str) -> list[date]:
 
             dates.append(date(year, month, day))
         except (IndexError, ValueError) as e:
-            print(f"Error parsing date: {e}")
+            logger.error(f"Error parsing date: {e}")
             continue
 
     return dates
@@ -87,7 +105,7 @@ def load_config() -> configparser.ConfigParser:
     config = configparser.ConfigParser()
     config.read(CONFIG_FILE)
     if "mail" not in config:
-        raise ValueError(f"Config file {CONFIG_FILE} must have an [email] section")
+        raise ValueError(f"Config file {CONFIG_FILE} must have an [mail] section")
     return config
 
 
@@ -105,9 +123,10 @@ def send_email(new_dates: list[date], config: configparser.ConfigParser) -> None
     try:
         with smtplib.SMTP(email_config["smtp_host"]) as server:
             server.send_message(msg)
-        print("Email sent successfully")
+        logger.info("Email sent successfully")
     except Exception as e:
-        print(f"Failed to send email: {e}")
+        logger.error(f"Failed to send email: {e}")
+        raise  # Re-raise to prevent saving dates if email fails
 
 
 def main() -> None:
@@ -121,13 +140,13 @@ def main() -> None:
         response.raise_for_status()
         html_content = response.text
     except requests.RequestException as e:
-        print(f"Failed to fetch webpage: {e}")
+        logger.error(f"Failed to fetch webpage: {e}")
         return
 
     # Parse current dates
     current_dates = set(parse_dates(html_content))
     if not current_dates:
-        print("No dates found on webpage")
+        logger.info("No dates found on webpage")
         return
 
     # Load previous dates
@@ -137,7 +156,7 @@ def main() -> None:
     new_dates = [d for d in current_dates if d.isoformat() not in previous_dates]
 
     if new_dates:
-        print(f"New dates found: {new_dates}")
+        logger.info(f"New dates found: {new_dates}")
         try:
             config = load_config()
             send_email(new_dates, config)
@@ -145,11 +164,11 @@ def main() -> None:
                 list(current_dates)
             )  # Update stored dates only if email succeeds
         except FileNotFoundError as e:
-            print(e)
+            logger.error(str(e))
         except Exception as e:
-            print(f"Error in processing: {e}")
+            logger.error(f"Error in processing: {e}")
     else:
-        print("No new dates found")
+        logger.info("No new dates found")
 
 
 if __name__ == "__main__":