Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/enable all cercanias optionally #201

Merged
merged 2 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v5.1.0 (2024-10-02)

* Enable Renfe Cercanías GTFS dataset [#200](https://github.com/gerardcl/renfe-cli/issues/200)

## v5.0.0 (2024-09-29)

* Major refactor using GTFS data from Renfe online datasets. No more scrapping required
Expand Down
26 changes: 14 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "renfe-cli"
version = "5.0.0"
version = "5.1.0"
edition = "2021"
license = "BSD-3-Clause"
description = "CLI for searching Renfe train timetables in the Spanish country"
readme = "README.md"
homepage = "https://github.com/gerardcl/renfe-cli"
repository = "https://github.com/gerardcl/renfe-cli"
keywords = ["cli", "timetables", "trains", "renfe", "spain"]
keywords = ["cli", "timetables", "schedules", "trains", "renfe", "spain"]
categories = ["command-line-utilities"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
64 changes: 56 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
Get faster Renfe trains timetables in your terminal, with Python3.7+ support.
No longer need to open the browser! Just keep using your terminal 😀

It supports both [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia) (default option, as in the web) and [Renfe Cercanías](https://data.renfe.com/dataset/horarios-cercanias) GTFS datasets.

`renfe-cli` is written in [Rust](https://www.rust-lang.org/) (since v4.0.0) and published to [pypi.org](https://pypi.org/project/renfe-cli/) as a Python package (CLI and library).

See the [changelog](https://github.com/gerardcl/renfe-cli/blob/master/CHANGELOG.md).

**NOTE** since I am more often using Rodalies trains I have created [rodalies-cli](https://github.com/gerardcl/rodalies-cli). I hope you like it too!

**DISCLAIMER**: Renfe's GTFS dataset might not be in sync with autonomic train schedules (e.g. Rodalies de la Generalitat de Catalunya), hence Renfe Cercanias train types (e.g.: REGIONAL or MD type) might not be accurate. For that, please use autonomic data/apps (.e.g: [rodalies-cli](https://github.com/gerardcl/rodalies-cli)).
**DISCLAIMER**: Renfe's GTFS dataset might not be in sync with autonomic train schedules systems (e.g. Rodalies de la Generalitat de Catalunya), hence Renfe Cercanias train types (e.g.: REGIONAL or MD type) might not be accurate, or when using the `cercanias` flag you won't find timetables for the stations belonging to autonomic systems. For that, please use autonomic data/apps (.e.g: [rodalies-cli](https://github.com/gerardcl/rodalies-cli)).

## Installation

Expand All @@ -23,7 +25,7 @@ pip install renfe-cli --upgrade

## Usage (CLI)

The CLI uses the official and latest Renfe's GTFS dataset, from [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia).
The CLI uses the official and latest Renfe's GTFS dataset, from [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia), by default. Optionally, one can enable searching over [Renfe Cercanías GTFS dataset](https://data.renfe.com/dataset/horarios-cercanias) (expect longer load time in this case).

```bash
$ renfe-cli -h
Expand All @@ -36,16 +38,17 @@ Options:
-m, --month MONTH Set the Month (default: today's month)
-y, --year YEAR Set the Year (default: today's year)
-s, --sort Option to sort the timetable by Duration
-c, --cercanias Option to search over Renfe Cercanías
-h, --help Print this help menu
```

### **Getting the timetable**

Let's show an example of minimal inputs (origin and destination stations) with specific date:
Let's show an example of minimal inputs (origin and destination stations) with specific date and default GTFS dataset:

```bash
$ renfe-cli -f girona -t "puerta de atocha" -d 30
Loading GTFS data from Renfe web
Loading default GTFS data from Renfe web - Alta velocidad, Larga distancia y Media distancia
Provided input 'girona' does a match with 'Estación de tren Girona'
Provided input 'puerta de atocha' does a match with 'Estación de tren Madrid-Puerta de Atocha'
Today is: 2024-9-29
Expand All @@ -70,6 +73,38 @@ Destination station: Estación de tren Madrid-Puerta de Atocha
===========================================================
```

Let's show an example using Renfe Cercanías GTFS dataset:

```bash
$ renfe-cli -f chamartín -t "tres cantos" -c
Loading Cercanías GTFS data from Renfe web - long load time
Provided input 'chamartín' does a match with 'Station { name: "Estación de tren Madrid-Chamartín-Clara Campoamor", id: "17000" }'
Provided input 'tres cantos' does a match with 'Station { name: "Estación de tren Tres Cantos (apt)", id: "17004" }'
Today is: 2024-10-2
Searching timetable for date: 2024-10-2
Origin station: Estación de tren Madrid-Chamartín-Clara Campoamor
Destination station: Estación de tren Tres Cantos (apt)

=========================TIMETABLE=========================
Train | Departure | Arrival | Duration
-----------------------------------------------------------
C4b | 05:06 | 05:22 | 00:16
-----------------------------------------------------------
C4b | 05:38 | 05:55 | 00:17
-----------------------------------------------------------
C4b | 06:10 | 06:27 | 00:17
-----------------------------------------------------------
.........
.........
-----------------------------------------------------------
C4b | 21:56 | 22:13 | 00:17
-----------------------------------------------------------
C4b | 22:20 | 22:37 | 00:17
-----------------------------------------------------------
C4b | 23:16 | 23:33 | 00:17
===========================================================
```

## Usage (Library)

`renfe-cli` can be imported as a python package into your project, offering utilities when willing to deal with the Renfe search web site.
Expand All @@ -82,7 +117,20 @@ Type "help", "copyright", "credits" or "license" for more information.
>>> renfe = renfe_cli.
renfe_cli.Renfe() renfe_cli.Schedule( renfe_cli.Station( renfe_cli.main() renfe_cli.renfe_cli
>>> renfe = renfe_cli.Renfe()
Loading GTFS data from Renfe web
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Renfe.__new__() missing 1 required positional argument: 'cercanias'
>>> renfe = renfe_cli.Renfe(False)
Loading default GTFS data from Renfe web - Alta velocidad, Larga distancia y Media distancia
GTFS data:
Read in 2171 ms
Stops: 793
Routes: 644
Trips: 4150
Agencies: 1
Shapes: 0
Fare attributes: 0
Feed info: 0
>>> renfe.filter_station("madrid")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Expand Down Expand Up @@ -138,10 +186,10 @@ $ maturin develop
🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.7
🐍 Not using a specific python interpreter
📡 Using build options features from pyproject.toml
Compiling renfe-cli v4.1.0 (/path/to/renfe-cli)
Compiling renfe-cli v5.1.0 (/path/to/renfe-cli)
Finished dev [unoptimized + debuginfo] target(s) in 7.07s
📦 Built wheel for abi3 Python ≥ 3.7 to /tmp/.tmpDsjowL/renfe_cli-4.1.0-cp37-abi3-linux_x86_64.whl
🛠 Installed renfe-cli-4.1.0
📦 Built wheel for abi3 Python ≥ 3.7 to /tmp/.tmpDsjowL/renfe_cli-5.1.0-cp37-abi3-linux_x86_64.whl
🛠 Installed renfe-cli-5.1.0
```

Maturin takes care of compiling the rust code, generating the bindings for python and installing the package for local use (as library or binary/CLI).
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ classifiers = [
"Operating System :: Microsoft :: Windows",
"Topic :: Utilities",
"Topic :: Terminals",
"Topic :: Text Processing :: Markup :: HTML",
]
dynamic = ["version"]

Expand Down
3 changes: 2 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn main() -> PyResult<()> {
return Ok(());
}

let mut renfe = Renfe::new()?;
let mut renfe = Renfe::new(matches.opt_present("c"))?;

let origin = renfe.filter_station(matches.opt_str("f").expect("Missing origin station"))?;
let destination =
Expand Down Expand Up @@ -74,6 +74,7 @@ fn set_opts() -> Options {
);
opts.optopt("y", "year", "Set the Year (default: today's year)", "YEAR");
opts.optflag("s", "sort", "Option to sort the timetable by Duration");
opts.optflag("c", "cercanias", "Option to search over Renfe Cercanías");
opts.optflag("h", "help", "Print this help menu");

opts
Expand Down
28 changes: 20 additions & 8 deletions src/renfe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,27 @@ pub struct Station {
#[pymethods]
impl Renfe {
#[new]
pub fn new() -> PyResult<Self> {
println!("Loading GTFS data from Renfe web");

pub fn new(cercanias: bool) -> PyResult<Self> {
let mut res = reqwest::blocking::get(
"https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_transit.zip",
match cercanias {
false => {
println!("Loading default GTFS data from Renfe web - Alta velocidad, Larga distancia y Media distancia");
"https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_transit.zip"
},
true => {
println!("Loading Cercanías GTFS data from Renfe web - long load time");
"https://ssl.renfe.com/ftransit/Fichero_CER_FOMENTO/fomento_transit.zip"
},
},
)
.expect("Error downloading GTFS zip file");
let mut body = Vec::new();
res.read_to_end(&mut body)?;
let cursor = std::io::Cursor::new(body);

let gtfs = Gtfs::from_reader(cursor).expect("Error parsing GTFS zip");
// gtfs.print_stats();

gtfs.print_stats();

Ok(Renfe {
gtfs,
Expand Down Expand Up @@ -143,18 +151,22 @@ impl Renfe {
let time_origin = origin.departure_time.unwrap();
let time_destination = destination.arrival_time.unwrap();
let departure_time = NaiveTime::from_hms_opt(
time_origin / 3600,
(time_origin / 3600) % 24,
time_origin % 3600 / 60,
time_origin % 60,
)
.unwrap();
let arrival_time = NaiveTime::from_hms_opt(
time_destination / 3600,
(time_destination / 3600) % 24,
time_destination % 3600 / 60,
time_destination % 60,
)
.unwrap();
let duration = arrival_time.signed_duration_since(departure_time);

let mut duration = arrival_time.signed_duration_since(departure_time);
if time_destination >= 86400 {
duration = duration.checked_add(&TimeDelta::seconds(86400)).unwrap();
}

schedules.push(Schedule {
train_type: gtfs
Expand Down
Loading