Initial commit.

This commit is contained in:
Edward Betts 2025-02-21 16:52:09 -05:00
commit a3f00de87e
2 changed files with 391 additions and 0 deletions

156
check.py Executable file
View file

@ -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()

235
sample/page.html Normal file
View file

@ -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>