diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index a924beb..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[target.x86_64-pc-windows-gnu] -linker = "/opt/homebrew/bin/x86_64-w64-mingw32-gcc" -ar = "/opt/homebrew/bin/x86_64-w64-mingw32-ar" diff --git a/.env.example b/.env.example index ad7fd11..8856212 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,11 @@ -# Airbnb keys -_AAT= -AIRBNB_API_KEY= - # Local keys EXAMPLE_CSV= BASE_XLSX= FIRST_SHEET= -SECOND_SHEET= \ No newline at end of file +SECOND_SHEET= +THIRD_SHEET= +OUTPUT_FILE_PREFIX_1= +OUTPUT_FILE_PREFIX_2= + +# AWS +SSM_PREFIX= \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index a1506ea..c0c5bae 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,9 @@ "editor.defaultFormatter": "rust-lang.rust-analyzer", "editor.formatOnSave": true }, + "[markdown]": { + "editor.formatOnSave": true + }, "files.watcherExclude": { "**/target": true } diff --git a/Cargo.lock b/Cargo.lock index 6e78bb5..bae6955 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,7 +48,6 @@ dependencies = [ "aws-sdk-ssm", "calamine", "chrono", - "crossterm", "dotenv", "lazy_static", "polars", @@ -113,9 +112,9 @@ checksum = "9ae037714f313c1353189ead58ef9eec30a8e8dc101b2622d461418fd59e28a9" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-config" @@ -462,9 +461,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64-simd" @@ -585,12 +584,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.94" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -762,10 +762,7 @@ dependencies = [ "bitflags 2.5.0", "crossterm_winapi", "libc", - "mio", "parking_lot", - "signal-hook", - "signal-hook-mio", "winapi", ] @@ -883,15 +880,15 @@ checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "flate2" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4556222738635b7a3417ae6130d8f52201e45a0c4d1a907f0826383adb5f85e7" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1077,9 +1074,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -1349,9 +1346,9 @@ checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" [[package]] name = "jobserver" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -1454,9 +1451,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libloading" @@ -1492,9 +1489,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1569,7 +1566,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "log", "wasi", "windows-sys 0.48.0", ] @@ -1659,9 +1655,9 @@ dependencies = [ [[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", "libm", @@ -1744,9 +1740,9 @@ checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -1754,15 +1750,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -1773,9 +1769,9 @@ checksum = "1131c54b167dd4e4799ce762e1ab01549ebb94d5bdd13e6ec1b467491c378e1f" [[package]] name = "parse-zoneinfo" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" dependencies = [ "regex", ] @@ -2356,9 +2352,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.1" +version = "11.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" dependencies = [ "bitflags 2.5.0", ] @@ -2405,11 +2401,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] @@ -2473,7 +2469,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "bytes", "encoding_rs", "futures-channel", @@ -2548,9 +2544,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -2598,15 +2594,15 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" [[package]] name = "rustls-webpki" @@ -2692,18 +2688,18 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -2751,32 +2747,11 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2839,9 +2814,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3023,18 +2998,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", @@ -3138,16 +3113,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -3260,9 +3234,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "untrusted" @@ -3643,18 +3617,18 @@ checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index deaedc2..d2c523b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ aws-credential-types = { version = "1.2.0", features = [ aws-sdk-ssm = "1.25.0" calamine = "0.24.0" chrono = "0.4.38" -crossterm = "0.27.0" dotenv = "0.15.0" lazy_static = "1.4.0" polars = { version = "0.39.2", features = ["json", "lazy"] } diff --git a/README.md b/README.md index baa8347..204fa76 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# airbnb-reservations-scraper +# Airbnb hosting reservations scraper + +For cross building (MacOS -> Windows) install: + +```zsh +cargo install cross +docker pull --platform linux/amd64 ghcr.io/cross-rs/x86_64-pc-windows-gnu:0.2.5 +cross build --target x86_64-pc-windows-gnu --release +``` diff --git a/src/config/globals.rs b/src/config/globals.rs index 8951c32..1ff4fd5 100644 --- a/src/config/globals.rs +++ b/src/config/globals.rs @@ -1,3 +1,4 @@ +use chrono::Local; use dotenv::dotenv; use std::env; @@ -7,7 +8,9 @@ pub struct Config { pub first_sheet: String, pub second_sheet: String, pub third_sheet: String, - pub output_file: String, + pub output_file_prefix_1: String, + pub output_file_prefix_2: String, + pub datetime_suffix: String, } impl Config { @@ -19,7 +22,11 @@ impl Config { let first_sheet: String = env::var("FIRST_SHEET").expect("FIRST_SHEET must be set"); let second_sheet: String = env::var("SECOND_SHEET").expect("SECOND_SHEET must be set"); let third_sheet: String = env::var("THIRD_SHEET").expect("THIRD_SHEET must be set"); - let output_file: String = env::var("OUTPUT_FILE").expect("OUTPUT_FILE must be set"); + let output_file_prefix_1: String = + env::var("OUTPUT_FILE_PREFIX_1").expect("OUTPUT_FILE_PREFIX_1 must be set"); + let output_file_prefix_2: String = + env::var("OUTPUT_FILE_PREFIX_2").expect("OUTPUT_FILE_PREFIX_2 must be set"); + let datetime_suffix: String = Local::now().format("%Y%m%d%H%M%S").to_string(); Config { example_csv, @@ -27,7 +34,9 @@ impl Config { first_sheet, second_sheet, third_sheet, - output_file, + output_file_prefix_1, + output_file_prefix_2, + datetime_suffix, } } } diff --git a/src/helpers/engine.rs b/src/helpers/engine.rs index ad513a6..93c07a5 100644 --- a/src/helpers/engine.rs +++ b/src/helpers/engine.rs @@ -1,8 +1,8 @@ use super::excel::write_to_excel_file; +use crate::config::globals::CONFIG; use crate::models::reservation::{Reservation, ReservationTable}; use aws_credential_types::Credentials; use aws_sdk_ssm::{config::Region, Client as ssm_client, Config}; -use chrono::{DateTime, Local}; use dotenv::dotenv; use polars::prelude::*; use regex::Regex; @@ -188,8 +188,11 @@ pub fn get_data(min_date: &str) -> Result<(String, Vec), reqwest::E _offset += delta; } - let now: DateTime = Local::now(); - let filename: String = format!("reservations_{}.xlsx", now.format("%Y%m%d%H%M%S")); + let filename: String = format!( + "{}_{}.xlsx", + CONFIG.output_file_prefix_1.as_str(), + CONFIG.datetime_suffix.as_str() + ); write_to_excel_file(&filename, &reservations).expect("Failed to write to file"); Ok((filename.to_string(), reservations)) diff --git a/src/main.rs b/src/main.rs index 7b49223..3726a8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,12 @@ mod config; mod helpers; mod models; use config::globals::CONFIG; -use crossterm::event; use helpers::engine::{get_data, get_dataframe, process_data}; use helpers::excel::{open_xlsx, write_to_excel_file_refac}; use polars::prelude::*; use std::collections::HashMap; use std::env; -use std::io::{self, stdin, Write}; +use std::io::{stdin, stdout, Read, Write}; use std::path::PathBuf; fn get_path(filename: &str) -> String { @@ -37,8 +36,8 @@ fn main() { } let mut min_date = String::new(); - print!("Enter a search date: "); - io::stdout().flush().expect("Failed to flush stdout"); + print!("Enter a min search date: "); + stdout().flush().expect("Failed to flush stdout"); stdin() .read_line(&mut min_date) .expect("Failed to read line"); @@ -115,24 +114,19 @@ fn main() { .collect() .expect("Failed to join dataframes"); - let _output_filepath = get_path(CONFIG.output_file.as_str()); - write_to_excel_file_refac(&_output_filepath, cons_df.clone()) - .expect("Failed to generate Excel"); + let output_filepath = format!( + "{}_{}.xlsx", + CONFIG.output_file_prefix_2.as_str(), + CONFIG.datetime_suffix.as_str() + ); + write_to_excel_file_refac(&output_filepath, cons_df.clone()).expect("Failed to generate Excel"); println!("Data has been processed..."); - println!("The Excel file was generated in {}", _output_filepath); + println!("The Excel file was generated in {}", output_filepath); println!("Showing the first 5 rows..."); println!("{:?}", cons_df.head(Some(5))); - println!("Press any key to close..."); - io::stdout().flush().expect("Failed to flush stdout"); - crossterm::terminal::enable_raw_mode().expect("Failed to enable raw mode"); - loop { - if event::poll(std::time::Duration::from_secs(0)).expect("Failed to poll event") { - if let event::Event::Key(_) = event::read().expect("Failed to read event") { - break; - } - } - } - crossterm::terminal::disable_raw_mode().expect("Failed to disable raw mode"); + println!("Press 'ENTER' to close..."); + stdout().flush().expect("Failed to flush stdout"); + stdin().read(&mut [0]).expect("Failed to read line"); }