feat(settings): ability to add more download dirs

This commit is contained in:
DecDuck
2024-11-24 21:04:56 +11:00
parent b065e101e6
commit 384f7a5be9
13 changed files with 291 additions and 80 deletions

View File

@ -6,7 +6,7 @@ use std::{
};
use directories::BaseDirs;
use log::debug;
use log::{debug, info};
use rustbreak::{deser::Bincode, PathDatabase};
use rustix::path::Arg;
use serde::{Deserialize, Serialize};
@ -68,23 +68,23 @@ impl DatabaseImpls for DatabaseInterface {
debug!("Creating games directory");
create_dir_all(games_base_dir.clone()).unwrap();
let default = Database {
auth: None,
base_url: "".to_string(),
games: DatabaseGames {
install_dirs: vec![games_base_dir.to_str().unwrap().to_string()],
games_statuses: HashMap::new(),
},
};
#[allow(clippy::let_and_return)]
let exists = fs::exists(db_path.clone()).unwrap();
let db = match exists {
true => PathDatabase::load_from_path(db_path).expect("Database loading failed"),
false => {
let default = Database {
auth: None,
base_url: "".to_string(),
games: DatabaseGames {
install_dirs: vec![games_base_dir.to_str().unwrap().to_string()],
games_statuses: HashMap::new(),
},
};
debug!("Creating database at path {}", db_path.as_str().unwrap());
PathDatabase::create_at_path(db_path, default).expect("Database could not be created")
},
PathDatabase::create_at_path(db_path, default)
.expect("Database could not be created")
}
};
db
@ -114,8 +114,8 @@ pub fn add_new_download_dir(new_dir: String) -> Result<(), String> {
let dir_contents = new_dir_path
.read_dir()
.map_err(|e| format!("Unable to check directory contents: {}", e))?;
if dir_contents.count() == 0 {
return Err("Path is not empty".to_string());
if dir_contents.count() != 0 {
return Err("Directory is not empty".to_string());
}
} else {
create_dir_all(new_dir_path)
@ -126,6 +126,18 @@ pub fn add_new_download_dir(new_dir: String) -> Result<(), String> {
let mut lock = DB.borrow_data_mut().unwrap();
lock.games.install_dirs.push(new_dir);
drop(lock);
DB.save().unwrap();
Ok(())
}
// Will, in future, return disk/remaining size
// Just returns the directories that have been set up
#[tauri::command]
pub fn fetch_download_dir_stats() -> Result<Vec<String>, String> {
let lock = DB.borrow_data().unwrap();
let directories = lock.games.install_dirs.clone();
drop(lock);
Ok(directories)
}

View File

@ -2,43 +2,39 @@ use std::sync::Mutex;
use log::info;
use crate::{AppError, AppState};
use crate::AppState;
#[tauri::command]
pub fn download_game(
game_id: String,
game_version: String,
state: tauri::State<'_, Mutex<AppState>>,
) -> Result<(), AppError> {
) -> Result<(), String> {
state
.lock()
.unwrap()
.download_manager
.queue_game(game_id, game_version, 0)
.map_err(|_| AppError::Signal)
.map_err(|_| "An error occurred while communicating with the download manager.".to_string())
}
#[tauri::command]
pub fn get_current_game_download_progress(
state: tauri::State<'_, Mutex<AppState>>,
) -> Result<f64, AppError> {
) -> Result<f64, String> {
match state
.lock()
.unwrap()
.download_manager
.get_current_game_download_progress()
{
Some(progress) => Ok(progress),
None => Err(AppError::DoesNotExist),
}
{
Some(progress) => Ok(progress),
None => Err("Game does not exist".to_string()),
}
}
#[tauri::command]
pub fn stop_game_download(
state: tauri::State<'_, Mutex<AppState>>,
game_id: String
) {
pub fn stop_game_download(state: tauri::State<'_, Mutex<AppState>>, game_id: String) {
info!("Cancelling game download {}", game_id);
state
.lock()
@ -47,12 +43,7 @@ pub fn stop_game_download(
.cancel_download(game_id);
}
#[tauri::command]
pub fn get_current_write_speed(
state: tauri::State<'_, Mutex<AppState>>,
) {
}
pub fn get_current_write_speed(state: tauri::State<'_, Mutex<AppState>>) {}
/*
fn use_download_agent(

View File

@ -10,7 +10,7 @@ mod tests;
use crate::db::DatabaseImpls;
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
use db::{add_new_download_dir, DatabaseInterface, DATA_ROOT_DIR};
use db::{add_new_download_dir, fetch_download_dir_stats, DatabaseInterface, DATA_ROOT_DIR};
use downloads::download_commands::*;
use downloads::download_manager::DownloadManagerBuilder;
use downloads::download_manager_interface::DownloadManager;
@ -36,12 +36,6 @@ pub enum AppStatus {
SignedInNeedsReauth,
ServerUnavailable,
}
#[derive(Debug, Serialize)]
pub enum AppError {
DoesNotExist,
Signal,
RemoteAccess(String)
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -65,7 +59,7 @@ pub struct AppState {
}
#[tauri::command]
fn fetch_state(state: tauri::State<'_, Mutex<AppState>>) -> Result<AppState, AppError> {
fn fetch_state(state: tauri::State<'_, Mutex<AppState>>) -> Result<AppState, String> {
let guard = state.lock().unwrap();
let cloned_state = guard.clone();
drop(guard);
@ -133,12 +127,14 @@ pub fn run() {
fetch_library,
fetch_game,
add_new_download_dir,
fetch_download_dir_stats,
// Downloads
download_game,
get_current_game_download_progress,
stop_game_download
])
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init())
.setup(|app| {
#[cfg(any(target_os = "linux", all(debug_assertions, windows)))]
{

View File

@ -1,5 +1,6 @@
use std::sync::Mutex;
use log::info;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tauri::{AppHandle, Manager};
@ -7,7 +8,6 @@ use tauri::{AppHandle, Manager};
use crate::db::DatabaseGameStatus;
use crate::db::DatabaseImpls;
use crate::remote::RemoteAccessError;
use crate::AppError;
use crate::{auth::generate_authorization_header, AppState, DB};
#[derive(serde::Serialize)]
@ -19,7 +19,7 @@ struct FetchGameStruct {
#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Game {
game_id: String,
id: String,
m_name: String,
m_short_description: String,
m_description: String,
@ -55,12 +55,12 @@ fn fetch_library_logic(app: AppHandle) -> Result<String, RemoteAccessError> {
let mut db_handle = DB.borrow_data_mut().unwrap();
for game in games.iter() {
handle.games.insert(game.game_id.clone(), game.clone());
if !db_handle.games.games_statuses.contains_key(&game.game_id) {
handle.games.insert(game.id.clone(), game.clone());
if !db_handle.games.games_statuses.contains_key(&game.id) {
db_handle
.games
.games_statuses
.insert(game.game_id.clone(), DatabaseGameStatus::Remote);
.insert(game.id.clone(), DatabaseGameStatus::Remote);
}
}
@ -70,9 +70,8 @@ fn fetch_library_logic(app: AppHandle) -> Result<String, RemoteAccessError> {
}
#[tauri::command]
pub fn fetch_library(app: AppHandle) -> Result<String, AppError> {
fetch_library_logic(app)
.map_err(|e| AppError::RemoteAccess(e.to_string()))
pub fn fetch_library(app: AppHandle) -> Result<String, String> {
fetch_library_logic(app).map_err(|e| e.to_string())
}
fn fetch_game_logic(id: String, app: tauri::AppHandle) -> Result<String, RemoteAccessError> {
@ -88,7 +87,7 @@ fn fetch_game_logic(id: String, app: tauri::AppHandle) -> Result<String, RemoteA
status: db_handle
.games
.games_statuses
.get(&game.game_id)
.get(&game.id)
.unwrap()
.clone(),
};

View File

@ -8,7 +8,7 @@ use log::{info, warn};
use serde::{Deserialize, Serialize};
use url::{ParseError, Url};
use crate::{AppError, AppState, AppStatus, DB};
use crate::{AppState, AppStatus, DB};
#[derive(Debug, Clone)]
pub enum RemoteAccessError {
@ -31,7 +31,6 @@ impl Display for RemoteAccessError {
write!(f, "{}", parse_error)
}
RemoteAccessError::InvalidCodeError(error) => write!(f, "HTTP {}", error),
RemoteAccessError::ParsingError(parse_error) => todo!(),
RemoteAccessError::InvalidEndpoint => write!(f, "Invalid drop endpoint"),
RemoteAccessError::HandshakeFailed => write!(f, "Failed to complete handshake"),
RemoteAccessError::GameNotFound => write!(f, "Could not find game on server"),