From f68d01d50f5fbfc0e1fd0eba9c97a5d7952ef4ef Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 21:26:05 +0000 Subject: [PATCH 01/30] Workflow changes (#9) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/9 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index d96250e..f5aa18c 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -3,7 +3,6 @@ name: Release Tagging on: push: branches: - - main - devel tags: - 'v*' # Trigger on tags matching v* @@ -20,7 +19,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 components: cargo - name: Extract Version from Cargo.toml @@ -43,6 +42,12 @@ jobs: echo "Printing version" echo "Version: ${{ steps.version.outputs.project_tag_release }}" + - name: Check Branch + if: github.ref != 'refs/heads/devel' || github.ref != 'refs/heads/devel' # Replace 'main' with your required branch + run: | + echo "::error::Release can only be created from the 'main' branch." + exit 1 + - name: Create GitHub Release uses: actions/create-release@v1 env: -- 2.43.0 From 8bc49e781b1041dc7c5c5a4affb8690e7488d524 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 22:00:41 +0000 Subject: [PATCH 02/30] Correcting action workflow (#12) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/12 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index f5aa18c..ace8180 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -3,9 +3,8 @@ name: Release Tagging on: push: branches: + - main - devel - tags: - - 'v*' # Trigger on tags matching v* jobs: release: @@ -42,12 +41,6 @@ jobs: echo "Printing version" echo "Version: ${{ steps.version.outputs.project_tag_release }}" - - name: Check Branch - if: github.ref != 'refs/heads/devel' || github.ref != 'refs/heads/devel' # Replace 'main' with your required branch - run: | - echo "::error::Release can only be created from the 'main' branch." - exit 1 - - name: Create GitHub Release uses: actions/create-release@v1 env: -- 2.43.0 From d1610d133197198dc0ac51764771da77a8a68ae0 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 12 Apr 2025 17:28:03 +0000 Subject: [PATCH 03/30] service (#11) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/11 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.toml | 1 + src/main.rs | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6e920aa..4ca89b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +tokio = { version = "1.44.1", features = ["full"] } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } diff --git a/src/main.rs b/src/main.rs index e7a11a9..ddbab38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,38 @@ -fn main() { - println!("Hello, world!"); +use std::error::Error; +use tokio::io::AsyncReadExt; +use tokio::net::{TcpListener, TcpStream}; +use tokio::spawn; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let listener = TcpListener::bind("127.0.0.1:8080").await?; + println!("API calling service listening on 127.0.0.1:8080"); + + loop { + let (stream, addr) = listener.accept().await?; + println!("Accepted connection from: {}", addr); + + spawn(async move { + if let Err(e) = handle_connection(stream).await { + eprintln!("Error handling connection from {}: {}", addr, e); + } + }); + } +} + +async fn handle_connection(mut stream: TcpStream) -> Result<(), Box> { + let mut buffer = [0; 1024]; + + loop { + let n = stream.read(&mut buffer).await?; + + if n == 0 { + break; // Connection closed + } + + let request_data = String::from_utf8_lossy(&buffer[..n]).trim().to_string(); + println!("Received request: {}", request_data); + } + + Ok(()) } -- 2.43.0 From b41933e05ef05a6aa457086387e8ed1952731d1a Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 28 May 2025 23:28:28 +0000 Subject: [PATCH 04/30] Stamped rust version (#14) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/14 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 4ca89b3..b8b54a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "songparser" version = "0.1.0" edition = "2024" +rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } -- 2.43.0 From f1375f5639b8ded2c0a2c078dce4e641d5fe7d58 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 28 May 2025 23:44:20 +0000 Subject: [PATCH 05/30] Update icarus_models (#15) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/15 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b8b54a5..7453057 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,4 @@ rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } -- 2.43.0 From c04c6cdd6ca1033115a0f03fbef1070e957318ef Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Thu, 29 May 2025 00:01:54 +0000 Subject: [PATCH 06/30] Updated rust version in gitea workflow (#16) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/16 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- .gitea/workflows/workflow.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 49dfdc3..21ec691 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key @@ -54,7 +54,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: rustup component add rustfmt - run: | mkdir -p ~/.ssh @@ -73,7 +73,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: rustup component add clippy - run: | mkdir -p ~/.ssh @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key -- 2.43.0 From ce1d5228147400b986df8be1773c4c443ae6d866 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Tue, 3 Jun 2025 00:18:18 +0000 Subject: [PATCH 07/30] Including Cargo.lock in source control (#17) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/17 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- .gitignore | 1 - Cargo.lock | 657 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 657 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 96ef6c0..ea8c4bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ /target -Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..252042f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,657 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "icarus_models" +version = "0.4.3" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_models.git?tag=v0.4.3#6aa4c3d74142f5fceb4a6e95078bb3ae0a2d99c5" +dependencies = [ + "rand", + "serde", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha", + "rand_core", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "songparser" +version = "0.1.0" +dependencies = [ + "icarus_models", + "tokio", +] + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tokio" +version = "1.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "uuid" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +dependencies = [ + "getrandom", + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] -- 2.43.0 From 817ea9fed2f61dd38df017bf90525938c1080691 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Tue, 3 Jun 2025 00:31:45 +0000 Subject: [PATCH 08/30] Add env (#18) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/18 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- .env.docker.sample | 2 ++ .env.sample | 2 ++ .gitignore | 1 + 3 files changed, 5 insertions(+) create mode 100644 .env.docker.sample create mode 100644 .env.sample diff --git a/.env.docker.sample b/.env.docker.sample new file mode 100644 index 0000000..be6a3d3 --- /dev/null +++ b/.env.docker.sample @@ -0,0 +1,2 @@ +ROOT_DIRECTORY=/home/songparser/mydata +ICARUS_BASE_API_URL=http://localhost:3000 diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..be6a3d3 --- /dev/null +++ b/.env.sample @@ -0,0 +1,2 @@ +ROOT_DIRECTORY=/home/songparser/mydata +ICARUS_BASE_API_URL=http://localhost:3000 diff --git a/.gitignore b/.gitignore index ea8c4bf..fedaa2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.env -- 2.43.0 From 5ced62ec7a3f7d70b9f1f081001807830594210c Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Tue, 10 Jun 2025 21:50:00 +0000 Subject: [PATCH 09/30] Modify application structure (#19) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/19 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 1167 ++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 + src/main.rs | 67 +-- 3 files changed, 1194 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 252042f..c0efd87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" @@ -35,9 +41,15 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "2.9.0" @@ -56,12 +68,37 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cc" +version = "1.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "deranged" version = "0.4.0" @@ -72,6 +109,134 @@ dependencies = [ "serde", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.3.2" @@ -90,6 +255,149 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "h2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + [[package]] name = "icarus_models" version = "0.4.3" @@ -102,6 +410,139 @@ dependencies = [ "uuid", ] +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "itoa" version = "1.0.15" @@ -124,6 +565,18 @@ version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + [[package]] name = "lock_api" version = "0.4.12" @@ -146,6 +599,12 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[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.8.8" @@ -166,6 +625,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -187,6 +663,50 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -207,15 +727,42 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -282,7 +829,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.2", ] [[package]] @@ -294,12 +841,114 @@ dependencies = [ "bitflags", ] +[[package]] +name = "reqwest" +version = "0.12.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.23.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.21" @@ -312,12 +961,44 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.219" @@ -350,6 +1031,24 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -359,6 +1058,15 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.15.0" @@ -379,10 +1087,24 @@ dependencies = [ name = "songparser" version = "0.1.0" dependencies = [ + "dotenvy", "icarus_models", + "reqwest", "tokio", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.100" @@ -394,6 +1116,60 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "time" version = "0.3.41" @@ -425,6 +1201,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tokio" version = "1.45.1" @@ -454,24 +1240,165 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[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.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +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 = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ - "getrandom", + "getrandom 0.3.2", "js-sys", "serde", "wasm-bindgen", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -513,6 +1440,19 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.100" @@ -545,13 +1485,58 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -560,7 +1545,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -569,14 +1554,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "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", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -585,48 +1586,96 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -636,6 +1685,36 @@ dependencies = [ "bitflags", ] +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.24" @@ -655,3 +1734,63 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 7453057..b357dec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,6 @@ rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } +reqwest = { version = "0.12.19" } +dotenvy = { version = "0.15.7" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } diff --git a/src/main.rs b/src/main.rs index ddbab38..68f8219 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,38 +1,49 @@ -use std::error::Error; -use tokio::io::AsyncReadExt; -use tokio::net::{TcpListener, TcpStream}; -use tokio::spawn; +// use std::error::Error; +// use tokio::io::AsyncReadExt; +// use tokio::net::{TcpListener, TcpStream}; +// use tokio::spawn; #[tokio::main] -async fn main() -> Result<(), Box> { - let listener = TcpListener::bind("127.0.0.1:8080").await?; - println!("API calling service listening on 127.0.0.1:8080"); +async fn main() -> Result<(), Box> { + let client = reqwest::Client::new(); + let app_base_url = get_icarus_url().await; loop { - let (stream, addr) = listener.accept().await?; - println!("Accepted connection from: {}", addr); + println!("Base URL: {}", app_base_url); - spawn(async move { - if let Err(e) = handle_connection(stream).await { - eprintln!("Error handling connection from {}: {}", addr, e); + // TODO: Update the api/v2/song/queue/next endpoint to only retrieve queued song that is + // ready to be processed. Make necessary changes to other endpoints + + let api_url = format!("{}/api/v2/song/queue/next", app_base_url); + + match client.get(api_url).send().await { + Ok(response) => { + let body = response.text().await?; + println!("API response: {}", body); + // Process data here... + + // TODO: Parse the response body to a struct + // TODO: Get queued song data + // TODO: Get queued song's metadata + // TODO: Get queued coverart + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart } - }); - } -} - -async fn handle_connection(mut stream: TcpStream) -> Result<(), Box> { - let mut buffer = [0; 1024]; - - loop { - let n = stream.read(&mut buffer).await?; - - if n == 0 { - break; // Connection closed + Err(e) => eprintln!("API call failed: {}", e), } - let request_data = String::from_utf8_lossy(&buffer[..n]).trim().to_string(); - println!("Received request: {}", request_data); + println!("Sleeping"); + tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; } - - Ok(()) + // Ok(()) +} + +async fn get_icarus_url() -> String { + dotenvy::dotenv().ok(); + std::env::var("ICARUS_BASE_API_URL").expect("Could not find url") } -- 2.43.0 From 2f11ff9e891f3ac5075c84be107b3220d18a2459 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Tue, 10 Jun 2025 22:44:38 +0000 Subject: [PATCH 10/30] Fetch queue item (#20) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/20 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 3 ++ Cargo.toml | 5 +++- src/main.rs | 86 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0efd87..8be8125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1090,7 +1090,10 @@ dependencies = [ "dotenvy", "icarus_models", "reqwest", + "serde", + "serde_json", "tokio", + "uuid", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b357dec..6999867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,9 @@ rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } -reqwest = { version = "0.12.19" } +reqwest = { version = "0.12.19", features = ["json"] } +serde = { version = "1.0.218", features = ["derive"] } +serde_json = { version = "1.0.139" } +uuid = { version = "1.16.0", features = ["v4", "serde"] } dotenvy = { version = "0.15.7" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } diff --git a/src/main.rs b/src/main.rs index 68f8219..8a0e0ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,38 +1,41 @@ -// use std::error::Error; -// use tokio::io::AsyncReadExt; -// use tokio::net::{TcpListener, TcpStream}; -// use tokio::spawn; - #[tokio::main] async fn main() -> Result<(), Box> { - let client = reqwest::Client::new(); let app_base_url = get_icarus_url().await; loop { println!("Base URL: {}", app_base_url); - // TODO: Update the api/v2/song/queue/next endpoint to only retrieve queued song that is - // ready to be processed. Make necessary changes to other endpoints - - let api_url = format!("{}/api/v2/song/queue/next", app_base_url); - - match client.get(api_url).send().await { + match api::fetch_next_queue_item(&app_base_url).await { Ok(response) => { - let body = response.text().await?; - println!("API response: {}", body); - // Process data here... + match response + .json::() + .await + { + Ok(song_queue_item) => { + if !song_queue_item.data.is_empty() { + println!("Song queue item: {:?}", song_queue_item); - // TODO: Parse the response body to a struct - // TODO: Get queued song data - // TODO: Get queued song's metadata - // TODO: Get queued coverart - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + // Process data here... + + // TODO: Parse the response body to a struct + // TODO: Get queued song data + // TODO: Get queued song's metadata + // TODO: Get queued coverart + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } else { + println!("No data to fetch"); + } + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } } Err(e) => eprintln!("API call failed: {}", e), } @@ -40,7 +43,36 @@ async fn main() -> Result<(), Box> { println!("Sleeping"); tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; } - // Ok(()) +} + +mod responses { + pub mod fetch_next_queue_item { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct QueueItem { + pub id: uuid::Uuid, + pub filename: String, + pub status: String, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct SongQueueItem { + pub message: String, + pub data: Vec, + } + } +} + +mod api { + pub async fn fetch_next_queue_item( + base_url: &String, + ) -> Result { + let client = reqwest::Client::new(); + let fetch_endpoint = String::from("api/v2/song/queue/next"); + let api_url = format!("{}/{}", base_url, fetch_endpoint); + client.get(api_url).send().await + } } async fn get_icarus_url() -> String { -- 2.43.0 From 006fa3a2d833a9a0e3c5fe538760666783c667d4 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Thu, 12 Jun 2025 18:57:02 +0000 Subject: [PATCH 11/30] fetch song queue data (#21) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/21 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 76 +++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +- src/main.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 178 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8be8125..2a0118a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -194,6 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -202,6 +218,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -220,10 +264,16 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -398,6 +448,14 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "icarus_envy" +version = "0.2.0" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_envy.git?tag=v0.2.0#3ee8c1e573ba9637769aa0538d2c11335e39ed9f" +dependencies = [ + "dotenvy", +] + [[package]] name = "icarus_models" version = "0.4.3" @@ -851,6 +909,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-core", + "futures-util", "h2", "http", "http-body", @@ -874,12 +933,14 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-native-tls", + "tokio-util", "tower", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", ] @@ -1088,6 +1149,8 @@ name = "songparser" version = "0.1.0" dependencies = [ "dotenvy", + "futures", + "icarus_envy", "icarus_models", "reqwest", "serde", @@ -1488,6 +1551,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.77" diff --git a/Cargo.toml b/Cargo.toml index 6999867..ed00706 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,9 +6,11 @@ rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } -reqwest = { version = "0.12.19", features = ["json"] } +futures = { version = "0.3.31" } +reqwest = { version = "0.12.19", features = ["json", "stream"] } serde = { version = "1.0.218", features = ["derive"] } serde_json = { version = "1.0.139" } uuid = { version = "1.16.0", features = ["v4", "serde"] } dotenvy = { version = "0.15.7" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } +icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.0" } diff --git a/src/main.rs b/src/main.rs index 8a0e0ab..efbb604 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +use std::io::Write; + +pub const SECONDS_TO_SLEEP: u64 = 5; + #[tokio::main] async fn main() -> Result<(), Box> { let app_base_url = get_icarus_url().await; @@ -15,19 +19,42 @@ async fn main() -> Result<(), Box> { if !song_queue_item.data.is_empty() { println!("Song queue item: {:?}", song_queue_item); - // Process data here... + println!("Fetching song queue data"); + match api::fetch_song_queue_data::get_data( + &app_base_url, + &song_queue_item.data[0].id, + ) + .await + { + Ok(response) => { + // Process data here... + let all_bytes = + api::fetch_song_queue_data::response::parse_response( + response, + ) + .await?; - // TODO: Parse the response body to a struct - // TODO: Get queued song data - // TODO: Get queued song's metadata - // TODO: Get queued coverart - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + let (directory, filename) = + generate_song_queue_dir_and_filename().await; + let save_path = + save_song_to_fs(&directory, &filename, &all_bytes).await; + + println!("Saved at: {:?}", save_path); + + // TODO: Get queued song's metadata + // TODO: Get queued coverart + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } + Err(err) => { + eprintln!("Error fetching song queue data: {:?}", err); + } + } } else { println!("No data to fetch"); } @@ -41,10 +68,37 @@ async fn main() -> Result<(), Box> { } println!("Sleeping"); - tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; + tokio::time::sleep(tokio::time::Duration::from_secs(SECONDS_TO_SLEEP)).await; } } +// TODO: Consider having something like this in icarus_models +pub async fn generate_song_queue_dir_and_filename() -> (String, String) { + let mut song = icarus_models::song::Song::default(); + song.filename = song.generate_filename(icarus_models::types::MusicTypes::FlacExtension, true); + + song.directory = icarus_envy::environment::get_root_directory().await; + + (song.directory, song.filename) +} + +// TODO: Check to see if this is available in icarus_models +pub async fn save_song_to_fs( + directory: &String, + filename: &String, + data: &[u8], +) -> std::path::PathBuf { + // TODO: Add function to save bytes to a file in icarus_models + // repo + let dir = std::path::Path::new(directory); + let save_path = dir.join(filename); + + let mut file = std::fs::File::create(&save_path).unwrap(); + file.write_all(data).unwrap(); + + save_path +} + mod responses { pub mod fetch_next_queue_item { use serde::{Deserialize, Serialize}; @@ -73,6 +127,38 @@ mod api { let api_url = format!("{}/{}", base_url, fetch_endpoint); client.get(api_url).send().await } + + pub mod fetch_song_queue_data { + pub async fn get_data( + base_url: &String, + id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/song/queue"); + let api_url = format!("{}/{}/{}", base_url, endpoint, id); + client.get(api_url).send().await + } + + pub mod response { + use futures::StreamExt; + + pub async fn parse_response( + response: reqwest::Response, + ) -> Result, reqwest::Error> { + // TODO: At some point, handle the flow if the size is small or + // large + let mut byte_stream = response.bytes_stream(); + let mut all_bytes = Vec::new(); + + while let Some(chunk) = byte_stream.next().await { + let chunk = chunk?; + all_bytes.extend_from_slice(&chunk); + } + + Ok(all_bytes) + } + } + } } async fn get_icarus_url() -> String { -- 2.43.0 From 79eea81e28d7bbd74b0796bd437ca6564e049036 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Thu, 12 Jun 2025 23:59:24 +0000 Subject: [PATCH 12/30] Updated icarus_envy (#22) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/22 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 32 +++++++++++++++++++++++++++++--- Cargo.toml | 3 +-- src/main.rs | 7 +------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a0118a..04dff48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,6 +83,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -450,9 +470,10 @@ dependencies = [ [[package]] name = "icarus_envy" -version = "0.2.0" -source = "git+ssh://git@git.kundeng.us/phoenix/icarus_envy.git?tag=v0.2.0#3ee8c1e573ba9637769aa0538d2c11335e39ed9f" +version = "0.2.2" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_envy.git?tag=v0.2.2-devel-84ea6e4c22-006#84ea6e4c223f19ff96f6b7cae944e831ef4aa831" dependencies = [ + "const_format", "dotenvy", ] @@ -1148,7 +1169,6 @@ dependencies = [ name = "songparser" version = "0.1.0" dependencies = [ - "dotenvy", "futures", "icarus_envy", "icarus_models", @@ -1415,6 +1435,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index ed00706..1c5aace 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,5 @@ reqwest = { version = "0.12.19", features = ["json", "stream"] } serde = { version = "1.0.218", features = ["derive"] } serde_json = { version = "1.0.139" } uuid = { version = "1.16.0", features = ["v4", "serde"] } -dotenvy = { version = "0.15.7" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } -icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.0" } +icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.2-devel-84ea6e4c22-006" } diff --git a/src/main.rs b/src/main.rs index efbb604..6a41d11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ pub const SECONDS_TO_SLEEP: u64 = 5; #[tokio::main] async fn main() -> Result<(), Box> { - let app_base_url = get_icarus_url().await; + let app_base_url = icarus_envy::environment::get_icarus_base_api_url().await; loop { println!("Base URL: {}", app_base_url); @@ -160,8 +160,3 @@ mod api { } } } - -async fn get_icarus_url() -> String { - dotenvy::dotenv().ok(); - std::env::var("ICARUS_BASE_API_URL").expect("Could not find url") -} -- 2.43.0 From eaa3c6f40e3619f8ade0241c82b814798971343d Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sat, 14 Jun 2025 00:30:25 +0000 Subject: [PATCH 13/30] Get Metadata queue (#23) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/23 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 96 +++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04dff48..6bb66fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1175,6 +1175,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "time", "tokio", "uuid", ] diff --git a/Cargo.toml b/Cargo.toml index 1c5aace..d2052b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ futures = { version = "0.3.31" } reqwest = { version = "0.12.19", features = ["json", "stream"] } serde = { version = "1.0.218", features = ["derive"] } serde_json = { version = "1.0.139" } +time = { version = "0.3.41", features = ["macros", "serde"] } uuid = { version = "1.16.0", features = ["v4", "serde"] } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.2-devel-84ea6e4c22-006" } diff --git a/src/main.rs b/src/main.rs index 6a41d11..58c76a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,11 +18,12 @@ async fn main() -> Result<(), Box> { Ok(song_queue_item) => { if !song_queue_item.data.is_empty() { println!("Song queue item: {:?}", song_queue_item); + let song_queue_id = song_queue_item.data[0].id; println!("Fetching song queue data"); match api::fetch_song_queue_data::get_data( &app_base_url, - &song_queue_item.data[0].id, + &song_queue_id, ) .await { @@ -41,15 +42,39 @@ async fn main() -> Result<(), Box> { println!("Saved at: {:?}", save_path); - // TODO: Get queued song's metadata - // TODO: Get queued coverart - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + match api::get_metadata_queue::get( + &app_base_url, + &song_queue_id, + ) + .await + { + Ok(response) => { + match response.json::().await { + Ok(response) => { + let id = &response.data[0].id; + let metadata = &response.data[0].metadata; + let created_at = &response.data[0].created_at; + println!("Id: {:?}", id); + println!("Metadata: {:?}", metadata); + println!("Created at: {:?}", created_at); + // TODO: Get queued coverart + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song (modifying file) + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } } Err(err) => { eprintln!("Error fetching song queue data: {:?}", err); @@ -159,4 +184,55 @@ mod api { } } } + + pub mod get_metadata_queue { + pub async fn get( + base_url: &String, + song_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/song/metadata/queue"); + let api_url = format!("{}/{}", base_url, endpoint); + client + .get(api_url) + .query(&[("song_queue_id", song_queue_id)]) + .send() + .await + } + + pub mod response { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct Metadata { + pub id: uuid::Uuid, + pub album: String, + pub album_artist: String, + pub artist: String, + pub disc: i32, + pub disc_count: i32, + pub duration: i64, + pub genre: String, + pub title: String, + pub track: i32, + pub track_count: i32, + pub year: i32, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct QueueItem { + pub id: uuid::Uuid, + pub metadata: Metadata, + #[serde(with = "time::serde::rfc3339")] + pub created_at: time::OffsetDateTime, + pub song_queue_id: uuid::Uuid, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } + } } -- 2.43.0 From 4e07ee5d0f207ad7e3f4bf093c66b3584236784a Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sat, 14 Jun 2025 01:30:49 +0000 Subject: [PATCH 14/30] Refactoring (#24) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/24 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- src/main.rs | 167 ++++++++++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 78 deletions(-) diff --git a/src/main.rs b/src/main.rs index 58c76a0..65b9af7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,87 +9,22 @@ async fn main() -> Result<(), Box> { loop { println!("Base URL: {}", app_base_url); - match api::fetch_next_queue_item(&app_base_url).await { - Ok(response) => { - match response - .json::() - .await - { - Ok(song_queue_item) => { - if !song_queue_item.data.is_empty() { - println!("Song queue item: {:?}", song_queue_item); - let song_queue_id = song_queue_item.data[0].id; + match is_queue_empty(&app_base_url).await { + Ok((empty, song_queue_item)) => { + if !empty { + println!("Queue is not empty"); + println!("SongQueueItem: {:?}", song_queue_item); + let song_queue_id = song_queue_item.data[0].id; - println!("Fetching song queue data"); - match api::fetch_song_queue_data::get_data( - &app_base_url, - &song_queue_id, - ) - .await - { - Ok(response) => { - // Process data here... - let all_bytes = - api::fetch_song_queue_data::response::parse_response( - response, - ) - .await?; - - let (directory, filename) = - generate_song_queue_dir_and_filename().await; - let save_path = - save_song_to_fs(&directory, &filename, &all_bytes).await; - - println!("Saved at: {:?}", save_path); - - match api::get_metadata_queue::get( - &app_base_url, - &song_queue_id, - ) - .await - { - Ok(response) => { - match response.json::().await { - Ok(response) => { - let id = &response.data[0].id; - let metadata = &response.data[0].metadata; - let created_at = &response.data[0].created_at; - println!("Id: {:?}", id); - println!("Metadata: {:?}", metadata); - println!("Created at: {:?}", created_at); - // TODO: Get queued coverart - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song (modifying file) - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart - } - Err(err) => { - eprintln!("Error: {:?}", err); - } - } - } - Err(err) => { - eprintln!("Error: {:?}", err); - } - } - } - Err(err) => { - eprintln!("Error fetching song queue data: {:?}", err); - } - } - } else { - println!("No data to fetch"); - } - } - Err(err) => { - eprintln!("Error: {:?}", err); - } + // TODO: Do something with the result later + let _ = process_song(&app_base_url, &song_queue_id).await; + } else { + println!("Queue is empty"); } } - Err(e) => eprintln!("API call failed: {}", e), + Err(err) => { + eprintln!("Error checking if queue is empty: {:?}", err); + } } println!("Sleeping"); @@ -97,6 +32,82 @@ async fn main() -> Result<(), Box> { } } +async fn is_queue_empty( + api_url: &String, +) -> Result<(bool, responses::fetch_next_queue_item::SongQueueItem), reqwest::Error> { + match api::fetch_next_queue_item(api_url).await { + Ok(response) => { + match response + .json::() + .await + { + Ok(response) => { + if response.data.is_empty() { + Ok((true, response)) + } else { + Ok((false, response)) + } + } + Err(err) => Err(err), + } + } + Err(err) => Err(err), + } +} + +async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<(), reqwest::Error> { + match api::fetch_song_queue_data::get_data(api_url, song_queue_id).await { + Ok(response) => { + // Process data here... + match api::fetch_song_queue_data::response::parse_response(response).await { + Ok(all_bytes) => { + let (directory, filename) = generate_song_queue_dir_and_filename().await; + let save_path = save_song_to_fs(&directory, &filename, &all_bytes).await; + + println!("Saved at: {:?}", save_path); + + match api::get_metadata_queue::get(api_url, song_queue_id).await { + Ok(response) => { + match response + .json::() + .await + { + Ok(response) => { + let id = &response.data[0].id; + let metadata = &response.data[0].metadata; + let created_at = &response.data[0].created_at; + println!("Id: {:?}", id); + println!("Metadata: {:?}", metadata); + println!("Created at: {:?}", created_at); + // TODO: Get queued coverart + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song (modifying file) + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + Ok(()) + } + Err(err) => { + eprintln!("Error: {:?}", err); + Err(err) + } + } + } + Err(err) => { + eprintln!("Error: {:?}", err); + Err(err) + } + } + } + Err(err) => Err(err), + } + } + Err(err) => Err(err), + } +} + // TODO: Consider having something like this in icarus_models pub async fn generate_song_queue_dir_and_filename() -> (String, String) { let mut song = icarus_models::song::Song::default(); -- 2.43.0 From 557264482fcd7b75738fd923880962dbffce8735 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 18 Jun 2025 01:07:03 +0000 Subject: [PATCH 15/30] Get queued coverart (#25) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/25 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- src/main.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 65b9af7..23cfb11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,14 +79,32 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() println!("Id: {:?}", id); println!("Metadata: {:?}", metadata); println!("Created at: {:?}", created_at); - // TODO: Get queued coverart - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song (modifying file) - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + + println!("Getting coverart queue"); + match api::get_coverart_queue::get(api_url, song_queue_id).await + { + Ok(response) => { + match response.json::().await { + Ok(response) => { + let coverart_queue_id = &response.data[0].id; + println!("Coverart queue Id: {:?}", coverart_queue_id); + // TODO: Get queued coverart's data + // TODO: Apply metadata to the queued song (modifying file) + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } Ok(()) } Err(err) => { @@ -246,4 +264,36 @@ mod api { } } } + + pub mod get_coverart_queue { + pub async fn get( + base_url: &String, + song_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/coverart/queue"); + let api_url = format!("{}/{}", base_url, endpoint); + client + .get(api_url) + .query(&[("song_queue_id", song_queue_id)]) + .send() + .await + } + + pub mod response { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct CoverArtQueue { + pub id: uuid::Uuid, + pub song_queue_id: uuid::Uuid, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } + } } -- 2.43.0 From 29b806fd02877c2fd39dba62ff1da4ecde757507 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Thu, 19 Jun 2025 00:54:13 +0000 Subject: [PATCH 16/30] Get queued coverart data (#26) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/26 Co-authored-by: kdeng00 Co-committed-by: kdeng00 --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 120 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bb66fb..701675d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1172,6 +1172,7 @@ dependencies = [ "futures", "icarus_envy", "icarus_models", + "rand", "reqwest", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d2052b5..e4d6182 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,6 @@ serde = { version = "1.0.218", features = ["derive"] } serde_json = { version = "1.0.139" } time = { version = "0.3.41", features = ["macros", "serde"] } uuid = { version = "1.16.0", features = ["v4", "serde"] } +rand = { version = "0.9" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.2-devel-84ea6e4c22-006" } diff --git a/src/main.rs b/src/main.rs index 23cfb11..5206990 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,10 +59,10 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() match api::fetch_song_queue_data::get_data(api_url, song_queue_id).await { Ok(response) => { // Process data here... - match api::fetch_song_queue_data::response::parse_response(response).await { - Ok(all_bytes) => { + match api::parsing::parse_response_into_bytes(response).await { + Ok(song_bytes) => { let (directory, filename) = generate_song_queue_dir_and_filename().await; - let save_path = save_song_to_fs(&directory, &filename, &all_bytes).await; + let save_path = save_file_to_fs(&directory, &filename, &song_bytes).await; println!("Saved at: {:?}", save_path); @@ -88,13 +88,30 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() Ok(response) => { let coverart_queue_id = &response.data[0].id; println!("Coverart queue Id: {:?}", coverart_queue_id); - // TODO: Get queued coverart's data - // TODO: Apply metadata to the queued song (modifying file) - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + + match api::get_coverart_queue::get_data(api_url, coverart_queue_id).await { + Ok(response) => match api::parsing::parse_response_into_bytes(response).await { + Ok(coverart_queue_bytes) => { + let (directory, filename) = generate_coverart_queue_dir_and_filename().await; + let save_path = save_file_to_fs(&directory, &filename, &coverart_queue_bytes).await; + + println!("Saved coverart queue file at: {:?}", save_path); + + // TODO: Apply metadata to the queued song (modifying file) + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } } Err(err) => { eprintln!("Error: {:?}", err); @@ -136,8 +153,37 @@ pub async fn generate_song_queue_dir_and_filename() -> (String, String) { (song.directory, song.filename) } +// TODO: Consider having something like this in icarus_models +pub async fn generate_coverart_queue_dir_and_filename() -> (String, String) { + use rand::Rng; + + let mut filename: String = String::new(); + let filename_len = 10; + + let some_chars: String = String::from("abcdefghij0123456789"); + let mut rng = rand::rng(); + + for _i in 0..filename_len { + let random_number: i32 = rng.random_range(0..=19); + let index = random_number as usize; + let rando_char = some_chars.chars().nth(index); + + if let Some(c) = rando_char { + filename.push(c); + } + } + + // TODO: Do not hard code the file extension + filename += ".jpeg"; + + // TODO: Consider separating song and coverart when saving to the filesystem + let directory = icarus_envy::environment::get_root_directory().await; + + (directory, filename) +} + // TODO: Check to see if this is available in icarus_models -pub async fn save_song_to_fs( +pub async fn save_file_to_fs( directory: &String, filename: &String, data: &[u8], @@ -182,6 +228,26 @@ mod api { client.get(api_url).send().await } + pub mod parsing { + use futures::StreamExt; + + pub async fn parse_response_into_bytes( + response: reqwest::Response, + ) -> Result, reqwest::Error> { + // TODO: At some point, handle the flow if the size is small or + // large + let mut byte_stream = response.bytes_stream(); + let mut all_bytes = Vec::new(); + + while let Some(chunk) = byte_stream.next().await { + let chunk = chunk?; + all_bytes.extend_from_slice(&chunk); + } + + Ok(all_bytes) + } + } + pub mod fetch_song_queue_data { pub async fn get_data( base_url: &String, @@ -192,26 +258,6 @@ mod api { let api_url = format!("{}/{}/{}", base_url, endpoint, id); client.get(api_url).send().await } - - pub mod response { - use futures::StreamExt; - - pub async fn parse_response( - response: reqwest::Response, - ) -> Result, reqwest::Error> { - // TODO: At some point, handle the flow if the size is small or - // large - let mut byte_stream = response.bytes_stream(); - let mut all_bytes = Vec::new(); - - while let Some(chunk) = byte_stream.next().await { - let chunk = chunk?; - all_bytes.extend_from_slice(&chunk); - } - - Ok(all_bytes) - } - } } pub mod get_metadata_queue { @@ -234,7 +280,7 @@ mod api { #[derive(Debug, Deserialize, Serialize)] pub struct Metadata { - pub id: uuid::Uuid, + pub song_queue_id: uuid::Uuid, pub album: String, pub album_artist: String, pub artist: String, @@ -280,6 +326,16 @@ mod api { .await } + pub async fn get_data( + base_url: &String, + coverart_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/coverart/queue/data"); + let api_url = format!("{}/{}/{}", base_url, endpoint, coverart_queue_id); + client.get(api_url).send().await + } + pub mod response { use serde::{Deserialize, Serialize}; -- 2.43.0 From e138bf7a2ed9686ff14cb9c26352ac8c7331352a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 26 Jun 2025 22:40:04 +0000 Subject: [PATCH 17/30] Apply metadata to queued song (#27) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/27 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 81 +++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 181 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 253 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 701675d..a2cd917 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,12 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.1" @@ -119,6 +125,21 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "deranged" version = "0.4.0" @@ -177,6 +198,16 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -477,6 +508,14 @@ dependencies = [ "dotenvy", ] +[[package]] +name = "icarus_meta" +version = "0.2.2" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_meta.git?tag=v0.2.2-devel-565d361b64-680#565d361b64f23c2a0100b33fceeebacfad3331c4" +dependencies = [ + "lofty", +] + [[package]] name = "icarus_models" version = "0.4.3" @@ -666,6 +705,32 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lofty" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca260c51a9c71f823fbfd2e6fbc8eb2ee09834b98c00763d877ca8bfa85cde3e" +dependencies = [ + "byteorder", + "data-encoding", + "flate2", + "lofty_attr", + "log", + "ogg_pager", + "paste", +] + +[[package]] +name = "lofty_attr" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9983e64b2358522f745c1251924e3ab7252d55637e80f6a0a3de642d6a9efc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "log" version = "0.4.27" @@ -736,6 +801,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ogg_pager" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e034c10fb5c1c012c1b327b85df89fb0ef98ae66ec28af30f0d1eed804a40c19" +dependencies = [ + "byteorder", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -809,6 +883,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1171,6 +1251,7 @@ version = "0.1.0" dependencies = [ "futures", "icarus_envy", + "icarus_meta", "icarus_models", "rand", "reqwest", diff --git a/Cargo.toml b/Cargo.toml index e4d6182..9ec7ef6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,6 @@ serde_json = { version = "1.0.139" } time = { version = "0.3.41", features = ["macros", "serde"] } uuid = { version = "1.16.0", features = ["v4", "serde"] } rand = { version = "0.9" } +icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.2.2-devel-565d361b64-680" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.2-devel-84ea6e4c22-006" } diff --git a/src/main.rs b/src/main.rs index 5206990..b29bc69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,9 +62,9 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() match api::parsing::parse_response_into_bytes(response).await { Ok(song_bytes) => { let (directory, filename) = generate_song_queue_dir_and_filename().await; - let save_path = save_file_to_fs(&directory, &filename, &song_bytes).await; + let song_queue_path = save_file_to_fs(&directory, &filename, &song_bytes).await; - println!("Saved at: {:?}", save_path); + println!("Saved at: {:?}", song_queue_path); match api::get_metadata_queue::get(api_url, song_queue_id).await { Ok(response) => { @@ -93,16 +93,22 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() Ok(response) => match api::parsing::parse_response_into_bytes(response).await { Ok(coverart_queue_bytes) => { let (directory, filename) = generate_coverart_queue_dir_and_filename().await; - let save_path = save_file_to_fs(&directory, &filename, &coverart_queue_bytes).await; + let coverart_queue_path = save_file_to_fs(&directory, &filename, &coverart_queue_bytes).await; - println!("Saved coverart queue file at: {:?}", save_path); + println!("Saved coverart queue file at: {:?}", coverart_queue_path); - // TODO: Apply metadata to the queued song (modifying file) - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart + match apply_metadata(song_queue_path, coverart_queue_path, metadata).await { + Ok(_) => { + // TODO: Update the queued song with the updated queued song + // TODO: Create song + // TODO: Create coverart + // TODO: Wipe data from queued song + // TODO: Wipe data from queued coverart + } + Err(err) => { + eprintln!("Error: {:?}", err); + } + } } Err(err) => { eprintln!("Error: {:?}", err); @@ -199,6 +205,161 @@ pub async fn save_file_to_fs( save_path } +pub async fn apply_metadata( + song_queue_path: std::path::PathBuf, + coverart_queue_path: std::path::PathBuf, + metadata: &api::get_metadata_queue::response::Metadata, +) -> Result { + // Apply metadata fields + let s_path = match song_queue_path.to_str() { + Some(val) => String::from(val), + None => String::new(), + }; + + if s_path.is_empty() { + println!("Song queue path is empty"); + return Ok(false); + } + + let types = icarus_meta::types::all_metadata_types(); + + for t in types { + match t { + icarus_meta::types::Type::Album => { + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.album.clone()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::AlbumArtist => { + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.album_artist.clone()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Artist => { + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.artist.clone()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Date => { + // TODO: Do something about this discrepancy + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.year.to_string()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Disc => { + let meta_type = icarus_meta::types::MetadataType::from_int(metadata.disc); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Genre => { + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.genre.clone()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Title => { + let meta_type = + icarus_meta::types::MetadataType::from_string(metadata.title.clone()); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::Track => { + let meta_type = icarus_meta::types::MetadataType::from_int(metadata.track); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::TrackCount => { + let meta_type = icarus_meta::types::MetadataType::from_int(metadata.track_count); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + icarus_meta::types::Type::DiscCount => { + let meta_type = icarus_meta::types::MetadataType::from_int(metadata.disc_count); + match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + Ok(_) => {} + Err(_err) => { + return Err(_err); + } + } + } + } + } + + // Apply coverart + let c_path: String = match coverart_queue_path.to_str() { + Some(val) => String::from(val), + None => String::new(), + }; + + match icarus_meta::meta::coverart::contains_coverart(&s_path) { + Ok((exists, size)) => { + if exists { + println!("Coverart exists: {:?} size", size); + match icarus_meta::meta::coverart::remove_coverart(&s_path) { + Ok(_data) => {} + Err(err) => { + return Err(err); + } + } + } + + match icarus_meta::meta::coverart::set_coverart(&s_path, &c_path) { + Ok(_data) => { + if _data.is_empty() { + println!("There was an issue"); + Ok(false) + } else { + println!("Success in applying coverart to song"); + Ok(true) + } + } + Err(err) => Err(err), + } + } + Err(err) => Err(err), + } +} + mod responses { pub mod fetch_next_queue_item { use serde::{Deserialize, Serialize}; -- 2.43.0 From 2f05c20d4ece14a82eacd0c789de8075cd78653a Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 28 Jun 2025 23:23:41 +0000 Subject: [PATCH 18/30] update queued song (#28) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/28 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 17 +++++ Cargo.toml | 2 +- src/main.rs | 138 +++++++++++++++++++++----------------- src/the_rest.rs | 6 ++ src/update_queued_song.rs | 35 ++++++++++ src/util.rs | 6 ++ 6 files changed, 142 insertions(+), 62 deletions(-) create mode 100644 src/the_rest.rs create mode 100644 src/update_queued_song.rs create mode 100644 src/util.rs diff --git a/Cargo.lock b/Cargo.lock index a2cd917..fc99adf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -749,6 +749,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.8" @@ -1023,6 +1033,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -1512,6 +1523,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.18" diff --git a/Cargo.toml b/Cargo.toml index 9ec7ef6..9cf368d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ rust-version = "1.86" [dependencies] tokio = { version = "1.44.1", features = ["full"] } futures = { version = "0.3.31" } -reqwest = { version = "0.12.19", features = ["json", "stream"] } +reqwest = { version = "0.12.19", features = ["json", "stream", "multipart"] } serde = { version = "1.0.218", features = ["derive"] } serde_json = { version = "1.0.139" } time = { version = "0.3.41", features = ["macros", "serde"] } diff --git a/src/main.rs b/src/main.rs index b29bc69..429eac7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +pub mod the_rest; +pub mod update_queued_song; +pub mod util; + use std::io::Write; pub const SECONDS_TO_SLEEP: u64 = 5; @@ -17,7 +21,12 @@ async fn main() -> Result<(), Box> { let song_queue_id = song_queue_item.data[0].id; // TODO: Do something with the result later - let _ = process_song(&app_base_url, &song_queue_id).await; + match some_work(&app_base_url, &song_queue_id).await { + Ok(_) => {} + Err(err) => { + eprintln!("Error: {:?}", err); + } + } } else { println!("Queue is empty"); } @@ -55,7 +64,47 @@ async fn is_queue_empty( } } -async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<(), reqwest::Error> { +async fn some_work( + app_base_url: &String, + song_queue_id: &uuid::Uuid, +) -> Result<(), std::io::Error> { + match prep_song(app_base_url, song_queue_id).await { + Ok((song_queue_path, coverart_queue_path, metadata)) => { + match apply_metadata(&song_queue_path, &coverart_queue_path, &metadata).await { + Ok(_applied) => { + match update_queued_song::update_queued_song( + app_base_url, + &song_queue_path, + song_queue_id, + ) + .await + { + Ok(response) => { + match response + .json::() + .await + { + Ok(_inner_response) => { + println!("Response: {:?}", _inner_response); + Ok(()) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } + Err(err) => Err(err), + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + +async fn prep_song( + api_url: &String, + song_queue_id: &uuid::Uuid, +) -> Result<(String, String, api::get_metadata_queue::response::Metadata), reqwest::Error> { match api::fetch_song_queue_data::get_data(api_url, song_queue_id).await { Ok(response) => { // Process data here... @@ -74,8 +123,8 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() { Ok(response) => { let id = &response.data[0].id; - let metadata = &response.data[0].metadata; let created_at = &response.data[0].created_at; + let metadata = &response.data[0].metadata; println!("Id: {:?}", id); println!("Metadata: {:?}", metadata); println!("Created at: {:?}", created_at); @@ -97,49 +146,31 @@ async fn process_song(api_url: &String, song_queue_id: &uuid::Uuid) -> Result<() println!("Saved coverart queue file at: {:?}", coverart_queue_path); - match apply_metadata(song_queue_path, coverart_queue_path, metadata).await { - Ok(_) => { - // TODO: Update the queued song with the updated queued song - // TODO: Create song - // TODO: Create coverart - // TODO: Wipe data from queued song - // TODO: Wipe data from queued coverart - } - Err(err) => { - eprintln!("Error: {:?}", err); - } - } + let c_path = util::path_buf_to_string(&coverart_queue_path); + let s_path = util::path_buf_to_string(&song_queue_path); + Ok((s_path, c_path, metadata.clone())) } Err(err) => { - eprintln!("Error: {:?}", err); + Err(err) } } Err(err) => { - eprintln!("Error: {:?}", err); + Err(err) } } } Err(err) => { - eprintln!("Error: {:?}", err); + Err(err) } } } - Err(err) => { - eprintln!("Error: {:?}", err); - } + Err(err) => Err(err), } - Ok(()) - } - Err(err) => { - eprintln!("Error: {:?}", err); - Err(err) } + Err(err) => Err(err), } } - Err(err) => { - eprintln!("Error: {:?}", err); - Err(err) - } + Err(err) => Err(err), } } Err(err) => Err(err), @@ -206,21 +237,11 @@ pub async fn save_file_to_fs( } pub async fn apply_metadata( - song_queue_path: std::path::PathBuf, - coverart_queue_path: std::path::PathBuf, + song_queue_path: &String, + coverart_queue_path: &String, metadata: &api::get_metadata_queue::response::Metadata, ) -> Result { // Apply metadata fields - let s_path = match song_queue_path.to_str() { - Some(val) => String::from(val), - None => String::new(), - }; - - if s_path.is_empty() { - println!("Song queue path is empty"); - return Ok(false); - } - let types = icarus_meta::types::all_metadata_types(); for t in types { @@ -228,7 +249,7 @@ pub async fn apply_metadata( icarus_meta::types::Type::Album => { let meta_type = icarus_meta::types::MetadataType::from_string(metadata.album.clone()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -238,7 +259,7 @@ pub async fn apply_metadata( icarus_meta::types::Type::AlbumArtist => { let meta_type = icarus_meta::types::MetadataType::from_string(metadata.album_artist.clone()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -248,7 +269,7 @@ pub async fn apply_metadata( icarus_meta::types::Type::Artist => { let meta_type = icarus_meta::types::MetadataType::from_string(metadata.artist.clone()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -259,7 +280,7 @@ pub async fn apply_metadata( // TODO: Do something about this discrepancy let meta_type = icarus_meta::types::MetadataType::from_string(metadata.year.to_string()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -268,7 +289,7 @@ pub async fn apply_metadata( } icarus_meta::types::Type::Disc => { let meta_type = icarus_meta::types::MetadataType::from_int(metadata.disc); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -278,7 +299,7 @@ pub async fn apply_metadata( icarus_meta::types::Type::Genre => { let meta_type = icarus_meta::types::MetadataType::from_string(metadata.genre.clone()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -288,7 +309,7 @@ pub async fn apply_metadata( icarus_meta::types::Type::Title => { let meta_type = icarus_meta::types::MetadataType::from_string(metadata.title.clone()); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -297,7 +318,7 @@ pub async fn apply_metadata( } icarus_meta::types::Type::Track => { let meta_type = icarus_meta::types::MetadataType::from_int(metadata.track); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -306,7 +327,7 @@ pub async fn apply_metadata( } icarus_meta::types::Type::TrackCount => { let meta_type = icarus_meta::types::MetadataType::from_int(metadata.track_count); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -315,7 +336,7 @@ pub async fn apply_metadata( } icarus_meta::types::Type::DiscCount => { let meta_type = icarus_meta::types::MetadataType::from_int(metadata.disc_count); - match icarus_meta::meta::metadata::set_meta_value(t, &s_path, meta_type) { + match icarus_meta::meta::metadata::set_meta_value(t, song_queue_path, meta_type) { Ok(_) => {} Err(_err) => { return Err(_err); @@ -326,16 +347,11 @@ pub async fn apply_metadata( } // Apply coverart - let c_path: String = match coverart_queue_path.to_str() { - Some(val) => String::from(val), - None => String::new(), - }; - - match icarus_meta::meta::coverart::contains_coverart(&s_path) { + match icarus_meta::meta::coverart::contains_coverart(song_queue_path) { Ok((exists, size)) => { if exists { println!("Coverart exists: {:?} size", size); - match icarus_meta::meta::coverart::remove_coverart(&s_path) { + match icarus_meta::meta::coverart::remove_coverart(song_queue_path) { Ok(_data) => {} Err(err) => { return Err(err); @@ -343,7 +359,7 @@ pub async fn apply_metadata( } } - match icarus_meta::meta::coverart::set_coverart(&s_path, &c_path) { + match icarus_meta::meta::coverart::set_coverart(song_queue_path, coverart_queue_path) { Ok(_data) => { if _data.is_empty() { println!("There was an issue"); @@ -439,7 +455,7 @@ mod api { pub mod response { use serde::{Deserialize, Serialize}; - #[derive(Debug, Deserialize, Serialize)] + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Metadata { pub song_queue_id: uuid::Uuid, pub album: String, diff --git a/src/the_rest.rs b/src/the_rest.rs new file mode 100644 index 0000000..ae021fd --- /dev/null +++ b/src/the_rest.rs @@ -0,0 +1,6 @@ +// TODO: Refactor this file when this app is functional + +// TODO: Create song +// TODO: Create coverart +// TODO: Wipe data from queued song +// TODO: Wipe data from queued coverart diff --git a/src/update_queued_song.rs b/src/update_queued_song.rs new file mode 100644 index 0000000..ba51eeb --- /dev/null +++ b/src/update_queued_song.rs @@ -0,0 +1,35 @@ +pub async fn update_queued_song( + base_url: &String, + song_path: &String, + song_queue_id: &uuid::Uuid, +) -> Result { + let client = reqwest::Client::builder().build()?; + + println!("Song path: {:?}", song_path); + + // TODO: Make the filename random + let form = reqwest::multipart::Form::new().part( + "file", + reqwest::multipart::Part::bytes(std::fs::read(song_path).unwrap()) + .file_name("track01.flac"), + ); + + let url = format!("{}/api/v2/song/queue/{}", base_url, song_queue_id); + println!("Url: {:?}", url); + + let request = client.patch(url).multipart(form); + + let response = request.send().await?; + + Ok(response) +} + +pub mod response { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } +} diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..3a873bc --- /dev/null +++ b/src/util.rs @@ -0,0 +1,6 @@ +pub fn path_buf_to_string(path: &std::path::Path) -> String { + match path.to_str() { + Some(val) => String::from(val), + None => String::new(), + } +} -- 2.43.0 From cd1be017e5e76b0d876ce2d7dc4f7b9d6ac5e8c5 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sun, 29 Jun 2025 21:50:04 +0000 Subject: [PATCH 19/30] rust std change (#29) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/29 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 4 ++-- .gitea/workflows/workflow.yml | 10 +++++----- Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index ace8180..09b4b46 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -18,7 +18,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 components: cargo - name: Extract Version from Cargo.toml @@ -29,7 +29,7 @@ jobs: BRANCH_REF="${GITHUB_REF}" BRANCH_NAME=$(echo "$BRANCH_REF" | cut -d '/' -f 3) PROJECT_TAG_RELEASE="v$VERSION-$BRANCH_NAME-$PROJECT_COMMIT_HASH" - echo "::set-output name=project_tag_release::$PROJECT_TAG_RELEASE-372" + echo "::set-output name=project_tag_release::$PROJECT_TAG_RELEASE-431" echo "Version: $VERSION" echo "Hash: $PROJECT_COMMIT_HASH" echo "Branch: $BRANCH_NAME" diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 21ec691..d545237 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key @@ -54,7 +54,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 - run: rustup component add rustfmt - run: | mkdir -p ~/.ssh @@ -73,7 +73,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 - run: rustup component add clippy - run: | mkdir -p ~/.ssh @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key diff --git a/Cargo.toml b/Cargo.toml index 9cf368d..d6c5091 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "songparser" version = "0.1.0" edition = "2024" -rust-version = "1.86" +rust-version = "1.88" [dependencies] tokio = { version = "1.44.1", features = ["full"] } -- 2.43.0 From 59ce1c294ca4c01f124914b2c02cc4c8b3f59df1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sun, 29 Jun 2025 21:50:34 +0000 Subject: [PATCH 20/30] Update dependencies (#30) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/30 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 23 ++++++++++------------- Cargo.toml | 18 +++++++++--------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc99adf..beae7e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -501,8 +501,8 @@ dependencies = [ [[package]] name = "icarus_envy" -version = "0.2.2" -source = "git+ssh://git@git.kundeng.us/phoenix/icarus_envy.git?tag=v0.2.2-devel-84ea6e4c22-006#84ea6e4c223f19ff96f6b7cae944e831ef4aa831" +version = "0.3.0" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_envy.git?tag=v0.3.0-devel-d73fba9899-006#d73fba9899372b0655a90cb426645930135152da" dependencies = [ "const_format", "dotenvy", @@ -510,16 +510,16 @@ dependencies = [ [[package]] name = "icarus_meta" -version = "0.2.2" -source = "git+ssh://git@git.kundeng.us/phoenix/icarus_meta.git?tag=v0.2.2-devel-565d361b64-680#565d361b64f23c2a0100b33fceeebacfad3331c4" +version = "0.3.0" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_meta.git?tag=v0.3.0-devel-f4b71de969-680#f4b71de9692029a706b1ce82c39f6715c560158e" dependencies = [ "lofty", ] [[package]] name = "icarus_models" -version = "0.4.3" -source = "git+ssh://git@git.kundeng.us/phoenix/icarus_models.git?tag=v0.4.3#6aa4c3d74142f5fceb4a6e95078bb3ae0a2d99c5" +version = "0.5.0" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_models.git?tag=v0.5.0-devel-7958b89abc-111#7958b89abc56bc9262015b3e201ea2906cc8a9ff" dependencies = [ "rand", "serde", @@ -973,13 +973,12 @@ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha", "rand_core", - "zerocopy", ] [[package]] @@ -1012,9 +1011,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.19" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "base64", "bytes", @@ -1029,13 +1028,11 @@ dependencies = [ "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "mime_guess", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "rustls-pki-types", diff --git a/Cargo.toml b/Cargo.toml index d6c5091..abcbb1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,14 +5,14 @@ edition = "2024" rust-version = "1.88" [dependencies] -tokio = { version = "1.44.1", features = ["full"] } +tokio = { version = "1.45.1", features = ["full"] } futures = { version = "0.3.31" } -reqwest = { version = "0.12.19", features = ["json", "stream", "multipart"] } -serde = { version = "1.0.218", features = ["derive"] } -serde_json = { version = "1.0.139" } +reqwest = { version = "0.12.20", features = ["json", "stream", "multipart"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_json = { version = "1.0.140" } time = { version = "0.3.41", features = ["macros", "serde"] } -uuid = { version = "1.16.0", features = ["v4", "serde"] } -rand = { version = "0.9" } -icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.2.2-devel-565d361b64-680" } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.3" } -icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.2.2-devel-84ea6e4c22-006" } +uuid = { version = "1.17.0", features = ["v4", "serde"] } +rand = { version = "0.9.1" } +icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.3.0-devel-f4b71de969-680" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.5.0-devel-7958b89abc-111" } +icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.3.0-devel-d73fba9899-006" } -- 2.43.0 From f9f3dbda367aff4e36620d812241400785ec24dd Mon Sep 17 00:00:00 2001 From: phoenix Date: Sun, 29 Jun 2025 22:08:23 +0000 Subject: [PATCH 21/30] Refactoring (#31) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/31 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 34 +++++++++++++++++----------------- src/update_queued_song.rs | 6 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index beae7e8..b8911f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "songparser" -version = "0.1.0" +version = "0.2.0" dependencies = [ "futures", "icarus_envy", diff --git a/Cargo.toml b/Cargo.toml index abcbb1b..b568463 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "songparser" -version = "0.1.0" +version = "0.2.0" edition = "2024" rust-version = "1.88" diff --git a/src/main.rs b/src/main.rs index 429eac7..8532b50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,20 +11,20 @@ async fn main() -> Result<(), Box> { let app_base_url = icarus_envy::environment::get_icarus_base_api_url().await; loop { - println!("Base URL: {}", app_base_url); + println!("Base URL: {app_base_url}"); match is_queue_empty(&app_base_url).await { Ok((empty, song_queue_item)) => { if !empty { println!("Queue is not empty"); - println!("SongQueueItem: {:?}", song_queue_item); + println!("SongQueueItem: {song_queue_item:?}"); let song_queue_id = song_queue_item.data[0].id; // TODO: Do something with the result later match some_work(&app_base_url, &song_queue_id).await { Ok(_) => {} Err(err) => { - eprintln!("Error: {:?}", err); + eprintln!("Error: {err:?}"); } } } else { @@ -32,7 +32,7 @@ async fn main() -> Result<(), Box> { } } Err(err) => { - eprintln!("Error checking if queue is empty: {:?}", err); + eprintln!("Error checking if queue is empty: {err:?}"); } } @@ -85,7 +85,7 @@ async fn some_work( .await { Ok(_inner_response) => { - println!("Response: {:?}", _inner_response); + println!("Response: {_inner_response:?}"); Ok(()) } Err(err) => Err(std::io::Error::other(err.to_string())), @@ -113,7 +113,7 @@ async fn prep_song( let (directory, filename) = generate_song_queue_dir_and_filename().await; let song_queue_path = save_file_to_fs(&directory, &filename, &song_bytes).await; - println!("Saved at: {:?}", song_queue_path); + println!("Saved at: {song_queue_path:?}"); match api::get_metadata_queue::get(api_url, song_queue_id).await { Ok(response) => { @@ -125,9 +125,9 @@ async fn prep_song( let id = &response.data[0].id; let created_at = &response.data[0].created_at; let metadata = &response.data[0].metadata; - println!("Id: {:?}", id); - println!("Metadata: {:?}", metadata); - println!("Created at: {:?}", created_at); + println!("Id: {id:?}"); + println!("Metadata: {metadata:?}"); + println!("Created at: {created_at:?}"); println!("Getting coverart queue"); match api::get_coverart_queue::get(api_url, song_queue_id).await @@ -136,7 +136,7 @@ async fn prep_song( match response.json::().await { Ok(response) => { let coverart_queue_id = &response.data[0].id; - println!("Coverart queue Id: {:?}", coverart_queue_id); + println!("Coverart queue Id: {coverart_queue_id:?}"); match api::get_coverart_queue::get_data(api_url, coverart_queue_id).await { Ok(response) => match api::parsing::parse_response_into_bytes(response).await { @@ -144,7 +144,7 @@ async fn prep_song( let (directory, filename) = generate_coverart_queue_dir_and_filename().await; let coverart_queue_path = save_file_to_fs(&directory, &filename, &coverart_queue_bytes).await; - println!("Saved coverart queue file at: {:?}", coverart_queue_path); + println!("Saved coverart queue file at: {coverart_queue_path:?}"); let c_path = util::path_buf_to_string(&coverart_queue_path); let s_path = util::path_buf_to_string(&song_queue_path); @@ -350,7 +350,7 @@ pub async fn apply_metadata( match icarus_meta::meta::coverart::contains_coverart(song_queue_path) { Ok((exists, size)) => { if exists { - println!("Coverart exists: {:?} size", size); + println!("Coverart exists: {size:?} size"); match icarus_meta::meta::coverart::remove_coverart(song_queue_path) { Ok(_data) => {} Err(err) => { @@ -401,7 +401,7 @@ mod api { ) -> Result { let client = reqwest::Client::new(); let fetch_endpoint = String::from("api/v2/song/queue/next"); - let api_url = format!("{}/{}", base_url, fetch_endpoint); + let api_url = format!("{base_url}/{fetch_endpoint}"); client.get(api_url).send().await } @@ -432,7 +432,7 @@ mod api { ) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v2/song/queue"); - let api_url = format!("{}/{}/{}", base_url, endpoint, id); + let api_url = format!("{base_url}/{endpoint}/{id}"); client.get(api_url).send().await } } @@ -444,7 +444,7 @@ mod api { ) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v2/song/metadata/queue"); - let api_url = format!("{}/{}", base_url, endpoint); + let api_url = format!("{base_url}/{endpoint}"); client .get(api_url) .query(&[("song_queue_id", song_queue_id)]) @@ -495,7 +495,7 @@ mod api { ) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v2/coverart/queue"); - let api_url = format!("{}/{}", base_url, endpoint); + let api_url = format!("{base_url}/{endpoint}"); client .get(api_url) .query(&[("song_queue_id", song_queue_id)]) @@ -509,7 +509,7 @@ mod api { ) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v2/coverart/queue/data"); - let api_url = format!("{}/{}/{}", base_url, endpoint, coverart_queue_id); + let api_url = format!("{base_url}/{endpoint}/{coverart_queue_id}"); client.get(api_url).send().await } diff --git a/src/update_queued_song.rs b/src/update_queued_song.rs index ba51eeb..b7f3322 100644 --- a/src/update_queued_song.rs +++ b/src/update_queued_song.rs @@ -5,7 +5,7 @@ pub async fn update_queued_song( ) -> Result { let client = reqwest::Client::builder().build()?; - println!("Song path: {:?}", song_path); + println!("Song path: {song_path:?}"); // TODO: Make the filename random let form = reqwest::multipart::Form::new().part( @@ -14,8 +14,8 @@ pub async fn update_queued_song( .file_name("track01.flac"), ); - let url = format!("{}/api/v2/song/queue/{}", base_url, song_queue_id); - println!("Url: {:?}", url); + let url = format!("{base_url}/api/v2/song/queue/{song_queue_id}"); + println!("Url: {url:?}"); let request = client.patch(url).multipart(form); -- 2.43.0 From fe61fe3efbfddf03501e7ab5ab0c2406d33914a4 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sun, 29 Jun 2025 22:20:40 +0000 Subject: [PATCH 22/30] Tag release change (#32) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/32 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index 09b4b46..ace8180 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -18,7 +18,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.88.0 + toolchain: 1.86.0 components: cargo - name: Extract Version from Cargo.toml @@ -29,7 +29,7 @@ jobs: BRANCH_REF="${GITHUB_REF}" BRANCH_NAME=$(echo "$BRANCH_REF" | cut -d '/' -f 3) PROJECT_TAG_RELEASE="v$VERSION-$BRANCH_NAME-$PROJECT_COMMIT_HASH" - echo "::set-output name=project_tag_release::$PROJECT_TAG_RELEASE-431" + echo "::set-output name=project_tag_release::$PROJECT_TAG_RELEASE-372" echo "Version: $VERSION" echo "Hash: $PROJECT_COMMIT_HASH" echo "Branch: $BRANCH_NAME" -- 2.43.0 From a779e13a7710a5ffbadbc485ae8674dc9399d446 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 15 Jul 2025 00:53:12 +0000 Subject: [PATCH 23/30] Create song (#33) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/33 Co-authored-by: phoenix Co-committed-by: phoenix --- src/api.rs | 131 +++++++++++++++++++++++++++++ src/main.rs | 209 ++++++++++++----------------------------------- src/responses.rs | 16 ++++ src/the_rest.rs | 43 ++++++++++ 4 files changed, 240 insertions(+), 159 deletions(-) create mode 100644 src/api.rs create mode 100644 src/responses.rs diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..f4d0933 --- /dev/null +++ b/src/api.rs @@ -0,0 +1,131 @@ +pub async fn fetch_next_queue_item(base_url: &String) -> Result { + let client = reqwest::Client::new(); + let fetch_endpoint = String::from("api/v2/song/queue/next"); + let api_url = format!("{base_url}/{fetch_endpoint}"); + client.get(api_url).send().await +} + +pub mod parsing { + use futures::StreamExt; + + pub async fn parse_response_into_bytes( + response: reqwest::Response, + ) -> Result, reqwest::Error> { + // TODO: At some point, handle the flow if the size is small or + // large + let mut byte_stream = response.bytes_stream(); + let mut all_bytes = Vec::new(); + + while let Some(chunk) = byte_stream.next().await { + let chunk = chunk?; + all_bytes.extend_from_slice(&chunk); + } + + Ok(all_bytes) + } +} + +pub mod fetch_song_queue_data { + pub async fn get_data( + base_url: &String, + id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/song/queue"); + let api_url = format!("{base_url}/{endpoint}/{id}"); + client.get(api_url).send().await + } +} + +pub mod get_metadata_queue { + pub async fn get( + base_url: &String, + song_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/song/metadata/queue"); + let api_url = format!("{base_url}/{endpoint}"); + client + .get(api_url) + .query(&[("song_queue_id", song_queue_id)]) + .send() + .await + } + + pub mod response { + use serde::{Deserialize, Serialize}; + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct Metadata { + pub song_queue_id: uuid::Uuid, + pub album: String, + pub album_artist: String, + pub artist: String, + pub disc: i32, + pub disc_count: i32, + pub duration: i64, + pub genre: String, + pub title: String, + pub track: i32, + pub track_count: i32, + pub year: i32, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct QueueItem { + pub id: uuid::Uuid, + pub metadata: Metadata, + #[serde(with = "time::serde::rfc3339")] + pub created_at: time::OffsetDateTime, + pub song_queue_id: uuid::Uuid, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } +} + +pub mod get_coverart_queue { + pub async fn get( + base_url: &String, + song_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/coverart/queue"); + let api_url = format!("{base_url}/{endpoint}"); + client + .get(api_url) + .query(&[("song_queue_id", song_queue_id)]) + .send() + .await + } + + pub async fn get_data( + base_url: &String, + coverart_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v2/coverart/queue/data"); + let api_url = format!("{base_url}/{endpoint}/{coverart_queue_id}"); + client.get(api_url).send().await + } + + pub mod response { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct CoverArtQueue { + pub id: uuid::Uuid, + pub song_queue_id: uuid::Uuid, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } +} diff --git a/src/main.rs b/src/main.rs index 8532b50..7bb1141 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +pub mod api; +pub mod responses; pub mod the_rest; pub mod update_queued_song; pub mod util; @@ -69,7 +71,7 @@ async fn some_work( song_queue_id: &uuid::Uuid, ) -> Result<(), std::io::Error> { match prep_song(app_base_url, song_queue_id).await { - Ok((song_queue_path, coverart_queue_path, metadata)) => { + Ok((song_queue_path, coverart_queue_path, metadata, coverart_queue_id)) => { match apply_metadata(&song_queue_path, &coverart_queue_path, &metadata).await { Ok(_applied) => { match update_queued_song::update_queued_song( @@ -86,7 +88,43 @@ async fn some_work( { Ok(_inner_response) => { println!("Response: {_inner_response:?}"); - Ok(()) + + // TODO: Do not hard code this. Check if one of the existing + // endpoints already have the user_id + let user_id = uuid::Uuid::new_v4(); + // TODO: Place this somewhere else + let song_type = String::from("flac"); + // Err(std::io::Error::other(err.to_string())) + match the_rest::create_song::create( + app_base_url, + &metadata, + &user_id, + &song_type, + ) + .await + { + Ok(response) => match response + .json::() + .await + { + Ok(resp) => { + println!("Response: {resp:?}"); + + let song = &resp.data[0]; + let url = format!("{app_base_url}/api/v2/coverart"); + let payload = serde_json::json!({ + "song_id": &song.id, + "coverart_queue_id": &coverart_queue_id, + }); + println!("Payload: {payload:?}"); + println!("Url: {url:?}"); + // println!("Response json: {:?}", response.text().await); + Ok(()) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } } Err(err) => Err(std::io::Error::other(err.to_string())), } @@ -104,7 +142,15 @@ async fn some_work( async fn prep_song( api_url: &String, song_queue_id: &uuid::Uuid, -) -> Result<(String, String, api::get_metadata_queue::response::Metadata), reqwest::Error> { +) -> Result< + ( + String, + String, + api::get_metadata_queue::response::Metadata, + uuid::Uuid, + ), + reqwest::Error, +> { match api::fetch_song_queue_data::get_data(api_url, song_queue_id).await { Ok(response) => { // Process data here... @@ -148,7 +194,7 @@ async fn prep_song( let c_path = util::path_buf_to_string(&coverart_queue_path); let s_path = util::path_buf_to_string(&song_queue_path); - Ok((s_path, c_path, metadata.clone())) + Ok((s_path, c_path, metadata.clone(), *coverart_queue_id)) } Err(err) => { Err(err) @@ -375,158 +421,3 @@ pub async fn apply_metadata( Err(err) => Err(err), } } - -mod responses { - pub mod fetch_next_queue_item { - use serde::{Deserialize, Serialize}; - - #[derive(Debug, Deserialize, Serialize)] - pub struct QueueItem { - pub id: uuid::Uuid, - pub filename: String, - pub status: String, - } - - #[derive(Debug, Deserialize, Serialize)] - pub struct SongQueueItem { - pub message: String, - pub data: Vec, - } - } -} - -mod api { - pub async fn fetch_next_queue_item( - base_url: &String, - ) -> Result { - let client = reqwest::Client::new(); - let fetch_endpoint = String::from("api/v2/song/queue/next"); - let api_url = format!("{base_url}/{fetch_endpoint}"); - client.get(api_url).send().await - } - - pub mod parsing { - use futures::StreamExt; - - pub async fn parse_response_into_bytes( - response: reqwest::Response, - ) -> Result, reqwest::Error> { - // TODO: At some point, handle the flow if the size is small or - // large - let mut byte_stream = response.bytes_stream(); - let mut all_bytes = Vec::new(); - - while let Some(chunk) = byte_stream.next().await { - let chunk = chunk?; - all_bytes.extend_from_slice(&chunk); - } - - Ok(all_bytes) - } - } - - pub mod fetch_song_queue_data { - pub async fn get_data( - base_url: &String, - id: &uuid::Uuid, - ) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v2/song/queue"); - let api_url = format!("{base_url}/{endpoint}/{id}"); - client.get(api_url).send().await - } - } - - pub mod get_metadata_queue { - pub async fn get( - base_url: &String, - song_queue_id: &uuid::Uuid, - ) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v2/song/metadata/queue"); - let api_url = format!("{base_url}/{endpoint}"); - client - .get(api_url) - .query(&[("song_queue_id", song_queue_id)]) - .send() - .await - } - - pub mod response { - use serde::{Deserialize, Serialize}; - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Metadata { - pub song_queue_id: uuid::Uuid, - pub album: String, - pub album_artist: String, - pub artist: String, - pub disc: i32, - pub disc_count: i32, - pub duration: i64, - pub genre: String, - pub title: String, - pub track: i32, - pub track_count: i32, - pub year: i32, - } - - #[derive(Debug, Deserialize, Serialize)] - pub struct QueueItem { - pub id: uuid::Uuid, - pub metadata: Metadata, - #[serde(with = "time::serde::rfc3339")] - pub created_at: time::OffsetDateTime, - pub song_queue_id: uuid::Uuid, - } - - #[derive(Debug, Deserialize, Serialize)] - pub struct Response { - pub message: String, - pub data: Vec, - } - } - } - - pub mod get_coverart_queue { - pub async fn get( - base_url: &String, - song_queue_id: &uuid::Uuid, - ) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v2/coverart/queue"); - let api_url = format!("{base_url}/{endpoint}"); - client - .get(api_url) - .query(&[("song_queue_id", song_queue_id)]) - .send() - .await - } - - pub async fn get_data( - base_url: &String, - coverart_queue_id: &uuid::Uuid, - ) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v2/coverart/queue/data"); - let api_url = format!("{base_url}/{endpoint}/{coverart_queue_id}"); - client.get(api_url).send().await - } - - pub mod response { - use serde::{Deserialize, Serialize}; - - #[derive(Debug, Deserialize, Serialize)] - pub struct CoverArtQueue { - pub id: uuid::Uuid, - pub song_queue_id: uuid::Uuid, - } - - #[derive(Debug, Deserialize, Serialize)] - pub struct Response { - pub message: String, - pub data: Vec, - } - } - } -} diff --git a/src/responses.rs b/src/responses.rs new file mode 100644 index 0000000..c5a090e --- /dev/null +++ b/src/responses.rs @@ -0,0 +1,16 @@ +pub mod fetch_next_queue_item { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Serialize)] + pub struct QueueItem { + pub id: uuid::Uuid, + pub filename: String, + pub status: String, + } + + #[derive(Debug, Deserialize, Serialize)] + pub struct SongQueueItem { + pub message: String, + pub data: Vec, + } +} diff --git a/src/the_rest.rs b/src/the_rest.rs index ae021fd..8afffe7 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -1,6 +1,49 @@ // TODO: Refactor this file when this app is functional // TODO: Create song +pub mod create_song { + pub async fn create( + base_url: &String, + metadata_queue: &crate::api::get_metadata_queue::response::Metadata, + user_id: &uuid::Uuid, + song_type: &String, + ) -> Result { + let payload = serde_json::json!( + { + "album": &metadata_queue.album, + "album_artist": &metadata_queue.album_artist, + "artist": &metadata_queue.artist, + "disc": metadata_queue.disc, + "disc_count": metadata_queue.disc_count, + "duration": metadata_queue.duration, + "genre": &metadata_queue.genre, + "title": &metadata_queue.title, + "track": metadata_queue.track, + "track_count": metadata_queue.track_count, + "date": metadata_queue.year.to_string(), + "audio_type": &song_type, + "user_id": &user_id, + "song_queue_id": &metadata_queue.song_queue_id, + } + ); + + let client = reqwest::Client::builder().build()?; + + let url = format!("{base_url}/api/v2/song"); + + let request = client.post(url).json(&payload); + request.send().await + } + + pub mod response { + #[derive(Debug, serde::Deserialize, serde::Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } +} + // TODO: Create coverart // TODO: Wipe data from queued song // TODO: Wipe data from queued coverart -- 2.43.0 From c16ad062d4092affe4518f856d259f4747432eff Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 15 Jul 2025 19:15:26 +0000 Subject: [PATCH 24/30] Create coverArt (#34) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/34 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- src/main.rs | 45 ++++++++++++++++++++++++++++++++++----------- src/the_rest.rs | 31 +++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8911f2..68cd5b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,8 +518,8 @@ dependencies = [ [[package]] name = "icarus_models" -version = "0.5.0" -source = "git+ssh://git@git.kundeng.us/phoenix/icarus_models.git?tag=v0.5.0-devel-7958b89abc-111#7958b89abc56bc9262015b3e201ea2906cc8a9ff" +version = "0.4.5" +source = "git+ssh://git@git.kundeng.us/phoenix/icarus_models.git?tag=v0.4.5-devel-655d05dabb-111#655d05dabbdadb9b28940564a1eb82470aa4f166" dependencies = [ "rand", "serde", @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "songparser" -version = "0.2.0" +version = "0.2.1" dependencies = [ "futures", "icarus_envy", diff --git a/Cargo.toml b/Cargo.toml index b568463..14cc263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "songparser" -version = "0.2.0" +version = "0.2.1" edition = "2024" rust-version = "1.88" @@ -14,5 +14,5 @@ time = { version = "0.3.41", features = ["macros", "serde"] } uuid = { version = "1.17.0", features = ["v4", "serde"] } rand = { version = "0.9.1" } icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.3.0-devel-f4b71de969-680" } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.5.0-devel-7958b89abc-111" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.5-devel-655d05dabb-111" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.3.0-devel-d73fba9899-006" } diff --git a/src/main.rs b/src/main.rs index 7bb1141..2cd73d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,15 @@ async fn main() -> Result<(), Box> { // TODO: Do something with the result later match some_work(&app_base_url, &song_queue_id).await { - Ok(_) => {} + Ok(( + song, + coverart, + (song_queue_id, song_queue_path), + (coverart_queue_id, coverart_queue_path), + )) => { + // TODO: Wipe data from song and coverart queues + // TODO: Cleanup files in local filesystem + } Err(err) => { eprintln!("Error: {err:?}"); } @@ -69,7 +77,15 @@ async fn is_queue_empty( async fn some_work( app_base_url: &String, song_queue_id: &uuid::Uuid, -) -> Result<(), std::io::Error> { +) -> Result< + ( + icarus_models::song::Song, + icarus_models::coverart::CoverArt, + (uuid::Uuid, String), + (uuid::Uuid, String), + ), + std::io::Error, +> { match prep_song(app_base_url, song_queue_id).await { Ok((song_queue_path, coverart_queue_path, metadata, coverart_queue_id)) => { match apply_metadata(&song_queue_path, &coverart_queue_path, &metadata).await { @@ -111,15 +127,22 @@ async fn some_work( println!("Response: {resp:?}"); let song = &resp.data[0]; - let url = format!("{app_base_url}/api/v2/coverart"); - let payload = serde_json::json!({ - "song_id": &song.id, - "coverart_queue_id": &coverart_queue_id, - }); - println!("Payload: {payload:?}"); - println!("Url: {url:?}"); - // println!("Response json: {:?}", response.text().await); - Ok(()) + match the_rest::create_coverart::create(app_base_url, &song.id, &coverart_queue_id).await { + Ok(response) => match response.json::().await { + Ok(resp) => { + println!("CoverArt sent and successfully parsed response"); + println!("json: {resp:?}"); + let coverart = &resp.data[0]; + Ok((song.clone(), coverart.clone(), (metadata.song_queue_id, song_queue_path), (coverart_queue_id, coverart_queue_path))) + } + Err(err) => { + Err(std::io::Error::other(err.to_string())) + } + } + Err(err) => { + Err(std::io::Error::other(err.to_string())) + } + } } Err(err) => Err(std::io::Error::other(err.to_string())), }, diff --git a/src/the_rest.rs b/src/the_rest.rs index 8afffe7..8b12392 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -45,5 +45,36 @@ pub mod create_song { } // TODO: Create coverart +pub mod create_coverart { + + pub async fn create( + base_url: &String, + song_id: &uuid::Uuid, + coverart_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::builder().build()?; + let url = format!("{base_url}/api/v2/coverart"); + let payload = get_payload(song_id, coverart_queue_id); + let request = client.post(url).json(&payload); + + request.send().await + } + + fn get_payload(song_id: &uuid::Uuid, coverart_queue_id: &uuid::Uuid) -> serde_json::Value { + serde_json::json!({ + "song_id": &song_id, + "coverart_queue_id": &coverart_queue_id, + }) + } + + pub mod response { + #[derive(Debug, serde::Deserialize, serde::Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } +} + // TODO: Wipe data from queued song // TODO: Wipe data from queued coverart -- 2.43.0 From 47bf24180ba8f7ab10b082b00a7636c811d9c99d Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 15 Jul 2025 19:49:24 +0000 Subject: [PATCH 25/30] Wipe data from song queue (#35) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/35 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 32 ++++++++++++++++++++++++++++++++ src/the_rest.rs | 30 ++++++++++++++++++++++++++---- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68cd5b2..dab90be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "songparser" -version = "0.2.1" +version = "0.2.2" dependencies = [ "futures", "icarus_envy", diff --git a/Cargo.toml b/Cargo.toml index 14cc263..97dae28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "songparser" -version = "0.2.1" +version = "0.2.2" edition = "2024" rust-version = "1.88" diff --git a/src/main.rs b/src/main.rs index 2cd73d2..226db68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,6 +31,18 @@ async fn main() -> Result<(), Box> { (coverart_queue_id, coverart_queue_path), )) => { // TODO: Wipe data from song and coverart queues + match wipe_data_from_queues( + &app_base_url, + &song_queue_id, + &coverart_queue_id, + ) + .await + { + Ok(_) => {} + Err(err) => { + eprintln!("Error: {err:?}"); + } + } // TODO: Cleanup files in local filesystem } Err(err) => { @@ -51,6 +63,26 @@ async fn main() -> Result<(), Box> { } } +async fn wipe_data_from_queues( + app_base_url: &String, + song_queue_id: &uuid::Uuid, + coverart_queue_id: &uuid::Uuid, +) -> Result<(), std::io::Error> { + match the_rest::wipe_data::song_queue::wipe_data(app_base_url, song_queue_id).await { + Ok(response) => match response + .json::() + .await + { + Ok(_resp) => { + println!("Wiped data from song queue"); + Ok(()) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + async fn is_queue_empty( api_url: &String, ) -> Result<(bool, responses::fetch_next_queue_item::SongQueueItem), reqwest::Error> { diff --git a/src/the_rest.rs b/src/the_rest.rs index 8b12392..b5fa85f 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -1,6 +1,5 @@ // TODO: Refactor this file when this app is functional -// TODO: Create song pub mod create_song { pub async fn create( base_url: &String, @@ -44,7 +43,6 @@ pub mod create_song { } } -// TODO: Create coverart pub mod create_coverart { pub async fn create( @@ -76,5 +74,29 @@ pub mod create_coverart { } } -// TODO: Wipe data from queued song -// TODO: Wipe data from queued coverart +pub mod wipe_data { + pub mod song_queue { + pub async fn wipe_data( + base_url: &String, + song_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::builder().build()?; + let url = format!("{base_url}/api/v2/song/queue/data/wipe"); + let payload = serde_json::json!({ + "song_queue_id": song_queue_id + }); + let request = client.patch(url).json(&payload); + + request.send().await + } + + pub mod response { + #[derive(Debug, serde::Deserialize, serde::Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } + } + // TODO: Wipe data from queued coverart +} -- 2.43.0 From 111d16515ffb54c6e35993edcf879eb438250c73 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 15 Jul 2025 20:10:12 +0000 Subject: [PATCH 26/30] Wipe data from CoverArt queue (#36) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/36 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 32 ++++++++++++++++++++++++-------- src/the_rest.rs | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dab90be..5f7e8b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "songparser" -version = "0.2.2" +version = "0.2.3" dependencies = [ "futures", "icarus_envy", diff --git a/Cargo.toml b/Cargo.toml index 97dae28..0861cc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "songparser" -version = "0.2.2" +version = "0.2.3" edition = "2024" rust-version = "1.88" diff --git a/src/main.rs b/src/main.rs index 226db68..d2907db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,8 +25,8 @@ async fn main() -> Result<(), Box> { // TODO: Do something with the result later match some_work(&app_base_url, &song_queue_id).await { Ok(( - song, - coverart, + _song, + _coverart, (song_queue_id, song_queue_path), (coverart_queue_id, coverart_queue_path), )) => { @@ -38,12 +38,13 @@ async fn main() -> Result<(), Box> { ) .await { - Ok(_) => {} + Ok(_) => { + // TODO: Cleanup files in local filesystem + } Err(err) => { eprintln!("Error: {err:?}"); } } - // TODO: Cleanup files in local filesystem } Err(err) => { eprintln!("Error: {err:?}"); @@ -73,10 +74,25 @@ async fn wipe_data_from_queues( .json::() .await { - Ok(_resp) => { - println!("Wiped data from song queue"); - Ok(()) - } + Ok(_resp) => match the_rest::wipe_data::coverart_queue::wipe_data( + app_base_url, + coverart_queue_id, + ) + .await + { + Ok(inner_response) => match inner_response + .json::() + .await + { + Ok(_inner_resp) => { + println!("Wiped data from CoverArt queue"); + println!("Resp: {_inner_resp:?}"); + Ok(()) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + }, Err(err) => Err(std::io::Error::other(err.to_string())), }, Err(err) => Err(std::io::Error::other(err.to_string())), diff --git a/src/the_rest.rs b/src/the_rest.rs index b5fa85f..c806f0f 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -99,4 +99,27 @@ pub mod wipe_data { } } // TODO: Wipe data from queued coverart + pub mod coverart_queue { + pub async fn wipe_data( + base_url: &String, + coverart_queue_id: &uuid::Uuid, + ) -> Result { + let client = reqwest::Client::builder().build()?; + let url = format!("{base_url}/api/v2/coverart/queue/data/wipe"); + let payload = serde_json::json!({ + "coverart_queue_id": coverart_queue_id + }); + let request = client.patch(url).json(&payload); + + request.send().await + } + + pub mod response { + #[derive(Debug, serde::Deserialize, serde::Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } + } } -- 2.43.0 From 99bb72ffb228ac08bf28c43c29dc791d3b16bac1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 23 Jul 2025 01:18:35 +0000 Subject: [PATCH 27/30] Removing hard coded user_id (#38) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/38 Co-authored-by: phoenix Co-committed-by: phoenix --- src/main.rs | 11 +++++------ src/responses.rs | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index d2907db..aef13f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,9 +21,10 @@ async fn main() -> Result<(), Box> { println!("Queue is not empty"); println!("SongQueueItem: {song_queue_item:?}"); let song_queue_id = song_queue_item.data[0].id; + let user_id = song_queue_item.data[0].user_id; // TODO: Do something with the result later - match some_work(&app_base_url, &song_queue_id).await { + match some_work(&app_base_url, &song_queue_id, &user_id).await { Ok(( _song, _coverart, @@ -125,6 +126,7 @@ async fn is_queue_empty( async fn some_work( app_base_url: &String, song_queue_id: &uuid::Uuid, + user_id: &uuid::Uuid, ) -> Result< ( icarus_models::song::Song, @@ -153,16 +155,13 @@ async fn some_work( Ok(_inner_response) => { println!("Response: {_inner_response:?}"); - // TODO: Do not hard code this. Check if one of the existing - // endpoints already have the user_id - let user_id = uuid::Uuid::new_v4(); // TODO: Place this somewhere else let song_type = String::from("flac"); - // Err(std::io::Error::other(err.to_string())) + match the_rest::create_song::create( app_base_url, &metadata, - &user_id, + user_id, &song_type, ) .await diff --git a/src/responses.rs b/src/responses.rs index c5a090e..3f990a5 100644 --- a/src/responses.rs +++ b/src/responses.rs @@ -6,6 +6,7 @@ pub mod fetch_next_queue_item { pub id: uuid::Uuid, pub filename: String, pub status: String, + pub user_id: uuid::Uuid, } #[derive(Debug, Deserialize, Serialize)] -- 2.43.0 From 27e4b30d21675edf646799b4746963cfe34f1af1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 23 Jul 2025 20:25:05 +0000 Subject: [PATCH 28/30] File cleanup post-parsing (#37) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/37 Co-authored-by: phoenix Co-committed-by: phoenix --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 26 ++++++++++++++++++++++++- src/the_rest.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f7e8b0..553b8e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "songparser" -version = "0.2.3" +version = "0.2.4" dependencies = [ "futures", "icarus_envy", diff --git a/Cargo.toml b/Cargo.toml index 0861cc9..cd5e6fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "songparser" -version = "0.2.3" +version = "0.2.4" edition = "2024" rust-version = "1.88" diff --git a/src/main.rs b/src/main.rs index aef13f4..9362977 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,14 @@ async fn main() -> Result<(), Box> { .await { Ok(_) => { - // TODO: Cleanup files in local filesystem + match cleanup(&song_queue_path, &coverart_queue_path).await { + Ok(_) => { + println!("Successful cleanup"); + } + Err(err) => { + eprintln!("Error: {err:?}"); + } + } } Err(err) => { eprintln!("Error: {err:?}"); @@ -100,6 +107,23 @@ async fn wipe_data_from_queues( } } +async fn cleanup( + song_queue_path: &String, + coverart_queue_path: &String, +) -> Result<(), std::io::Error> { + match the_rest::cleanup::clean_song_queue(song_queue_path) { + Ok(_) => {} + Err(err) => { + eprintln!("Error: Problem cleaning up SongQueue files {err:?}"); + } + } + + match the_rest::cleanup::clean_coverart_queue(coverart_queue_path) { + Ok(_) => Ok(()), + Err(err) => Err(err), + } +} + async fn is_queue_empty( api_url: &String, ) -> Result<(bool, responses::fetch_next_queue_item::SongQueueItem), reqwest::Error> { diff --git a/src/the_rest.rs b/src/the_rest.rs index c806f0f..b3f0b2e 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -123,3 +123,54 @@ pub mod wipe_data { } } } + +pub mod cleanup { + pub fn clean_song_queue(song_queue_path: &String) -> Result<(), std::io::Error> { + let file_path = std::path::Path::new(song_queue_path); + if file_path.exists() { + match std::fs::remove_file(file_path) { + Ok(_) => { + if check_file_existence(song_queue_path) { + Err(std::io::Error::other(String::from( + "SongQueue file exists after a deletion", + ))) + } else { + Ok(()) + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } else { + Err(std::io::Error::other(String::from( + "SongQueue file path does not exists", + ))) + } + } + + pub fn clean_coverart_queue(coverart_queue_path: &String) -> Result<(), std::io::Error> { + let coverart_file_path = std::path::Path::new(coverart_queue_path); + if coverart_file_path.exists() { + match std::fs::remove_file(coverart_file_path) { + Ok(_) => { + if !check_file_existence(coverart_queue_path) { + Ok(()) + } else { + Err(std::io::Error::other(String::from( + "CoverArt file stil exists", + ))) + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } else { + Err(std::io::Error::other(String::from( + "CoverArt file does not exists", + ))) + } + } + + fn check_file_existence(file_path: &String) -> bool { + let path = std::path::Path::new(file_path); + path.exists() + } +} -- 2.43.0 From d5e24f9114c10b31ffa3b18284069a1b803016ea Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 23 Jul 2025 20:50:40 +0000 Subject: [PATCH 29/30] Minor changes (#39) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/39 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 6 +----- src/main.rs | 1 - src/the_rest.rs | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index ace8180..ee32b4a 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -3,7 +3,6 @@ name: Release Tagging on: push: branches: - - main - devel jobs: @@ -18,7 +17,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.86.0 + toolchain: 1.88.0 components: cargo - name: Extract Version from Cargo.toml @@ -50,6 +49,3 @@ jobs: release_name: Release ${{ steps.version.outputs.project_tag_release }} body: | Release of version ${{ steps.version.outputs.project_tag_release }} - # draft: false - # prerelease: ${{ startsWith(github.ref, 'v') == false }} # prerelease if not a valid release tag - diff --git a/src/main.rs b/src/main.rs index 9362977..aa85b54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,6 @@ async fn main() -> Result<(), Box> { (song_queue_id, song_queue_path), (coverart_queue_id, coverart_queue_path), )) => { - // TODO: Wipe data from song and coverart queues match wipe_data_from_queues( &app_base_url, &song_queue_id, diff --git a/src/the_rest.rs b/src/the_rest.rs index b3f0b2e..dbf85fb 100644 --- a/src/the_rest.rs +++ b/src/the_rest.rs @@ -98,7 +98,6 @@ pub mod wipe_data { } } } - // TODO: Wipe data from queued coverart pub mod coverart_queue { pub async fn wipe_data( base_url: &String, -- 2.43.0 From af4f1acb87f927d6f9400c2bf40a4831198cff96 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 23 Jul 2025 21:01:36 +0000 Subject: [PATCH 30/30] Reverting change (#40) Reviewed-on: https://git.kundeng.us/phoenix/songparser/pulls/40 Co-authored-by: phoenix Co-committed-by: phoenix --- .gitea/workflows/tag_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index ee32b4a..7ab6fe4 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -17,7 +17,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.88.0 + toolchain: 1.86.0 components: cargo - name: Extract Version from Cargo.toml -- 2.43.0