diff --git a/gdriver-backend/Cargo.toml b/gdriver-backend/Cargo.toml index 8c0ac8b..5329494 100644 --- a/gdriver-backend/Cargo.toml +++ b/gdriver-backend/Cargo.toml @@ -6,13 +6,16 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -fuser={ version = "0.14", default_features = true, features = ["serializable"] } tracing.workspace = true tokio.workspace = true serde.workspace = true tarpc.workspace = true futures.workspace = true chrono.workspace = true +lazy_static = "1.4.0" +thiserror = "1.0.56" +google-drive3 = "5.0.4" +const_format = "0.2" [dependencies.gdriver-common] -path = "../gdriver-common/" +path = "../gdriver-common" diff --git a/gdriver-backend/src/main.rs b/gdriver-backend/src/main.rs index d20fe81..fb7b352 100644 --- a/gdriver-backend/src/main.rs +++ b/gdriver-backend/src/main.rs @@ -1,3 +1,4 @@ +use crate::prelude::*; use futures::{future, prelude::*}; use std::net::SocketAddr; use tarpc::{ @@ -5,10 +6,9 @@ use tarpc::{ server::{self, incoming::Incoming, Channel}, tokio_serde::formats::Json, }; -mod prelude; -use crate::prelude::*; -pub(crate) use gdriver_common::prelude::*; + mod drive; +mod prelude; mod sample; mod service; @@ -17,6 +17,7 @@ pub(crate) async fn spawn(fut: impl Future + Send + 'static) { } #[tokio::main] async fn main() -> Result<()> { + gdriver_common::tracing_setup::init_tracing(); // sample::main().await?; service::start().await?; Ok(()) diff --git a/gdriver-backend/src/service.rs b/gdriver-backend/src/service.rs index a400c5c..b83380e 100644 --- a/gdriver-backend/src/service.rs +++ b/gdriver-backend/src/service.rs @@ -1,26 +1,24 @@ +use super::*; +use crate::drive::Drive; use chrono::Duration; use gdriver_common::{ drive_structure::drive_id::{DriveId, ROOT_ID}, - ipc::gdriver_service::{*, errors::*}, - + ipc::gdriver_service::{errors::*, *}, }; -use std::{path::PathBuf, sync::Arc, thread}; use std::ffi::OsString; +use std::{path::PathBuf, sync::Arc, thread}; use tarpc::context::Context; use tokio::sync::Mutex; -use crate::drive::Drive; - -use super::*; #[derive(Clone)] struct GdriverServer { socket_address: SocketAddr, drive: Arc>, } impl GDriverService for GdriverServer { - async fn get_settings(self, context: Context) -> StdResult { - todo!() - } + // async fn get_settings(self, context: Context) -> StdResult { + // todo!() + // } async fn get_file_by_name(self, context: Context, name: OsString, parent: DriveId) -> StdResult { todo!() @@ -62,8 +60,17 @@ impl GDriverService for GdriverServer { self, context: Context, id: DriveId, - ) -> StdResult<(), GetFileListError> { - todo!() + ) -> StdResult, GetFileListError> { + Err(GetFileListError::Other) + } + + async fn list_files_in_directory_with_offset( + self, + context: Context, + id: DriveId, + offset: u64, + ) -> StdResult, GetFileListError> { + Err(GetFileListError::Other) } async fn mark_file_as_deleted( @@ -99,11 +106,21 @@ impl GDriverService for GdriverServer { todo!() } - async fn update_changes( - self, - context: Context, - ) -> StdResult<(), UpdateChangesError> { - todo!() + async fn update_changes(self, context: Context) -> StdResult<(), UpdateChangesError> { + let drive = self.drive.try_lock(); + match drive { + Ok(mut drive) => { + drive.update().await.map_err(|e| { + info!("Error while updating: {e}"); + dbg!(e); + UpdateChangesError::Remote + })?; + } + Err(_) => { + return Err(UpdateChangesError::Running); + } + } + Ok(()) } async fn do_something2( @@ -111,32 +128,32 @@ impl GDriverService for GdriverServer { _: Context, req: BackendActionRequest, ) -> std::result::Result { - println!("You are connected from {}", self.socket_address); + info!("You are connected from {}", self.socket_address); match req { BackendActionRequest::ShutdownGracefully => { - println!("Shutdown request received, but I dont want to."); + info!("Shutdown request received, but I dont want to."); Err(BackendActionError::CouldNotComplete) //Ok(String::from("OK. Shutting down")) } BackendActionRequest::UpdateChanges => { - println!("UpdateChanges request received"); + info!("UpdateChanges request received"); let drive = &self.drive; print_sample_tracking_state(drive).await; Ok(String::from("OK")) } BackendActionRequest::Ping => { - println!("Ping request received"); + info!("Ping request received"); Ok(String::from("Pong")) } BackendActionRequest::RunLong => { - println!("RunLong request received"); + info!("RunLong request received"); long_running_task(&self.drive).await; Ok(String::from("OK")) } BackendActionRequest::StartLong => { - println!("StartLong request received"); + info!("StartLong request received"); tokio::spawn(async move { long_running_task(&self.drive).await }); Ok(String::from("OK")) } @@ -153,9 +170,9 @@ async fn print_sample_tracking_state(drive: &Arc>) { dbg!(state); } pub async fn start() -> Result<()> { - println!("Hello, world!"); + info!("Hello, world!"); let config = &CONFIGURATION; - println!("Config: {:?}", **config); + info!("Config: {:?}", **config); let drive = Drive::new(); let m = Arc::new(Mutex::new(drive)); @@ -164,7 +181,7 @@ pub async fn start() -> Result<()> { let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; listener.config_mut().max_frame_length(usize::MAX); - println!("Listening"); + info!("Listening"); listener // Ignore accept errors. .filter_map(|r| future::ready(r.ok())) diff --git a/gdriver-client/src/filesystem/attributes.rs b/gdriver-client/src/filesystem/attributes.rs index 4bc6ae7..15acedb 100644 --- a/gdriver-client/src/filesystem/attributes.rs +++ b/gdriver-client/src/filesystem/attributes.rs @@ -9,7 +9,7 @@ use tarpc::serde::{Deserialize, Serialize}; type Inode = u64; const BLOCK_SIZE: u64 = 512; -trait ConvertFileType { +pub trait ConvertFileType { fn from_ft(kind: FileType) -> Self; fn into_ft(self) -> FileType; } diff --git a/gdriver-client/src/service.rs b/gdriver-client/src/service.rs index 5fb2081..59dbae3 100644 --- a/gdriver-client/src/service.rs +++ b/gdriver-client/src/service.rs @@ -1,4 +1,3 @@ - use std::time; use gdriver_common::ipc::gdriver_service::{BackendActionRequest, GDriverServiceClient}; @@ -14,14 +13,14 @@ pub async fn start() -> Result<()> { Ok(()) } -async fn ping(client: &GDriverServiceClient) -> Result<()>{ +async fn ping(client: &GDriverServiceClient) -> Result<()> { let hello = client .do_something2(tarpc::context::current(), BackendActionRequest::Ping) .await; match hello { - Ok(hello) => println!("Yay: {:?}", hello), + Ok(hello) => info!("Yay: {:?}", hello), Err(e) => { - println!(":( {:?}", (e)); + error!(":( {:?}", (e)); dbg!(&e); return Err(Box::new(e)); } @@ -40,8 +39,8 @@ async fn run_long_stuff_test(client: &GDriverServiceClient) { .as_secs(); match hello { - Ok(hello) => println!("Run Long returned after {} seconds: {:?}", seconds, hello), - Err(e) => println!(":( {:?}", (e)), + Ok(hello) => info!("Run Long returned after {} seconds: {:?}", seconds, hello), + Err(e) => error!(":( {:?}", (e)), } let start = time::SystemTime::now(); let hello = client @@ -52,8 +51,8 @@ async fn run_long_stuff_test(client: &GDriverServiceClient) { .as_secs(); match hello { - Ok(hello) => println!("Start Long returned after {} seconds: {:?}", seconds, hello), - Err(e) => println!(":( {:?}", (e)), + Ok(hello) => info!("Start Long returned after {} seconds: {:?}", seconds, hello), + Err(e) => info!(":( {:?}", (e)), } } @@ -62,7 +61,7 @@ pub async fn create_client(ip: IpAddr, port: u16) -> Result From for DriveId diff --git a/gdriver-common/src/drive_structure/meta.rs b/gdriver-common/src/drive_structure/meta.rs index 7ffe012..e3a40b8 100644 --- a/gdriver-common/src/drive_structure/meta.rs +++ b/gdriver-common/src/drive_structure/meta.rs @@ -3,8 +3,10 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fs::File; use std::path::Path; + pub type TIMESTAMP = (i64, u32); -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] + +#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Serialize, Deserialize, Clone, Hash)] pub struct Metadata { pub state: FileState, pub size: u64, @@ -26,14 +28,14 @@ pub fn write_metadata_file(path: &Path, metadata: &Metadata) -> Result<()> { let reader = File::open(path)?; Ok(serde_json::to_writer(reader, metadata)?) } -#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Debug)] +#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Serialize, Deserialize, Clone, Hash)] pub enum FileState { Downloaded, Cached, MetadataOnly, } -#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Debug)] +#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Serialize, Deserialize, Clone, Hash)] pub enum FileKind { File, Directory, diff --git a/gdriver-common/src/ipc.rs b/gdriver-common/src/ipc.rs index 90e5f6d..d4cce74 100644 --- a/gdriver-common/src/ipc.rs +++ b/gdriver-common/src/ipc.rs @@ -1,3 +1,4 @@ use serde::{Deserialize, Serialize}; pub mod gdriver_service; +pub mod gdriver_settings; pub mod sample; diff --git a/gdriver-common/src/ipc/gdriver_service.rs b/gdriver-common/src/ipc/gdriver_service.rs index 6d65e2c..a118165 100644 --- a/gdriver-common/src/ipc/gdriver_service.rs +++ b/gdriver-common/src/ipc/gdriver_service.rs @@ -1,14 +1,15 @@ -use crate::prelude::*; -use std::ffi::OsString; -use std::path::{Path, PathBuf}; - -use serde::{Deserialize, Serialize}; - use crate::drive_structure::drive_id::DriveId; +use crate::drive_structure::meta::FileKind; +use crate::ipc::gdriver_settings::GDriverSettings; +use crate::prelude::*; +use errors::*; +use lazy_static::lazy_static; +use serde::{Deserialize, Serialize}; +use std::ffi::OsString; +use std::path::PathBuf; #[tarpc::service] pub trait GDriverService { - async fn get_settings() -> StdResult; async fn get_file_by_name( name: OsString, parent: DriveId, @@ -17,7 +18,13 @@ pub trait GDriverService { async fn write_local_change(id: DriveId) -> StdResult<(), WriteLocalChangeError>; async fn get_metadata_for_file(id: DriveId) -> StdResult<(), GetMetadataError>; async fn download_content_for_file(id: DriveId) -> StdResult<(), GetContentError>; - async fn list_files_in_directory(id: DriveId) -> StdResult<(), GetFileListError>; + async fn list_files_in_directory( + id: DriveId, + ) -> StdResult, GetFileListError>; + async fn list_files_in_directory_with_offset( + id: DriveId, + offset: u64, + ) -> StdResult, GetFileListError>; async fn mark_file_as_deleted(id: DriveId) -> StdResult<(), MarkFileAsDeletedError>; async fn mark_file_for_keeping_local( id: DriveId, @@ -39,49 +46,10 @@ pub enum BackendActionRequest { StartLong, } -#[derive(Debug, Serialize, Deserialize)] -pub struct GDriverSettings { - metadata_path: PathBuf, - cache_path: PathBuf, - downloaded_path: PathBuf, -} -impl GDriverSettings { - pub fn metadata_path(&self) -> &Path { - &self.metadata_path - } - pub fn cache_path(&self) -> &Path { - &self.cache_path - } - pub fn downloaded_path(&self) -> &Path { - &self.downloaded_path - } - - pub fn get_metadata_file_path(&self, id: &DriveId) -> PathBuf { - self.metadata_path.join(id.as_ref()).with_extension("meta") - } - pub fn get_downloaded_file_path(&self, id: &DriveId) -> PathBuf { - self.downloaded_path.join(id.as_ref()) - } - pub fn get_cache_file_path(&self, id: &DriveId) -> PathBuf { - self.cache_path.join(id.as_ref()) - } +lazy_static! { + pub static ref SETTINGS: GDriverSettings = GDriverSettings::default(); } -impl Default for GDriverSettings { - fn default() -> Self { - let p = directories::ProjectDirs::from("com", "OMGeeky", "gdriver2").expect( - "Getting the Project dir needs to work (on all platforms) otherwise nothing will work as expected. \ - This is where all files will be stored, so there is not much use for this app without it.", - ); - Self { - metadata_path: p.data_dir().join("meta"), - downloaded_path: p.data_dir().join("downloads"), - cache_path: p.cache_dir().to_path_buf(), - } - } -} - -use errors::*; pub mod errors { use super::*; #[derive(Debug, Serialize, Deserialize, thiserror::Error)] @@ -125,10 +93,26 @@ pub mod errors { } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum GetFileByPathError {} + pub enum GetFileByPathError { + #[error("Other")] + Other, + #[error("The Specified name is invalid")] + InvalidName, + #[error("Could not find name specified")] + NotFound, + #[error("Could not update drive info")] + Update(String), + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum UpdateChangesError {} + pub enum UpdateChangesError { + #[error("Other")] + Other, + #[error("Remote error")] + Remote, + #[error("Already running")] + Running, + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] pub enum WriteLocalChangeError { @@ -143,22 +127,47 @@ pub mod errors { } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum GetMetadataError {} + pub enum GetMetadataError { + #[error("Other")] + Other, + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum GetContentError {} + pub enum GetContentError { + #[error("Other")] + Other, + } //#[derive(Debug, Serialize, Deserialize)] //pub enum GetContentError {} #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum GetFileListError {} + pub enum GetFileListError { + #[error("Other")] + Other, + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum MarkFileAsDeletedError {} + pub enum MarkFileAsDeletedError { + #[error("Other")] + Other, + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum MarkFileForKeepingLocalError {} + pub enum MarkFileForKeepingLocalError { + #[error("Other")] + Other, + } #[derive(Debug, Serialize, Deserialize, thiserror::Error)] - pub enum UnmarkFileForKeepingLocalError {} + pub enum UnmarkFileForKeepingLocalError { + #[error("Other")] + Other, + } +} + +#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Serialize, Deserialize, Clone, Hash)] +pub struct ReadDirResult { + pub id: DriveId, + pub kind: FileKind, + pub name: String, } diff --git a/gdriver-common/src/ipc/gdriver_settings.rs b/gdriver-common/src/ipc/gdriver_settings.rs new file mode 100644 index 0000000..1be4532 --- /dev/null +++ b/gdriver-common/src/ipc/gdriver_settings.rs @@ -0,0 +1,53 @@ +use crate::prelude::DriveId; +use crate::project_dirs::PROJECT_DIRS; +use serde::{Deserialize, Serialize}; +use std::path::{Path, PathBuf}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct GDriverSettings { + metadata_path: PathBuf, + cache_path: PathBuf, + downloaded_path: PathBuf, + data_path: PathBuf, +} + +impl GDriverSettings { + pub fn metadata_path(&self) -> &Path { + &self.metadata_path + } + pub fn cache_path(&self) -> &Path { + &self.cache_path + } + pub fn downloaded_path(&self) -> &Path { + &self.downloaded_path + } + pub fn data_path(&self) -> &Path { + &self.data_path + } + + pub fn get_changes_file_path(&self) -> PathBuf { + self.data_path.join("changes.txt") + } + + pub fn get_metadata_file_path(&self, id: &DriveId) -> PathBuf { + self.metadata_path.join(id.as_ref()).with_extension("meta") + } + pub fn get_downloaded_file_path(&self, id: &DriveId) -> PathBuf { + self.downloaded_path.join(id.as_ref()) + } + pub fn get_cache_file_path(&self, id: &DriveId) -> PathBuf { + self.cache_path.join(id.as_ref()) + } +} + +impl Default for GDriverSettings { + fn default() -> Self { + let p = &PROJECT_DIRS; + Self { + metadata_path: p.data_dir().join("meta"), + downloaded_path: p.data_dir().join("downloads"), + cache_path: p.cache_dir().to_path_buf(), + data_path: p.data_dir().join("data"), + } + } +} diff --git a/gdriver-common/src/lib.rs b/gdriver-common/src/lib.rs index b116f20..74c758a 100644 --- a/gdriver-common/src/lib.rs +++ b/gdriver-common/src/lib.rs @@ -5,4 +5,5 @@ pub mod prelude; pub mod config; pub mod drive_structure; pub mod ipc; +pub mod project_dirs; pub mod tracing_setup; diff --git a/gdriver-common/src/project_dirs.rs b/gdriver-common/src/project_dirs.rs new file mode 100644 index 0000000..a90a01f --- /dev/null +++ b/gdriver-common/src/project_dirs.rs @@ -0,0 +1,7 @@ +use lazy_static::lazy_static; +lazy_static!( + pub static ref PROJECT_DIRS: directories::ProjectDirs = directories::ProjectDirs::from("com", "OMGeeky", "gdriver2").expect( + "Getting the Project dir needs to work (on all platforms) otherwise nothing will work as expected. \ + This is where all files will be stored, so there is not much use for this app without it.", + ); +);