Skip to content

Commit 79ddcc6

Browse files
authored
Merge pull request #884 from RustyNova016/move_bumps
refactor: moved bump commands
2 parents 2c7008a + afb198e commit 79ddcc6

18 files changed

Lines changed: 269 additions & 147 deletions

File tree

alistral_cli/src/models/cli/mod.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use unstable::UnstableCommand;
1919
use crate::models::cli::interzic::InterzicCommand;
2020
#[cfg(feature = "radio")]
2121
use crate::models::cli::radio::RadioCommand;
22-
use crate::tools::bumps::bump_command;
23-
use crate::tools::bumps::bump_down_command;
22+
use crate::tools::bump::BumpCommand;
23+
use crate::tools::bump::bump_down::BumpDownCommand;
2424
use crate::tools::cache::CacheCommand;
2525
use crate::tools::compatibility::compatibility_command;
2626
use crate::tools::daily::DailyCommand;
@@ -90,38 +90,16 @@ impl Cli {
9090
}
9191
}
9292

93-
/// bump a recording to show up more frequently in radios that uses scores. By default, it uses the lastest listen as target.
94-
///
95-
/// bump-down is an alias for `bump <RECORDING> <DURATION> 0.9`
96-
///
97-
/// All the bumps are added multiplicatively, so a recording won't disapear. Use the blacklist to remove them.
98-
#[derive(Parser, Debug, Clone)]
99-
pub struct BumpCLI {
100-
/// The recording to bump
101-
pub recording: Option<String>,
102-
103-
/// The duration the bump last for (Default: 3 months)
104-
#[arg(short, long)]
105-
pub duration: Option<String>,
106-
107-
/// The multiplier added to the score (Default: 1.1)
108-
#[arg(short, long)]
109-
pub multiplier: Option<String>,
110-
111-
#[arg(short, long)]
112-
pub username: Option<String>,
113-
}
114-
11593
#[derive(Subcommand, Debug, Clone)]
11694
pub enum Commands {
117-
Bump(BumpCLI),
95+
Bump(BumpCommand),
11896

11997
/// bump a recording to show up more frequently in radios that uses scores. By default, it uses the lastest listen as target.
12098
///
12199
/// bump-down is an alias for `bump <RECORDING> <DURATION> 0.9`
122100
///
123101
/// All the bumps are added multiplicatively, so a recording won't disapear. Use the blacklist to remove them.
124-
BumpDown(BumpCLI),
102+
BumpDown(BumpDownCommand),
125103

126104
/// Commands to deal with the local cache
127105
Cache(CacheCommand),
@@ -176,6 +154,8 @@ pub enum Commands {
176154
impl Commands {
177155
pub async fn run(&self, conn: &mut sqlx::SqliteConnection) -> Result<(), FatalError> {
178156
match self {
157+
Self::Bump(val) => val.run().await,
158+
Self::BumpDown(val) => val.run().await,
179159
Self::Cache(val) => val.run().await,
180160

181161
#[cfg(feature = "stats")]
@@ -207,11 +187,6 @@ impl Commands {
207187

208188
#[cfg(feature = "interzicf")]
209189
Self::Playlist(val) => val.run(conn).await?,
210-
211-
Self::Bump(val) => bump_command(conn, val.clone()).await,
212-
213-
Self::BumpDown(val) => bump_down_command(conn, val.clone()).await,
214-
215190
Self::Unstable(val) => val.command.run(conn).await,
216191
}
217192

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use clap::Parser;
2+
3+
use crate::tools::bump::BumpCommand;
4+
5+
/// bump a recording to show up more frequently in radios that uses scores. By default, it uses the lastest listen as target.
6+
///
7+
/// bump-down is an alias for `bump <RECORDING> <DURATION> 0.9`
8+
///
9+
/// All the bumps are added multiplicatively, so a recording won't disapear. Use the blacklist to remove them.
10+
#[derive(Parser, Debug, Clone)]
11+
pub struct BumpDownCommand {
12+
/// The recording to bump
13+
pub recording: Option<String>,
14+
15+
/// The duration the bump last for (Default: 3 months)
16+
#[arg(short, long)]
17+
pub duration: Option<String>,
18+
19+
/// The multiplier added to the score (Default: 1.1)
20+
#[arg(short, long)]
21+
pub multiplier: Option<String>,
22+
23+
#[arg(short, long)]
24+
pub username: Option<String>,
25+
}
26+
27+
impl BumpDownCommand {
28+
pub async fn run(&self) {
29+
let cmd = BumpCommand {
30+
duration: self.duration.clone(),
31+
multiplier: self.multiplier.clone().or_else(|| Some("0.9".to_string())),
32+
recording: self.recording.clone(),
33+
username: self.username.clone(),
34+
};
35+
36+
cmd.run().await
37+
}
38+
}

alistral_cli/src/tools/bump/mod.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use std::str::FromStr;
2+
3+
use alistral_core::datastructures::listen_collection::traits::ListenCollectionReadable as _;
4+
use alistral_core::models::listen_statistics_data::ListenStatisticsData;
5+
use chrono::Duration;
6+
use chrono::Utc;
7+
use clap::Parser;
8+
use rust_decimal::Decimal;
9+
use tuillez::extensions::chrono_exts::DurationExt as _;
10+
use tuillez::formatter::FormatWithAsync;
11+
12+
use crate::ALISTRAL_CLIENT;
13+
use crate::models::config::Config;
14+
use crate::utils::constants::LISTENBRAINZ_FMT;
15+
use crate::utils::user_inputs::UserInputParser;
16+
17+
pub mod bump_down;
18+
19+
/// bump a recording to show up more frequently in radios that uses scores. By default, it uses the lastest listen as target.
20+
///
21+
/// bump-down is an alias for `bump <RECORDING> <DURATION> 0.9`
22+
///
23+
/// All the bumps are added multiplicatively, so a recording won't disapear. Use the blacklist to remove them.
24+
#[derive(Parser, Debug, Clone)]
25+
pub struct BumpCommand {
26+
/// The recording to bump
27+
pub recording: Option<String>,
28+
29+
/// The duration the bump last for (Default: 3 months)
30+
#[arg(short, long)]
31+
pub duration: Option<String>,
32+
33+
/// The multiplier added to the score (Default: 1.1)
34+
#[arg(short, long)]
35+
pub multiplier: Option<String>,
36+
37+
#[arg(short, long)]
38+
pub username: Option<String>,
39+
}
40+
41+
impl BumpCommand {
42+
pub async fn run(&self) {
43+
let username = UserInputParser::username_or_default(&self.username);
44+
45+
let recording = match &self.recording {
46+
Some(mbid) => UserInputParser::parse_recording(mbid).await,
47+
None => {
48+
let user_data = ListenStatisticsData::new_from_user_listens(
49+
ALISTRAL_CLIENT.core.clone(),
50+
UserInputParser::username_or_default(&self.username),
51+
)
52+
.await
53+
.unwrap();
54+
user_data
55+
.listens()
56+
.get_latest_listen()
57+
.unwrap()
58+
.get_recording_or_fetch_with_task(ALISTRAL_CLIENT.musicbrainz_db.clone())
59+
.await
60+
.unwrap()
61+
.unwrap()
62+
}
63+
};
64+
65+
let multiplier = Decimal::from_str(self.multiplier.as_deref().unwrap_or("1.1"))
66+
.expect("Couldn't parse the multiplier");
67+
68+
let duration = match &self.duration {
69+
Some(dur) => Duration::from_human_string(dur).expect("Couldn't parse the duration."),
70+
None => Duration::from_human_string("3 months").expect("Couldn't parse the duration."),
71+
};
72+
73+
let conf = Config::load_or_panic();
74+
75+
println!(
76+
"Adding bump to {}, giving a {} multiplier for {}",
77+
recording
78+
.format_with_async(&LISTENBRAINZ_FMT)
79+
.await
80+
.expect("Error while getting recording credits"),
81+
multiplier,
82+
duration.to_humantime().unwrap()
83+
);
84+
85+
conf.write_or_panic().bumps.add_bump(
86+
recording.mbid.clone(),
87+
username,
88+
multiplier,
89+
Utc::now() + duration,
90+
);
91+
}
92+
}

alistral_cli/src/tools/bumps.rs

Lines changed: 0 additions & 83 deletions
This file was deleted.

alistral_cli/src/tools/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub mod bumps;
1+
pub mod bump;
22
pub mod cache;
33
pub mod compatibility;
44
pub mod daily;

alistral_cli/src/utils/cli/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use std::io;
55
#[cfg(feature = "lookup")]
66
use clap::CommandFactory as _;
77

8-
use super::regex::is_string_mbid;
98
#[cfg(feature = "lookup")]
109
use crate::models::cli::Cli;
1110
use crate::utils::regex::get_raw_mbid_from_url;
11+
use crate::utils::user_inputs::UserInputParser;
1212

1313
pub mod formating;
1414
#[cfg(feature = "lookup")]
@@ -21,7 +21,7 @@ pub fn await_next() {
2121
}
2222

2323
pub fn read_mbid_from_input(input: &str) -> Option<String> {
24-
if is_string_mbid(input) {
24+
if UserInputParser::is_uuid(input) {
2525
return Some(input.to_string());
2626
}
2727

alistral_cli/src/utils/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ pub mod extensions;
88
pub mod listenbrainz_api;
99
pub mod radio;
1010
pub mod regex;
11+
/// Holds all of the user input parsers and sanitasation
12+
pub mod user_inputs;
1113
#[cfg(feature = "musicbrainz")]
1214
pub mod whitelist_blacklist;

alistral_cli/src/utils/regex/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
use regex::Regex;
22

3-
pub fn is_string_mbid(string: &str) -> bool {
4-
let regex = Regex::new(
5-
r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
6-
)
7-
.unwrap();
8-
9-
// result will be a tuple containing the start and end indices for the first match in the string
10-
let result = regex.captures(string);
11-
12-
result.is_some()
13-
}
14-
153
pub fn get_raw_mbid_from_url(string: &str) -> Option<String> {
164
let regex = Regex::new(r"(area|instrument|recording|release|album|work|release-group|url|track)/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})").unwrap();
175

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use musicbrainz_db_lite::GetOrFetch;
2+
use musicbrainz_db_lite::Recording;
3+
4+
use crate::ALISTRAL_CLIENT;
5+
use crate::utils::user_inputs::UserInputParser;
6+
7+
impl UserInputParser {
8+
/// Parse a recording from the input. End the program with no panics if the data is wrong
9+
pub async fn parse_recording(mbid: &str) -> Recording {
10+
let Some(mbid) = Self::read_mbid_from_input(mbid) else {
11+
tracing::error!("Couldn't read mbid from input");
12+
std::process::exit(2);
13+
};
14+
15+
match Recording::get_or_fetch_as_task(ALISTRAL_CLIENT.musicbrainz_db.clone(), &mbid)
16+
.await
17+
.unwrap()
18+
{
19+
Some(val) => val,
20+
None => {
21+
tracing::error!("Couldn't find a recording with mbid {mbid}");
22+
std::process::exit(2);
23+
}
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)