Skip to content

Commit

Permalink
Merge pull request #201 from gerardcl/feat/enable-all-cercanias-optio…
Browse files Browse the repository at this point in the history
…nally

Feat/enable all cercanias optionally
  • Loading branch information
gerardcl authored Oct 2, 2024
2 parents b582ba2 + 3928f96 commit a4e8fa4
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 32 deletions.
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

0 comments on commit a4e8fa4

Please sign in to comment.