From 3360eeee0743fbad7ff1779e90eacc5e3de7c968 Mon Sep 17 00:00:00 2001 From: JenChieh Date: Thu, 6 Jun 2024 04:08:07 -0700 Subject: [PATCH] handle sync --- Cargo.toml | 1 + src/file.rs | 21 ++++++--------------- src/handler/mod.rs | 1 + src/handler/room.rs | 33 +++++++++++++++++++++++++++++++-- src/main.rs | 1 + src/room.rs | 10 ++++++++++ src/user.rs | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 src/user.rs diff --git a/Cargo.toml b/Cargo.toml index 2ed231a..8b24afd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ chrono = "0.4.38" clap = "4.5.4" dunce = "1.0.4" ignore = "0.4.22" +path-slash = "0.2.1" rpassword = "7.3.1" serde_json = "1.0.117" tokio = { version = "1.37.0", features = ["full"] } diff --git a/src/file.rs b/src/file.rs index 590f97f..0589fc3 100644 --- a/src/file.rs +++ b/src/file.rs @@ -14,21 +14,7 @@ * limitations under the License. */ use crate::chat::*; - -struct Region { - start: u64, - end: u64, -} - -struct Mouse { - point: u64, -} - -struct User { - username: String, - mouse: Mouse, - region: Region, -} +use crate::user::*; pub struct File { path: String, // absolute path @@ -47,6 +33,11 @@ impl File { } } + /// Return the file path. + pub fn get_path(&self) -> &String { + &self.path + } + /// Write the content to file. pub async fn save(&self) { // TODO: .. diff --git a/src/handler/mod.rs b/src/handler/mod.rs index e75c98b..117fa49 100644 --- a/src/handler/mod.rs +++ b/src/handler/mod.rs @@ -38,6 +38,7 @@ pub async fn handle(channel: &mut Channel, room: &Arc>, json: &str) "room::kick" => room::kick::handle(channel, room, &val).await, "room::broadcast" => room::broadcast::handle(channel, room, &val).await, "room::list_users" => room::list_users::handle(channel, room, &val).await, + "room::sync" => room::sync::handle(channel, room, &val).await, "file::open" => file::open::handle(channel, room, &val).await, "file::close" => file::close::handle(channel, room, &val).await, "file::say" => file::say::handle(channel, room, &val).await, diff --git a/src/handler/room.rs b/src/handler/room.rs index 0800e5c..e6c49a3 100644 --- a/src/handler/room.rs +++ b/src/handler/room.rs @@ -17,6 +17,7 @@ use crate::channel::*; use crate::client::*; use crate::room::*; use serde_json::Value; +use std::fs; use std::sync::Arc; use tokio::sync::Mutex; @@ -298,17 +299,45 @@ pub mod sync { use crate::channel::*; use crate::handler::room::*; use crate::room::*; + use path_slash::PathBufExt as _; use serde_json::Value; + use std::path::{Path, PathBuf}; use std::sync::Arc; use tokio::sync::Mutex; const METHOD: &str = "room::sync"; pub async fn handle(channel: &mut Channel, room: &Arc>, json: &Value) { - if !ensure_entered(channel, room, METHOD).await { + let addr = &channel.get_connection().addr; + let mut room = room.lock().await; + let client = room.get_client_mut(addr).unwrap(); + + if !check_entered(channel, client, METHOD).await { return; } - // TODO: .. + let project_path = json["path"].as_str().unwrap().to_string(); + + let room_path = room.get_path().clone(); + let files = room.get_files(); + + for file in files.iter() { + let abs_path = file.get_path(); + let content = fs::read_to_string(abs_path).expect("Unable to read file"); + + // Replace the room path to client's project path, so the client + // can use the path directly. + let path = abs_path.replace(&room_path, &project_path); + let path = PathBuf::from_slash(&path).to_slash().unwrap().to_string(); + + channel + .send_json(&serde_json::json!({ + "method": METHOD, + "path": path, + "content": content, + "status": "success", + })) + .await; + } } } diff --git a/src/main.rs b/src/main.rs index 45f77bc..afb753c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ mod file; mod handler; mod room; mod server; +mod user; use crate::room::*; use clap::{arg, Arg, ArgMatches, Command}; use dunce; diff --git a/src/room.rs b/src/room.rs index 22fda9b..8a5f072 100644 --- a/src/room.rs +++ b/src/room.rs @@ -73,6 +73,16 @@ impl Room { } } + /// Return the project path. + pub fn get_path(&self) -> &String { + &self.path + } + + /// Return a list of files need to be sync. + pub fn get_files(&mut self) -> &mut Vec { + &mut self.files + } + /// Return the custom ignore file path. fn ignore_file(&self) -> String { let ignore = Path::new(&self.path).join(COGUREIGNORE); diff --git a/src/user.rs b/src/user.rs new file mode 100644 index 0000000..86f08d3 --- /dev/null +++ b/src/user.rs @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2024 Cogru Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#[derive(Default)] +struct Region { + start: u64, + end: u64, +} + +#[derive(Default)] +struct Mouse { + point: u64, +} + +#[derive(Default)] +pub struct User { + username: String, + mouse: Mouse, + region: Region, +}