Skip to content

Commit

Permalink
Merge pull request #295 from opeolluwa/master
Browse files Browse the repository at this point in the history
new patch
  • Loading branch information
opeolluwa authored May 2, 2024
2 parents dc76a4e + f846469 commit b56a38d
Show file tree
Hide file tree
Showing 62 changed files with 1,737 additions and 812 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ core/views
mobile/node_modules

core/test.db
core/src/scripts
core/src/scripts

public/test
22 changes: 12 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
install-toolchain:


install:



run:


build:
npm install -g yarn
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
#install the system depencies
install-deps:
yarn install
cd core && cargo build
# run the dev server
dev:
yarn tauri dev
# build the binary for the current OS
build:
yarn tauri build
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ _⚠️ the application is still a work in progress, hence, Some features are mi

## Description

FIleSync is an offline file-sharing application designed for Windows, Mac, and Linux operating systems. It allows users to transfer files seamlessly between PCs over WiFi without an internet connection.
FIleSync is an wifi file-sharing application designed for Windows, Mac, and Linux operating systems. It allows users to transfer files seamlessly between PCs over WiFi without an internet connection.

## Getting Started

Expand Down
7 changes: 7 additions & 0 deletions core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ tauri-build = {version = "1.3", features = [] }

[dependencies]
assert_fs = "1.0.13"
axum = {version = "0.6.12", features = ["multipart", "headers"] }
axum = { version = "0.6.12", features = ["multipart", "headers"] }
battery = "0.7.8"
chrono = "0.4.31"
dirs = "5.0.0"
Expand All @@ -37,7 +37,7 @@ serde_json = "1.0"
sqlx = {version = "0.6.2", features = ["sqlite", "runtime-tokio-native-tls"] }
sys-info = "0.9.1"
sysinfo = "0.29.2"
tauri = {version = "1.2", features = ["app-all", "dialog-all", "fs-all", "path-all", "shell-open"] }
tauri = {version = "1.2", features = [ "window-all", "app-all", "dialog-all", "fs-all", "path-all", "shell-open"] }
tokio = {version = "1.26.0", features = ["full"] }
tokio-util = {version = "0.7", features = ["io"] }
tower = {version = "0.4", features = ["util"] }
Expand All @@ -52,6 +52,7 @@ ts-rs = "7.0.0"
pnet = "0.34.0"
open = "5.1.2"
path-absolutize = "3.1.1"
fs_extra = "1.3.0"
[features]
# this feature is used for production builds or when `devPath` points to the filesystem
# DO NOT REMOVE!!
Expand Down
2 changes: 1 addition & 1 deletion core/src/api/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde_json::{json, Value};
use ts_rs::TS;

use crate::database::{self, TransferHistory, TransferHistoryBuilder};
use crate::fs::search::search_files;
// use crate::fs::search::search_files;
use crate::wifi::ip_manager;
use tokio::io::AsyncReadExt;

Expand Down
14 changes: 14 additions & 0 deletions core/src/api/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::net::Ipv4Addr;
use local_ip_address::local_ip;

use crate::{
utils::{system_info::SystemInformation, CommandData},
Expand Down Expand Up @@ -33,3 +34,16 @@ pub fn get_ip_address() -> String {
pub fn get_system_information() -> CommandData<SystemInformation> {
CommandData::ok("connected system information ", SystemInformation::new())
}



#[tauri::command]
pub fn is_connected_to_wifi() -> CommandData<bool> {
// the app would have a local ip address if it is connected to a network
// else it would crash, this is leveraged to check the network status
let has_ip_addr = local_ip().ok();
if has_ip_addr.is_none() {
return CommandData::ok("wifi status", false);
}
CommandData::ok("server address", true)
}
2 changes: 1 addition & 1 deletion core/src/api/wifi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/// once this is done pass the network conf
use crate::{
utils::CommandData,
wifi::{hotspot, network_scanner, WifiHotspotConfig},
wifi::{network_scanner, WifiHotspotConfig},
};

#[tauri::command]
Expand Down
10 changes: 2 additions & 8 deletions core/src/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#[allow(dead_code)]
use crate::database::{Settings, TransferHistory};

#[derive(Default)]
pub struct State {
pub settings: Settings,
pub transfer_history: Vec<TransferHistory>,
Expand All @@ -19,11 +20,4 @@ impl State {
}
}

impl Default for State {
fn default() -> Self {
Self {
settings: Settings::default(),
transfer_history: Vec::new(),
}
}
}

7 changes: 5 additions & 2 deletions core/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl File {
pub fn from_path(path: &PathBuf) -> Self {
let file_name = path.file_name().unwrap().to_str().unwrap();
let file_path = path.display().to_string();
let file_size: u128 = path.size_on_disk().unwrap_or(0).into();
let mut file_size: u128 = path.size_on_disk().unwrap_or(0).into();
let file_format = path
.extension()
.unwrap_or_default()
Expand All @@ -57,11 +57,14 @@ impl File {

let is_folder = path.is_dir();

if is_folder {
file_size = fs_extra::dir::get_size(path).unwrap_or(0) as u128;
}
let is_hidden = path
.file_name()
.unwrap()
.to_str()
.map(|s| s.starts_with("."))
.map(|s| s.starts_with('.'))
.unwrap();

Self {
Expand Down
18 changes: 10 additions & 8 deletions core/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

extern crate uptime_lib;

use crate::api::fs_api::get_transfer_history;
/**
* the application is structured thus
* src
Expand All @@ -11,15 +12,14 @@ extern crate uptime_lib;
* __fs
* ...
*/


use crate::api::fs_api::read_dir;
use crate::api::fs_api::get_transfer_history;
use crate::api::fs_api::read_dir;
// Import individual items from crate::api::settings
use crate::api::settings::{get_settings, update_settings};

// Import individual items from crate::api::utils
use crate::api::utils::{generate_qr_code, get_ip_address, get_system_information};
use crate::api::utils::{
generate_qr_code, get_ip_address, get_system_information, is_connected_to_wifi,
};

// Import individual items from crate::api::wifi
use crate::api::wifi::{create_wifi_hotspot, kill_wifi_hotspot, scan_wifi};
Expand All @@ -45,8 +45,8 @@ lazy_static! {
*
* Herein the server port made globally available, this allow for ease of sharing same with file upload directory
*/
pub static ref SERVER_PORT: u16 =
portpicker::pick_unused_port().expect("failed to get an unused port");
pub static ref SERVER_PORT: u16 = 18005;
// portpicker::pick_unused_port().expect("failed to get an unused port");
pub static ref UPLOAD_DIRECTORY: std::string::String = String::from("filesync");

/* create a database in the home dir and / save files to $HOME/filesync/.dat */
Expand Down Expand Up @@ -86,7 +86,6 @@ fn main() -> Result<(), tauri::Error> {
..Default::default()
};

scan_wifi();
// run core the server in a separate thread from tauri
tauri::async_runtime::spawn(http_server::core_server());
// run the UI code and the IPC (internal Procedure Call functions)
Expand All @@ -100,9 +99,12 @@ fn main() -> Result<(), tauri::Error> {
get_system_information,
get_transfer_history,
get_settings,
is_connected_to_wifi,
update_settings,
read_dir,
scan_wifi // download_file, TODO: implement file transfering between peers
])
.run(tauri::generate_context!())

// Ok(())
}
10 changes: 4 additions & 6 deletions core/src/server/http_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use axum::extract::DefaultBodyLimit;

use crate::database::Database;
use crate::server::router;

use crate::server::routes::handle_404;
use crate::SERVER_PORT;

Expand Down Expand Up @@ -52,17 +53,14 @@ pub async fn core_server() {
.parse::<std::net::SocketAddr>()
.expect("invalid socket address");

tracing::debug!("server running on http://{}", &ip_address.to_string());
println!(" the server port is http://{}", ip_address);

// build our application with the required routes
let app = router::app()
.layer(file_limit)
.layer(cors_layer)
.layer(tower_http::trace::TraceLayer::new_for_http());
// .fallback(handle_404);

// add a fallback service for handling routes to unknown paths
// let app = app.fallback(handle_404);
.layer(tower_http::trace::TraceLayer::new_for_http())
.fallback(handle_404);

// run the server
axum::Server::bind(&ip_address)
Expand Down
4 changes: 3 additions & 1 deletion core/src/server/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ use axum::{
};

use super::routes::{
accept_file_upload, download_file, file_upload_form, get_file, system_information,
accept_file_upload, download_file, file_upload_form, get_file, health_check, ping_server, system_information
};

// the app is moved here to allow sharing across test modules
pub fn app() -> Router {
Router::new()
.route("/", get(ping_server))
.route("/upload", post(accept_file_upload).get(file_upload_form))
.route("/health", post(accept_file_upload).get(health_check))
.route("/api/sys-info", get(system_information))
.route("/api/download", get(download_file))
.route("/api/file", get(get_file))
Expand Down
49 changes: 43 additions & 6 deletions core/src/server/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ use crate::UPLOAD_DIRECTORY;
#[derive(Debug, Serialize, Deserialize)]

/// destructure query parameter
pub struct Params {
pub struct QueryParams {
pub file_path: String,
}
/// accept file path amd return the file
pub async fn download_file(Query(params): Query<Params>) -> impl IntoResponse {
let Params { file_path } = params;
pub async fn download_file(Query(params): Query<QueryParams>) -> impl IntoResponse {
let QueryParams { file_path } = params;

let Some(file) = tokio::fs::File::open(file_path).await.ok() else {
return Err((
Expand Down Expand Up @@ -64,7 +64,7 @@ pub async fn system_information() -> (StatusCode, Json<CommandData<SystemInforma
)
}

// return an html page to receive file upload
/// return an html page to receive file upload
pub async fn file_upload_form() -> Html<&'static str> {
Html(
r#"
Expand Down Expand Up @@ -235,9 +235,46 @@ pub async fn handle_404() -> impl IntoResponse {
)
}


/// health check handler
pub async fn health_check() -> impl IntoResponse {
(
StatusCode::OK,
axum::response::Json(serde_json::json!({
"success":true,
"message":String::from("Server is ready to accept connection"),
})),
)
}

/// ping the server
pub async fn ping_server() -> impl IntoResponse {
"FileSync Server 1.0.0"
}



/// for a given file path, return the file the the used as a downloadable one
pub async fn get_file() {
unimplemented!()
pub async fn get_file(Query(QueryParams { file_path }): Query<QueryParams>) -> impl IntoResponse {
// `File` implements `AsyncRead`
let file = match tokio::fs::File::open(file_path).await {
Ok(file) => file,
Err(err) => return Err((StatusCode::NOT_FOUND, format!("File not found: {}", err))),
};
// convert the `AsyncRead` into a `Stream`
let stream = ReaderStream::new(file);
// convert the `Stream` into an `axum::body::HttpBody`
let body = StreamBody::new(stream);

let headers =[
(header::CONTENT_TYPE, "text/toml; charset=utf-8"),
(
header::CONTENT_DISPOSITION,
"attachment; filename=\"Cargo.toml\"",
),
];

Ok((headers, body))
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions core/src/utils/fs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::process::Command;
use sysinfo::{DiskExt, System, SystemExt};

use sysinfo::{DiskExt, SystemExt};
// pub mod storage_information;
/// a function to compute file size
/// accept files size in byte and parse it to human readable KB, MB, TB, GB e.t.c
Expand Down
Loading

0 comments on commit b56a38d

Please sign in to comment.