From a3f00de87ecccfb087640ea2b2db47e3f2f536de Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Fri, 21 Feb 2025 16:52:09 -0500
Subject: [PATCH] Initial commit.

---
 check.py         | 156 +++++++++++++++++++++++++++++++
 sample/page.html | 235 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 391 insertions(+)
 create mode 100755 check.py
 create mode 100644 sample/page.html

diff --git a/check.py b/check.py
new file mode 100755
index 0000000..2eba7ea
--- /dev/null
+++ b/check.py
@@ -0,0 +1,156 @@
+#!/usr/bin/python3
+
+import configparser
+import json
+import smtplib
+from datetime import date
+from email.mime.text import MIMEText
+from pathlib import Path
+
+import lxml.html
+import requests
+
+# Spanish months with corresponding numbers (1-12)
+spanish_months = {
+    "enero": 1,
+    "febrero": 2,
+    "marzo": 3,
+    "abril": 4,
+    "mayo": 5,
+    "junio": 6,
+    "julio": 7,
+    "agosto": 8,
+    "septiembre": 9,
+    "octubre": 10,
+    "noviembre": 11,
+    "diciembre": 12,
+}
+
+# Paths
+CONFIG_DIR = Path.home() / ".config" / "ferrocarril"
+CONFIG_FILE = CONFIG_DIR / "config"
+DATA_DIR = Path.home() / "lib" / "data"
+DATA_FILE = DATA_DIR / "ferrocarril_dates.json"
+URL = "https://ferrocarrilcentral.com.pe/appfcca/"
+
+
+def parse_dates(html_content: str) -> list[date]:
+    doc = lxml.html.fromstring(html_content)
+    dates = []
+
+    for tour in doc.xpath('//div[contains(@class, "tourdate")]'):
+        try:
+            day = int(tour.xpath('.//div[contains(@class, "day")]')[0].text.strip())
+            yeardate = tour.xpath('.//div[contains(@class, "yeardate")]')[0]
+            month_str = (
+                yeardate.xpath('.//div[contains(@class, "month")]')[0]
+                .text.strip()
+                .lower()
+            )
+            year = int(
+                yeardate.xpath('.//div[contains(@class, "year")]')[0].text.strip()
+            )
+
+            month = spanish_months.get(month_str)
+            if month is None:
+                raise ValueError(f"Unknown month: {month_str}")
+
+            dates.append(date(year, month, day))
+        except (IndexError, ValueError) as e:
+            print(f"Error parsing date: {e}")
+            continue
+
+    return dates
+
+
+def load_previous_dates() -> set[str]:
+    """Load previously seen dates from file, return as set of ISO strings."""
+    if DATA_FILE.exists():
+        with open(DATA_FILE, "r") as f:
+            return set(json.load(f))
+    return set()
+
+
+def save_dates(dates: list[date]):
+    """Save current dates to file as ISO strings."""
+    DATA_DIR.mkdir(parents=True, exist_ok=True)
+    with open(DATA_FILE, "w") as f:
+        json.dump([d.isoformat() for d in dates], f)
+
+
+def load_config() -> configparser.ConfigParser:
+    """Load email configuration from INI file."""
+    if not CONFIG_FILE.exists():
+        raise FileNotFoundError(
+            f"Config file not found at {CONFIG_FILE}. Please create it with SMTP details."
+        )
+    config = configparser.ConfigParser()
+    config.read(CONFIG_FILE)
+    if "mail" not in config:
+        raise ValueError(f"Config file {CONFIG_FILE} must have an [email] section")
+    return config
+
+
+def send_email(new_dates: list[date], config: configparser.ConfigParser) -> None:
+    """Send email with new dates."""
+    email_config = config["mail"]
+    subject = "New Ferrocarril Central Dates Available!"
+    body = "New dates found:\n" + "\n".join(d.strftime("%d %B %Y") for d in new_dates)
+
+    msg = MIMEText(body)
+    msg["Subject"] = subject
+    msg["From"] = email_config["from_address"]
+    msg["To"] = email_config["to_address"]
+
+    try:
+        with smtplib.SMTP(email_config["smtp_host"]) as server:
+            server.send_message(msg)
+        print("Email sent successfully")
+    except Exception as e:
+        print(f"Failed to send email: {e}")
+
+
+def main() -> None:
+    # Ensure directories exist
+    CONFIG_DIR.mkdir(parents=True, exist_ok=True)
+    DATA_DIR.mkdir(parents=True, exist_ok=True)
+
+    # Fetch webpage
+    try:
+        response = requests.get(URL, timeout=10)
+        response.raise_for_status()
+        html_content = response.text
+    except requests.RequestException as e:
+        print(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")
+        return
+
+    # Load previous dates
+    previous_dates = load_previous_dates()
+
+    # Check for new dates
+    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}")
+        try:
+            config = load_config()
+            send_email(new_dates, config)
+            save_dates(
+                list(current_dates)
+            )  # Update stored dates only if email succeeds
+        except FileNotFoundError as e:
+            print(e)
+        except Exception as e:
+            print(f"Error in processing: {e}")
+    else:
+        print("No new dates found")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/sample/page.html b/sample/page.html
new file mode 100644
index 0000000..3708f31
--- /dev/null
+++ b/sample/page.html
@@ -0,0 +1,235 @@
+<!DOCTYPE html>
+<html lang="es">
+
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>FCCA - Viajes disponibles</title>
+
+    <link rel="icon" href="https://ferrocarrilcentral.com.pe/appfcca/assets/img/fav.png" type="image/x-icon">
+    <link rel="apple-touch-icon" href="https://ferrocarrilcentral.com.pe/appfcca/assets/img/fav.png">
+
+    <link rel="stylesheet" href="https://ferrocarrilcentral.com.pe/appfcca/assets/css/style.css">
+
+    <!-- Icon Font -->
+    <link rel="stylesheet" href="https://ferrocarrilcentral.com.pe/appfcca/assets/css/linearicons.css">
+
+    <!-- Carousel -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glider-js@1.7.3/glider.min.css">
+    
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
+
+</head>
+<body>
+
+<header>
+    <nav class="navbar navbar-expand-lg navbar-light bg-white pt-3 pb-3">
+        <div class="container">
+            <a class="navbar-brand logotipo" href="https://www.ferrocarrilcentral.com.pe/">
+                <img src="https://ferrocarrilcentral.com.pe/appfcca/assets/img/logo_fcca.svg" alt="Ferrocarril Central FCCA" width="207" height="60">
+            </a>
+            <div class="navbar-expand nav-fcca" id="navbarNavDropdown">
+                <ul class="navbar-nav">
+                    <li class="nav-item home"><a class="nav-link" href="https://www.ferrocarrilcentral.com.pe/">inicio</a></li>
+                    <li class="nav-item language dropdown">
+                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+                            <i class="icon-fcca-20"></i> Idioma                        </a>
+                        <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
+                            <li><a class="dropdown-item" href="/appfcca/index.php?lang=es">Español</a></li>
+                            <li><a class="dropdown-item" href="/appfcca/index.php?lang=en">Ingles</a></li>
+                        </ul>
+                    </li>
+                </ul>
+            </div>
+    </nav>
+</header>
+    <section class="pt-5 pb-5">
+        <div class="container">
+
+            <div class="d-flex justify-content-between mb-5">
+    <div class="nav-reserve departure"><a href="https://ferrocarrilcentral.com.pe/appfcca/index.php"><i class="icon-fcca-05"></i> <span>1. Salida</span></a></div>
+    <div class="nav-reserve seating"><a href="https://ferrocarrilcentral.com.pe/appfcca/seating.php"><i class="icon-fcca-06"></i> <span>2. Asientos</span></a></div>
+    <div class="nav-reserve passengers"><a href="https://ferrocarrilcentral.com.pe/appfcca/passengers.php"><i class="icon-fcca-07"></i> <span>3. Pasajeros</span></a></div>
+    <div class="nav-reserve payment"><a href="https://ferrocarrilcentral.com.pe/appfcca/checkout.php"><i class="icon-fcca-08"></i> <span>4. Pago</span></a></div>
+</div>
+            <h3 class="subtitles mb-4">Selecciona tu Viaje:</h3>
+
+            <div class="carousel mb-5">
+                <div class="carousel-container">
+                    <div class="carousel-list">
+                        <div class="glider-track">
+
+                                                            <div class="item-glid" data-ccprog="00226" data-rutas="100">
+                                    <div class="tourdate d-flex justify-content-center align-items-center">
+                                        <div class="day p-1">17</div>
+                                        <div class="yeardate d-flex flex-column bd-highlight p-1">
+                                            <div class="month">Abril</div>
+                                            <div class="year">2025</div>
+                                        </div>
+                                    </div>
+                                </div>
+                            
+                        </div>
+                    </div>
+                </div>
+
+                <div class="glide-arrows">
+                    <button class="glide-left"><i class="icon-fcca-15"></i></button>
+                    <button class="glide-right"><i class="icon-fcca-16"></i></button>
+                </div>
+            </div>
+
+            <h3 class="subtitles mb-3">Selecciona tu Ruta:</h3>
+
+            <div id="rutaselect"></div>
+
+            <div class="heading-services d-flex justify-content-center align-items-center mt-2">
+                <div class="title-item tservicio d-none d-md-block">
+                    <h4>Servicio</h4>
+                </div>
+                <div class="title-item tpartida">
+                    <h4>Partida</h4>
+                </div>
+                <div class="title-item tretorno">
+                    <h4>Retorno</h4>
+                </div>
+                <div class="title-item ttarifa d-none d-md-block">
+                    <h4>Tarifas <span>(Inc. IGV)</span></h4>
+                </div>
+                <div class="title-item tmensaje d-none d-md-block">El viaje durará<br> aproximadamente 14 horas</div>
+            </div>
+
+            <!-- <div class='preloader mt-4 mb-4'><img src='./assets/img/prelouder-icon.svg'/></div> -->
+            <!-- 
+            <div id="devices">
+                <input type="hidden" class="mobile" value="//$devices['mobile']['status']">
+                <input type="hidden" class="desktop" value="//$devices['desktop']['status']">
+            </div> -->
+
+            <div id="dataServices"></div>
+
+        </div>
+    </section>
+
+<!-- Crear Preloder -->
+<div class="preloader-wrapper">
+    <div class="sniper">
+        <img src='https://ferrocarrilcentral.com.pe/appfcca/assets/img/prelouder-icon.svg'/>
+    </div>
+</div>
+<footer class="footer">
+        <div class="footer-top pt-4 pb-4">
+            <div class="container">
+                <div class="secure-payment d-md-flex justify-content-between align-items-center">
+                    <div class="guaranteed pt-3 pb-3">
+                        
+                    </div>
+                    <div class="cards-payment pt-3 pb-3"><img class="img-fluid" src="https://ferrocarrilcentral.com.pe/appfcca/assets/img/cads-checkout.png" alt="Sitio Web Protegido"></div>
+                </div>
+            </div>
+        </div>
+        <div class="footer-bottom bg-rojo text-white">
+            <div class="container pt-5 pb-5">
+                <div class="support d-lg-flex align-items-center mt-4">
+                    <div class="info callcenter d-flex align-items-center pt-3 pb-3">
+                        <div class="iconinfo"><i class="icon-fcca-02"></i></div>
+                        <div class="textinfo">Soporte en Línea <span>(01)390-5858</span> anexo 222</div>
+                    </div>
+                    <div class="info office d-flex align-items-center pt-3 pb-3">
+                        <div class="iconinfo"><i class="icon-fcca-03"></i></div>
+                        <div class="textinfo">Av. Circunvalación Golf Los Incas 170,<br> Edificio MORE, Oficina 302,<br> Santiago de Surco - Lima</div>
+                    </div>
+                    <div class="info Contact d-flex align-items-center pt-3 pb-3">
+                        <div class="iconinfo"><i class="icon-fcca-04"></i></div>
+                        <div class="textinfo">Escríbenos al <span>reservas@fcca.com.pe</span></div>
+                    </div>
+                </div>
+                <div class="nav-footer mt-5">
+                    <ul class="menu-footer d-md-flex align-items-center">
+                        <li><a href="https://www.ferrocarrilcentral.com.pe/politica-privacidad"><i class="icon-fcca-23"></i> Política De Privacidad</a></li>
+                        <li><a href="https://www.ferrocarrilcentral.com.pe/terminos-y-condiciones"><i class="icon-fcca-23"></i> Terminos Y Condiciones</a></li>
+                        <li><a href="https://www.ferrocarrilcentral.com.pe/preguntas-frecuentes"><i class="icon-fcca-23"></i> Preguntas Frecuentes</a></li>
+                        <li><a href="https://www.ferrocarrilcentral.com.pe/libro-de-reclamos"><i class="icon-fcca-23"></i> Libro De Reclamaciones</a></li>
+                        <li><a href="https://www.ferrocarrilcentral.com.pe/contactenos"><i class="icon-fcca-23"></i> Contáctenos</a></li>
+                    </ul>
+                </div>
+            </div>
+            <div class="copyright pt-3 pb-3">
+                <div class="container">
+                    <div class="credits d-flex align-items-center">
+                        <div class="copyfcca">copyright &copy; <a href="https://ferrocarrilcentral.com.pe/">www.ferrocarrilcentral.com.pe</a></div>
+                        <div class="developer">Desarrollado por: <a href="https://ferrocarrilcentral.com.pe/">www.ferrocarrilcentral.com.pe</a></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </footer>
+
+    <script src="https://ferrocarrilcentral.com.pe/appfcca/assets/js/jquery.min.js"></script>
+    <!-- <script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script> -->
+    <script src="https://ferrocarrilcentral.com.pe/appfcca/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
+    <script src="https://ferrocarrilcentral.com.pe/appfcca/assets/js/main.js"></script>
+<script src="https://ferrocarrilcentral.com.pe/appfcca/assets/js/glider.min.js"></script>
+<script src="https://ferrocarrilcentral.com.pe/appfcca/assets/js/glideslider.js"></script>
+
+<script type="text/javascript">
+	$(document).ready(function(){
+
+        reloadRutas();
+
+        $('.carousel-list .item-glid').click(function() {
+            $(this).siblings('.item-glid').removeClass('active');
+			$(this).addClass('active');
+
+            reloadRutas();
+
+        });
+
+        function reloadRutas() {
+            $rutas = $('.item-glid.active').data('rutas');
+            if (typeof $rutas === "undefined") {
+                var $rutas = $('.item-glid:eq(0)').data('rutas');
+            }else {
+                var $rutas = $('.item-glid.active').data('rutas');
+            }
+            
+            $.ajax({
+                type:"POST",
+                url:"https://ferrocarrilcentral.com.pe/appfcca/inc/ajax/rutas.php",
+                data:{ rutas: $rutas },
+                beforeSend: function() {
+                    $('#rutaselect').html("<div class='preloader mt-4 mb-4'><img src='https://ferrocarrilcentral.com.pe/appfcca/assets/img/prelouder-icon.svg'/></div>");
+                },
+                success:function(r){
+                    $('#rutaselect').html(r);
+                }
+            });
+        }
+        
+        // Active nav progress
+        $('.departure').addClass('active');
+
+        // Reconocimiento de medida de pantalla del usuario
+        var mediaMobile = window.matchMedia("(max-width: 990px)");
+        var mediaDesktop = window.matchMedia("(min-width: 991px)");
+
+        var mobile = {status: mediaMobile.matches};
+        var desktop = {status: mediaDesktop.matches};
+
+        $.ajax({
+            type: "POST",
+            url: "https://ferrocarrilcentral.com.pe/appfcca/config/device-screen.php",
+            data: { mobile: mobile, desktop: desktop },
+            success: function(r) { //response
+                console.log('se genero correctamente');
+            }
+        });
+
+    });
+</script>
+
+</body>
+</html>