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(())
|
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 {
|
let Some(dl_location) = root_config.download_location() else {
|
||||||
return Err(anyhow!("No download location set"));
|
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"));
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -156,7 +171,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
api.validate_key()?;
|
api.validate_key()?;
|
||||||
}
|
}
|
||||||
cli::Commands::Download { url } => {
|
cli::Commands::Download { url } => {
|
||||||
command_download(&root_config, &url)?;
|
command_download(&mut root_config, &url)?;
|
||||||
}
|
}
|
||||||
cli::Commands::Unpack { id, path } => {
|
cli::Commands::Unpack { id, path } => {
|
||||||
command_unpack(&mut root_config, &id, path)?;
|
command_unpack(&mut root_config, &id, path)?;
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ pub struct ModInfo {
|
|||||||
// pub endorsement_count: u64,
|
// pub endorsement_count: u64,
|
||||||
// pub created_timestamp: u64,
|
// pub created_timestamp: u64,
|
||||||
// pub created_time: String,
|
// pub created_time: String,
|
||||||
pub updated_timestamp: u64,
|
// pub updated_timestamp: u64,
|
||||||
pub updated_time: String,
|
// pub updated_time: String,
|
||||||
// pub author: String,
|
// pub author: String,
|
||||||
// pub uploaded_by: String,
|
// pub uploaded_by: String,
|
||||||
// pub uploaded_users_profile_url: String,
|
// pub uploaded_users_profile_url: String,
|
||||||
@@ -112,3 +112,39 @@ pub struct ModInfo {
|
|||||||
// pub user: String /* Complex struct */,
|
// pub user: String /* Complex struct */,
|
||||||
// pub endorsement: 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},
|
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 api = NexusAPI::new(api_key);
|
||||||
let Some(parsed_url) = NXMUrl::parse_url(link) else {
|
let Some(parsed_url) = NXMUrl::parse_url(link) else {
|
||||||
return Err(anyhow!("Failed to parse url"));
|
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)?;
|
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<()> {
|
fn download_mod(mod_dl_link: &DownloadLocation, target: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user