forked from akanyan/STARTLINER
feat: initial chunithm support
This commit is contained in:
@ -5,15 +5,20 @@ use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Emitter};
|
||||
use tokio::fs;
|
||||
use tokio::task::JoinSet;
|
||||
use crate::model::local::{PackageList, PackageListEntry};
|
||||
use crate::model::misc::Game;
|
||||
use crate::model::rainy;
|
||||
use crate::pkg::{Package, PkgKey, Remote};
|
||||
use crate::pkg::{Package, PkgKey, Remote, Status};
|
||||
use crate::util;
|
||||
use crate::download_handler::DownloadHandler;
|
||||
|
||||
pub struct PackageStore {
|
||||
store: HashMap<PkgKey, Package>,
|
||||
app: AppHandle,
|
||||
meta_list: PackageList,
|
||||
dlh: DownloadHandler,
|
||||
|
||||
app: AppHandle,
|
||||
|
||||
offline: bool,
|
||||
}
|
||||
|
||||
@ -29,8 +34,17 @@ pub enum InstallResult {
|
||||
|
||||
impl PackageStore {
|
||||
pub fn new(app: AppHandle) -> PackageStore {
|
||||
let meta_list = std::fs::read_to_string(util::config_dir().join("package-list.json"))
|
||||
.map_err(|e| anyhow!(e))
|
||||
.and_then(|s| serde_json::from_str::<PackageList>(&s).map_err(|e| anyhow!(e)))
|
||||
.unwrap_or_else(|e| {
|
||||
log::warn!("unable to read package-list: {e}");
|
||||
PackageList::new()
|
||||
});
|
||||
|
||||
PackageStore {
|
||||
store: HashMap::new(),
|
||||
meta_list,
|
||||
app: app.clone(),
|
||||
dlh: DownloadHandler::new(app),
|
||||
offline: true
|
||||
@ -46,6 +60,13 @@ impl PackageStore {
|
||||
self.store.clone()
|
||||
}
|
||||
|
||||
pub fn get_game_list(&self, game: Game) -> Vec<PkgKey> {
|
||||
self.meta_list.iter()
|
||||
.filter(|(_, v)| v.games.contains(&game))
|
||||
.map(|(k, _)| k.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub async fn reload_package(&mut self, key: PkgKey) {
|
||||
let dir = util::pkg_dir().join(&key.0);
|
||||
if let Ok(pkg) = Package::from_dir(dir).await {
|
||||
@ -75,14 +96,23 @@ impl PackageStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn fetch_listings() -> Result<Vec<rainy::V1Package>> {
|
||||
pub async fn save(&self) -> Result<()> {
|
||||
tokio::fs::write(
|
||||
util::config_dir().join("package-list.json"),
|
||||
serde_json::to_string_pretty(&self.meta_list)?
|
||||
).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn fetch_listings(game: Game) -> Result<Vec<rainy::V1Package>> {
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use futures::{
|
||||
io::{self, BufReader, ErrorKind},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
let response = reqwest::get("https://rainy.patafour.zip/c/ongeki/api/v1/package/").await?;
|
||||
let response = reqwest::get(format!("https://rainy.patafour.zip/c/{game}/api/v1/package/")).await?;
|
||||
|
||||
let reader = response
|
||||
.bytes_stream()
|
||||
@ -100,11 +130,23 @@ impl PackageStore {
|
||||
self.offline
|
||||
}
|
||||
|
||||
pub fn process_fetched_listings(&mut self, listings: Vec<rainy::V1Package>) {
|
||||
pub fn process_fetched_listings(&mut self, listings: Vec<rainy::V1Package>, game: Game) {
|
||||
for listing in listings {
|
||||
// This is None if the package has no versions for whatever reason
|
||||
if let Some(r) = Package::from_rainy(listing) {
|
||||
//log::warn!("D {}", &r.rmt.as_ref().unwrap().dependencies.first().unwrap_or(&"Nothing".to_owned()));
|
||||
let mut meta_entry = self.meta_list.remove(&r.key()).unwrap_or_else(|| {
|
||||
PackageListEntry {
|
||||
// from_rainy() is guaranteed to include rmt
|
||||
version: r.rmt.as_ref().unwrap().version.clone(),
|
||||
status: Status::Unchecked,
|
||||
games: vec![ game ],
|
||||
}
|
||||
});
|
||||
if !meta_entry.games.contains(&game) {
|
||||
meta_entry.games.push(game);
|
||||
}
|
||||
self.meta_list.insert(r.key(), meta_entry);
|
||||
|
||||
match self.store.get_mut(&r.key()) {
|
||||
Some(l) => {
|
||||
l.rmt = r.rmt;
|
||||
@ -226,9 +268,8 @@ impl PackageStore {
|
||||
async fn clean_up_file(path: impl AsRef<Path>, name: &str, force: bool) -> Result<()> {
|
||||
let path = path.as_ref().join(name);
|
||||
if force || path.exists() {
|
||||
tokio::fs::remove_file(path)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Could not delete /{}: {}", name, e))?;
|
||||
tokio::fs::remove_file(path).await
|
||||
.map_err(|e| anyhow!("Could not delete /{}: {}", name, e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -242,6 +283,7 @@ impl PackageStore {
|
||||
Self::clean_up_file(&path, "icon.png", true).await?;
|
||||
Self::clean_up_file(&path, "manifest.json", true).await?;
|
||||
Self::clean_up_file(&path, "README.md", true).await?;
|
||||
Self::clean_up_file(&path, "post_load.ps1", false).await?;
|
||||
|
||||
tokio::fs::remove_dir(path.as_ref())
|
||||
.await
|
||||
|
Reference in New Issue
Block a user