Skip to content

Commit

Permalink
Add back file watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Geometrically committed Jul 18, 2024
1 parent 294ace9 commit 92e7bc0
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 208 deletions.
3 changes: 3 additions & 0 deletions packages/app-lib/migrations/20240711194701_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ CREATE TABLE profiles (
mod_loader TEXT NOT NULL,
mod_loader_version TEXT NULL,

-- array of strings
groups JSONB NOT NULL,

linked_project_id TEXT NULL,
linked_version_id TEXT NULL,
locked INTEGER NULL,
Expand Down
2 changes: 1 addition & 1 deletion packages/app-lib/src/api/pack/install_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ pub async fn set_profile_information(
let mod_loader = mod_loader.unwrap_or(ModLoader::Vanilla);
let loader_version = if mod_loader != ModLoader::Vanilla {
crate::launcher::get_loader_version_from_profile(
&game_version,
game_version,
mod_loader,
loader_version.cloned().as_deref(),
)
Expand Down
5 changes: 2 additions & 3 deletions packages/app-lib/src/api/pack/install_mrpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@ pub async fn remove_all_related_files(
// Iterate over all Modrinth project file paths in the json, and remove them
// (There should be few, but this removes any files the .mrpack intended as Modrinth projects but were unrecognized)
for file in pack.files {
let path: PathBuf = profile::get_full_path(&profile_path)
.await?
.join(file.path.to_string());
let path: PathBuf =
profile::get_full_path(&profile_path).await?.join(file.path);
if path.exists() {
io::remove_file(&path).await?;
}
Expand Down
12 changes: 10 additions & 2 deletions packages/app-lib/src/api/profile/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub async fn profile_create(
game_version,
loader: modloader,
loader_version: loader.map(|x| x.id),
groups: Vec::new(),
linked_data,
created: Utc::now(),
modified: Utc::now(),
Expand Down Expand Up @@ -110,13 +111,20 @@ pub async fn profile_create(
&state.directories.caches_dir(),
&state.io_semaphore,
bytes::Bytes::from(bytes),
&icon,
icon,
)
.await?;
}

emit_profile(&profile.path, ProfilePayloadType::Created).await?;

crate::state::fs_watcher::watch_profile(
&profile.path,
&state.file_watcher,
&state.directories,
)
.await?;

profile.upsert(&state.pool).await?;

if !skip_install_profile.unwrap_or(false) {
Expand All @@ -141,7 +149,7 @@ pub async fn profile_create_from_duplicate(
copy_from: &str,
) -> crate::Result<String> {
// Original profile
let profile = profile::get(&copy_from).await?.ok_or_else(|| {
let profile = profile::get(copy_from).await?.ok_or_else(|| {
ErrorKind::UnmanagedProfileError(copy_from.to_string())
})?;

Expand Down
38 changes: 21 additions & 17 deletions packages/app-lib/src/api/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ pub async fn update_all_projects(
.await?;

let state = State::get().await?;
let keys = profile.get_projects(&state.pool, &state.fetch_semaphore).await?
let keys = profile
.get_projects(&state.pool, &state.fetch_semaphore)
.await?
.into_iter()
.filter(|(_, project)| {
project.update_version_id.is_some()
})
.filter(|(_, project)| project.update_version_id.is_some())
.map(|x| x.0)
.collect::<Vec<_>>();
let len = keys.len();
Expand Down Expand Up @@ -323,7 +323,7 @@ pub async fn update_project(
)
.await?;

if path != project_path.clone() {
if path != project_path {
Profile::remove_project(profile_path, project_path).await?;
}

Expand Down Expand Up @@ -441,8 +441,8 @@ pub async fn export_mrpack(
_name: Option<String>,
) -> crate::Result<()> {
let state = State::get().await?;
let io_semaphore = state.io_semaphore.0.read().await;
let _permit: tokio::sync::SemaphorePermit = io_semaphore.acquire().await?;
let _permit: tokio::sync::SemaphorePermit =
state.io_semaphore.0.acquire().await?;
let profile = get(profile_path).await?.ok_or_else(|| {
crate::ErrorKind::OtherError(format!(
"Tried to export a nonexistent or unloaded profile at path {}!",
Expand Down Expand Up @@ -476,9 +476,9 @@ pub async fn export_mrpack(
create_mrpack_json(&profile, version_id, description).await?;
let included_candidates_set =
HashSet::<_>::from_iter(included_export_candidates.iter());
packfile.files.retain(|f| {
included_candidates_set.contains(&f.path)
});
packfile
.files
.retain(|f| included_candidates_set.contains(&f.path));

// Build vec of all files in the folder
let mut path_list = Vec::new();
Expand All @@ -503,8 +503,7 @@ pub async fn export_mrpack(
let relative_path = pack_get_relative_path(&profile_base_path, &path)?;

if packfile.files.iter().any(|f| f.path == relative_path)
|| !included_candidates_set
.contains(&relative_path)
|| !included_candidates_set.contains(&relative_path)
{
continue;
}
Expand Down Expand Up @@ -580,7 +579,8 @@ pub async fn get_pack_export_candidates(
{
let path: PathBuf = entry.path();

path_list.push(pack_get_relative_path(&profile_base_dir, &path)?);
path_list
.push(pack_get_relative_path(&profile_base_dir, &path)?);
}
} else {
// One layer of files/folders if its a file
Expand All @@ -590,8 +590,12 @@ pub async fn get_pack_export_candidates(
Ok(path_list)
}

fn pack_get_relative_path(profile_path: &PathBuf, path: &PathBuf) -> crate::Result<String> {
Ok(path.strip_prefix(profile_path)
fn pack_get_relative_path(
profile_path: &PathBuf,
path: &PathBuf,
) -> crate::Result<String> {
Ok(path
.strip_prefix(profile_path)
.map_err(|_| {
crate::ErrorKind::FSError(format!(
"Path {path:?} does not correspond to a profile",
Expand Down Expand Up @@ -700,8 +704,8 @@ pub async fn run_credentials(
}

let mc_process = crate::launcher::launch_minecraft(
&*java_args,
&*env_args,
&java_args,
&env_args,
&mc_set_options,
&wrapper,
&memory,
Expand Down
12 changes: 0 additions & 12 deletions packages/app-lib/src/api/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ pub async fn set(settings: Settings) -> crate::Result<()> {
let state = State::get().await?;
let old_settings = Settings::get(&state.pool).await?;

if settings.max_concurrent_writes != old_settings.max_concurrent_writes {
let mut io_semaphore = state.io_semaphore.0.write().await;
*io_semaphore =
tokio::sync::Semaphore::new(settings.max_concurrent_writes);
}
if settings.max_concurrent_downloads
!= old_settings.max_concurrent_downloads
{
let mut fetch_semaphore = state.fetch_semaphore.0.write().await;
*fetch_semaphore =
tokio::sync::Semaphore::new(settings.max_concurrent_downloads);
}
if settings.discord_rpc != old_settings.discord_rpc {
state.discord_rpc.clear_to_default(true).await?;
}
Expand Down
1 change: 0 additions & 1 deletion packages/app-lib/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ pub struct ProfilePayload {
#[serde(rename_all = "snake_case")]
pub enum ProfilePayloadType {
Created,
Added, // also triggered when Created
Synced,
Edited,
Removed,
Expand Down
24 changes: 11 additions & 13 deletions packages/app-lib/src/state/cache.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use crate::config::{META_URL, MODRINTH_API_URL, MODRINTH_API_URL_V3};
use crate::state::ProjectType;
use crate::util::fetch::{fetch_json, FetchSemaphore};
use chrono::{DateTime, Utc};
use dashmap::{DashMap, DashSet};
use dashmap::DashSet;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Display;
use std::hash::Hash;
use std::path::PathBuf;
use std::path::{Path, PathBuf};

// 1 day
const DEFAULT_ID: &'static str = "0";
const DEFAULT_ID: &str = "0";

#[derive(Serialize, Deserialize, Copy, Clone, Debug)]
#[serde(rename_all = "snake_case")]
Expand Down Expand Up @@ -611,7 +610,7 @@ impl CachedEntry {
.await?;

if !values.is_empty() {
Self::upsert_many(&*values, &mut *exec).await?;
Self::upsert_many(&values, &mut *exec).await?;

return_vals.append(&mut values);
}
Expand All @@ -620,7 +619,7 @@ impl CachedEntry {
if !expired_keys.is_empty()
&& cache_behaviour == CacheBehaviour::StaleWhileRevalidate
{
let _ = tokio::task::spawn(async move {
tokio::task::spawn(async move {
// TODO: if possible- find a way to do this without invoking state get
let state = crate::state::State::get().await?;

Expand All @@ -632,7 +631,7 @@ impl CachedEntry {
.await?;

if !values.is_empty() {
Self::upsert_many(&*values, &state.pool).await?;
Self::upsert_many(&values, &state.pool).await?;
}

Ok::<(), crate::Error>(())
Expand All @@ -644,7 +643,7 @@ impl CachedEntry {

async fn fetch_many(
type_: CacheValueType,
mut keys: DashSet<impl Display + Eq + PartialEq + Hash + Serialize>,
keys: DashSet<impl Display + Eq + Hash + Serialize>,
fetch_semaphore: &FetchSemaphore,
) -> crate::Result<Vec<Self>> {
macro_rules! fetch_original_values {
Expand Down Expand Up @@ -745,13 +744,13 @@ impl CachedEntry {
CacheValueType::File => {
let mut versions = fetch_json::<HashMap<String, Version>>(
Method::POST,
&*format!("{}version_files", MODRINTH_API_URL),
&format!("{}version_files", MODRINTH_API_URL),
None,
Some(serde_json::json!({
"algorithm": "sha1",
"hashes": &keys,
})),
&fetch_semaphore,
fetch_semaphore,
)
.await?;

Expand Down Expand Up @@ -877,7 +876,7 @@ impl CachedEntry {
let profiles_dir = state.directories.profiles_dir().await;

async fn hash_file(
profiles_dir: &PathBuf,
profiles_dir: &Path,
path: String,
) -> crate::Result<CachedEntry> {
let path =
Expand Down Expand Up @@ -930,8 +929,7 @@ impl CachedEntry {
.collect::<Vec<_>>()
.await
.into_iter()
.map(|x| x.ok())
.flatten()
.filter_map(|x| x.ok())
.collect();

results
Expand Down
23 changes: 23 additions & 0 deletions packages/app-lib/src/state/db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::state::DirectoryInfo;
use sqlx::migrate::MigrateDatabase;
use sqlx::sqlite::SqlitePoolOptions;
use sqlx::{Connection, Pool, Sqlite, SqliteConnection};

pub(crate) async fn connect() -> crate::Result<Pool<Sqlite>> {
let uri =
format!("sqlite:{}", DirectoryInfo::get_database_file()?.display());

if !Sqlite::database_exists(&uri).await? {
Sqlite::create_database(&uri).await?;
}

let mut conn: SqliteConnection = SqliteConnection::connect(&uri).await?;
sqlx::migrate!().run(&mut conn).await?;

let pool = SqlitePoolOptions::new()
.max_connections(100)
.connect(&uri)
.await?;

Ok(pool)
}
Empty file.
Loading

0 comments on commit 92e7bc0

Please sign in to comment.