mirror of
https://github.com/crunchy-labs/crunchy-cli.git
synced 2026-01-21 12:12:00 -06:00
Add option to select seasons when season number is duplicated (#199)
This commit is contained in:
parent
d75c04fbb6
commit
fc44b8af8a
10 changed files with 227 additions and 52 deletions
73
crunchy-cli-core/src/utils/interactive_select.rs
Normal file
73
crunchy-cli-core/src/utils/interactive_select.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use crate::utils::log::progress_pause;
|
||||
use crunchyroll_rs::Season;
|
||||
use dialoguer::console::Term;
|
||||
use dialoguer::MultiSelect;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub fn get_duplicated_seasons(seasons: &Vec<Season>) -> Vec<u32> {
|
||||
let mut season_number_counter = BTreeMap::<u32, u32>::new();
|
||||
for season in seasons {
|
||||
season_number_counter
|
||||
.entry(season.season_number)
|
||||
.and_modify(|c| *c += 1)
|
||||
.or_default();
|
||||
}
|
||||
season_number_counter
|
||||
.into_iter()
|
||||
.filter_map(|(k, v)| if v > 0 { Some(k) } else { None })
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn check_for_duplicated_seasons(seasons: &mut Vec<Season>) {
|
||||
let mut as_map = BTreeMap::new();
|
||||
for season in seasons.iter() {
|
||||
as_map
|
||||
.entry(season.season_number)
|
||||
.or_insert(vec![])
|
||||
.push(season)
|
||||
}
|
||||
|
||||
let duplicates: Vec<&Season> = as_map
|
||||
.into_values()
|
||||
.filter(|s| s.len() > 1)
|
||||
.flatten()
|
||||
.collect();
|
||||
progress_pause!();
|
||||
let _ = Term::stdout().clear_line();
|
||||
let keep = select(
|
||||
"Duplicated seasons were found. Select the one you want to download (space to select/deselect; enter to continue)",
|
||||
duplicates
|
||||
.iter()
|
||||
.map(|s| format!("Season {} ({})", s.season_number, s.title))
|
||||
.collect(),
|
||||
);
|
||||
progress_pause!();
|
||||
|
||||
let mut remove_ids = vec![];
|
||||
for (i, duplicate) in duplicates.into_iter().enumerate() {
|
||||
if !keep.contains(&i) {
|
||||
remove_ids.push(duplicate.id.clone())
|
||||
}
|
||||
}
|
||||
|
||||
seasons.retain(|s| !remove_ids.contains(&s.id));
|
||||
}
|
||||
|
||||
pub fn select(prompt: &str, input: Vec<String>) -> Vec<usize> {
|
||||
if input.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let def: Vec<bool> = (0..input.len()).map(|_| true).collect();
|
||||
|
||||
let selection = MultiSelect::new()
|
||||
.with_prompt(prompt)
|
||||
.items(&input[..])
|
||||
.defaults(&def[..])
|
||||
.clear(false)
|
||||
.report(false)
|
||||
.interact_on(&Term::stdout())
|
||||
.unwrap_or_default();
|
||||
|
||||
selection
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
|
||||
use log::{
|
||||
info, set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record,
|
||||
SetLoggerError,
|
||||
|
|
@ -37,6 +37,15 @@ macro_rules! progress {
|
|||
}
|
||||
pub(crate) use progress;
|
||||
|
||||
macro_rules! progress_pause {
|
||||
() => {
|
||||
{
|
||||
log::info!(target: "progress_pause", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) use progress_pause;
|
||||
|
||||
macro_rules! tab_info {
|
||||
($($arg:tt)+) => {
|
||||
if log::max_level() == log::LevelFilter::Debug {
|
||||
|
|
@ -62,6 +71,7 @@ impl Log for CliLogger {
|
|||
fn log(&self, record: &Record) {
|
||||
if !self.enabled(record.metadata())
|
||||
|| (record.target() != "progress"
|
||||
&& record.target() != "progress_pause"
|
||||
&& record.target() != "progress_end"
|
||||
&& !record.target().starts_with("crunchy_cli"))
|
||||
{
|
||||
|
|
@ -75,6 +85,16 @@ impl Log for CliLogger {
|
|||
|
||||
match record.target() {
|
||||
"progress" => self.progress(record, false),
|
||||
"progress_pause" => {
|
||||
let progress = self.progress.lock().unwrap();
|
||||
if let Some(p) = &*progress {
|
||||
p.set_draw_target(if p.is_hidden() {
|
||||
ProgressDrawTarget::stdout()
|
||||
} else {
|
||||
ProgressDrawTarget::hidden()
|
||||
})
|
||||
}
|
||||
}
|
||||
"progress_end" => self.progress(record, true),
|
||||
_ => {
|
||||
if self.progress.lock().unwrap().is_some() {
|
||||
|
|
@ -158,6 +178,7 @@ impl CliLogger {
|
|||
.unwrap()
|
||||
.tick_strings(&["—", "\\", "|", "/", finish_str]),
|
||||
);
|
||||
pb.set_draw_target(ProgressDrawTarget::stdout());
|
||||
pb.enable_steady_tick(Duration::from_millis(200));
|
||||
pb.set_message(msg);
|
||||
*progress = Some(pb)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ pub mod download;
|
|||
pub mod ffmpeg;
|
||||
pub mod filter;
|
||||
pub mod format;
|
||||
pub mod interactive_select;
|
||||
pub mod locale;
|
||||
pub mod log;
|
||||
pub mod os;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue