optimize createmodlist
This commit is contained in:
parent
3d84356cfb
commit
7d1a09abf1
|
@ -38,25 +38,81 @@ pub async fn run(
|
|||
let len = version.relations.len();
|
||||
|
||||
let mut futures = stream::iter(version.relations.into_iter())
|
||||
.map(|rel| get_meta(Arc::clone(&http), rel, &repos))
|
||||
.map(|rel| get_meta(rel, &repos))
|
||||
.buffer_unordered(config.downloads.max_threads);
|
||||
|
||||
let mut metas = vec![];
|
||||
let pb = ProgressBar::new(len as u64)
|
||||
.with_style(util::progress_style())
|
||||
.with_prefix("Resolving metadata");
|
||||
while let Some(meta) = futures.next().await {
|
||||
|
||||
let mut cf_rels = vec![];
|
||||
while let Some(mi) = futures.next().await {
|
||||
pb.inc(1);
|
||||
let meta = meta?;
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Got meta for".green(),
|
||||
AsRef::<str>::as_ref(&meta.name).cyan().bold()
|
||||
));
|
||||
metas.push(meta);
|
||||
let mi = mi?;
|
||||
match mi {
|
||||
MetaInfo::Meta(meta) => {
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Got meta for".green(),
|
||||
AsRef::<str>::as_ref(&meta.name).cyan().bold()
|
||||
));
|
||||
metas.push(meta);
|
||||
},
|
||||
|
||||
MetaInfo::CfId(id) => {
|
||||
pb.println(format!(
|
||||
"{} {}",
|
||||
"Found curseforge artifact with id".green(),
|
||||
id.to_string().cyan().bold()
|
||||
));
|
||||
|
||||
cf_rels.push(id);
|
||||
},
|
||||
}
|
||||
}
|
||||
pb.finish();
|
||||
|
||||
println!("{}", "Querying CF metas.".info());
|
||||
|
||||
let res = http
|
||||
.post("https://addons-ecs.forgesvc.net/api/v2/addon")
|
||||
.body(
|
||||
serde_json::to_string(&cf_rels)
|
||||
.context("Failed to serialize curseforge relation IDs")?,
|
||||
)
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.await
|
||||
.context("Failed sending CF relation request")?
|
||||
.bytes()
|
||||
.await
|
||||
.context("Failed getting CF relation response body")?;
|
||||
|
||||
let cf_metas = serde_json::from_slice::<Vec<AddonInfoResponse>>(&res)
|
||||
.context("Failed deserializing CF relation response")?;
|
||||
|
||||
let cf_metas = cf_metas.into_iter().map(|m| Meta {
|
||||
name: m.name,
|
||||
contributors: m
|
||||
.authors
|
||||
.into_iter()
|
||||
.map(|a| Contributor {
|
||||
name: a.name,
|
||||
roles: vec!["author".into()],
|
||||
})
|
||||
.collect(),
|
||||
description: Some(m.summary),
|
||||
icon_url: m
|
||||
.attachments
|
||||
.into_iter()
|
||||
.find(|a| a.is_default)
|
||||
.map(|a| a.url.to_string()),
|
||||
website_url: Some(m.website_url),
|
||||
});
|
||||
|
||||
metas.extend(cf_metas);
|
||||
|
||||
metas.sort_by_key(|m| m.name.to_ascii_lowercase());
|
||||
|
||||
println!("{}", "Rendering modlist.".info());
|
||||
|
@ -78,30 +134,26 @@ pub async fn run(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_meta(
|
||||
http: Arc<Client>,
|
||||
rel: Relation,
|
||||
repos: &HashMap<String, Repository>,
|
||||
) -> anyhow::Result<Meta> {
|
||||
async fn get_meta(rel: Relation, repos: &HashMap<String, Repository>) -> anyhow::Result<MetaInfo> {
|
||||
if let Some(meta) = rel.meta {
|
||||
return Ok(meta);
|
||||
return Ok(MetaInfo::Meta(meta));
|
||||
}
|
||||
|
||||
if rel.file.is_none() {
|
||||
return Ok(Meta {
|
||||
return Ok(MetaInfo::Meta(Meta {
|
||||
name: rel.id.clone(),
|
||||
contributors: vec![],
|
||||
description: rel.versions.map(|v| format!("version {}", v)),
|
||||
icon_url: None,
|
||||
website_url: None,
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let file = rel.file.unwrap();
|
||||
|
||||
match file {
|
||||
File::Link { link, id, .. } => {
|
||||
Ok(Meta {
|
||||
Ok(MetaInfo::Meta(Meta {
|
||||
name: if let Some(id) = id {
|
||||
id
|
||||
} else {
|
||||
|
@ -113,7 +165,7 @@ async fn get_meta(
|
|||
description: Some(format!("{:?}", &link)),
|
||||
icon_url: None,
|
||||
website_url: None,
|
||||
})
|
||||
}))
|
||||
},
|
||||
File::Maven {
|
||||
repository,
|
||||
|
@ -125,50 +177,20 @@ async fn get_meta(
|
|||
.context("File references unknown repository!")?;
|
||||
|
||||
match repo.repo_type {
|
||||
RepositoryType::Maven => Ok(Meta {
|
||||
RepositoryType::Maven => Ok(MetaInfo::Meta(Meta {
|
||||
name: artifact,
|
||||
contributors: vec![],
|
||||
description: None,
|
||||
icon_url: None,
|
||||
website_url: None,
|
||||
}),
|
||||
})),
|
||||
RepositoryType::Curseforge => {
|
||||
let (p_id, _) = util::parse_curseforge_artifact(&artifact)?;
|
||||
let resp = http
|
||||
.get(format!(
|
||||
"https://addons-ecs.forgesvc.net/api/v2/addon/{}",
|
||||
p_id
|
||||
))
|
||||
.send()
|
||||
.await?
|
||||
.bytes()
|
||||
.await?;
|
||||
let p_id = p_id
|
||||
.parse::<u32>()
|
||||
.context("Failed to parse curseforge ID")?;
|
||||
|
||||
let resp = serde_json::from_slice::<AddonInfoResponse>(&resp)
|
||||
.context("Failed to deserialize addon info!")?;
|
||||
|
||||
let icon_url = resp.attachments.into_iter().find_map(|a| {
|
||||
if a.is_default {
|
||||
Some(a.url.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Meta {
|
||||
name: resp.name,
|
||||
contributors: resp
|
||||
.authors
|
||||
.into_iter()
|
||||
.map(|a| Contributor {
|
||||
name: a.name,
|
||||
roles: vec![],
|
||||
})
|
||||
.collect(),
|
||||
description: Some(resp.summary),
|
||||
icon_url,
|
||||
website_url: Some(resp.website_url),
|
||||
})
|
||||
Ok(MetaInfo::CfId(p_id))
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -180,3 +202,8 @@ struct ModListContent {
|
|||
metas: Vec<Meta>,
|
||||
pack_meta: Meta,
|
||||
}
|
||||
|
||||
enum MetaInfo {
|
||||
Meta(Meta),
|
||||
CfId(u32),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue