mirror of
https://github.com/WarrenHood/MCModpackManager.git
synced 2025-04-29 22:44:59 +01:00
Added a download command
This commit is contained in:
parent
9105596c87
commit
9700206b02
11
src/main.rs
11
src/main.rs
|
@ -74,6 +74,11 @@ enum Commands {
|
||||||
/// Name of the mod to remove from the modpack
|
/// Name of the mod to remove from the modpack
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
/// Download the mods in the pack to a specified folder
|
||||||
|
Download {
|
||||||
|
/// Mods directory
|
||||||
|
mods_dir: PathBuf,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread")]
|
#[tokio::main(flavor = "multi_thread")]
|
||||||
|
@ -236,6 +241,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Commands::Download { mods_dir } => {
|
||||||
|
let pack_lock =
|
||||||
|
resolver::PinnedPackMeta::load_from_current_directory(false).await?;
|
||||||
|
pack_lock.download_mods(&mods_dir).await?;
|
||||||
|
println!("Mods updated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@ pub mod modrinth;
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
enum FileSource {
|
pub enum FileSource {
|
||||||
Download { url: String, sha1: String, sha512: String},
|
Download { url: String, sha1: String, sha512: String, filename: String},
|
||||||
Local { path: PathBuf, sha1: String, sha512: String },
|
Local { path: PathBuf, sha1: String, sha512: String, filename: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct PinnedMod {
|
pub struct PinnedMod {
|
||||||
/// Source of the files for the mod
|
/// Source of the files for the mod
|
||||||
source: Vec<FileSource>,
|
pub source: Vec<FileSource>,
|
||||||
/// Version of mod
|
/// Version of mod
|
||||||
pub version: String,
|
pub version: String,
|
||||||
/// Pinned dependencies of a pinned mod
|
/// Pinned dependencies of a pinned mod
|
||||||
|
|
|
@ -12,27 +12,6 @@ pub struct Modrinth {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct DonationUrls1 {
|
|
||||||
id: String,
|
|
||||||
platform: String,
|
|
||||||
url: String,
|
|
||||||
}
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct Gallery1 {
|
|
||||||
created: String,
|
|
||||||
description: String,
|
|
||||||
featured: bool,
|
|
||||||
ordering: i64,
|
|
||||||
title: String,
|
|
||||||
url: String,
|
|
||||||
}
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct License1 {
|
|
||||||
id: String,
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
}
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct ModrinthProject {
|
struct ModrinthProject {
|
||||||
slug: String,
|
slug: String,
|
||||||
|
@ -65,7 +44,7 @@ struct VersionFiles {
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
struct ModrinthProjectVersion {
|
struct ModrinthProjectVersion {
|
||||||
// author_id: String,
|
// author_id: String,
|
||||||
// date_published: String,
|
date_published: String,
|
||||||
dependencies: Option<Vec<VersionDeps>>,
|
dependencies: Option<Vec<VersionDeps>>,
|
||||||
// downloads: i64,
|
// downloads: i64,
|
||||||
files: Vec<VersionFiles>,
|
files: Vec<VersionFiles>,
|
||||||
|
@ -188,6 +167,7 @@ impl Modrinth {
|
||||||
url: f.url.clone(),
|
url: f.url.clone(),
|
||||||
sha1: f.hashes.sha1.clone(),
|
sha1: f.hashes.sha1.clone(),
|
||||||
sha512: f.hashes.sha512.clone(),
|
sha512: f.hashes.sha512.clone(),
|
||||||
|
filename: f.filename.clone()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
version: package.version_number.clone(),
|
version: package.version_number.clone(),
|
||||||
|
|
|
@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
error::Error,
|
error::Error,
|
||||||
|
ffi::OsStr,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +29,86 @@ impl PinnedPackMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clears out anything not in the mods list, and then downloads anything in the mods list not present
|
||||||
|
pub async fn download_mods(&self, mods_dir: &PathBuf) -> Result<(), Box<dyn Error>> {
|
||||||
|
let files = std::fs::read_dir(mods_dir)?;
|
||||||
|
for file in files.into_iter() {
|
||||||
|
let file = file?;
|
||||||
|
if file.file_type()?.is_file() {
|
||||||
|
println!("Checking if file {:#?} exists in pinned mods...", file.file_name());
|
||||||
|
let filename = file.file_name();
|
||||||
|
if !self.file_is_pinned(&filename) {
|
||||||
|
println!(
|
||||||
|
"Deleting file {:#?} as it is not in the pinned mods",
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
tokio::fs::remove_file(file.path()).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_, pinned_mod) in self.mods.iter() {
|
||||||
|
for filesource in pinned_mod.source.iter() {
|
||||||
|
match filesource {
|
||||||
|
crate::providers::FileSource::Download {
|
||||||
|
url,
|
||||||
|
sha1,
|
||||||
|
sha512,
|
||||||
|
filename,
|
||||||
|
} => {
|
||||||
|
if mods_dir.join(PathBuf::from(filename)).exists() {
|
||||||
|
println!("Found existing mod {}", filename);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
println!("Downloading {} from {}", filename, url);
|
||||||
|
let file_contents = reqwest::get(url).await?.bytes().await?;
|
||||||
|
// TODO: Check hash
|
||||||
|
tokio::fs::write(mods_dir.join(filename), file_contents).await?;
|
||||||
|
},
|
||||||
|
crate::providers::FileSource::Local {
|
||||||
|
path,
|
||||||
|
sha1,
|
||||||
|
sha512,
|
||||||
|
filename,
|
||||||
|
} => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn file_is_pinned(&self, file_name: &OsStr) -> bool {
|
||||||
|
for (pinned_mod_name, pinned_mod) in self.mods.iter() {
|
||||||
|
for filesource in pinned_mod.source.iter() {
|
||||||
|
match filesource {
|
||||||
|
crate::providers::FileSource::Download {
|
||||||
|
url,
|
||||||
|
sha1,
|
||||||
|
sha512,
|
||||||
|
filename,
|
||||||
|
} => {
|
||||||
|
if OsStr::new(filename) == file_name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
crate::providers::FileSource::Local {
|
||||||
|
path,
|
||||||
|
sha1,
|
||||||
|
sha512,
|
||||||
|
filename,
|
||||||
|
} => {
|
||||||
|
if OsStr::new(filename) == file_name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn pin_mod_and_deps(
|
pub async fn pin_mod_and_deps(
|
||||||
&mut self,
|
&mut self,
|
||||||
mod_metadata: &ModMeta,
|
mod_metadata: &ModMeta,
|
||||||
|
|
Loading…
Reference in a new issue