Fetch mod version info

This commit is contained in:
marceline-cramer 2021-11-28 17:21:18 -07:00
parent f4a6b94031
commit 24d50b1e3c
2 changed files with 73 additions and 22 deletions

View File

@ -15,6 +15,10 @@ Long-term/host-dependent:
- conflict resolution - conflict resolution
- dependency resolution - dependency resolution
- shaderpack and resource pack management - shaderpack and resource pack management
- integrate into multimc or theseus
- graphical frontend (w/ notifications?)
[Modrinth REST API docs](https://github.com/modrinth/labrinth/wiki/API-Documentation)
# File Architecture # File Architecture

View File

@ -1,5 +1,6 @@
use console::style; use console::style;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
@ -112,6 +113,31 @@ struct ModResult {
host: String, host: String,
} }
impl ModResult {
fn format_info(&self) -> String {
let title = style(self.title.clone()).bold();
let downloads = style(self.downloads.clone()).bold().green();
if let Some(latest_release) = self.versions.last() {
// TODO fetch version numbers to display
let latest_release = style(latest_release).bold().blue();
format!("{} [{}] ({} downloads)", title, latest_release, downloads)
} else {
format!("{} [no releases]", title)
}
}
fn format_description(&self) -> String {
self.description.to_owned()
}
fn display(&self, index: usize) {
let index = style(index).magenta();
let info = self.format_info();
let description = self.format_description();
println!("{} {}\n {}", index, info, description);
}
}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
struct ModInfo { struct ModInfo {
id: String, // TODO serialize mod id? id: String, // TODO serialize mod id?
@ -139,29 +165,31 @@ struct ModInfo {
donation_urls: Vec<String>, donation_urls: Vec<String>,
} }
impl ModResult { #[derive(Deserialize, Debug)]
fn format_info(&self) -> String { struct ModVersion {
let title = style(self.title.clone()).bold(); id: String, // version id
let downloads = style(self.downloads.clone()).bold().green(); mod_id: String, // mod id
if let Some(latest_release) = self.versions.last() { author_id: String, // user id
// TODO fetch version numbers to display // NOTE modrinth docs list this as a String, but is actually a bool?
let latest_release = style(latest_release).bold().blue(); // featured: String, // user id
format!("{} [{}] ({} downloads)", title, latest_release, downloads) name: String,
} else { version_number: String,
format!("{} [no releases]", title) changelog: Option<String>,
} changelog_url: Option<String>,
} date_published: String, // TODO serialize datetime
downloads: isize,
version_type: String, // TODO {alpha | beta | release}
files: Vec<ModVersionFile>,
dependencies: Vec<String>, // TODO dependency wrangling, thank you modrinth, very cool
game_versions: Vec<String>,
loaders: Vec<String>,
}
fn format_description(&self) -> String { #[derive(Deserialize, Debug)]
self.description.to_owned() struct ModVersionFile {
} hashes: HashMap<String, String>,
url: String,
fn display(&self, index: usize) { filename: String,
let index = style(index).magenta();
let info = self.format_info();
let description = self.format_description();
println!("{} {}\n {}", index, info, description);
}
} }
async fn search_mods(config: &Config, query: String) -> anyhow::Result<SearchResponse> { async fn search_mods(config: &Config, query: String) -> anyhow::Result<SearchResponse> {
@ -217,6 +245,17 @@ async fn fetch_mod_info(config: &Config, mod_result: &ModResult) -> anyhow::Resu
Ok(response) Ok(response)
} }
async fn fetch_mod_version(config: &Config, version_id: &String) -> anyhow::Result<ModVersion> {
let client = reqwest::Client::new();
let url = format!(
"https://{}/api/v1/version/{}",
config.upstream.server_address, version_id
);
let response = client.get(url).send().await?;
let response = response.json::<ModVersion>().await?;
Ok(response)
}
async fn cmd_get(config: &Config, package_name: String) -> anyhow::Result<()> { async fn cmd_get(config: &Config, package_name: String) -> anyhow::Result<()> {
let response = search_mods(config, package_name).await?; let response = search_mods(config, package_name).await?;
@ -238,6 +277,14 @@ async fn cmd_get(config: &Config, package_name: String) -> anyhow::Result<()> {
for to_get in selected.iter() { for to_get in selected.iter() {
let mod_info = fetch_mod_info(config, to_get).await?; let mod_info = fetch_mod_info(config, to_get).await?;
println!("mod: {:#?}", mod_info); println!("mod: {:#?}", mod_info);
// TODO allow the user to select multiple versions
if let Some(version_id) = mod_info.versions.first() {
println!("fetching version {}", version_id);
let version = fetch_mod_version(config, version_id).await?;
println!("version: {:#?}", version);
}
} }
Ok(()) Ok(())