parallelize downloadmods resolving
This commit is contained in:
parent
52d21fba63
commit
86560f8e19
|
@ -16,11 +16,13 @@ use addonscript::manifest::{
|
|||
File,
|
||||
Manifest,
|
||||
RelationType,
|
||||
Repository,
|
||||
RepositoryType,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use async_trait::async_trait;
|
||||
use crossterm::style::Stylize;
|
||||
use futures::{stream, StreamExt};
|
||||
use indicatif::ProgressBar;
|
||||
use percent_encoding::percent_decode;
|
||||
use reqwest::Client;
|
||||
|
@ -30,7 +32,6 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use url::Url;
|
||||
|
||||
pub async fn run(
|
||||
|
@ -52,15 +53,12 @@ pub async fn run(
|
|||
repos.insert(repo.id.clone(), repo);
|
||||
}
|
||||
|
||||
let mut links = vec![];
|
||||
|
||||
let pb = ProgressBar::new(version.relations.len() as u64)
|
||||
.with_prefix("Resolving")
|
||||
.with_style(progress_style());
|
||||
|
||||
let mut files = vec![];
|
||||
for rel in version.relations {
|
||||
pb.inc(1);
|
||||
|
||||
// Only mods
|
||||
if rel.relation_type != RelationType::Mod {
|
||||
pb.println(
|
||||
|
@ -85,62 +83,20 @@ pub async fn run(
|
|||
continue;
|
||||
}
|
||||
|
||||
let rels = match file {
|
||||
File::Link {
|
||||
link, installer, ..
|
||||
} => (installer, link),
|
||||
File::Maven {
|
||||
installer,
|
||||
artifact,
|
||||
repository,
|
||||
} => {
|
||||
let repo = repos.get(&repository).with_context(|| {
|
||||
format!("File references non-existant repository `{}`", repository)
|
||||
})?;
|
||||
|
||||
let url = match repo.repo_type {
|
||||
RepositoryType::Maven => {
|
||||
let url = mvn_artifact_to_url(&artifact, &repo)?;
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Resolved maven artifact with url".green(),
|
||||
url.as_str().cyan().bold()
|
||||
));
|
||||
url
|
||||
},
|
||||
RepositoryType::Curseforge => {
|
||||
let mut splits = artifact.split(':').skip(1);
|
||||
let p_id = splits
|
||||
.next()
|
||||
.context("Couldn't parse curseforge artifact!")?;
|
||||
let f_id = splits
|
||||
.next()
|
||||
.context("Couldn't parse curseforge artifact!")?;
|
||||
|
||||
let url = format!(
|
||||
"https://addons-ecs.forgesvc.net/api/v2/addon/{}/file/{}/download-url",
|
||||
p_id, f_id
|
||||
);
|
||||
|
||||
let url = Url::parse(http.get(url).send().await?.text().await?.trim())
|
||||
.context("failed to parse curseforge URL")?;
|
||||
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Resolved curseforge artifact with url".green(),
|
||||
url.as_str().cyan().bold()
|
||||
));
|
||||
|
||||
url
|
||||
},
|
||||
};
|
||||
|
||||
(installer, Link::Http(url))
|
||||
},
|
||||
};
|
||||
|
||||
links.push(rels);
|
||||
files.push(file);
|
||||
}
|
||||
|
||||
let http_ = Arc::clone(&http);
|
||||
let mut futures = stream::iter(files.into_iter())
|
||||
.map(|f| process_file(f, &repos, &pb, Arc::clone(&http_)))
|
||||
.buffer_unordered(config.downloads.max_threads);
|
||||
|
||||
let mut links = vec![];
|
||||
while let Some(x) = futures.next().await {
|
||||
pb.inc(1);
|
||||
links.push(x?);
|
||||
}
|
||||
|
||||
pb.finish();
|
||||
|
||||
let mut files = vec![];
|
||||
|
@ -233,3 +189,64 @@ pub async fn run(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn process_file(
|
||||
file: File,
|
||||
repos: &HashMap<String, Repository>,
|
||||
pb: &ProgressBar,
|
||||
http: Arc<Client>,
|
||||
) -> anyhow::Result<(Installer, Link)> {
|
||||
Ok(match file {
|
||||
File::Link {
|
||||
link, installer, ..
|
||||
} => (installer, link),
|
||||
File::Maven {
|
||||
installer,
|
||||
artifact,
|
||||
repository,
|
||||
} => {
|
||||
let repo = repos.get(&repository).with_context(|| {
|
||||
format!("File references non-existant repository `{}`", repository)
|
||||
})?;
|
||||
|
||||
let url = match repo.repo_type {
|
||||
RepositoryType::Maven => {
|
||||
let url = mvn_artifact_to_url(&artifact, &repo)?;
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Resolved maven artifact with url".green(),
|
||||
url.as_str().cyan().bold()
|
||||
));
|
||||
url
|
||||
},
|
||||
RepositoryType::Curseforge => {
|
||||
let mut splits = artifact.split(':').skip(1);
|
||||
let p_id = splits
|
||||
.next()
|
||||
.context("Couldn't parse curseforge artifact!")?;
|
||||
let f_id = splits
|
||||
.next()
|
||||
.context("Couldn't parse curseforge artifact!")?;
|
||||
|
||||
let url = format!(
|
||||
"https://addons-ecs.forgesvc.net/api/v2/addon/{}/file/{}/download-url",
|
||||
p_id, f_id
|
||||
);
|
||||
|
||||
let url = Url::parse(http.get(url).send().await?.text().await?.trim())
|
||||
.context("failed to parse curseforge URL")?;
|
||||
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Resolved curseforge artifact with url".green(),
|
||||
url.as_str().cyan().bold()
|
||||
));
|
||||
|
||||
url
|
||||
},
|
||||
};
|
||||
|
||||
(installer, Link::Http(url))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue