16 Commits
Author SHA1 Message Date
phoenix f32f6812b3 Adding openssl (#104)
sidm / build (push) Successful in 3m26s
Reviewed-on: #104
2026-07-21 15:32:48 -04:00
phoenix 68c0b06280 Dependency name change (#103)
sidm / build (push) Successful in 1m36s
Reviewed-on: #103
2026-07-16 13:47:33 -04:00
phoenix 592c5aaf60 Update rust (#102)
Rust / build (push) Successful in 3m25s
Reviewed-on: phoenix/idm#102
2026-07-10 19:29:05 -04:00
phoenix a8ed05c278 tsk-100: Name change (#101)
Rust / build (push) Successful in 1m44s
Rust / build (pull_request) Successful in 3m10s
From `icarus_dm` -> `idm`.

Closes #100

Reviewed-on: phoenix/icarus_dm#101
2026-07-10 19:03:11 -04:00
phoenixandGitHub 489d13227b Update rust (#99)
Rust / build (pull_request) Failing after 4s
* bump: rust

* bump: rust ci

* Updated License

* bump: reqwest

* bump: tokio

* bump: uuid

* bump: icarus_models

* cargo update

* bump: icarus_dm
2026-05-05 21:05:40 -04:00
phoenixandGitHub 0e6438cf0d Updated rust (#95)
* Updated rust version in workflow

* Using variable in workflow file

* Updating packages

* cargo update

* Version bump
2026-04-05 17:14:50 -04:00
KDandGitHub 00615532ce icarus_models version bump (#93)
* icarus_models version bump

* Build fix

* Removed method

* Some refactoring

* More cleanup

* Version bump

* Using standard version
2025-10-30 15:33:09 -04:00
KDandGitHub abd16eeba2 tsk-79: Simplifying functions (#92)
* tsk-79: Changed return type of function and cleaned up other functions

* tsk-79: Version bump

* tsk-79: Code formatting
2025-10-27 12:42:42 -04:00
KDandGitHub 5c9fcf2ec5 tsk-83: Add token code prior to action execution (#91)
* tsk-83: Code cleanup

* tsk-83: Added code to get token before an action begins

* tsk-83: Small fix

* tsk-83: Version bump

* tsk-83: Cleanup
2025-10-26 16:39:16 -04:00
KDandGitHub 6bedab0d88 tsk-82: Refactor validate_args() method (#90)
* tsk-82: Refactored validate_flags() method

* tsk-82: Warning fix

* tsk-82: Code formatting

* tsk-82: Version bump

* tsk-82: Forgot this

* tsk-82: Fix
2025-10-24 20:51:33 -04:00
KDandGitHub 686e0d8f1f tsk-81: Simplify downloading song (#89)
* tsk-81: Using method in Song to save to filesystem

* tsk-81: icaurs_models version bump

* tsk-81: Code formatting

* tsk-81: icarus_models version bump

* tsk-81: Version bump
2025-10-24 13:34:55 -04:00
KDandGitHub 05a9134aaa tsk-80: Removing unused serde references (#88)
* tsk-80: Removing unused serde references

* tsk-80: Version bump

* tsk-80: Formatting code
2025-10-23 21:10:08 -04:00
KDandGitHub 3cadac4efd tsk-78: Updating returned error on converting ostring to string (#87)
* tsk-78: Making error to get string from o string more robust

* tsk-78: Version bump
2025-10-23 16:52:26 -04:00
KDandGitHub 2188c2b746 tsk-77: Print version of the software (#86)
* tsk-77: Added code to print version

* tsk-77: Removed print statement

* tsk-77: Code formatting

* tsk-77: Version bump

* tsk-77: Updated help
2025-10-22 21:40:12 -04:00
KDandGitHub 9328f3d3da tsk-76: Remove songs directory (#85)
* tsk-76: Removed songs directory

* tsk-76: Version bump
2025-10-22 20:59:20 -04:00
KDandGitHub ca13f101d7 icarus_models version bump (#84)
* icarus_models version bump

* icarus_models related changes

* Removing method

* Code formatting

* Warning fix

* Removing comments

* Version bump

* cargo update
2025-10-19 23:52:43 -04:00
22 changed files with 914 additions and 906 deletions
@@ -1,4 +1,4 @@
name: Rust name: sidm
on: on:
push: push:
@@ -15,19 +15,17 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Install Rust version - uses: actions-rust-lang/setup-rust-toolchain@v1
run: rustup install 1.90.0 && rustup default 1.90.0 with:
toolchain: 1.97
- name: Debug secret - uses: Swatinem/rust-cache@v2
run: echo "${{ secrets.MYREPO_TOKEN }}" | head -c 10 ; echo "..."
- name: Build - name: Build
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
echo "$EXTREPO_KEY" > ~/.ssh/gitlab_deploy_key echo "$EXTREPO_KEY" > ~/.ssh/gitlab_deploy_key
chmod 600 ~/.ssh/gitlab_deploy_key chmod 600 ~/.ssh/gitlab_deploy_key
ssh-keyscan git.kundeng.us ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLl/OZiKVDxwnyvMxa+rjKvDpKqTxH1GWuGuDPLmENGQMbTVulajZWr9x8Q1cotoJiHZkt7DA5vczcjB/4lwgWA= >> ~/.ssh/known_hosts ssh-keyscan ${{ secrets.MYHOST }}= >> ~/.ssh/known_hosts
eval $(ssh-agent -s) eval $(ssh-agent -s)
ssh-add -v ~/.ssh/gitlab_deploy_key ssh-add -v ~/.ssh/gitlab_deploy_key
Generated
+655 -580
View File
File diff suppressed because it is too large Load Diff
+13 -11
View File
@@ -1,17 +1,19 @@
[package] [package]
name = "icarus-dm" name = "sidm"
version = "0.8.1" version = "0.10.1"
rust-version = "1.90" rust-version = "1.95"
edition = "2024" edition = "2024"
license = "MIT"
description = "CLI tool to download and upload music from soaricarus"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
futures = { version = "0.3.31" } http = { version = "1.4.2" }
http = { version = "1.3.1" } reqwest = { version = "0.13.4", features = ["json", "blocking", "multipart", "stream"] }
reqwest = { version = "0.12.23", features = ["json", "blocking", "multipart", "stream"] } openssl = { version = "0.10.81", features = ["vendored"] }
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145" serde_json = { version = "1.0.150" }
tokio = { version = "1.47.1", features = ["full"] } tokio = { version = "1.52.4", features = ["full"] }
tokio-util = { version = "0.7.16", features = ["codec"] } tokio-util = { version = "0.7.18", features = ["codec"] }
uuid = { version = "1.18.1", features = ["v4", "serde"] } uuid = { version = "1.23.4", features = ["v4", "serde"] }
icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.7.0" } simodels = { git = "ssh://git@git.kundeng.us/phoenix/simodels.git", tag = "v0.11.3-main-fe9d101bd0-111" }
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2025 Kun Deng Copyright (c) 2026 Kun Deng
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+9 -27
View File
@@ -1,72 +1,54 @@
# IcarusDownloadManager # sidm
IcarusDownloadManager is a CLI software client application that has the feature of uploading and downloading songs from the [Icarus](https://github.com/kdeng00/Icarus) Music Server. sidm (SoarIcarusDownloadManager) is a CLI software client application that has the feature of uploading and downloading songs from the [soaricarus_api](https://git.kundeng.us/phoenix/soaricarus_api) Music Server.
## Built With
* Rust
* Cargo
* futures
* http
* reqwst
* serde
* serde_json
* tokio
* tokio-util
* icarus_models
### Getting Started ### Getting Started
Clone the repo Clone the repo
```BASH ```BASH
git clone git@github.com:kdeng00/IcarusDownloadManager.git git clone git@git.kundeng.us:phoenix/sidm.git
``` ```
Build the project: Build the project:
```BASH ```BASH
cd IcarusDownloadManager cd sidm
cargo build cargo build
``` ```
Even though this project is open source, there are some libraries that are closed source (may be opened later).
In order to successfully build it, your ssh public key would be needed to add to the closed libraries. If you
have interest, something could be worked out to provide access.
The program has been built and can be executed by the binary file *icarus-dm*. For information on how to use icarua-dm, merely execute the program without any command line arguments.
### Downloading Song ### Downloading Song
```BASH ```BASH
icarus-dm download -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -b e8407fc6-edd2-44c1-993f-08dd7324d91a sidm download -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -b e8407fc6-edd2-44c1-993f-08dd7324d91a
``` ```
### Uploading Song with metadata ### Uploading Song with metadata
```BASH ```BASH
icarus-dm upload-meta -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -s /path/of/song.flac -t 1 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png sidm upload-meta -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -s /path/of/song.flac -t 1 -m /path/to/metadata/config/collection.json -ca /path/to/cover/art/image.png
``` ```
### Uploading Song with metadata from directory ### Uploading Song with metadata from directory
```BASH ```BASH
icarus-dm upload-meta -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -smca /path/where/songs/and/metadata/exists/ sidm upload-meta -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -smca /path/where/songs/and/metadata/exists/
``` ```
### Retrieving Song in json ### Retrieving Song in json
```Bash ```Bash
icarus-dm retrieve -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -rt songs sidm retrieve -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -rt songs
``` ```
### Deleting Song ### Deleting Song
```BASH ```BASH
icarus-dm delete -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -D e8407fc6-edd2-44c1-993f-08dd7324d91a sidm delete -u spacecadet -p stellar40 -h https://icarus.com -ha https://auth.icarus.com -D e8407fc6-edd2-44c1-993f-08dd7324d91a
``` ```
View File
+4 -1
View File
@@ -30,7 +30,10 @@ pub fn print_help() {
-rt retrieve type (songs is only accepted) -rt retrieve type (songs is only accepted)
Required for deleting a song Required for deleting a song
-D song id"#, -D song id
Print version
-v"#,
); );
println!("{msg}"); println!("{msg}");
+13 -7
View File
@@ -4,6 +4,7 @@ mod models;
mod parsers; mod parsers;
mod syncers; mod syncers;
mod utilities; mod utilities;
mod version;
use std::env; use std::env;
@@ -17,17 +18,22 @@ async fn main() {
utilities::checks::exit_program(-1); utilities::checks::exit_program(-1);
} }
println!("Argument count: {args_len}");
let mut act_mgr = managers::action_managers::ActionManager::default(); let mut act_mgr = managers::action_managers::ActionManager::default();
act_mgr.set_params(&args); act_mgr.set_params(&args);
act_mgr.initialize(); act_mgr.initialize();
let chosen_act = act_mgr.retrieve_icarus_action(); let chosen_act = act_mgr.retrieve_icarus_action();
for act in &chosen_act.flags {
if act.flag == "-v" {
version::print_version();
utilities::checks::exit_program(-1);
}
}
chosen_act.print_action_and_flags(); chosen_act.print_action_and_flags();
let mut cmt_mgr = managers::commit_manager::CommitManager { let mut cmt_mgr = managers::commit_manager::CommitManager {
ica_action: chosen_act, ica_action: chosen_act,
..Default::default()
}; };
cmt_mgr.commit_action().await; cmt_mgr.commit_action().await;
@@ -45,7 +51,7 @@ mod tests {
assert!(false, "File does not exists: {meta_path:?}"); assert!(false, "File does not exists: {meta_path:?}");
} }
match icarus_models::album::collection::parse_album(&meta_path) { match simodels::album::collection::parse_album(&meta_path) {
Ok(album) => { Ok(album) => {
for track in 1..3 { for track in 1..3 {
let directory_path = std::path::Path::new(&meta_path); let directory_path = std::path::Path::new(&meta_path);
@@ -53,17 +59,17 @@ mod tests {
let filename: String = if track < 10 { let filename: String = if track < 10 {
String::from("track0") String::from("track0")
+ &track.to_string() + &track.to_string()
+ icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION + simodels::constants::file_extensions::audio::DEFAULTMUSICEXTENSION
} else { } else {
String::from("track") String::from("track")
+ &track.to_string() + &track.to_string()
+ icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION + simodels::constants::file_extensions::audio::DEFAULTMUSICEXTENSION
}; };
let disc = 1; let disc = 1;
match managers::commit_manager::retrieve_song( match managers::commit_manager::retrieve_song(
&album, track, disc, &directory, &filename, &album, track, disc, &directory, &filename,
) { ) {
Ok(song) => match icarus_models::song::io::to_data(&song) { Ok(song) => match simodels::song::io::to_data(&song) {
Ok(_) => { Ok(_) => {
print!("Success"); print!("Success");
} }
@@ -86,7 +92,7 @@ mod tests {
#[test] #[test]
fn test_minimum_action_and_args() { fn test_minimum_action_and_args() {
let args: Vec<String> = vec![ let args: Vec<String> = vec![
"icarus-dm".to_string(), "idm".to_string(),
"download".to_string(), "download".to_string(),
"-u".to_string(), "-u".to_string(),
"jamborie".to_string(), "jamborie".to_string(),
+14 -15
View File
@@ -1,8 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::{models, utilities}; use crate::{models, utilities};
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug)]
pub struct ActionManager { pub struct ActionManager {
pub action: String, pub action: String,
pub flags: Vec<models::flags::Flags>, pub flags: Vec<models::flags::Flags>,
@@ -48,6 +46,7 @@ impl ActionManager {
String::from("-ca"), String::from("-ca"),
String::from("-smca"), String::from("-smca"),
String::from("-t"), String::from("-t"),
String::from("-v"),
] ]
} }
@@ -63,31 +62,24 @@ impl ActionManager {
} }
fn validate_flags(&mut self) { fn validate_flags(&mut self) {
println!("Validating flags");
let flag_vals = self.parsed_flags(); let flag_vals = self.parsed_flags();
let mut i = 0; let mut i = 0;
println!("Flag count: {}", flag_vals.len());
while i < flag_vals.len() { while i < flag_vals.len() {
let flag = &flag_vals[i]; let flag = &flag_vals[i];
println!("Index: {i} | Value: {flag}");
let mut flg = models::flags::Flags::default(); let mut flg = models::flags::Flags::default();
// TODO: Refactor this if self.is_valid_flag(flag) {
if self.is_valid_flag(flag) && self.does_flag_have_value(flag) { if self.does_flag_have_value(flag) {
println!("Flag has value");
flg.flag = String::from(flag); flg.flag = String::from(flag);
flg.value = String::from(&flag_vals[i + 1]); flg.value = String::from(&flag_vals[i + 1]);
i += 1; i += 1;
} else if self.is_valid_flag(flag) {
println!("Flag does not have a value");
flg.flag = String::from(flag);
} else { } else {
println!("Flag {flag} is not valid"); flg.flag = String::from(flag);
}
} else {
utilities::checks::exit_program(-1); utilities::checks::exit_program(-1);
} }
@@ -155,10 +147,17 @@ impl ActionManager {
fn parsed_flags(&self) -> Vec<String> { fn parsed_flags(&self) -> Vec<String> {
let mut parsed: Vec<String> = Vec::new(); let mut parsed: Vec<String> = Vec::new();
if self.param_count <= 2 {
let flag = String::from(&self.params[1]);
if flag == "-v" {
parsed.push(flag);
}
} else {
for i in 2..self.params.len() { for i in 2..self.params.len() {
let flag = String::from(&self.params[i]); let flag = String::from(&self.params[i]);
parsed.push(flag); parsed.push(flag);
} }
}
parsed parsed
} }
+131 -180
View File
@@ -1,20 +1,20 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::default::Default; use std::default::Default;
use std::fs::read_dir; use std::fs::read_dir;
use std::io::{Result, Write}; use std::io::Result;
use std::str::FromStr; use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::managers; use crate::managers;
use crate::models::{self}; use crate::models::{self};
use crate::parsers; use crate::parsers;
use crate::syncers; use crate::syncers;
use crate::utilities; use crate::utilities;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Default)]
pub struct CommitManager { pub struct CommitManager {
pub ica_action: models::icarus_action::IcarusAction, pub ica_action: models::icarus_action::IcarusAction,
pub api: models::api::Api,
pub auth_api: models::api::Api,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@@ -36,21 +36,21 @@ enum En {
#[derive(Debug)] #[derive(Debug)]
struct UploadSongMembers { struct UploadSongMembers {
pub song: icarus_models::song::Song, pub song: simodels::song::Song,
pub coverart: icarus_models::coverart::CoverArt, pub coverart: simodels::coverart::CoverArt,
pub token: icarus_models::token::AccessToken, pub token: simodels::token::AccessToken,
pub album: icarus_models::album::collection::Album, pub album: simodels::album::collection::Album,
} }
pub fn retrieve_song( pub fn retrieve_song(
album: &icarus_models::album::collection::Album, album: &simodels::album::collection::Album,
track: i32, track: i32,
disc: i32, disc: i32,
directory: &str, directory: &str,
filename: &str, filename: &str,
) -> Result<icarus_models::song::Song> { ) -> Result<simodels::song::Song> {
let mut found = false; let mut found = false;
let mut song = icarus_models::song::Song::default(); let mut song = simodels::song::Song::default();
for song_i in &album.tracks { for song_i in &album.tracks {
if song_i.track == track && song_i.disc == disc { if song_i.track == track && song_i.disc == disc {
@@ -58,9 +58,8 @@ pub fn retrieve_song(
song.album = album.title.clone(); song.album = album.title.clone();
song.album_artist = album.artist.clone(); song.album_artist = album.artist.clone();
song.artist = track.artist.clone(); song.artist = track.artist.clone();
song.audio_type = String::from( song.audio_type =
icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION, String::from(simodels::constants::file_extensions::audio::DEFAULTMUSICEXTENSION);
);
song.disc = track.disc; song.disc = track.disc;
song.disc_count = album.disc_count; song.disc_count = album.disc_count;
song.duration = track.duration as i32; song.duration = track.duration as i32;
@@ -86,27 +85,36 @@ pub fn retrieve_song(
impl CommitManager { impl CommitManager {
pub async fn commit_action(&mut self) { pub async fn commit_action(&mut self) {
self.init_api().await;
let action = &self.ica_action.action; let action = &self.ica_action.action;
println!("Committing {action} action"); println!("Committing {action} action");
let mapped_actions = &self.map_actions(); let mapped_actions = &self.map_actions();
let mapped_action = self.find_mapped_action(mapped_actions, action); let token = self.parse_token(&self.auth_api).await;
println!("{mapped_action:?}"); match self.find_mapped_action(mapped_actions, action) {
ActionValues::DeleteAct => self.delete_song(&token).await,
// TODO: Move code to get token here and then pass it to the respective functions ActionValues::DownloadAct => self.download_song(&token).await,
ActionValues::RetrieveAct => self.retrieve_object(&token).await,
match mapped_action { ActionValues::UploadSongWithMetadata => self.upload_song_with_metadata(&token).await,
ActionValues::DeleteAct => self.delete_song().await,
ActionValues::DownloadAct => self.download_song().await,
ActionValues::RetrieveAct => self.retrieve_object().await,
ActionValues::UploadSongWithMetadata => self.upload_song_with_metadata().await,
_ => { _ => {
println!("Nothing good here"); println!("Nothing good here");
} }
} }
} }
async fn init_api(&mut self) {
let mut prsr = parsers::api_parser::APIParser {
apis: vec![models::api::Api::default(), models::api::Api::default()],
ica_act: self.ica_action.clone(),
};
prsr.parse_api(parsers::api_parser::APIType::Main);
prsr.parse_api(parsers::api_parser::APIType::Auth);
self.api = prsr.retrieve_api(parsers::api_parser::APIType::Main);
self.auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth);
}
fn find_mapped_action( fn find_mapped_action(
&self, &self,
actions: &HashMap<String, ActionValues>, actions: &HashMap<String, ActionValues>,
@@ -122,7 +130,7 @@ impl CommitManager {
} }
fn map_actions(&self) -> HashMap<String, ActionValues> { fn map_actions(&self) -> HashMap<String, ActionValues> {
let actions: HashMap<String, ActionValues> = HashMap::from([ HashMap::from([
("download".to_string(), ActionValues::DownloadAct), ("download".to_string(), ActionValues::DownloadAct),
("download".to_string(), ActionValues::DownloadAct), ("download".to_string(), ActionValues::DownloadAct),
( (
@@ -131,25 +139,16 @@ impl CommitManager {
), ),
("retrieve".to_string(), ActionValues::RetrieveAct), ("retrieve".to_string(), ActionValues::RetrieveAct),
("delete".to_string(), ActionValues::DeleteAct), ("delete".to_string(), ActionValues::DeleteAct),
]); ])
actions
} }
async fn delete_song(&self) { async fn delete_song(&self, token: &simodels::token::AccessToken) {
let mut prsr = parsers::api_parser::APIParser {
apis: vec![models::api::Api::default(), models::api::Api::default()],
ica_act: self.ica_action.clone(),
};
prsr.parse_api(parsers::api_parser::APIType::Main);
prsr.parse_api(parsers::api_parser::APIType::Auth);
let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth);
let token = self.parse_token(&auth_api).await;
println!("Deleting song"); println!("Deleting song");
let mut song = icarus_models::song::Song::default(); let mut del = syncers::delete::Delete {
api: self.api.clone(),
};
let mut song = simodels::song::Song::default();
for arg in &self.ica_action.flags { for arg in &self.ica_action.flags {
let flag = &arg.flag; let flag = &arg.flag;
@@ -160,12 +159,7 @@ impl CommitManager {
} }
} }
let api = prsr.retrieve_api(parsers::api_parser::APIType::Main); match del.delete_song(token, &song).await {
let mut del = syncers::delete::Delete { api: api.clone() };
println!("Deleting song..");
match del.delete_song(&token, &song).await {
Ok((song, _coverart)) => { Ok((song, _coverart)) => {
println!("Song (Id {:?}) has been successfully deleted", song.id); println!("Song (Id {:?}) has been successfully deleted", song.id);
} }
@@ -175,39 +169,42 @@ impl CommitManager {
} }
} }
async fn download_song(&self) { async fn download_song(&self, token: &simodels::token::AccessToken) {
println!("Deleting song"); println!("Downloading song");
let dwn = self.ica_action.retrieve_flag_value(&String::from("-b")); let dwn = self.ica_action.retrieve_flag_value(&String::from("-b"));
let song_id = uuid::Uuid::from_str(dwn.as_str()).unwrap(); let mut dwn_loader = syncers::download::Download {
api: self.api.clone(),
let mut prsr = parsers::api_parser::APIParser {
apis: vec![models::api::Api::default(), models::api::Api::default()],
ica_act: self.ica_action.clone(),
}; };
prsr.parse_api(parsers::api_parser::APIType::Main); let mut song = simodels::song::Song {
prsr.parse_api(parsers::api_parser::APIType::Auth); id: uuid::Uuid::from_str(dwn.as_str()).unwrap(),
let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth);
let token = self.parse_token(&auth_api).await;
println!("Message: {}", token.message);
let api = prsr.retrieve_api(parsers::api_parser::APIType::Main);
let mut dwn_loader = syncers::download::Download { api: api.clone() };
let song = icarus_models::song::Song {
id: song_id,
..Default::default() ..Default::default()
}; };
match dwn_loader.download_song(&token, &song).await { match dwn_loader.download_song(token, &song).await {
Ok(o) => { Ok(o) => {
println!("Success"); println!("Song downloaded");
let filename = String::from("audio")
+ icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION; song.data = o.as_bytes().to_vec();
let data = o.as_bytes(); song.directory = String::from(".");
let mut file = std::fs::File::create(filename).expect("Failed to save"); song.filename = match simodels::song::generate_filename(
file.write_all(data) simodels::types::MusicType::FlacExtension,
.expect("Failed to save downloaded song"); true,
) {
Ok(filename) => filename,
Err(err) => {
eprintln!("Error generating song filename: {err:?}");
utilities::checks::exit_program(-3);
return;
}
};
match song.save_to_filesystem() {
Ok(_) => {
println!("Song saved");
}
Err(err) => {
eprintln!("Error saving song: {err:?}");
}
}
} }
Err(er) => { Err(er) => {
println!("Error {er:?}"); println!("Error {er:?}");
@@ -223,7 +220,7 @@ impl CommitManager {
} }
} }
async fn retrieve_object(&self) { async fn retrieve_object(&self, token: &simodels::token::AccessToken) {
println!("Retrieving song"); println!("Retrieving song");
let rt = self.ica_action.retrieve_flag_value(&String::from("-rt")); let rt = self.ica_action.retrieve_flag_value(&String::from("-rt"));
@@ -231,22 +228,11 @@ impl CommitManager {
panic!("Unsupported -rt: {rt}"); panic!("Unsupported -rt: {rt}");
} }
let mut prsr = parsers::api_parser::APIParser { let mut repo = syncers::retrieve_records::RetrieveRecords {
apis: vec![models::api::Api::default(), models::api::Api::default()], api: self.api.clone(),
ica_act: self.ica_action.clone(),
}; };
prsr.parse_api(parsers::api_parser::APIType::Main);
prsr.parse_api(parsers::api_parser::APIType::Auth);
let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); match repo.get_all_songs(token).await {
let token = self.parse_token(&auth_api).await;
println!("Token {token:?}");
let api = prsr.retrieve_api(parsers::api_parser::APIType::Main);
let mut repo = syncers::retrieve_records::RetrieveRecords { api: api.clone() };
match repo.get_all_songs(&token).await {
Ok(o) => { Ok(o) => {
println!("Songs"); println!("Songs");
println!("====="); println!("=====");
@@ -263,12 +249,12 @@ impl CommitManager {
} }
} }
async fn parse_token(&self, api: &models::api::Api) -> icarus_models::token::AccessToken { async fn parse_token(&self, api: &models::api::Api) -> simodels::token::AccessToken {
println!("Fetching token"); println!("Fetching token");
let mut usr_mgr: managers::user_manager::UserManager = let mut usr_mgr: managers::user_manager::UserManager =
managers::user_manager::UserManager { managers::user_manager::UserManager {
user: icarus_models::user::User::default(), user: simodels::user::User::default(),
ica_action: self.ica_action.clone(), ica_action: self.ica_action.clone(),
}; };
usr_mgr.parse_user_from_actions(); usr_mgr.parse_user_from_actions();
@@ -285,7 +271,7 @@ impl CommitManager {
token.unwrap() token.unwrap()
} }
async fn upload_song_with_metadata(&mut self) { async fn upload_song_with_metadata(&mut self, token: &simodels::token::AccessToken) {
println!("Uplodaring song with metadara"); println!("Uplodaring song with metadara");
let songpath = self.ica_action.retrieve_flag_value(&String::from("-s")); let songpath = self.ica_action.retrieve_flag_value(&String::from("-s"));
@@ -313,12 +299,12 @@ impl CommitManager {
println!("cover art path: {coverpath}"); println!("cover art path: {coverpath}");
let _ = self let _ = self
.sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath) .sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath, token)
.await; .await;
} else if multitarget { } else if multitarget {
let _ = self.multi_target_upload(&uni).await; let _ = self.multi_target_upload(&uni, token).await;
} else { } else {
println!("Single or Multi target has not been chosen"); eprintln!("Single or Multi target has not been chosen");
} }
} }
@@ -329,19 +315,8 @@ impl CommitManager {
track_id: &str, track_id: &str,
meta_path: &String, meta_path: &String,
cover_path: &str, cover_path: &str,
token: &simodels::token::AccessToken,
) -> Result<()> { ) -> Result<()> {
let mut prsr = parsers::api_parser::APIParser {
apis: vec![models::api::Api::default(), models::api::Api::default()],
ica_act: self.ica_action.clone(),
};
prsr.parse_api(parsers::api_parser::APIType::Main);
prsr.parse_api(parsers::api_parser::APIType::Auth);
let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth);
let token = self.parse_token(&auth_api).await;
println!("Token: {:?}", token.token);
let song_file = std::path::Path::new(&songpath); let song_file = std::path::Path::new(&songpath);
if !song_file.exists() { if !song_file.exists() {
@@ -349,11 +324,11 @@ impl CommitManager {
panic!("Error"); panic!("Error");
} }
let mut cover_art = icarus_models::coverart::CoverArt { let pa = std::path::Path::new(&cover_path);
id: uuid::Uuid::nil(),
title: String::new(), let mut cover_art = simodels::coverart::CoverArt {
path: cover_path.to_owned(), directory: String::from(pa.parent().unwrap().to_str().unwrap()),
data: Vec::new(), filename: String::from(pa.file_name().unwrap().to_str().unwrap()),
..Default::default() ..Default::default()
}; };
let file_name = std::ffi::OsString::from(&song_file.file_name().unwrap()); let file_name = std::ffi::OsString::from(&song_file.file_name().unwrap());
@@ -363,7 +338,7 @@ impl CommitManager {
Ok(s) => { Ok(s) => {
println!("file name: {file_name:?}"); println!("file name: {file_name:?}");
match icarus_models::album::collection::parse_album(meta_path) { match simodels::album::collection::parse_album(meta_path) {
Ok(album) => { Ok(album) => {
let filename = s.clone(); let filename = s.clone();
let directory = song_file.parent().unwrap().display().to_string(); let directory = song_file.parent().unwrap().display().to_string();
@@ -373,15 +348,13 @@ impl CommitManager {
println!("Directory: {:?}", s.directory); println!("Directory: {:?}", s.directory);
println!("Filename: {:?}", s.filename); println!("Filename: {:?}", s.filename);
println!("Path: {:?}", s.song_path()); println!("Path: {:?}", s.song_path());
s.data = icarus_models::song::io::to_data(&s).unwrap(); s.data = simodels::song::io::to_data(&s).unwrap();
cover_art.data = simodels::coverart::io::to_data(&cover_art).unwrap();
cover_art.data =
icarus_models::coverart::io::to_data(&cover_art).unwrap();
let members = UploadSongMembers { let members = UploadSongMembers {
song: s, song: s,
coverart: cover_art, coverart: cover_art,
token, token: token.clone(),
album, album,
}; };
@@ -459,45 +432,37 @@ impl CommitManager {
println!("Queued coverart Id: {id:?}"); println!("Queued coverart Id: {id:?}");
println!("Linked queued song to queued coverart"); println!("Linked queued song to queued coverart");
println!("Queued status updated"); println!("Queued status updated");
}
Err(err) => {
return Err(std::io::Error::other(err.to_string()));
}
},
Err(err) => {
return Err(std::io::Error::other(err.to_string()));
}
},
Err(err) => {
return Err(std::io::Error::other(err.to_string()));
}
}
Ok(()) 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())),
}
}
fn get_songs( fn get_songs(
&self, &self,
metadata_path: &String, metadata_path: &String,
source_directory: &str, source_directory: &str,
) -> Result<Vec<icarus_models::song::Song>> { ) -> Result<Vec<simodels::song::Song>> {
match icarus_models::album::collection::parse_album(metadata_path) { match simodels::album::collection::parse_album(metadata_path) {
Ok(albums) => { Ok(albums) => {
let mut songs: Vec<icarus_models::song::Song> = Vec::new(); let mut songs: Vec<simodels::song::Song> = Vec::new();
for track in &albums.tracks { for track in &albums.tracks {
let song_filename = if track.track < 10 { let song_filename = if track.track < 10 {
"track0".to_owned() "track0".to_owned()
+ &track.track.to_string() + &track.track.to_string()
+ icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION + simodels::constants::file_extensions::audio::DEFAULTMUSICEXTENSION
} else { } else {
"track".to_owned() "track".to_owned()
+ &track.track.to_string() + &track.track.to_string()
+ icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION + simodels::constants::file_extensions::audio::DEFAULTMUSICEXTENSION
}; };
songs.push(icarus_models::song::Song { songs.push(simodels::song::Song {
id: uuid::Uuid::nil(),
title: track.title.clone(), title: track.title.clone(),
artist: track.artist.clone(), artist: track.artist.clone(),
disc: track.disc, disc: track.disc,
@@ -512,46 +477,42 @@ impl CommitManager {
audio_type: String::from("FLAC"), audio_type: String::from("FLAC"),
directory: source_directory.to_owned(), directory: source_directory.to_owned(),
filename: song_filename, filename: song_filename,
user_id: uuid::Uuid::nil(), ..Default::default()
data: Vec::new(),
date_created: String::new(),
}); });
} }
Ok(songs) Ok(songs)
} }
Err(_) => Ok(Vec::new()), Err(_) => Err(std::io::Error::other("Songs not retrieved")),
} }
} }
async fn multi_target_upload(&mut self, sourcepath: &String) -> std::io::Result<()> { async fn multi_target_upload(
let mut prsr = parsers::api_parser::APIParser { &mut self,
apis: vec![models::api::Api::default(), models::api::Api::default()], sourcepath: &String,
ica_act: self.ica_action.clone(), token: &simodels::token::AccessToken,
}; ) -> std::io::Result<()> {
prsr.parse_api(parsers::api_parser::APIType::Main);
prsr.parse_api(parsers::api_parser::APIType::Auth);
let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth);
let token = self.parse_token(&auth_api).await;
let directory_path = std::path::Path::new(&sourcepath); let directory_path = std::path::Path::new(&sourcepath);
if !directory_path.exists() { if !directory_path.exists() {
panic!("Directory does not exist"); panic!("Directory does not exist");
} }
let coverart_path = self.get_cover_art_path(sourcepath).unwrap_or_default(); let (coverart_directory, coverart_filename) =
let mut cover_art = self.get_coverart_dir_and_filename(sourcepath).unwrap();
icarus_models::coverart::init::init_coverart_only_path(coverart_path.clone()); let mut cover_art = simodels::coverart::init::init_coverart_dir_and_filename(
&coverart_directory,
&coverart_filename,
);
let metadatapath = self.get_metadata_path(sourcepath).unwrap_or_default(); let metadatapath = self.get_metadata_path(sourcepath).unwrap_or_default();
let mut up = syncers::upload::Upload::default(); let mut up = syncers::upload::Upload::default();
let host = self.ica_action.retrieve_flag_value(&String::from("-h")); let host = self.ica_action.retrieve_flag_value(&String::from("-h"));
up.set_api(&host); up.set_api(&host);
cover_art.data = icarus_models::coverart::io::to_data(&cover_art).unwrap(); cover_art.data = simodels::coverart::io::to_data(&cover_art).unwrap();
match self.get_songs(&metadatapath, sourcepath) { match self.get_songs(&metadatapath, sourcepath) {
Ok(sngs) => match icarus_models::album::collection::parse_album(&metadatapath) { Ok(sngs) => match simodels::album::collection::parse_album(&metadatapath) {
Ok(album) => { Ok(album) => {
for song in sngs { for song in sngs {
let members = UploadSongMembers { let members = UploadSongMembers {
@@ -566,7 +527,7 @@ impl CommitManager {
println!("Response: {o:?}"); println!("Response: {o:?}");
} }
Err(err) => { Err(err) => {
println!("Error: {err:?}"); eprintln!("Error: {err:?}");
return Err(err); return Err(err);
} }
} }
@@ -575,19 +536,19 @@ impl CommitManager {
Ok(()) Ok(())
} }
Err(err) => { Err(err) => {
println!("Error: {err:?}"); eprintln!("Error: {err:?}");
Err(std::io::Error::other(err.to_string())) Err(std::io::Error::other(err.to_string()))
} }
}, },
Err(error) => { Err(error) => {
println!("Error: {error:?}"); eprintln!("Error: {error:?}");
Err(std::io::Error::other(error.to_string())) Err(std::io::Error::other(error.to_string()))
} }
} }
} }
fn get_cover_art_path(&self, directory_path: &String) -> Result<String> { fn get_coverart_dir_and_filename(&self, directory: &str) -> Result<(String, String)> {
for entry in read_dir(std::path::Path::new(directory_path))? { for entry in read_dir(std::path::Path::new(directory))? {
let entry = entry?; let entry = entry?;
let file_type = entry.file_type(); let file_type = entry.file_type();
@@ -597,14 +558,14 @@ impl CommitManager {
println!("file name: {file_name:?}"); println!("file name: {file_name:?}");
if let En::ImageFile = self.find_file_extension(&file_name) { if let En::ImageFile = self.find_file_extension(&file_name) {
let directory_part = directory_path.clone();
let fname = utilities::string::o_to_string(&file_name); let fname = utilities::string::o_to_string(&file_name);
let fullpath = format!("{}/{}", directory_part, &fname.unwrap()); return Ok((directory.to_string(), fname.unwrap()));
return Ok(fullpath);
} }
} }
Ok(String::new()) Err(std::io::Error::other(
"CoverArt directory and filename not found",
))
} }
fn find_file_extension(&self, file_name: &std::ffi::OsString) -> En { fn find_file_extension(&self, file_name: &std::ffi::OsString) -> En {
@@ -632,15 +593,14 @@ impl CommitManager {
index += 1; index += 1;
} }
if extension == icarus_models::constants::file_extensions::audio::WAVEXTENSION[1..] if extension == simodels::constants::file_extensions::audio::WAVEXTENSION[1..]
|| extension || extension == simodels::constants::file_extensions::audio::FLACEXTENSION[1..]
== icarus_models::constants::file_extensions::audio::FLACEXTENSION[1..]
{ {
return En::SongFile; return En::SongFile;
} else if extension == "json" { } else if extension == "json" {
return En::MetadataFile; return En::MetadataFile;
} else if extension } else if extension
== icarus_models::constants::file_extensions::image::JPGEXTENSION[1..] == simodels::constants::file_extensions::image::JPGEXTENSION[1..]
|| extension == "jpeg" || extension == "jpeg"
|| extension == "png" || extension == "png"
{ {
@@ -672,15 +632,6 @@ impl CommitManager {
} }
} }
Ok(String::new()) Err(std::io::Error::other("Metadata path not found"))
}
fn _check_for_no_confirm(&self) -> bool {
for flag in self.ica_action.flags.iter() {
if flag.flag == "-nc" {
return true;
}
}
false
} }
} }
+10 -17
View File
@@ -7,23 +7,22 @@ mod response {
#[derive(Debug, serde::Deserialize, serde::Serialize)] #[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Response { pub struct Response {
pub message: String, pub message: String,
pub data: Vec<icarus_models::login_result::LoginResult>, pub data: Vec<simodels::login_result::LoginResult>,
} }
} }
} }
pub struct TokenManager { pub struct TokenManager {
pub user: icarus_models::user::User, pub user: simodels::user::User,
pub api: models::api::Api, pub api: models::api::Api,
} }
impl Default for TokenManager { impl Default for TokenManager {
fn default() -> Self { fn default() -> Self {
let mut token = TokenManager { let mut token = TokenManager {
user: icarus_models::user::User::default(), user: simodels::user::User::default(),
api: models::api::Api::default(), api: models::api::Api::default(),
}; };
token.init(); token.init();
token token
@@ -31,14 +30,13 @@ impl Default for TokenManager {
} }
impl TokenManager { impl TokenManager {
pub async fn request_token(&self) -> Result<icarus_models::token::AccessToken, std::io::Error> { pub async fn request_token(&self) -> Result<simodels::token::AccessToken, std::io::Error> {
println!("Sending request for a token"); println!("Sending request for a token");
let url = self.retrieve_url(); let url = self.retrieve_url();
println!("URL: {url}"); println!("URL: {url}");
let mut token = icarus_models::token::AccessToken { let mut token = simodels::token::AccessToken {
user_id: uuid::Uuid::nil(), user_id: uuid::Uuid::nil(),
username: String::new(), username: String::new(),
token: String::new(), token: String::new(),
@@ -62,19 +60,18 @@ impl TokenManager {
token.token_type = login_result.token_type.clone(); token.token_type = login_result.token_type.clone();
token.expiration = login_result.expiration; token.expiration = login_result.expiration;
token.message = response.message; token.message = response.message;
Ok(token)
}
Err(err) => Err(std::io::Error::other(err.to_string())),
} }
Err(_) => println!("Hm, the response didn't match the shape we expected."),
};
} }
reqwest::StatusCode::UNAUTHORIZED => { reqwest::StatusCode::UNAUTHORIZED => {
println!("Need to grab a new token"); Err(std::io::Error::other("Need to grab a new token"))
} }
other => { other => {
panic!("Uh oh! Something unexpected happened: {other:?}"); panic!("Uh oh! Something unexpected happened: {other:?}");
} }
} }
Ok(token)
} }
pub fn init(&mut self) { pub fn init(&mut self) {
@@ -84,10 +81,6 @@ impl TokenManager {
} }
pub fn retrieve_url(&self) -> String { pub fn retrieve_url(&self) -> String {
let api = &self.api; format!("{}{}", self.api.url, self.api.endpoint)
let mut url = String::from(&api.url);
url += &String::from(&api.endpoint);
url
} }
} }
+3 -5
View File
@@ -1,17 +1,15 @@
use std::default::Default; use std::default::Default;
use serde::{Deserialize, Serialize};
use crate::models::{self}; use crate::models::{self};
#[derive(Debug, Default, Deserialize, Serialize)] #[derive(Debug, Default)]
pub struct UserManager { pub struct UserManager {
pub user: icarus_models::user::User, pub user: simodels::user::User,
pub ica_action: models::icarus_action::IcarusAction, pub ica_action: models::icarus_action::IcarusAction,
} }
impl UserManager { impl UserManager {
pub fn retrieve_user(&self) -> icarus_models::user::User { pub fn retrieve_user(&self) -> simodels::user::User {
self.user.clone() self.user.clone()
} }
+1 -3
View File
@@ -1,8 +1,6 @@
use std::default::Default; use std::default::Default;
use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Api { pub struct Api {
pub url: String, pub url: String,
pub endpoint: String, pub endpoint: String,
+1 -3
View File
@@ -1,8 +1,6 @@
use std::default::Default; use std::default::Default;
use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Flags { pub struct Flags {
pub flag: String, pub flag: String,
pub value: String, pub value: String,
+1 -3
View File
@@ -1,10 +1,8 @@
use std::default::Default; use std::default::Default;
use serde::{Deserialize, Serialize};
use crate::models; use crate::models;
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default)]
pub struct IcarusAction { pub struct IcarusAction {
pub action: String, pub action: String,
pub flags: Vec<models::flags::Flags>, pub flags: Vec<models::flags::Flags>,
+8 -12
View File
@@ -9,22 +9,18 @@ pub fn retrieve_url(api: &models::api::Api, with_id: bool, id: &uuid::Uuid) -> S
} }
fn retrieve_url_reg(api: &models::api::Api) -> String { fn retrieve_url_reg(api: &models::api::Api) -> String {
let url = format!("{}api/{}/{}/", api.url, api.version, api.endpoint); format!("{}api/{}/{}/", api.url, api.version, api.endpoint)
url
} }
fn retrieve_url_with_id(api: &models::api::Api, id: &uuid::Uuid) -> String { fn retrieve_url_with_id(api: &models::api::Api, id: &uuid::Uuid) -> String {
let url = format!("{}api/{}/{}/{}", api.url, api.version, api.endpoint, id); format!("{}api/{}/{}/{}", api.url, api.version, api.endpoint, id)
url
} }
pub async fn auth_header( pub async fn auth_header(
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
) -> (http::HeaderName, http::HeaderValue) { ) -> Result<(http::HeaderName, http::HeaderValue), http::header::InvalidHeaderValue> {
let auth = reqwest::header::AUTHORIZATION; match http::HeaderValue::from_str(&token.bearer_token()) {
let auth_value = http::HeaderValue::from_str(&token.bearer_token()).unwrap(); Ok(auth_value) => Ok((reqwest::header::AUTHORIZATION, auth_value)),
Err(err) => Err(err),
(auth, auth_value) }
} }
+5 -6
View File
@@ -13,8 +13,8 @@ mod response {
pub mod delete_song { pub mod delete_song {
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
pub struct SongAndCoverArt { pub struct SongAndCoverArt {
pub song: icarus_models::song::Song, pub song: simodels::song::Song,
pub coverart: icarus_models::coverart::CoverArt, pub coverart: simodels::coverart::CoverArt,
} }
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
@@ -28,10 +28,9 @@ mod response {
impl Delete { impl Delete {
pub async fn delete_song( pub async fn delete_song(
&mut self, &mut self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
song: &icarus_models::song::Song, song: &simodels::song::Song,
) -> Result<(icarus_models::song::Song, icarus_models::coverart::CoverArt), std::io::Error> ) -> Result<(simodels::song::Song, simodels::coverart::CoverArt), std::io::Error> {
{
self.api.endpoint = "api/v2/song".to_owned(); self.api.endpoint = "api/v2/song".to_owned();
let url = format!("{}{}/{}", self.api.url, self.api.endpoint, song.id); let url = format!("{}{}/{}", self.api.url, self.api.endpoint, song.id);
println!("Url: {url:?}"); println!("Url: {url:?}");
+2 -2
View File
@@ -17,8 +17,8 @@ pub enum MyError {
impl Download { impl Download {
pub async fn download_song( pub async fn download_song(
&mut self, &mut self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
song: &icarus_models::song::Song, song: &simodels::song::Song,
) -> Result<String, MyError> { ) -> Result<String, MyError> {
self.api.endpoint = String::from("song/download"); self.api.endpoint = String::from("song/download");
let url = syncers::common::retrieve_url(&self.api, true, &song.id); let url = syncers::common::retrieve_url(&self.api, true, &song.id);
+3 -3
View File
@@ -13,7 +13,7 @@ mod response {
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
pub struct Response { pub struct Response {
pub message: String, pub message: String,
pub data: Vec<icarus_models::song::Song>, pub data: Vec<simodels::song::Song>,
} }
} }
} }
@@ -21,8 +21,8 @@ mod response {
impl RetrieveRecords { impl RetrieveRecords {
pub async fn get_all_songs( pub async fn get_all_songs(
&mut self, &mut self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
) -> Result<Vec<icarus_models::song::Song>, Error> { ) -> Result<Vec<simodels::song::Song>, Error> {
self.api.endpoint = String::from("api/v2/song/all"); self.api.endpoint = String::from("api/v2/song/all");
let url = format!("{}{}", self.api.url, self.api.endpoint); let url = format!("{}{}", self.api.url, self.api.endpoint);
let access_token = token.bearer_token(); let access_token = token.bearer_token();
+17 -17
View File
@@ -40,8 +40,8 @@ mod response {
impl Upload { impl Upload {
pub async fn queue_song( pub async fn queue_song(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
song: &icarus_models::song::Song, song: &simodels::song::Song,
) -> Result<uuid::Uuid, reqwest::Error> { ) -> Result<uuid::Uuid, reqwest::Error> {
let songpath = song.song_path().unwrap(); let songpath = song.song_path().unwrap();
let file = tokio::fs::File::open(&songpath).await.unwrap(); let file = tokio::fs::File::open(&songpath).await.unwrap();
@@ -61,7 +61,7 @@ impl Upload {
println!("Url: {url:?}"); println!("Url: {url:?}");
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
headers.insert("Accept", HeaderValue::from_str("*/*").unwrap()); headers.insert("Accept", HeaderValue::from_str("*/*").unwrap());
headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap()); headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap());
@@ -92,14 +92,14 @@ impl Upload {
pub async fn link_user_to_queued_song( pub async fn link_user_to_queued_song(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
queued_song_id: &uuid::Uuid, queued_song_id: &uuid::Uuid,
) -> Result<(), reqwest::Error> { ) -> Result<(), reqwest::Error> {
let endpoint = String::from("api/v2/song/queue/link"); let endpoint = String::from("api/v2/song/queue/link");
let url = format!("{}/{endpoint}", self.api.url); let url = format!("{}/{endpoint}", self.api.url);
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
let payload = serde_json::json!({ let payload = serde_json::json!({
@@ -123,16 +123,16 @@ impl Upload {
pub async fn queue_metadata( pub async fn queue_metadata(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
album: &icarus_models::album::collection::Album, album: &simodels::album::collection::Album,
song: &icarus_models::song::Song, song: &simodels::song::Song,
queued_song_id: &uuid::Uuid, queued_song_id: &uuid::Uuid,
) -> Result<uuid::Uuid, reqwest::Error> { ) -> Result<uuid::Uuid, reqwest::Error> {
let endpoint = String::from("api/v2/song/metadata/queue"); let endpoint = String::from("api/v2/song/metadata/queue");
let url = format!("{}/{endpoint}", self.api.url); let url = format!("{}/{endpoint}", self.api.url);
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
let payload = serde_json::json!({ let payload = serde_json::json!({
@@ -173,10 +173,10 @@ impl Upload {
pub async fn queue_coverart( pub async fn queue_coverart(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
coverart: &icarus_models::coverart::CoverArt, coverart: &simodels::coverart::CoverArt,
) -> Result<uuid::Uuid, reqwest::Error> { ) -> Result<uuid::Uuid, reqwest::Error> {
let coverartpath = coverart.path.clone(); let coverartpath = coverart.get_path().unwrap();
let file = tokio::fs::File::open(&coverartpath).await.unwrap(); let file = tokio::fs::File::open(&coverartpath).await.unwrap();
let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new()); let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new());
let file_body = reqwest::Body::wrap_stream(stream); let file_body = reqwest::Body::wrap_stream(stream);
@@ -200,7 +200,7 @@ impl Upload {
println!("Url: {url:?}"); println!("Url: {url:?}");
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
headers.insert("Accept", HeaderValue::from_str("*/*").unwrap()); headers.insert("Accept", HeaderValue::from_str("*/*").unwrap());
headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap()); headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap());
@@ -231,7 +231,7 @@ impl Upload {
pub async fn link_queued_song_to_queued_coverart( pub async fn link_queued_song_to_queued_coverart(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
queued_song_id: &uuid::Uuid, queued_song_id: &uuid::Uuid,
queued_coverart_id: &uuid::Uuid, queued_coverart_id: &uuid::Uuid,
) -> Result<(), reqwest::Error> { ) -> Result<(), reqwest::Error> {
@@ -239,7 +239,7 @@ impl Upload {
let url = format!("{}/{endpoint}", self.api.url); let url = format!("{}/{endpoint}", self.api.url);
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
let payload = serde_json::json!({ let payload = serde_json::json!({
@@ -263,7 +263,7 @@ impl Upload {
pub async fn update_queued_song_status( pub async fn update_queued_song_status(
&self, &self,
token: &icarus_models::token::AccessToken, token: &simodels::token::AccessToken,
queued_song_id: &uuid::Uuid, queued_song_id: &uuid::Uuid,
status: &str, status: &str,
) -> Result<(), reqwest::Error> { ) -> Result<(), reqwest::Error> {
@@ -271,7 +271,7 @@ impl Upload {
let url = format!("{}/{endpoint}", self.api.url); let url = format!("{}/{endpoint}", self.api.url);
let mut headers = reqwest::header::HeaderMap::new(); let mut headers = reqwest::header::HeaderMap::new();
let (auth, auth_val) = syncers::common::auth_header(token).await; let (auth, auth_val) = syncers::common::auth_header(token).await.unwrap();
headers.insert(auth, auth_val); headers.insert(auth, auth_val);
let payload = serde_json::json!({ let payload = serde_json::json!({
+7 -1
View File
@@ -1,6 +1,12 @@
pub fn o_to_string(val: &std::ffi::OsString) -> Result<std::string::String, std::io::Error> { pub fn o_to_string(val: &std::ffi::OsString) -> Result<std::string::String, std::io::Error> {
match val.clone().into_string() { match val.clone().into_string() {
Ok(value) => Ok(value), Ok(value) => Ok(value),
Err(_) => Err(std::io::Error::other(String::from("Error"))), Err(err) => match err.into_string() {
Ok(res) => Err(std::io::Error::other(res.to_string())),
Err(err) => match err.to_str() {
Some(err) => Err(std::io::Error::other(err)),
None => Err(std::io::Error::other("Undefined error")),
},
},
} }
} }
+6
View File
@@ -0,0 +1,6 @@
pub fn print_version() {
let name = env!("CARGO_PKG_NAME");
let version = env!("CARGO_PKG_VERSION");
println!("{name:?} {version:?}");
}