Compare commits
	
		
			2 commits
		
	
	
		
			a3f00de87e
			...
			7f7cbfe65e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							
							
								
									
								
								 | 
						7f7cbfe65e | ||
| 
							
							
								
									
								
								 | 
						9f0b2c843f | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
.mypy_cache
 | 
			
		||||
							
								
								
									
										39
									
								
								check.py
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								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__":
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue