From 0ec1bfc0c752aa35620a35a51f6fe270437527b4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 29 Sep 2021 05:59:04 -0700 Subject: [PATCH] spacedrive born --- .vscode/settings.json | 2 +- package.json | 2 +- src-tauri/Cargo.lock | 55 ++++++++++++----- src-tauri/Cargo.toml | 7 ++- src-tauri/default.db3 | 0 src-tauri/src/app/config.rs | 2 +- src-tauri/src/commands.rs | 11 ++++ src-tauri/src/filesystem/checksum.rs | 8 +-- src-tauri/src/filesystem/directory.rs | 20 ++++++ src-tauri/src/filesystem/file.rs | 89 ++++++++++++++++----------- src-tauri/src/filesystem/mod.rs | 1 + src-tauri/src/main.rs | 23 ++----- src-tauri/src/util/time.rs | 10 ++- src-tauri/tauri.conf.json | 6 +- src/App.tsx | 10 ++- src/index.html | 2 +- 16 files changed, 157 insertions(+), 91 deletions(-) delete mode 100644 src-tauri/default.db3 create mode 100644 src-tauri/src/commands.rs create mode 100644 src-tauri/src/filesystem/directory.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index a5f0ea70c..458b8e10a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "cSpell.words": [ "ipfs", - "nexusapp", + "spacedriveapp", "tailwindcss" ] } \ No newline at end of file diff --git a/package.json b/package.json index 5848a62b2..78b4c3c88 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "nexus-client", + "name": "spacedrive-client", "version": "1.0.0", "main": "index.js", "license": "MIT", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 24eaf351e..e30b067e6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -492,6 +492,20 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crossbeam" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -526,6 +540,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.5" @@ -1662,21 +1686,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nexus" -version = "0.1.0" -dependencies = [ - "chrono", - "data-encoding", - "rebind", - "ring", - "rusqlite", - "serde", - "serde_json", - "tauri", - "tauri-build", -] - [[package]] name = "nix" version = "0.17.0" @@ -2756,6 +2765,22 @@ dependencies = [ "pango", ] +[[package]] +name = "spacedrive" +version = "0.1.0" +dependencies = [ + "chrono", + "crossbeam", + "data-encoding", + "rebind", + "ring", + "rusqlite", + "serde", + "serde_json", + "tauri", + "tauri-build", +] + [[package]] name = "spin" version = "0.5.2" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b57d70adb..287fa1c41 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "nexus" +name = "spacedrive" version = "0.1.0" description = "The next gen private virtual filesystem." authors = ["you"] license = "" repository = "" -default-run = "nexus" +default-run = "spacedrive" edition = "2018" build = "src/build.rs" @@ -22,7 +22,8 @@ rebind = "0.2.1" data-encoding = "2.3.2" ring = "0.17.0-alpha.10" rusqlite = "0.25.3" -chrono = { version = "0.4.0", features = ["serde"]} +chrono = { version = "0.4.0", features = ["serde"] } +crossbeam = "0.8.1" [features] default = [ "custom-protocol" ] diff --git a/src-tauri/default.db3 b/src-tauri/default.db3 deleted file mode 100644 index e69de29bb..000000000 diff --git a/src-tauri/src/app/config.rs b/src-tauri/src/app/config.rs index 7621bca87..1aa6fca48 100644 --- a/src-tauri/src/app/config.rs +++ b/src-tauri/src/app/config.rs @@ -8,7 +8,7 @@ pub struct AppConfig { // returns the app config struct with complete values pub fn get_config() -> AppConfig { - let app_name = "Nexus"; + let app_name = "spacedrive"; let data_dir = path::data_dir() .unwrap_or(std::path::PathBuf::from("./")) .join(app_name); diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs new file mode 100644 index 000000000..8d006e679 --- /dev/null +++ b/src-tauri/src/commands.rs @@ -0,0 +1,11 @@ +use crate::filesystem::file; +use crate::filesystem::file::File; +use tauri::InvokeError; + +#[tauri::command(async)] +pub async fn read_file_command(path: &str) -> Result { + let file = file::read_file(path) + .await + .map_err(|error| InvokeError::from(format!("Failed to read file: {}", error)))?; + Ok(file) +} diff --git a/src-tauri/src/filesystem/checksum.rs b/src-tauri/src/filesystem/checksum.rs index 04fd9037e..ce2250109 100644 --- a/src-tauri/src/filesystem/checksum.rs +++ b/src-tauri/src/filesystem/checksum.rs @@ -7,7 +7,6 @@ use std::io::{BufReader, Read}; fn sha256_digest(mut reader: R) -> io::Result { let mut context = Context::new(&SHA256); let mut buffer = [0; 1024]; - loop { let count = reader.read(&mut buffer)?; if count == 0 { @@ -15,13 +14,14 @@ fn sha256_digest(mut reader: R) -> io::Result { } context.update(&buffer[..count]); } - Ok(context.finish()) } -pub fn create_hash(path: &str) -> io::Result { +pub async fn create_hash(path: &str) -> io::Result { let input = File::open(path)?; let reader = BufReader::new(input); let digest = sha256_digest(reader)?; - Ok(HEXUPPER.encode(digest.as_ref())) + let hash = HEXUPPER.encode(digest.as_ref()); + println!("hashing complete {}", hash); + Ok(hash) } diff --git a/src-tauri/src/filesystem/directory.rs b/src-tauri/src/filesystem/directory.rs new file mode 100644 index 000000000..836330fc6 --- /dev/null +++ b/src-tauri/src/filesystem/directory.rs @@ -0,0 +1,20 @@ +use chrono::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Directory { + // identity + pub id: Option, + pub name: String, + // calculations + pub calculated_size_in_bytes: u64, + pub calculated_file_count: u32, + // ownership + pub user_id: Option, + pub storage_device_id: Option, + pub parent_directory_id: Option, + // date + pub date_created: DateTime, + pub date_modified: DateTime, + pub date_indexed: DateTime, +} diff --git a/src-tauri/src/filesystem/file.rs b/src-tauri/src/filesystem/file.rs index 0ebe2e34d..a24f69e15 100644 --- a/src-tauri/src/filesystem/file.rs +++ b/src-tauri/src/filesystem/file.rs @@ -1,8 +1,12 @@ use crate::crypto; use chrono::prelude::*; +use crossbeam::thread; use serde::{Deserialize, Serialize}; +use std::ffi::OsStr; use std::fs; +use std::io; use std::path; +use std::time::Instant; use crate::filesystem::checksum; use crate::util::time; @@ -11,7 +15,7 @@ use crate::util::time; pub struct File { // identity pub id: Option, - pub checksum: String, + pub checksum: Option, pub uri: String, // metadata pub name: String, @@ -30,48 +34,50 @@ pub struct File { pub date_indexed: DateTime, } -pub struct Directory { - // identity - pub id: Option, - pub name: String, - // calculations - pub calculated_size_in_bytes: u64, - pub calculated_file_count: u32, - // ownership - pub user_id: Option, - pub storage_device_id: Option, - pub parent_directory_id: Option, - // date - pub date_created: DateTime, - pub date_modified: DateTime, - pub date_indexed: DateTime, -} - -#[tauri::command] -pub fn read_file_command(path: &str) -> Result { - let file = read_file(path).unwrap(); - Ok(file) -} - -pub fn read_file(path: &str) -> Result { +// Read a file from path returning the File struct +// Generates checksum and extracts metadata +pub async fn read_file(path: &str) -> io::Result { + // let start = Instant::now(); let path_buff = path::PathBuf::from(path); // extract metadata - let metadata = fs::metadata(&path).unwrap(); - if metadata.is_dir() { - panic!("Not a file, this is a directory"); - } + let metadata = match fs::metadata(&path) { + Ok(metadata) => metadata, + Err(e) => return Err(e), + }; + // if metadata.is_dir() { + // return Err(); + // } + + // let checksum = thread::scope(|s| { + // let res = s.spawn(move |_| checksum::create_hash(path).unwrap()); + // res.join() + // }) + // .unwrap() + // .unwrap(); + + // let checksum = match checksum { + // Ok(metadata) => metadata, // Err(e) => return Err(e.into()), + // }; + + // generate checksum + // let checksum = match checksum::create_hash(path) { + // Ok(checksum) => checksum, + // Err(e) => return Err(e), + // }; + // assemble File struct with initial values let file = File { - id: None, - name: path_buff.file_name().unwrap().to_str().unwrap().to_owned(), - extension: path_buff.extension().unwrap().to_str().unwrap().to_owned(), + name: extract_name(path_buff.file_name()), + extension: extract_name(path_buff.extension()), uri: path.to_owned(), - checksum: checksum::create_hash(path).unwrap(), size_in_bytes: metadata.len(), - date_created: time::system_time_to_date_time(metadata.created().unwrap()).unwrap(), - date_modified: time::system_time_to_date_time(metadata.created().unwrap()).unwrap(), - date_indexed: chrono::offset::Utc::now(), + date_created: time::system_time_to_date_time(metadata.created()).unwrap_or(Utc::now()), + date_modified: time::system_time_to_date_time(metadata.created()).unwrap_or(Utc::now()), + date_indexed: Utc::now(), encryption: crypto::Encryption::NONE, + // this will be populated later, either by the database or other functions + id: None, + checksum: None, ipfs_id: None, user_id: None, storage_device_id: None, @@ -79,7 +85,16 @@ pub fn read_file(path: &str) -> Result { parent_file_id: None, }; - println!("file: {:?}", file); + checksum::create_hash(path).await; Ok(file) } + +// extract name from OsStr returned by PathBuff +fn extract_name(os_string: Option<&OsStr>) -> String { + os_string + .unwrap_or_default() + .to_str() + .unwrap_or_default() + .to_owned() +} diff --git a/src-tauri/src/filesystem/mod.rs b/src-tauri/src/filesystem/mod.rs index 8ba7cb2e4..ca7d53824 100644 --- a/src-tauri/src/filesystem/mod.rs +++ b/src-tauri/src/filesystem/mod.rs @@ -1,2 +1,3 @@ pub mod checksum; +pub mod directory; pub mod file; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 2af4c86ba..864e82082 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,35 +4,20 @@ )] mod app; +mod commands; mod crypto; mod db; mod filesystem; mod util; use crate::app::menu; -#[derive(serde::Serialize)] -struct CustomResponse { - message: String, -} - -#[tauri::command] -async fn fn_exposed_to_js(window: tauri::Window) -> Result { - println!("Called from window {}", window.label()); - Ok(CustomResponse { - message: "Hello from rust!".to_string(), - }) -} - fn main() { let connection = db::init::create_connection(); - // let hash = filestuff::create_hash("/Users/jamie/Desktop/jeff.MP4"); - println!("jeff {:?}", connection); + + println!("primary database connected {:?}", connection); tauri::Builder::default() - .invoke_handler(tauri::generate_handler![ - fn_exposed_to_js, - filesystem::file::read_file_command - ]) + .invoke_handler(tauri::generate_handler![commands::read_file_command]) .menu(menu::get_menu()) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/util/time.rs b/src-tauri/src/util/time.rs index 02d8397fa..8cd65fda4 100644 --- a/src-tauri/src/util/time.rs +++ b/src-tauri/src/util/time.rs @@ -2,9 +2,13 @@ use chrono::{offset::TimeZone, DateTime, NaiveDateTime, Utc}; use std::io; use std::time::{SystemTime, UNIX_EPOCH}; -pub fn system_time_to_date_time(system_time: SystemTime) -> io::Result> { - let std_duration = system_time.duration_since(UNIX_EPOCH).unwrap(); - let chrono_duration = chrono::Duration::from_std(std_duration).unwrap(); +pub fn system_time_to_date_time( + system_time: io::Result, +) -> Result, Box> { + // extract system time or resort to current time if failure + let system_time = system_time.unwrap_or(SystemTime::now()); + let std_duration = system_time.duration_since(UNIX_EPOCH)?; + let chrono_duration = chrono::Duration::from_std(std_duration)?; let unix = NaiveDateTime::from_timestamp(0, 0); let naive = unix + chrono_duration; let date_time: DateTime = Utc.from_local_datetime(&naive).unwrap(); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d0c8583cf..12c94450f 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "package": { - "productName": "nexus", + "productName": "spacedrive", "version": "0.1.0" }, "build": { @@ -13,7 +13,7 @@ "bundle": { "active": true, "targets": "all", - "identifier": "org.nexusapp", + "identifier": "co.spacedrive.client", "icon": ["icons/icon.icns"], "resources": [], "externalBin": [], @@ -52,7 +52,7 @@ }, "windows": [ { - "title": "Nexus", + "title": "spacedrive", "width": 1200, "height": 700, "resizable": true, diff --git a/src/App.tsx b/src/App.tsx index 1bf75f5da..92df53ff2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { Button, colors, ColorScheme, extendTheme, Icon, Input, Switch } from '@vechaiui/react'; import { VechaiProvider } from '@vechaiui/react'; import { CookingPot } from 'phosphor-react'; @@ -30,21 +30,25 @@ const theme = extendTheme({ export default function App() { const fileUploader = useRef(null); + const [fileInputVal, setFileInputVal] = useState('/Users/jamie/Downloads/lol.mkv'); + function changeHandler(e: any) { console.log(e); } + return (
- + setFileInputVal(e.target.value)} /> +