diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index af636f0..be48d18 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -12,7 +12,7 @@ on: tags: - '*' pull_request: - branches: [ master ] + branches: [ main ] workflow_dispatch: permissions: diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c7175..293299a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## v5.0.0 (2024-09-29) + +* Major refactor using GTFS data from Renfe online datasets. No more scrapping required + * [#194](https://github.com/gerardcl/renfe-cli/issues/194) + * [#198](https://github.com/gerardcl/renfe-cli/issues/198) + +## v4.3.2 (2024-04-21) + +* General dependencies maintenance with rustls focus [#196](https://github.com/gerardcl/renfe-cli/issues/196) + ## v4.3.1 (2024-03-30) * Upgrade PyO3 with general dependencies maintenance [#192](https://github.com/gerardcl/renfe-cli/issues/192) diff --git a/Cargo.lock b/Cargo.lock index 41d0d6c..2bf6596 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,10 +3,19 @@ version = 3 [[package]] -name = "adler" -version = "1.0.2" +name = "addr2line" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aes" @@ -19,28 +28,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -57,36 +44,31 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.81" +name = "autocfg" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] -name = "auto_generate_cdp" -version = "0.4.4" +name = "backtrace" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af08ed49930c50104b2f1699d257e5053fb1809e370647bde9c58b31d65d417" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "serde", - "serde_json", - "ureq", + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", ] -[[package]] -name = "autocfg" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" - [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -94,18 +76,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - [[package]] name = "block-buffer" version = "0.10.4" @@ -117,9 +87,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -129,9 +105,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bzip2" @@ -156,12 +132,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -172,16 +149,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets", ] [[package]] @@ -200,41 +177,35 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -247,69 +218,26 @@ dependencies = [ ] [[package]] -name = "cssparser" -version = "0.31.2" +name = "csv" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" dependencies = [ - "cssparser-macros", - "dtoa-short", + "csv-core", "itoa", - "phf 0.11.2", - "smallvec", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.57", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", + "ryu", + "serde", ] [[package]] -name = "darling_macro" -version = "0.14.4" +name = "csv-core" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", + "memchr", ] -[[package]] -name = "data-encoding" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" - [[package]] name = "deranged" version = "0.3.11" @@ -320,41 +248,10 @@ dependencies = [ ] [[package]] -name = "derive_builder" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.17" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", @@ -373,111 +270,84 @@ dependencies = [ ] [[package]] -name = "directories" -version = "5.0.1" +name = "either" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] -name = "dirs-sys" -version = "0.4.1" +name = "flate2" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "dtoa" -version = "1.0.9" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "dtoa-short" -version = "0.3.4" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "dtoa", + "percent-encoding", ] [[package]] -name = "ego-tree" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" - -[[package]] -name = "errno" -version = "0.3.8" +name = "futures-channel" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ - "libc", - "windows-sys 0.52.0", + "futures-core", + "futures-sink", ] [[package]] -name = "fastrand" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" - -[[package]] -name = "flate2" -version = "1.0.28" +name = "futures-core" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] -name = "fnv" -version = "1.0.7" +name = "futures-io" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "futures-sink" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] -name = "futf" -version = "0.1.5" +name = "futures-task" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] -name = "fxhash" -version = "0.2.1" +name = "futures-util" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "byteorder", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] @@ -501,9 +371,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -511,37 +381,41 @@ dependencies = [ ] [[package]] -name = "headless_chrome" -version = "1.0.9" +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" + +[[package]] +name = "gtfs-structures" +version = "0.41.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05dec19562a4024376a8a13c3a1b40a3b8006c5bb35c43f7d62d672cfe7b943c" +checksum = "ad38521102d1da04102f3ff28b3f0d8d4b8812cadccc3ff60d858473d9aa3a88" dependencies = [ - "anyhow", - "auto_generate_cdp", - "base64", - "derive_builder", - "directories", - "log", - "rand", - "regex", + "bytes", + "chrono", + "csv", + "derivative", + "itertools", + "rgb", "serde", - "serde_json", - "tempfile", + "serde_derive", + "sha2", "thiserror", - "tungstenite", - "ureq", - "url", - "walkdir", - "which", - "winreg", "zip", ] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hmac" @@ -553,50 +427,106 @@ dependencies = [ ] [[package]] -name = "home" -version = "0.5.9" +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "windows-sys 0.52.0", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "html5ever" -version = "0.26.0" +name = "http-body" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "log", - "mac", - "markup5ever", - "proc-macro2", - "quote", - "syn 1.0.109", + "bytes", + "http", ] [[package]] -name = "http" -version = "1.1.0" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "fnv", - "itoa", + "futures-util", + "http", + "http-body", + "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -615,12 +545,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.5.0" @@ -647,93 +571,61 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.11" +name = "ipnet" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] -name = "jobserver" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.69" +name = "itertools" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ - "wasm-bindgen", + "either", ] [[package]] -name = "libc" -version = "0.2.153" +name = "itoa" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "libredox" -version = "0.0.1" +name = "jobserver" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ - "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "lock_api" -version = "0.4.11" +name = "js-sys" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ - "autocfg", - "scopeguard", + "wasm-bindgen", ] [[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "mac" -version = "0.1.1" +name = "libc" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] -name = "markup5ever" -version = "0.11.0" +name = "log" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" -dependencies = [ - "log", - "phf 0.10.1", - "phf_codegen", - "string_cache", - "string_cache_codegen", - "tendril", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -744,20 +636,32 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] -name = "new_debug_unreachable" -version = "1.0.6" +name = "mio" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] [[package]] name = "num-conv" @@ -767,47 +671,27 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "parking_lot" -version = "0.12.1" +name = "object" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ - "lock_api", - "parking_lot_core", + "memchr", ] [[package]] -name = "parking_lot_core" -version = "0.9.9" +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "password-hash" @@ -839,96 +723,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared 0.10.0", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" +name = "pin-project-lite" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand", -] +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared 0.11.2", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.57", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "powerfmt" @@ -938,36 +754,33 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.21.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a02a88a17e74cadbc8ce77855e1d6c8ad0ab82901a4a9b5046bd01c1c0bd95cd" +checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -977,9 +790,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.21.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5eb0b6ecba38961f6f4bd6cd5906dfab3cd426ff37b2eed5771006aa31656f1" +checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3" dependencies = [ "once_cell", "target-lexicon", @@ -987,9 +800,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8a6e48a29b5d22e4fdaf132d8ba8d3203ee9f06362d48f244346902a594ec3" +checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c" dependencies = [ "libc", "pyo3-build-config", @@ -997,34 +810,82 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e80493c5965f94a747d0782a607b2328a4eea5391327b152b00e2f3b001cede" +checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.57", + "syn 2.0.79", ] [[package]] name = "pyo3-macros-backend" -version = "0.21.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd7d86f42004025200e12a6a8119bd878329e6fddef8178eaafa4e4b5906c5b" +checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1" dependencies = [ "heck", "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.57", + "syn 2.0.79", +] + +[[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand", + "ring", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1060,64 +921,66 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +name = "renfe-cli" +version = "5.0.0" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "chrono", + "getopts", + "gtfs-structures", + "pyo3", + "reqwest", ] [[package]] -name = "regex-automata" -version = "0.4.6" +name = "reqwest" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "windows-registry", ] [[package]] -name = "regex-syntax" -version = "0.8.3" +name = "rgb" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "renfe-cli" -version = "4.3.1" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ - "chrono", - "getopts", - "headless_chrome", - "pyo3", - "scraper", - "ureq", + "bytemuck", ] [[package]] @@ -1136,25 +999,24 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.38.32" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustls" -version = "0.22.3" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ - "log", + "once_cell", "ring", "rustls-pki-types", "rustls-webpki", @@ -1163,116 +1025,80 @@ dependencies = [ ] [[package]] -name = "rustls-pki-types" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" - -[[package]] -name = "rustls-webpki" -version = "0.102.2" +name = "rustls-pemfile" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ - "ring", + "base64", "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", ] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "rustls-pki-types" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] -name = "scraper" -version = "0.19.0" +name = "rustls-webpki" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b80b33679ff7a0ea53d37f3b39de77ea0c75b12c5805ac43ec0c33b3051af1b" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "ahash", - "cssparser", - "ego-tree", - "getopts", - "html5ever", - "once_cell", - "selectors", - "tendril", + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] -name = "selectors" -version = "0.25.0" +name = "ryu" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" -dependencies = [ - "bitflags 2.5.0", - "cssparser", - "derive_more", - "fxhash", - "log", - "new_debug_unreachable", - "phf 0.10.1", - "phf_codegen", - "precomputed-hash", - "servo_arc", - "smallvec", -] +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] -name = "servo_arc" -version = "0.3.0" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "stable_deref_trait", + "form_urlencoded", + "itoa", + "ryu", + "serde", ] [[package]] @@ -1298,10 +1124,19 @@ dependencies = [ ] [[package]] -name = "siphasher" -version = "0.3.11" +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" @@ -1310,14 +1145,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "socks" -version = "0.3.4" +name = "socket2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ - "byteorder", "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -1326,49 +1160,11 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro2", - "quote", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1383,9 +1179,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.57" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -1393,59 +1189,45 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - -[[package]] -name = "tempfile" -version = "3.10.1" +name = "sync_wrapper" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", + "futures-core", ] [[package]] -name = "tendril" -version = "0.4.3" +name = "target-lexicon" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.79", ] [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "num-conv", @@ -1462,9 +1244,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1476,24 +1258,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "tungstenite" -version = "0.21.0" +name = "tokio" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ - "byteorder", + "backtrace", "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "sha1", - "thiserror", - "url", - "utf-8", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.17.0" @@ -1508,24 +1328,24 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unindent" @@ -1539,55 +1359,30 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "ureq" -version = "2.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f214ce18d8b2cbe84ed3aa6486ed3f5b285cf8d8fbdbce9f3f767a724adc35" -dependencies = [ - "base64", - "flate2", - "log", - "once_cell", - "rustls", - "rustls-pki-types", - "rustls-webpki", - "socks", - "url", - "webpki-roots", -] - [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "walkdir" -version = "2.5.0" +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "same-file", - "winapi-util", + "try-lock", ] [[package]] @@ -1598,34 +1393,47 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.79", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1633,92 +1441,79 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] -name = "webpki-roots" -version = "0.26.1" +name = "web-sys" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ - "rustls-pki-types", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "which" -version = "5.0.0" +name = "webpki-roots" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ - "either", - "home", - "once_cell", - "rustix", - "windows-sys 0.48.0", + "rustls-pki-types", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "winapi", + "windows-result", + "windows-strings", + "windows-targets", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.4", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-targets 0.48.5", + "windows-result", + "windows-targets", ] [[package]] @@ -1727,158 +1522,108 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" - -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.79", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" @@ -1921,9 +1666,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 2911c26..9bda8fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "renfe-cli" -version = "4.3.1" +version = "5.0.0" edition = "2021" license = "BSD-3-Clause" description = "CLI for searching Renfe train timetables in the Spanish country" @@ -16,9 +16,8 @@ name = "renfe_cli" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21", features = ["abi3-py37"] } -headless_chrome = { version = "1.0", features = ["fetch"] } -scraper = "0.19" -ureq = "2.9" +pyo3 = { version = "0.22", features = ["abi3-py37"] } getopts = "0.2" chrono = "0.4" +gtfs-structures = { version = "0.41", default-features = false } +reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] } diff --git a/README.md b/README.md index 419f9bf..1c14ac8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ See the [changelog](https://github.com/gerardcl/renfe-cli/blob/master/CHANGELOG. **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)). + ## Installation Install Python CLI package [renfe-cli](https://pypi.org/project/renfe-cli/) @@ -21,18 +23,7 @@ pip install renfe-cli --upgrade ## Usage (CLI) -This CLI behaves as a person/bot going through the official renfe.com search site, using headless chrome browser. -If the headless chrome browser is not found it will be downloaded. - -The navigation through the site happens in the following steps: - -1. Writes down and selects origin station -2. Writes down and selects destination station -3. Writes down and selects the day to search for -4. Writes down and selects the month to search for -5. Writes down and selects the year to search for -6. Clicks on search button -7. Parses the HTML data, optionally sorts the connections and prints the timetable +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). ```bash $ renfe-cli -h @@ -41,10 +32,9 @@ Usage: renfe-cli [options] Options: -f ORIGIN Set From origin station -t DESTINATION Set To destination station - -d, --day DAY Set Day to search timetable for (default: today) - -m, --month MONTH Set Month to search timetable for (default: today's month) - -y, --year YEAR Set Year to search timetable for (default: today's year) - -w, --wait SECONDS Set Wait time in seconds for Renfe search result page (default: 2) + -d, --day DAY Set the Day (default: today's day) + -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 -h, --help Print this help menu ``` @@ -54,83 +44,29 @@ Options: Let's show an example of minimal inputs (origin and destination stations) with specific date: ```bash -$ renfe-cli -f Barc -t Mad -d 27 -Loading stations from Renfe web -Provided input 'Barc' station matches with 'Barcelona (ALL) '...continue -Provided input 'Mad' station matches with 'Madrid (ALL) '...continue -Today is: 2023-11-26 -Searching timetable for date: 2023-11-27 -loading headless chrome browser -navigating to renfe timetable search page -waiting for search page -adding origin station -adding destination station -adding day -adding month -adding year -searching timetable -got timetable page -loading timetable +$ renfe-cli -f girona -t "puerta de atocha" -d 30 +Loading GTFS data from Renfe web +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 +Searching timetable for date: 2024-9-30 +Origin station: Estación de tren Girona +Destination station: Estación de tren Madrid-Puerta de Atocha + =========================TIMETABLE========================= -Train | Departure | Arrival | Duration ------------------------------------------------------------ -AVE | 05.50 | 09.10 | 3 h. 20 min. ------------------------------------------------------------ -AVE | 06.20 | 08.50 | 2 h. 30 min. ------------------------------------------------------------ -AVLO | 06.35 | 09.20 | 2 h. 45 min. ------------------------------------------------------------ -AVE | 07.00 | 09.30 | 2 h. 30 min. ------------------------------------------------------------ -AVE | 07.40 | 10.10 | 2 h. 30 min. ------------------------------------------------------------ -LD-AVE | 07.45 | 15.35 | 7 h. 50 min. ------------------------------------------------------------ -AVE | 08.00 | 11.12 | 3 h. 12 min. ------------------------------------------------------------ -AVE | 08.25 | 10.55 | 2 h. 30 min. ------------------------------------------------------------ -REG.EXP. | 08.43 | 18.09 | 9 h. 26 min. ------------------------------------------------------------ -AVE | 09.00 | 11.45 | 2 h. 45 min. ------------------------------------------------------------ -AVLO | 10.00 | 13.17 | 3 h. 17 min. ------------------------------------------------------------ -AVE | 11.00 | 13.45 | 2 h. 45 min. ------------------------------------------------------------ -AVE | 12.00 | 15.12 | 3 h. 12 min. ------------------------------------------------------------ -AVE INT | 12.50 | 15.45 | 2 h. 55 min. + Train | Departure | Arrival | Duration ----------------------------------------------------------- -AVE | 13.25 | 15.54 | 2 h. 29 min. + AVLO | 05:46 | 09:20 | 03:34 ----------------------------------------------------------- -AVE | 14.00 | 17.12 | 3 h. 12 min. + AVE | 06:41 | 10:10 | 03:29 ----------------------------------------------------------- -AVLO | 15.00 | 17.45 | 2 h. 45 min. + AVE | 08:11 | 11:45 | 03:34 ----------------------------------------------------------- -AVE | 15.25 | 17.55 | 2 h. 30 min. + AVE INT | 11:59 | 15:45 | 03:46 ----------------------------------------------------------- -AVE | 16.00 | 19.12 | 3 h. 12 min. + AVE | 15:11 | 19:12 | 04:01 ----------------------------------------------------------- -AVE | 16.25 | 18.55 | 2 h. 30 min. ------------------------------------------------------------ -AVE | 17.00 | 19.45 | 2 h. 45 min. ------------------------------------------------------------ -AVE | 17.25 | 19.55 | 2 h. 30 min. ------------------------------------------------------------ -AVE | 18.00 | 21.12 | 3 h. 12 min. ------------------------------------------------------------ -AVE | 18.25 | 20.55 | 2 h. 30 min. ------------------------------------------------------------ -AVE | 18.40 | 21.45 | 3 h. 5 min. ------------------------------------------------------------ -AVE | 19.25 | 21.55 | 2 h. 30 min. ------------------------------------------------------------ -AVE | 20.00 | 23.12 | 3 h. 12 min. ------------------------------------------------------------ -AVLO | 21.00 | 23.45 | 2 h. 45 min. ------------------------------------------------------------ -AVE | 21.25 | 23.55 | 2 h. 30 min. + AVE | 17:51 | 21:45 | 03:54 =========================================================== ``` @@ -140,25 +76,49 @@ AVE | 21.25 | 23.55 | 2 h. 30 min. ```bash $ python -Python 3.8.18 (default, Aug 25 2023, 13:20:30) -[GCC 11.4.0] on linux +Python 3.12.6 (main, Sep 8 2024, 13:18:56) [GCC 14.2.1 20240805] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import renfe_cli >>> renfe = renfe_cli. -renfe_cli.Renfe( renfe_cli.main( renfe_cli.print_timetable( renfe_cli.renfe_cli renfe_cli.search_timetable( +renfe_cli.Renfe() renfe_cli.Schedule( renfe_cli.Station( renfe_cli.main() renfe_cli.renfe_cli >>> renfe = renfe_cli.Renfe() -Loading stations from Renfe web ->>> renfe. -renfe.filter_station( renfe.stations_match( ->>> renfe.stations_match("Bar") -['Barcelona (ALL) ', 'Padrón-Barbanza'] +Loading GTFS data from Renfe web +>>> renfe.filter_station("madrid") +Traceback (most recent call last): + File "", line 1, in +ValueError: Provided input 'madrid' does match with '[Station { name: "Estación de tren Madrid-Puerta de Atocha", id: "60000" }, Station { name: "Estación de tren Madrid - Atocha Cercanias", id: "18000" }, Station { name: "Estación de tren Madrid-Principe Pio", id: "10000" }, Station { name: "Estación de tren Madrid-Ramon Y Cajal", id: "97201" }, Station { name: "Estación de tren Madrid-Nuevos Ministerios", id: "18002" }, Station { name: "Estación de tren Madrid-Chamartin", id: "17000" }, Station { name: "Estación de tren Madrid-Recoletos", id: "18001" }]' -> There must be ONLY one match +>>> renfe.filter_station("girona") +Provided input 'girona' does a match with 'Station { name: "Estación de tren Girona", id: "79300" }' + +>>> renfe.print_timetable() + +No schedules available...won't print timetable. +>>> renfe.set_train_schedules("79300", "60000", 30, 9, 2024, False) +>>> renfe.print_timetable() + +=========================TIMETABLE========================= + Train | Departure | Arrival | Duration +----------------------------------------------------------- + AVLO | 05:46 | 09:20 | 03:34 +----------------------------------------------------------- + AVE | 06:41 | 10:10 | 03:29 +----------------------------------------------------------- + AVE | 08:11 | 11:45 | 03:34 +----------------------------------------------------------- + AVE INT | 11:59 | 15:45 | 03:46 +----------------------------------------------------------- + AVE | 15:11 | 19:12 | 04:01 +----------------------------------------------------------- + AVE | 17:51 | 21:45 | 03:54 +=========================================================== +>>> ... ``` --- ## Contribute or Report with Issues -If Renfe's website is changed or you find any issue to be fixed or nice enhancements to have, please: [create an issue](https://github.com/gerardcl/renfe-cli/issues). +If Renfe's GTFS dataset is being kept not up to date or you find any issue to be fixed or nice enhancements to have, please: [create an issue](https://github.com/gerardcl/renfe-cli/issues). ### Development @@ -170,8 +130,8 @@ Example of first time working with this repository: ```bash $ git clone https://github.com/gerardcl/renfe-cli.git && cd renfe-cli -$ python -m venv venv -$ . venv/bin/activate +$ python -m venv .venv +$ . .venv/bin/activate $ pip install -U pip $ pip install -U maturin $ maturin develop diff --git a/pyproject.toml b/pyproject.toml index 8896a73..46d9993 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Get faster Renfe Spanish Trains timetables in your terminal." readme = "README.md" license = {file = "LICENSE"} -keywords = ["timetables", "trains", "renfe", "cli", "rust", "pyo3", "maturin"] +keywords = ["timetables", "schedules", "trains", "renfe", "cli", "rust", "python", "pyo3", "maturin"] classifiers = [ "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", diff --git a/src/cli.rs b/src/cli.rs index 3decc88..f93fc1c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -3,10 +3,7 @@ use getopts::Options; use pyo3::{exceptions::PyValueError, pyfunction, PyResult}; use std::env; -use crate::{ - stations::Renfe, - timetable::{print_timetable, search_timetable}, -}; +use crate::renfe::Renfe; #[pyfunction] pub fn main() -> PyResult<()> { @@ -14,7 +11,6 @@ pub fn main() -> PyResult<()> { let program = args[0].clone(); let now = Utc::now(); let opts = set_opts(); - let renfe = Renfe::new()?; let matches = match opts.parse(&args[1..]) { Ok(m) => m, @@ -27,37 +23,37 @@ pub fn main() -> PyResult<()> { print_usage(&program, opts); return Ok(()); } - let origin = renfe.filter_station(matches.opt_str("f").unwrap_or("".to_owned()))?; - let destination = renfe.filter_station(matches.opt_str("t").unwrap_or("".to_owned()))?; - let day = enrich_day(matches.opt_str("d").unwrap_or(now.day().to_string())); - let month = matches.opt_str("m").unwrap_or(now.month().to_string()); - let year = matches.opt_str("y").unwrap_or(now.year().to_string()); - let wait = matches - .opt_str("w") - .unwrap_or(2.to_string()) - .parse::()?; + + let mut renfe = Renfe::new()?; + + let origin = renfe.filter_station(matches.opt_str("f").expect("Missing origin station"))?; + let destination = + renfe.filter_station(matches.opt_str("t").expect("Missing destination station"))?; + let day = match matches.opt_str("d") { + Some(day) => day.parse()?, + None => now.day(), + }; + let month = match matches.opt_str("m") { + Some(day) => day.parse()?, + None => now.month(), + }; + let year = match matches.opt_str("y") { + Some(day) => day.parse()?, + None => now.year(), + }; let sorted: bool = matches.opt_present("s"); - println!( - "Today is: {}-{}-{}", - now.year(), - now.month(), - enrich_day(now.day().to_string()) - ); + println!("Today is: {}-{}-{}", now.year(), now.month(), now.day()); println!("Searching timetable for date: {}-{}-{}", year, month, day); - let timetable = search_timetable(origin, destination, day, month, year, wait, sorted)?; + renfe.set_train_schedules(&origin.id, &destination.id, day, month, year, sorted)?; - print_timetable(timetable); - Ok(()) -} + println!("Origin station: {}", origin.name); + println!("Destination station: {}", destination.name); -fn enrich_day(day: String) -> String { - if day.len() == 1 { - "0".to_owned() + &day - } else { - day - } + renfe.print_timetable(); + + Ok(()) } fn print_usage(program: &str, opts: Options) { @@ -69,30 +65,14 @@ fn set_opts() -> Options { let mut opts = Options::new(); opts.optopt("f", "", "Set From origin station", "ORIGIN"); opts.optopt("t", "", "Set To destination station", "DESTINATION"); - opts.optopt( - "d", - "day", - "Set Day to search timetable for (default: today)", - "DAY", - ); + opts.optopt("d", "day", "Set the Day (default: today's day)", "DAY"); opts.optopt( "m", "month", - "Set Month to search timetable for (default: today's month)", + "Set the Month (default: today's month)", "MONTH", ); - opts.optopt( - "y", - "year", - "Set Year to search timetable for (default: today's year)", - "YEAR", - ); - opts.optopt( - "w", - "wait", - "Set Wait time in seconds for Renfe search result page (default: 2)", - "SECONDS", - ); + 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("h", "help", "Print this help menu"); diff --git a/src/lib.rs b/src/lib.rs index 2cb0b3b..81fc71b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,7 @@ use pyo3::prelude::*; -mod stations; -use stations::Renfe; -mod timetable; -use timetable::{print_timetable, search_timetable}; +mod renfe; +use renfe::{Renfe, Schedule, Station}; mod cli; use cli::main; @@ -13,8 +11,8 @@ use cli::main; #[pymodule] fn renfe_cli(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; - m.add_function(wrap_pyfunction!(search_timetable, m)?)?; - m.add_function(wrap_pyfunction!(print_timetable, m)?)?; + m.add_class::()?; + m.add_class::()?; m.add_function(wrap_pyfunction!(main, m)?)?; Ok(()) diff --git a/src/renfe.rs b/src/renfe.rs new file mode 100644 index 0000000..4e88ddd --- /dev/null +++ b/src/renfe.rs @@ -0,0 +1,267 @@ +use std::io::Read; + +use chrono::{Datelike, NaiveDate, NaiveTime, TimeDelta, Timelike}; +use gtfs_structures::Gtfs; +use pyo3::{exceptions::PyValueError, pyclass, pymethods, PyResult}; + +#[pyclass] +pub struct Renfe { + gtfs: Gtfs, + schedules: Vec, +} + +// Struct to hold the schedule details +#[pyclass] +pub struct Schedule { + train_type: String, + // origin_stop_name: String, + // destination_stop_name: String, + departure_time: NaiveTime, + arrival_time: NaiveTime, + duration: TimeDelta, +} + +// Struct to hold the station name and ID +#[pyclass] +#[derive(Debug, Clone)] +pub struct Station { + pub name: String, + pub id: String, +} + +#[pymethods] +impl Renfe { + #[new] + pub fn new() -> PyResult { + println!("Loading GTFS data from Renfe web"); + + let mut res = reqwest::blocking::get( + "https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_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(); + + Ok(Renfe { + gtfs, + schedules: Vec::new(), + }) + } + + pub fn all_stations(&self) -> PyResult> { + let stations: Vec = self + .gtfs + .stops + .iter() + .map(|s| Station { + name: s.1.name.clone().unwrap(), + id: s.1.id.clone(), + }) + .collect(); + Ok(stations) + } + + pub fn stations_match(&self, station: String) -> PyResult> { + let found: Vec = self + .gtfs + .stops + .iter() + .filter(|s| { + s.1.name + .clone() + .unwrap() + .to_lowercase() + .contains(&station.to_lowercase()) + }) + .map(|s| Station { + name: s.1.name.clone().unwrap(), + id: s.1.id.clone(), + }) + .collect(); + Ok(found) + } + + pub fn filter_station(&self, station: String) -> PyResult { + match self.stations_match(station.clone()) { + Ok(v) if v.len() == 1 => { + println!( + "Provided input '{}' does a match with '{:?}'", + station, v[0] + ); + Ok(v[0].clone()) + } + Ok(v) => Err(PyValueError::new_err(format!( + "Provided input '{station}' does match with '{v:?}' -> There must be ONLY one match" + ))), + Err(e) => Err(e), + } + } + + // Function to get train schedules between an origin and a destination on a given date + pub fn set_train_schedules( + &mut self, + origin_station_id: &str, + destination_station_id: &str, + day: u32, + month: u32, + year: i32, + sorted: bool, + ) -> PyResult<()> { + let gtfs = &self.gtfs; + // the date for which schedules are needed + let date = match NaiveDate::from_ymd_opt(year, month, day) { + Some(date) => date, + None => { + return Err(PyValueError::new_err(format!( + "Provided date '{year}-{month}-{day}' does not exist" + ))) + } + }; + + let mut schedules = Vec::new(); + + // Loop through each trip to find ones active on the given date + for trip in gtfs.trips.values() { + // Check if the trip's service is active on the given date + if is_service_active(gtfs, &trip.service_id, date) { + // Filter stop times for the trip + let stop_times: Vec<_> = trip.stop_times.clone(); + + // Find the origin and destination stops in the trip's stop times + let origin_stop = stop_times.iter().find(|st| st.stop.id == origin_station_id); + let destination_stop = stop_times + .iter() + .find(|st| st.stop.id == destination_station_id); + + // If the trip includes both origin and destination, and origin is before destination + if let (Some(origin), Some(destination)) = (origin_stop, destination_stop) { + if origin.stop_sequence < destination.stop_sequence { + 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 / 60, + time_origin % 60, + ) + .unwrap(); + let arrival_time = NaiveTime::from_hms_opt( + time_destination / 3600, + time_destination % 3600 / 60, + time_destination % 60, + ) + .unwrap(); + let duration = arrival_time.signed_duration_since(departure_time); + + schedules.push(Schedule { + train_type: gtfs + .get_route(&trip.route_id) + .unwrap() + .short_name + .clone() + .unwrap(), + // origin_stop_name: gtfs.stops[&origin.stop.id].name.clone().unwrap(), + // destination_stop_name: gtfs.stops[&destination.stop.id] + // .name + // .clone() + // .unwrap(), + departure_time, + arrival_time, + duration, + }); + } + } + } + } + + // Sort schedules by departure_time + schedules.sort_by_key(|schedule| schedule.departure_time); + + if sorted { + println!("sorting timetable by duration"); + schedules.sort_by(|a, b| a.duration.cmp(&b.duration)); + } + + self.schedules = schedules; + + Ok(()) + } + + pub fn print_timetable(&self) { + if self.schedules.is_empty() { + println!("\nNo schedules available...won't print timetable."); + } else { + println!("\n=========================TIMETABLE========================="); + println!( + " {0: <12} | {1: <10} | {2: <10} | {3: <12}", + "Train", "Departure", "Arrival", "Duration" + ); + for track in &self.schedules { + println!("-----------------------------------------------------------"); + println!( + " {0: <11} | {1: <9} | {2: <9} | {3: <10}", + track.train_type, + format!( + "{:02}:{:02}", + track.departure_time.hour(), + track.departure_time.minute() % 60 + ), + format!( + "{:02}:{:02}", + track.arrival_time.hour(), + track.arrival_time.minute() % 60 + ), + format!( + "{:02}:{:02}", + track.duration.num_hours(), + track.duration.num_minutes() % 60 + ) + ); + } + println!("==========================================================="); + } + } +} + +// Helper function to check if a service is active on a given date +fn is_service_active(gtfs: &Gtfs, service_id: &str, date: NaiveDate) -> bool { + // First check the `calendar.txt` + if let Some(calendar) = gtfs.calendar.get(service_id) { + let weekday = match date.weekday() { + chrono::Weekday::Mon => calendar.monday, + chrono::Weekday::Tue => calendar.tuesday, + chrono::Weekday::Wed => calendar.wednesday, + chrono::Weekday::Thu => calendar.thursday, + chrono::Weekday::Fri => calendar.friday, + chrono::Weekday::Sat => calendar.saturday, + chrono::Weekday::Sun => calendar.sunday, + }; + + if weekday && date >= calendar.start_date && date <= calendar.end_date { + // this should never happen - but a check is for free + if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { + for date_override in calendar_dates { + if date_override.date == date { + return !(date_override.exception_type + == gtfs_structures::Exception::Deleted); + } + } + } + return true; + } + } + + // Then check the `calendar_dates.txt` for exceptions + if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { + for date_override in calendar_dates { + if date_override.date == date { + return date_override.exception_type == gtfs_structures::Exception::Added; + } + } + } + + false +} diff --git a/src/stations.rs b/src/stations.rs deleted file mode 100644 index a3efbc1..0000000 --- a/src/stations.rs +++ /dev/null @@ -1,61 +0,0 @@ -use pyo3::{ - exceptions::{PyConnectionError, PyValueError}, - pyclass, pymethods, PyResult, -}; -use scraper::{Html, Selector}; - -#[pyclass] -pub struct Renfe { - stations: Vec, -} - -#[pymethods] -impl Renfe { - #[new] - pub fn new() -> PyResult { - println!("Loading stations from Renfe web"); - let response = match ureq::get("https://www.renfe.com/content/renfe/es/en/viajar/informacion-util/horarios/app-horarios.html").call() { - Ok(response) => { response }, - Err(_) => { return Err(PyConnectionError::new_err("something wrong")) } - }; - - let parsed_html = Html::parse_document(&response.into_string().unwrap()); - - let selector = &Selector::parse(r#"#O > option"#).unwrap(); - - let stations: Vec = parsed_html - .select(selector) - .flat_map(|el| el.text()) - .map(|t| t.to_string()) - .collect(); - - Ok(Renfe { - stations: stations[1..].to_vec(), - }) - } - - pub fn stations_match(&self, station: String) -> PyResult> { - let found: Vec<&String> = self - .stations - .iter() - .filter(|s| s.contains(&station)) - .collect(); - Ok(found) - } - - pub fn filter_station(&self, station: String) -> PyResult { - match self.stations_match(station.clone()) { - Ok(v) if v.len() == 1 => { - println!( - "Provided input '{}' station matches with '{}'...continue", - station, v[0] - ); - Ok(v[0].to_owned()) - } - Ok(v) => Err(PyValueError::new_err(format!( - "Provided input '{station}' station does not match one '{v:?}'" - ))), - Err(e) => Err(e), - } - } -} diff --git a/src/timetable.rs b/src/timetable.rs deleted file mode 100644 index db5d993..0000000 --- a/src/timetable.rs +++ /dev/null @@ -1,252 +0,0 @@ -use headless_chrome::{Browser, LaunchOptions}; -use pyo3::{pyfunction, PyResult}; -use scraper::{ElementRef, Html, Selector}; -use std::{collections::HashMap, thread::sleep, time::Duration}; - -trait VecParser { - fn texts_parser(&self, selector: Selector) -> Vec; -} - -impl VecParser for ElementRef<'_> { - fn texts_parser(&self, selector: Selector) -> Vec { - self.select(&selector) - .flat_map(|el| el.text()) - .map(|t| t.to_string()) - .map(|x| x.trim().to_string()) - .filter(|x| !x.is_empty()) - .collect() - } -} - -// Convenience function to avoid unwrap()ing all the time -fn make_selector(selector: &str) -> Selector { - Selector::parse(selector).unwrap() -} - -fn to_renfe_day(day: String) -> String { - let first_digit: u8 = day.parse::().unwrap() / 10; - let last_digit: u8 = day.parse::().unwrap() % 10; - let mut renfe_day: String = String::new(); - if day.starts_with('0') { - day - } else { - for _ in 0..last_digit + 1 { - renfe_day += &first_digit.to_string(); - } - renfe_day - } -} - -fn to_renfe_month(month: String) -> String { - let months: HashMap<&str, &str> = HashMap::from([ - ("1", "Ene"), - ("2", "Feb"), - ("3", "Mar"), - ("4", "Abr"), - ("5", "May"), - ("6", "Jun"), - ("7", "Jul"), - ("8", "Ago"), - ("9", "Sep"), - ("10", "Oct"), - ("11", "Nov"), - ("12", "Dec"), - ]); - months[month.as_str()].to_owned() -} - -fn get_duration_from_renfe_string(s: &str) -> u16 { - let splits: Vec<&str> = s.split(' ').collect(); - if s.contains('h') { - let hours = splits[0].parse::().unwrap(); - let minutes = splits[2].parse::().unwrap(); - hours * 60 + minutes - } else { - splits[0].parse::().unwrap() - } -} - -#[pyfunction] -pub fn search_timetable( - origin: String, - destination: String, - day: String, - month: String, - year: String, - wait: u64, - sorted: bool, -) -> PyResult>> { - println!("loading headless chrome browser"); - let browser = Browser::new(LaunchOptions { - headless: true, - sandbox: true, - enable_gpu: false, - enable_logging: false, - idle_browser_timeout: Duration::from_secs(30), - window_size: Some((1920, 1080)), - path: None, - user_data_dir: None, - port: None, - ignore_certificate_errors: true, - extensions: Vec::new(), - process_envs: None, - fetcher_options: Default::default(), - args: Vec::new(), - disable_default_args: false, - proxy_server: None, - }) - .unwrap(); - - let tab = browser.new_tab().unwrap(); - tab.set_default_timeout(Duration::from_secs(wait)); - - println!("navigating to renfe timetable search page"); - tab.navigate_to("https://www.renfe.com/es/es/viajar/informacion-util/horarios") - .unwrap() - .wait_until_navigated() - .unwrap(); - - println!("waiting for search page"); - tab.wait_until_navigated() - .unwrap() - .wait_for_elements_by_xpath(r#"//*[@id="O"]"#) - .unwrap(); - - // let _jpeg_data = tab - // .capture_screenshot(Page::CaptureScreenshotFormatOption::Jpeg, None, None, true) - // .unwrap(); - // std::fs::write("./screenshot1.jpg", _jpeg_data)?; - - println!("adding origin station"); - tab.find_element_by_xpath(r#"//*[@id="O"]"#) - .unwrap() - .type_into(&origin) - .unwrap(); - - println!("adding destination station"); - tab.find_element_by_xpath(r#"//*[@id="D"]"#) - .unwrap() - .type_into(&destination) - .unwrap(); - - println!("adding day"); - tab.find_element_by_xpath(r#"//*[@id="DF"]"#) - .unwrap() - .type_into(&to_renfe_day(day)) - .unwrap(); - - println!("adding month"); - tab.find_element_by_xpath(r#"//*[@id="MF"]"#) - .unwrap() - .type_into(&to_renfe_month(month)) - .unwrap(); - - println!("adding year"); - tab.find_element_by_xpath(r#"//*[@id="AF"]"#) - .unwrap() - .type_into(&year) - .unwrap(); - - println!("searching timetable"); - - tab.find_element_by_xpath(r#"//*[@id="seleccion"]/fieldset/div[3]/button"#) - .unwrap() - .click() - .unwrap(); - - // wait on navigating and prepare search in result page - let html = tab.wait_until_navigated().unwrap(); - println!("got timetable page"); - - println!("wait for timetable iframe"); - sleep(Duration::from_secs(wait)); - - let table_content = html - .wait_for_elements_by_xpath(r#"//*[@id="contenedor"]"#) - .unwrap() - .first() - .unwrap() - .get_content() - .unwrap(); - - println!("loading timetable"); - - let parsed_html = Html::parse_document(&table_content); - - let resum_selector = make_selector(r#"tr.odd"#); - let total_tracks = parsed_html.select(&resum_selector); - // println!("#trajectes: {:?}", &total_tracks.count()); - - let mut tracks: Vec> = Vec::new(); - for track in total_tracks { - let columns_selector: Selector = make_selector(r#"td"#); - let columns = track.texts_parser(columns_selector); - let mut row = Vec::::with_capacity(4); - for (idx, column) in columns.iter().enumerate() { - if idx == 0 { - let train = column - .trim_start_matches(char::is_numeric) - .trim() - .to_owned(); - // println!("#sortida: {:?}", &train); - row.push(train); - } - if (1..4).contains(&idx) { - let timing = column.trim().to_owned(); - // println!("#sortida: {:?}", &timing); - row.push(timing); - } - } - tracks.push(row); - } - - if sorted { - println!("sorting timetable"); - tracks.sort_by(|a, b| { - get_duration_from_renfe_string(&a[3]).cmp(&get_duration_from_renfe_string(&b[3])) - }); - } - - Ok(tracks) -} - -#[pyfunction] -pub fn print_timetable(tracks: Vec>) { - println!("=========================TIMETABLE========================="); - println!( - "{0: <12} | {1: <10} | {2: <10} | {3: <12}", - "Train", "Departure", "Arrival", "Duration" - ); - for track in tracks { - println!("-----------------------------------------------------------"); - println!( - "{0: <12} | {1: <9} | {2: <9} | {3: <12}", - track[0], track[1], track[2], track[3] - ); - } - println!("==========================================================="); -} - -#[cfg(test)] -mod tests { - use chrono::{Datelike, Utc}; - - use crate::{print_timetable, search_timetable}; - - #[test] - fn test_search_and_print_timetable() -> Result<(), Box> { - let now = Utc::now(); - - print_timetable(search_timetable( - "Girona".to_owned(), - "Barcelona".to_owned(), - now.day().to_string(), - now.month().to_string(), - now.year().to_string(), - 15, - false, - )?); - - Ok(()) - } -}