You've already forked AstralRinth
forked from didirus/AstralRinth
Updating + Profile Repairs + Performance Improvements (#97)
* repairing * Main framework for updating * add jsconfig * more work * Improve performance * Finish updating * run lint
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
//! Project management + inference
|
||||
|
||||
use crate::config::MODRINTH_API_URL;
|
||||
use crate::data::ModLoader;
|
||||
use crate::state::Profile;
|
||||
use crate::util::fetch::{fetch_json, write_cached_icon};
|
||||
use async_zip::tokio::read::fs::ZipFileReader;
|
||||
use chrono::{DateTime, Utc};
|
||||
@@ -185,6 +187,8 @@ pub enum ProjectMetadata {
|
||||
project: Box<ModrinthProject>,
|
||||
version: Box<ModrinthVersion>,
|
||||
members: Vec<ModrinthTeamMember>,
|
||||
update_version: Option<Box<ModrinthVersion>>,
|
||||
incompatible: bool,
|
||||
},
|
||||
Inferred {
|
||||
title: Option<String>,
|
||||
@@ -246,21 +250,23 @@ async fn read_icon_from_file(
|
||||
}
|
||||
|
||||
pub async fn infer_data_from_files(
|
||||
paths: Vec<PathBuf>,
|
||||
paths: &[(Profile, Vec<PathBuf>)],
|
||||
cache_dir: PathBuf,
|
||||
io_semaphore: &RwLock<Semaphore>,
|
||||
) -> crate::Result<HashMap<PathBuf, Project>> {
|
||||
let mut file_path_hashes = HashMap::new();
|
||||
|
||||
// TODO: Make this concurrent and use progressive hashing to avoid loading each JAR in memory
|
||||
for path in paths.clone() {
|
||||
let mut file = tokio::fs::File::open(path.clone()).await?;
|
||||
for set in paths {
|
||||
for path in &set.1 {
|
||||
let mut file = tokio::fs::File::open(path.clone()).await?;
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
file.read_to_end(&mut buffer).await?;
|
||||
let mut buffer = Vec::new();
|
||||
file.read_to_end(&mut buffer).await?;
|
||||
|
||||
let hash = format!("{:x}", sha2::Sha512::digest(&buffer));
|
||||
file_path_hashes.insert(hash, path.clone());
|
||||
let hash = format!("{:x}", sha2::Sha512::digest(&buffer));
|
||||
file_path_hashes.insert(hash, path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let files: HashMap<String, ModrinthVersion> = fetch_json(
|
||||
@@ -291,7 +297,6 @@ pub async fn infer_data_from_files(
|
||||
io_semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let teams: Vec<ModrinthTeamMember> = fetch_json::<
|
||||
Vec<Vec<ModrinthTeamMember>>,
|
||||
>(
|
||||
@@ -312,6 +317,26 @@ pub async fn infer_data_from_files(
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let mut update_versions: Vec<ModrinthVersion> = fetch_json(
|
||||
Method::GET,
|
||||
&format!(
|
||||
"{}versions?ids={}",
|
||||
MODRINTH_API_URL,
|
||||
serde_json::to_string(
|
||||
&projects
|
||||
.iter()
|
||||
.flat_map(|x| x.versions.clone())
|
||||
.collect::<Vec<String>>()
|
||||
)?
|
||||
),
|
||||
None,
|
||||
None,
|
||||
io_semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
update_versions.sort_by(|a, b| b.date_published.cmp(&a.date_published));
|
||||
|
||||
let mut return_projects = HashMap::new();
|
||||
let mut further_analyze_projects: Vec<(String, PathBuf)> = Vec::new();
|
||||
|
||||
@@ -320,18 +345,14 @@ pub async fn infer_data_from_files(
|
||||
if let Some(project) =
|
||||
projects.iter().find(|x| version.project_id == x.id)
|
||||
{
|
||||
let profile = paths.iter().find(|x| x.1.contains(&path));
|
||||
|
||||
let file_name = path
|
||||
.file_name()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
let team_members = teams
|
||||
.iter()
|
||||
.filter(|x| x.team_id == project.team)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return_projects.insert(
|
||||
path,
|
||||
Project {
|
||||
@@ -340,7 +361,52 @@ pub async fn infer_data_from_files(
|
||||
metadata: ProjectMetadata::Modrinth {
|
||||
project: Box::new(project.clone()),
|
||||
version: Box::new(version.clone()),
|
||||
members: team_members,
|
||||
members: teams
|
||||
.iter()
|
||||
.filter(|x| x.team_id == project.team)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>(),
|
||||
update_version: if let Some((profile, _)) = &profile
|
||||
{
|
||||
update_versions
|
||||
.iter()
|
||||
.find(|x| {
|
||||
x.project_id == project.id
|
||||
&& x.game_versions.contains(
|
||||
&profile.metadata.game_version,
|
||||
)
|
||||
&& if profile.metadata.loader
|
||||
== ModLoader::Vanilla
|
||||
{
|
||||
true
|
||||
} else {
|
||||
x.loaders.contains(
|
||||
&profile
|
||||
.metadata
|
||||
.loader
|
||||
.as_api_str()
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.map(Box::new)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
incompatible: if let Some((profile, _)) = &profile {
|
||||
!version.loaders.contains(
|
||||
&profile
|
||||
.metadata
|
||||
.loader
|
||||
.as_api_str()
|
||||
.to_string(),
|
||||
) || version
|
||||
.game_versions
|
||||
.contains(&profile.metadata.game_version)
|
||||
} else {
|
||||
false
|
||||
},
|
||||
},
|
||||
file_name,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user