use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use crate::apis::modrinth::get_raw_versions;
use crate::{config::Cfg, List};
use crate::{
db::userlist_get_all_current_versions_with_mods,
error::{EType, MLErr, MLE},
files::{
clean_list_dir, delete_version, disable_version, download_versions,
get_downloaded_versions,
},
};
use crate::{PROGRESS_CHARS, STYLE_BAR_POS};
/// # Errors
pub async fn download(
config: &Cfg,
liststack: Vec<List>,
clean: bool,
delete_old: bool,
) -> MLE<()> {
let mp = MultiProgress::new();
let download_p = mp.add(ProgressBar::new(
liststack
.len()
.try_into()
.map_err(|_| MLErr::new(EType::Other, "ListStackLen"))?,
));
download_p.set_style(
ProgressStyle::with_template(STYLE_BAR_POS)
.map_err(|_| MLErr::new(EType::LibIndicatif, "template error"))?
.progress_chars(PROGRESS_CHARS),
);
for current_list in liststack {
download_list(config, mp.clone(), download_p.clone(), current_list, clean, delete_old).await?;
}
download_p.finish_with_message("Downloaded all lists");
Ok(())
}
async fn download_list(
config: &Cfg,
mp: MultiProgress,
download_p: ProgressBar,
current_list: List,
clean: bool,
delete_old: bool,
) -> MLE<()> {
download_p.set_message(format!("Download in {}", current_list.id));
let downloaded_versions = get_downloaded_versions(¤t_list)?;
let current_version_ids = match userlist_get_all_current_versions_with_mods(
config,
¤t_list.id,
) {
Ok(i) => Ok(i),
Err(e) => Err(MLErr::new(EType::DBError, e.to_string().as_str())),
}?;
let mut to_download: Vec<String> = vec![];
//(mod_id, version_id)
let mut to_disable: Vec<(String, String)> = vec![];
for version in current_version_ids {
let mod_id = version.0;
let current_version = version.1;
let current_download = downloaded_versions.get(&mod_id);
if current_download.is_none() || clean {
to_download.push(current_version);
} else {
let downloaded_version =
current_download.ok_or(MLErr::new(EType::Other, "IDK, WTF"))?;
if ¤t_version != downloaded_version {
to_disable
.push((mod_id.clone(), String::from(downloaded_version)));
to_download.push(current_version);
}
}
}
if clean {
clean_list_dir(¤t_list)?;
};
if to_download.is_empty() {
download_p.println(format!(
"There are no new versions to download for {}",
current_list.id
));
} else {
download_versions(
current_list.clone(),
config.clone(),
get_raw_versions(&config.apis.modrinth, to_download).await?,
&mp,
&download_p,
)
.await?;
}
if !to_disable.is_empty() {
let d_p = mp.insert_before(
&download_p,
ProgressBar::new(
to_disable
.len()
.try_into()
.map_err(|_| MLErr::new(EType::Other, "ListStackLen"))?,
),
);
d_p.set_style(
ProgressStyle::with_template(STYLE_BAR_POS)
.map_err(|_| MLErr::new(EType::LibIndicatif, "template error"))?
.progress_chars(PROGRESS_CHARS),
);
for ver in to_disable {
if delete_old {
d_p.set_message(format!("Delete version {}", ver.1));
d_p.inc(1);
delete_version(¤t_list, &ver.1)?;
} else {
d_p.set_message(format!("Disable version {}", ver.1));
d_p.inc(1);
disable_version(config, ¤t_list, ver.1, ver.0)?;
};
}
let del_msg = if delete_old {
"Deleted all old versions"
} else {
"Disabled all old versions"
};
d_p.finish_with_message(del_msg);
}
download_p.inc(1);
Ok(())
}