Compare commits
4 Commits
ed599d1399
...
f56dcd30b8
Author | SHA1 | Date | |
---|---|---|---|
|
f56dcd30b8 | ||
|
ddf2169950 | ||
|
5ccce48381 | ||
|
4ec389b6cc |
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -113,7 +113,7 @@ dependencies = [
|
|||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim",
|
"strsim",
|
||||||
"textwrap",
|
"textwrap 0.11.0",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
@ -588,6 +588,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rust-crypto",
|
"rust-crypto",
|
||||||
|
"textwrap 0.13.4",
|
||||||
"tokio",
|
"tokio",
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
]
|
]
|
||||||
@ -976,6 +977,12 @@ version = "1.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smawk"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@ -1025,6 +1032,16 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835"
|
||||||
|
dependencies = [
|
||||||
|
"smawk",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.45"
|
version = "0.1.45"
|
||||||
|
@ -16,6 +16,7 @@ xml-rs = "0.8.0"
|
|||||||
regex = "1.8.3"
|
regex = "1.8.3"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
|
textwrap = "0.13"
|
||||||
chrono = "0.4.26"
|
chrono = "0.4.26"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
@ -104,7 +104,7 @@ pub fn clone(remote: Values<'_>) {
|
|||||||
// add tree
|
// add tree
|
||||||
let path_folder = p.strip_prefix(ref_path.clone()).unwrap();
|
let path_folder = p.strip_prefix(ref_path.clone()).unwrap();
|
||||||
let lastmodified = folder.lastmodified.unwrap().timestamp_millis();
|
let lastmodified = folder.lastmodified.unwrap().timestamp_millis();
|
||||||
if let Err(err) = tree::add(&path_folder, &lastmodified.to_string()) {
|
if let Err(err) = tree::add(path_folder.to_path_buf(), &lastmodified.to_string()) {
|
||||||
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ fn download_files(ref_p: PathBuf, files: Vec<ObjProps>, api_props: &ApiProps) {
|
|||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let relative_p = Path::new(&relative_s);
|
let relative_p = PathBuf::from(&relative_s);
|
||||||
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
|
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
|
||||||
if let Err(err) = blob::add(relative_p, &lastmodified.to_string()) {
|
if let Err(err) = blob::add(relative_p, &lastmodified.to_string()) {
|
||||||
eprintln!("err: saving ref of {} ({})", relative_s.clone(), err);
|
eprintln!("err: saving ref of {} ({})", relative_s.clone(), err);
|
||||||
|
@ -9,7 +9,8 @@ pub mod rm_dir;
|
|||||||
pub mod deleted;
|
pub mod deleted;
|
||||||
|
|
||||||
pub fn push() {
|
pub fn push() {
|
||||||
let remote = match config::get("remote") {
|
// todo
|
||||||
|
let _remote = match config::get("remote") {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => {
|
None => {
|
||||||
eprintln!("fatal: no remote set in configuration");
|
eprintln!("fatal: no remote set in configuration");
|
||||||
@ -27,20 +28,35 @@ pub fn push() {
|
|||||||
|
|
||||||
for obj in staged_objs {
|
for obj in staged_objs {
|
||||||
if obj.otype == String::from("tree") {
|
if obj.otype == String::from("tree") {
|
||||||
dbg!(("folder", obj.clone()));
|
|
||||||
let push_factory = PushFactory.new_dir(obj.clone());
|
let push_factory = PushFactory.new_dir(obj.clone());
|
||||||
let res = match push_factory.can_push(&mut whitelist) {
|
let res = push_factory.can_push(&mut whitelist);
|
||||||
PushState::Valid => push_factory.push(),
|
match res {
|
||||||
|
PushState::Valid => {
|
||||||
|
match push_factory.push() {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("err: pushing {}: {}", obj.name, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
PushState::Done => (),
|
PushState::Done => (),
|
||||||
PushState::Conflict => (),
|
PushState::Conflict => {
|
||||||
|
println!("CONFLICT: {}", obj.clone().name);
|
||||||
|
},
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
dbg!(("file", obj.clone()));
|
|
||||||
let push_factory = PushFactory.new(obj.clone());
|
let push_factory = PushFactory.new(obj.clone());
|
||||||
match push_factory.can_push(&mut whitelist) {
|
match push_factory.can_push(&mut whitelist) {
|
||||||
PushState::Valid => push_factory.push(),
|
PushState::Valid => {
|
||||||
|
match push_factory.push() {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("err: pushing {}: {}", obj.name, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
PushState::Done => (),
|
PushState::Done => (),
|
||||||
PushState::Conflict => {
|
PushState::Conflict => {
|
||||||
// download file
|
// download file
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::io;
|
||||||
use crate::services::api::ApiError;
|
use crate::services::api::ApiError;
|
||||||
use crate::services::req_props::ReqProps;
|
|
||||||
use crate::services::delete_path::DeletePath;
|
use crate::services::delete_path::DeletePath;
|
||||||
use crate::store::index;
|
use crate::store::index;
|
||||||
use crate::store::object::blob;
|
use crate::store::object::blob;
|
||||||
@ -22,7 +22,7 @@ impl PushChange for Deleted {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&self) {
|
fn push(&self) -> io::Result<()> {
|
||||||
let obj = &self.obj;
|
let obj = &self.obj;
|
||||||
let res = DeletePath::new()
|
let res = DeletePath::new()
|
||||||
.set_url(obj.path.to_str().unwrap())
|
.set_url(obj.path.to_str().unwrap())
|
||||||
@ -41,9 +41,13 @@ impl PushChange for Deleted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update tree
|
// update tree
|
||||||
blob::rm(&obj.path.clone());
|
// todo date
|
||||||
|
blob::rm(obj.path.clone())?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap());
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conflict(&self) {
|
fn conflict(&self) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::io;
|
||||||
use crate::services::api::ApiError;
|
use crate::services::api::ApiError;
|
||||||
|
use crate::services::req_props::ReqProps;
|
||||||
use crate::services::upload_file::UploadFile;
|
use crate::services::upload_file::UploadFile;
|
||||||
use crate::store::index;
|
use crate::store::index;
|
||||||
use crate::store::object::blob;
|
use crate::store::object::blob;
|
||||||
@ -21,7 +23,7 @@ impl PushChange for New {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&self) {
|
fn push(&self) -> io::Result<()> {
|
||||||
let obj = &self.obj;
|
let obj = &self.obj;
|
||||||
let res = UploadFile::new()
|
let res = UploadFile::new()
|
||||||
.set_url(obj.path.to_str().unwrap())
|
.set_url(obj.path.to_str().unwrap())
|
||||||
@ -40,11 +42,38 @@ impl PushChange for New {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
// update tree
|
// get lastmodified props to update it
|
||||||
blob::add(&obj.path.clone(), "todo_date");
|
let props = ReqProps::new()
|
||||||
|
.set_url(obj.path.to_str().unwrap())
|
||||||
|
.getlastmodified()
|
||||||
|
.send_req_single();
|
||||||
|
|
||||||
|
let prop = match props {
|
||||||
|
Ok(o) => o,
|
||||||
|
Err(ApiError::IncorrectRequest(err)) => {
|
||||||
|
eprintln!("fatal: {}", err.status());
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
Err(ApiError::EmptyError(_)) => {
|
||||||
|
eprintln!("Failed to get body");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
Err(ApiError::RequestError(err)) => {
|
||||||
|
eprintln!("fatal: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
Err(ApiError::Unexpected(_)) => todo!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastmodified = prop.lastmodified.unwrap().timestamp_millis();
|
||||||
|
|
||||||
|
// update blob
|
||||||
|
blob::add(obj.path.clone(), &lastmodified.to_string())?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap());
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// download file with .distant at the end
|
// download file with .distant at the end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::io;
|
||||||
use crate::services::api::ApiError;
|
use crate::services::api::ApiError;
|
||||||
use crate::services::req_props::ReqProps;
|
use crate::services::req_props::ReqProps;
|
||||||
use crate::services::create_folder::CreateFolder;
|
use crate::services::create_folder::CreateFolder;
|
||||||
@ -28,7 +29,7 @@ impl PushChange for NewDir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&self) {
|
fn push(&self) -> io::Result<()> {
|
||||||
let obj = &self.obj;
|
let obj = &self.obj;
|
||||||
let res = CreateFolder::new()
|
let res = CreateFolder::new()
|
||||||
.set_url(obj.path.to_str().unwrap())
|
.set_url(obj.path.to_str().unwrap())
|
||||||
@ -46,11 +47,39 @@ impl PushChange for NewDir {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get lastmodified props to update it
|
||||||
|
let props = ReqProps::new()
|
||||||
|
.set_url(obj.path.to_str().unwrap())
|
||||||
|
.getlastmodified()
|
||||||
|
.send_req_single();
|
||||||
|
|
||||||
|
let prop = match props {
|
||||||
|
Ok(o) => o,
|
||||||
|
Err(ApiError::IncorrectRequest(err)) => {
|
||||||
|
eprintln!("fatal: {}", err.status());
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
Err(ApiError::EmptyError(_)) => {
|
||||||
|
eprintln!("Failed to get body");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
Err(ApiError::RequestError(err)) => {
|
||||||
|
eprintln!("fatal: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
Err(ApiError::Unexpected(_)) => todo!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastmodified = prop.lastmodified.unwrap().timestamp_millis();
|
||||||
|
|
||||||
// update tree
|
// update tree
|
||||||
tree::add(&obj.path.clone(), "todo_date");
|
tree::add(obj.path.clone(), &lastmodified.to_string())?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap());
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conflict(&self) {}
|
fn conflict(&self) {}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::io;
|
||||||
use crate::commands::status::{State, LocalObj};
|
use crate::commands::status::{State, LocalObj};
|
||||||
use crate::services::api::ApiError;
|
use crate::services::api::ApiError;
|
||||||
use crate::store::object;
|
use crate::store::object;
|
||||||
use crate::services::req_props::{ObjProps, ReqProps};
|
use crate::services::req_props::ReqProps;
|
||||||
use crate::commands::push::new::New;
|
use crate::commands::push::new::New;
|
||||||
use crate::commands::push::new_dir::NewDir;
|
use crate::commands::push::new_dir::NewDir;
|
||||||
use crate::commands::push::rm_dir::RmDir;
|
use crate::commands::push::rm_dir::RmDir;
|
||||||
@ -26,18 +27,9 @@ pub enum PushFlowState {
|
|||||||
|
|
||||||
pub trait PushChange {
|
pub trait PushChange {
|
||||||
fn can_push(&self, whitelist: &mut Option<PathBuf>) -> PushState;
|
fn can_push(&self, whitelist: &mut Option<PathBuf>) -> PushState;
|
||||||
fn push(&self);
|
fn push(&self) -> io::Result<()>;
|
||||||
fn conflict(&self);
|
fn conflict(&self);
|
||||||
|
|
||||||
fn try_push(&self, whitelist: &mut Option<PathBuf>) {
|
|
||||||
match self.can_push(whitelist) {
|
|
||||||
PushState::Valid => self.push(),
|
|
||||||
PushState::Conflict => self.conflict(),
|
|
||||||
PushState::Done => (),
|
|
||||||
PushState::Error => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_whitelisted(&self, obj: &LocalObj, path: Option<PathBuf>) -> bool {
|
fn is_whitelisted(&self, obj: &LocalObj, path: Option<PathBuf>) -> bool {
|
||||||
match path {
|
match path {
|
||||||
Some(p) => obj.path.starts_with(p),
|
Some(p) => obj.path.starts_with(p),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::io;
|
||||||
use crate::services::api::ApiError;
|
use crate::services::api::ApiError;
|
||||||
use crate::services::delete_path::DeletePath;
|
use crate::services::delete_path::DeletePath;
|
||||||
use crate::store::index;
|
use crate::store::index;
|
||||||
@ -27,7 +28,7 @@ impl PushChange for RmDir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&self) {
|
fn push(&self) -> io::Result<()> {
|
||||||
let obj = &self.obj;
|
let obj = &self.obj;
|
||||||
let res = DeletePath::new()
|
let res = DeletePath::new()
|
||||||
.set_url(obj.path.to_str().unwrap())
|
.set_url(obj.path.to_str().unwrap())
|
||||||
@ -46,9 +47,13 @@ impl PushChange for RmDir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update tree
|
// update tree
|
||||||
tree::rm(&obj.path.clone());
|
// todo update date
|
||||||
|
tree::rm(obj.path.clone())?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap());
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conflict(&self) {}
|
fn conflict(&self) {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::io::{self, Lines, BufReader};
|
use std::io::{self, Lines, BufReader};
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::HashMap;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
use crypto::sha1::Sha1;
|
use crypto::sha1::Sha1;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@ -31,7 +31,7 @@ pub enum State {
|
|||||||
pub fn status() {
|
pub fn status() {
|
||||||
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
||||||
// get copy, modified
|
// get copy, modified
|
||||||
let mut staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
let staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
||||||
|
|
||||||
let mut objs: Vec<LocalObj> = del_objs_hashes.iter().map(|x| {
|
let mut objs: Vec<LocalObj> = del_objs_hashes.iter().map(|x| {
|
||||||
x.1.clone()
|
x.1.clone()
|
||||||
@ -41,8 +41,6 @@ pub fn status() {
|
|||||||
objs.push(elt.clone());
|
objs.push(elt.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(objs.clone());
|
|
||||||
dbg!(staged_objs.clone());
|
|
||||||
print_status(staged_objs, objs);
|
print_status(staged_objs, objs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ pub struct LocalObj {
|
|||||||
pub fn get_all_staged() -> Vec<LocalObj> {
|
pub fn get_all_staged() -> Vec<LocalObj> {
|
||||||
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
||||||
// get copy, modified
|
// get copy, modified
|
||||||
let mut staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
let staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
||||||
|
|
||||||
staged_objs.clone()
|
staged_objs.clone()
|
||||||
// todo opti getting staged and then finding differences ?
|
// todo opti getting staged and then finding differences ?
|
||||||
@ -92,11 +90,12 @@ fn get_staged(new_objs_h: &mut HashMap<String, LocalObj>, del_objs_h: &mut HashM
|
|||||||
del_objs_h.remove(&hash);
|
del_objs_h.remove(&hash);
|
||||||
}else {
|
}else {
|
||||||
let mut t_path = ref_p.clone();
|
let mut t_path = ref_p.clone();
|
||||||
t_path.push(PathBuf::from(obj.clone()));
|
let relative_p = PathBuf::from(obj.clone());
|
||||||
|
t_path.push(relative_p.clone());
|
||||||
staged_objs.push(LocalObj {
|
staged_objs.push(LocalObj {
|
||||||
otype: get_otype(t_path.clone()),
|
otype: get_otype(t_path.clone()),
|
||||||
name: obj.to_string(),
|
name: obj.to_string(),
|
||||||
path: t_path.clone(),
|
path: relative_p.clone(),
|
||||||
state: {
|
state: {
|
||||||
if t_path.exists() {
|
if t_path.exists() {
|
||||||
State::New
|
State::New
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use clap::{App, Arg, SubCommand};
|
use clap::{App, Arg, SubCommand};
|
||||||
|
use textwrap::{fill, Options};
|
||||||
use crate::commands::add::AddArgs;
|
use crate::commands::add::AddArgs;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
@ -20,6 +21,10 @@ fn main() {
|
|||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.value_name("REMOTE")
|
.value_name("REMOTE")
|
||||||
|
.help(&fill(
|
||||||
|
"The repository to clone from. See the NEXTSYNC URLS section below for more information on specifying repositories.",
|
||||||
|
Options::new(80).width,
|
||||||
|
))
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("directory")
|
Arg::with_name("directory")
|
||||||
@ -28,6 +33,7 @@ fn main() {
|
|||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
)
|
)
|
||||||
.about("Clone a repository into a new directory")
|
.about("Clone a repository into a new directory")
|
||||||
|
.after_help("NEXTSYNC URLS\nThe following syntaxes may be used:\n\t- user@host.xz/path/to/repo\n\t- http[s]://host.xz/apps/files/?dir=/path/to/repo&fileid=111111\n\t- [http[s]://]host.xz/remote.php/dav/files/user/path/to/repo\n")
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("init")
|
SubCommand::with_name("init")
|
||||||
|
@ -73,7 +73,7 @@ impl ReqProps {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getcontentlenght(&mut self) -> &mut ReqProps {
|
pub fn _getcontentlenght(&mut self) -> &mut ReqProps {
|
||||||
self.xml_balises.push(String::from("getcontentlength"));
|
self.xml_balises.push(String::from("getcontentlength"));
|
||||||
self.xml_payload.push_str(r#"<d:getcontentlength/>"#);
|
self.xml_payload.push_str(r#"<d:getcontentlength/>"#);
|
||||||
self
|
self
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::fs::{OpenOptions, self};
|
use std::fs::{self, OpenOptions};
|
||||||
use crypto::sha1::Sha1;
|
use crypto::sha1::Sha1;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
|
use std::io::{Seek, SeekFrom, Read};
|
||||||
use crate::utils::{read, path};
|
use crate::utils::{read, path};
|
||||||
|
|
||||||
pub mod tree;
|
pub mod tree;
|
||||||
@ -13,7 +14,7 @@ pub mod blob;
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
/// Input: /foo/bar
|
/// Input: /foo/bar
|
||||||
/// Result: ("tree hash(/foo/bar) bar", hash(/foo/bar), bar)
|
/// Result: ("tree hash(/foo/bar) bar", hash(/foo/bar), bar)
|
||||||
pub fn parse_path(path: &Path, is_blob: bool) -> (String, String, String) {
|
pub fn parse_path(path: PathBuf, is_blob: bool) -> (String, String, String) {
|
||||||
let file_name = path.file_name().unwrap().to_str().unwrap();
|
let file_name = path.file_name().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
@ -86,6 +87,48 @@ fn add_node(path: &Path, node: &str) -> io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_dates(mut path: PathBuf, date: &str) -> io::Result<()> {
|
||||||
|
let mut obj_p = path::objects();
|
||||||
|
|
||||||
|
while path.pop() {
|
||||||
|
let (dir, res) = hash_obj(path.to_str().unwrap());
|
||||||
|
obj_p.push(dir);
|
||||||
|
obj_p.push(res);
|
||||||
|
update_date(obj_p.clone(), date.clone())?;
|
||||||
|
obj_p.pop();
|
||||||
|
obj_p.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_date(path: PathBuf, date: &str) -> io::Result<()> {
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.open(path.clone())?;
|
||||||
|
|
||||||
|
let mut buffer = [0; 1];
|
||||||
|
file.seek(SeekFrom::Start(0))?;
|
||||||
|
|
||||||
|
// Seek and read until a space is found
|
||||||
|
loop {
|
||||||
|
let bytes_read = file.read(&mut buffer)?;
|
||||||
|
if bytes_read == 0 {
|
||||||
|
// Reached the end of the file without finding a space
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if buffer[0] == b' ' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write_all(&date.as_bytes())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn create_obj(name: String, content: &str) -> io::Result<()> {
|
fn create_obj(name: String, content: &str) -> io::Result<()> {
|
||||||
let mut root = path::objects();
|
let mut root = path::objects();
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use std::io::{self};
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::PathBuf;
|
||||||
use std::fs::{self};
|
use std::fs;
|
||||||
use crate::utils::path;
|
use crate::utils::path;
|
||||||
use crate::store::head;
|
use crate::store::head;
|
||||||
use crate::store::object::{parse_path, add_node, create_obj, rm_node};
|
use crate::store::object::{update_dates, parse_path, add_node, create_obj, rm_node};
|
||||||
|
|
||||||
pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
pub fn add(path: PathBuf, date: &str) -> io::Result<()> {
|
||||||
let (line, hash, name) = parse_path(path.clone(), true);
|
let (line, hash, name) = parse_path(path.clone(), true);
|
||||||
// add blob reference to parent
|
// add blob reference to parent
|
||||||
if path.iter().count() == 1 {
|
if path.iter().count() == 1 {
|
||||||
@ -21,10 +21,13 @@ pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
|||||||
// create blob object
|
// create blob object
|
||||||
create_obj(hash, &content)?;
|
create_obj(hash, &content)?;
|
||||||
|
|
||||||
|
// update date for all parent
|
||||||
|
update_dates(path, date)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rm(path: &Path) -> io::Result<()> {
|
pub fn rm(path: PathBuf) -> io::Result<()> {
|
||||||
let (line, hash, _) = parse_path(path.clone(), true);
|
let (line, hash, _) = parse_path(path.clone(), true);
|
||||||
|
|
||||||
// remove blob reference to parent
|
// remove blob reference to parent
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self};
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::PathBuf;
|
||||||
use crate::utils::{read, path};
|
use crate::utils::{read, path};
|
||||||
use crate::store::head;
|
use crate::store::head;
|
||||||
use crate::store::object::{self, parse_path, hash_obj, add_node, create_obj};
|
use crate::store::object::{self, update_dates, parse_path, hash_obj, add_node, create_obj};
|
||||||
|
|
||||||
pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
pub fn add(path: PathBuf, date: &str) -> io::Result<()> {
|
||||||
let (line, hash, name) = parse_path(path.clone(), false);
|
let (line, hash, name) = parse_path(path.clone(), false);
|
||||||
|
|
||||||
// add tree reference to parent
|
// add tree reference to parent
|
||||||
@ -21,23 +21,26 @@ pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
|||||||
content.push_str(date);
|
content.push_str(date);
|
||||||
create_obj(hash, &content)?;
|
create_obj(hash, &content)?;
|
||||||
|
|
||||||
|
// update date for all parent
|
||||||
|
update_dates(path, date)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rm(path: &Path) -> io::Result<()> {
|
pub fn rm(path: PathBuf) -> io::Result<()> {
|
||||||
let (_, lines) = read(path.to_path_buf().to_str().unwrap().to_string()).unwrap();
|
let (_, lines) = read(path.to_path_buf().to_str().unwrap().to_string()).unwrap();
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let (ftype, hash, _) = parse_line(line.unwrap());
|
let (ftype, hash, _) = parse_line(line.unwrap());
|
||||||
if ftype == String::from("blob") {
|
if ftype == String::from("blob") {
|
||||||
object::rm(&hash);
|
object::rm(&hash)?;
|
||||||
} else {
|
} else {
|
||||||
rm_hash(hash);
|
rm_hash(hash)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rm_hash(hash: String) {
|
fn rm_hash(hash: String) -> io::Result<()> {
|
||||||
let mut obj_p = path::objects();
|
let mut obj_p = path::objects();
|
||||||
let (dir, res) = hash.split_at(2);
|
let (dir, res) = hash.split_at(2);
|
||||||
obj_p.push(dir);
|
obj_p.push(dir);
|
||||||
@ -49,9 +52,9 @@ fn rm_hash(hash: String) {
|
|||||||
for line in reader {
|
for line in reader {
|
||||||
let (ftype, hash, _) = parse_line(line.unwrap());
|
let (ftype, hash, _) = parse_line(line.unwrap());
|
||||||
if ftype == String::from("blob") {
|
if ftype == String::from("blob") {
|
||||||
object::rm(&hash);
|
object::rm(&hash)?;
|
||||||
} else {
|
} else {
|
||||||
rm_hash(hash);
|
rm_hash(hash)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -59,6 +62,7 @@ fn rm_hash(hash: String) {
|
|||||||
eprintln!("error reading tree: {}", err);
|
eprintln!("error reading tree: {}", err);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(tree: String) -> Option<(String, io::Lines<io::BufReader<File>>)> {
|
pub fn read(tree: String) -> Option<(String, io::Lines<io::BufReader<File>>)> {
|
||||||
|
@ -2,4 +2,4 @@ pub mod path;
|
|||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod nextsyncignore;
|
pub mod nextsyncignore;
|
||||||
pub mod api;
|
pub mod api;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
Loading…
Reference in New Issue
Block a user