unpack and add downloaded mod
This commit is contained in:
21
src/main.rs
21
src/main.rs
@@ -92,7 +92,7 @@ fn command_order(root_config: &RootConfig, instance_id: &str) -> anyhow::Result<
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn command_download(root_config: &RootConfig, nxm_url: &str) -> anyhow::Result<()> {
|
||||
fn command_download(root_config: &mut RootConfig, nxm_url: &str) -> anyhow::Result<()> {
|
||||
let Some(dl_location) = root_config.download_location() else {
|
||||
return Err(anyhow!("No download location set"));
|
||||
};
|
||||
@@ -101,7 +101,22 @@ fn command_download(root_config: &RootConfig, nxm_url: &str) -> anyhow::Result<(
|
||||
return Err(anyhow!("No API key provided"));
|
||||
};
|
||||
|
||||
download_nxm(api_key, nxm_url, dl_location)?;
|
||||
let (dl_file, mod_info) = download_nxm(api_key, nxm_url, dl_location)?;
|
||||
|
||||
let mod_id = mod_info.generate_id();
|
||||
if root_config.game_by_id(&mod_id).is_some() {
|
||||
error!(
|
||||
"Generated mod id already exists. Pleas install downloaded mod manually. Downloaded at {}",
|
||||
&dl_file.to_string_lossy()
|
||||
);
|
||||
return Err(anyhow!("Mod with generated already exists"));
|
||||
}
|
||||
|
||||
let new_mod = unpack(root_config, &mod_id, dl_file)?;
|
||||
|
||||
root_config.add_mod(&new_mod);
|
||||
|
||||
root_config.save_to_file()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -156,7 +171,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
api.validate_key()?;
|
||||
}
|
||||
cli::Commands::Download { url } => {
|
||||
command_download(&root_config, &url)?;
|
||||
command_download(&mut root_config, &url)?;
|
||||
}
|
||||
cli::Commands::Unpack { id, path } => {
|
||||
command_unpack(&mut root_config, &id, path)?;
|
||||
|
||||
@@ -101,8 +101,8 @@ pub struct ModInfo {
|
||||
// pub endorsement_count: u64,
|
||||
// pub created_timestamp: u64,
|
||||
// pub created_time: String,
|
||||
pub updated_timestamp: u64,
|
||||
pub updated_time: String,
|
||||
// pub updated_timestamp: u64,
|
||||
// pub updated_time: String,
|
||||
// pub author: String,
|
||||
// pub uploaded_by: String,
|
||||
// pub uploaded_users_profile_url: String,
|
||||
@@ -112,3 +112,39 @@ pub struct ModInfo {
|
||||
// pub user: String /* Complex struct */,
|
||||
// pub endorsement: String /* Complex struct*/ ,
|
||||
}
|
||||
|
||||
impl ModInfo {
|
||||
/// Try to generate a id for a mod based on name, mod_id and version
|
||||
pub fn generate_id(&self) -> String {
|
||||
const MAX_CHARS: usize = 16;
|
||||
const MIN_CHARS: usize = 8;
|
||||
|
||||
let mut short_name = String::new();
|
||||
|
||||
for word in self.name.split_whitespace() {
|
||||
let cleaned: String = word.chars().filter(|c| !c.is_ascii_punctuation()).collect();
|
||||
|
||||
if cleaned.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if short_name.is_empty() {
|
||||
short_name.push_str(&cleaned);
|
||||
} else {
|
||||
short_name.push('_');
|
||||
short_name.push_str(&cleaned);
|
||||
}
|
||||
|
||||
// Ensure at least two words, then stop when >= 8 chars
|
||||
let words = short_name.matches('_').count() + 1;
|
||||
if words >= 2 && short_name.len() >= MIN_CHARS {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if short_name.len() > MAX_CHARS {
|
||||
short_name.truncate(MAX_CHARS);
|
||||
}
|
||||
format!("{}-{}-{}", short_name, self.mod_id, self.version)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,11 @@ use crate::nexus::{
|
||||
api::{DownloadLocation, ModInfo},
|
||||
};
|
||||
|
||||
pub fn download_nxm(api_key: &str, link: &str, target_dir: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||
pub fn download_nxm(
|
||||
api_key: &str,
|
||||
link: &str,
|
||||
target_dir: impl AsRef<Path>,
|
||||
) -> anyhow::Result<(PathBuf, ModInfo)> {
|
||||
let api = NexusAPI::new(api_key);
|
||||
let Some(parsed_url) = NXMUrl::parse_url(link) else {
|
||||
return Err(anyhow!("Failed to parse url"));
|
||||
@@ -30,9 +34,9 @@ pub fn download_nxm(api_key: &str, link: &str, target_dir: impl AsRef<Path>) ->
|
||||
create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
download_mod(selected_mirror, download_path)?;
|
||||
download_mod(selected_mirror, &download_path)?;
|
||||
|
||||
Ok(())
|
||||
Ok((download_path, mod_info))
|
||||
}
|
||||
|
||||
fn download_mod(mod_dl_link: &DownloadLocation, target: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user