|
|
@ -2,11 +2,10 @@ use crate::encoder; |
|
|
|
|
|
|
|
|
|
|
|
use encoder::Encoder; |
|
|
|
use encoder::Encoder; |
|
|
|
|
|
|
|
|
|
|
|
use once_cell::sync::Lazy; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::collections::HashSet; |
|
|
|
use std::collections::HashSet; |
|
|
|
use std::hash::{Hash, Hasher}; |
|
|
|
use std::hash::{Hash, Hasher}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::env; |
|
|
|
use std::fs; |
|
|
|
use std::fs; |
|
|
|
use std::path::Path; |
|
|
|
use std::path::Path; |
|
|
|
use std::io::{self, Write, BufRead}; |
|
|
|
use std::io::{self, Write, BufRead}; |
|
|
@ -14,10 +13,10 @@ use std::fmt; |
|
|
|
use std::cmp::{PartialEq, Ordering}; |
|
|
|
use std::cmp::{PartialEq, Ordering}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static STORAGE_FOLDER: Lazy<String> = Lazy::new(|| "storage".to_string() ); |
|
|
|
static ENV_MPS_HOME: &str = "MPS_HOME"; |
|
|
|
static STORAGE_PATH: Lazy<String> = Lazy::new(|| {
|
|
|
|
|
|
|
|
format!("{}/db.mps", &*STORAGE_FOLDER) |
|
|
|
static PATH_STORAGE: &str = "storage"; // should be under git
|
|
|
|
}); |
|
|
|
static PATH_DB: &str = "db.mps"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)] |
|
|
|
#[derive(Clone)] |
|
|
@ -82,15 +81,30 @@ impl Storage { |
|
|
|
encoder: Encoder::from(&passphrase) |
|
|
|
encoder: Encoder::from(&passphrase) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn get_storage_path() -> io::Result<String> { |
|
|
|
|
|
|
|
let mps_home = env::var(ENV_MPS_HOME).map_err(|err| { |
|
|
|
|
|
|
|
io::Error::new(io::ErrorKind::NotFound, format!("{} error: {}", ENV_MPS_HOME, err)) |
|
|
|
|
|
|
|
})?; |
|
|
|
|
|
|
|
let result = format!("{}/{}", mps_home, PATH_STORAGE); |
|
|
|
|
|
|
|
Ok(result) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn get_storage_db_path() -> io::Result<String> { |
|
|
|
|
|
|
|
let st = Storage::get_storage_path()?; |
|
|
|
|
|
|
|
let result = format!("{}/{}", st, PATH_DB); |
|
|
|
|
|
|
|
Ok(result) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn from_db(passphrase: String) -> io::Result<Storage> { |
|
|
|
pub fn from_db(passphrase: String) -> io::Result<Storage> { |
|
|
|
if !Storage::is_inited() { |
|
|
|
if !Storage::is_inited()? { |
|
|
|
return Err(io::Error::new( |
|
|
|
return Err(io::Error::new( |
|
|
|
io::ErrorKind::Other, |
|
|
|
io::ErrorKind::Other, |
|
|
|
"Storage is not initialized" |
|
|
|
"Storage is not initialized" |
|
|
|
)); |
|
|
|
)); |
|
|
|
} |
|
|
|
} |
|
|
|
let encoder = Encoder::from(&passphrase); |
|
|
|
let encoder = Encoder::from(&passphrase); |
|
|
|
let file = fs::File::open(&*STORAGE_PATH)?; |
|
|
|
let file = fs::File::open(Storage::get_storage_db_path()?)?; |
|
|
|
let reader = io::BufReader::new(file); |
|
|
|
let reader = io::BufReader::new(file); |
|
|
|
let mut items = HashSet::<Item>::new(); |
|
|
|
let mut items = HashSet::<Item>::new(); |
|
|
|
let mut id: Option<String> = None; |
|
|
|
let mut id: Option<String> = None; |
|
|
@ -129,31 +143,36 @@ impl Storage { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn init(passphrase: String) -> io::Result<()> { |
|
|
|
pub fn init(passphrase: String) -> io::Result<()> { |
|
|
|
fs::create_dir(&*STORAGE_FOLDER)?; |
|
|
|
// TODO: revrite all logic
|
|
|
|
println!("Storage folder created"); |
|
|
|
// Check if the folder exists and is a directory
|
|
|
|
fs::File::create(&*STORAGE_PATH)?; |
|
|
|
//if path.exists() && path.is_dir() {
|
|
|
|
let st = Storage::new(passphrase); |
|
|
|
// Err(io::Error::new(io::ErrorKind::NotFound, "Folder does not exist"))
|
|
|
|
st.dump()?; |
|
|
|
//}
|
|
|
|
println!("Storage db created."); |
|
|
|
//fs::File::create(&*STORAGE_PATH)?;
|
|
|
|
println!("Initialization complete."); |
|
|
|
//let st = Storage::new(passphrase);
|
|
|
|
println!(""); |
|
|
|
//st.dump()?;
|
|
|
|
println!("Now it's required to add folder `{}` under git manually.", &*STORAGE_FOLDER); |
|
|
|
//println!("Storage db created.");
|
|
|
|
println!("Don't worry it's going to be encrypted."); |
|
|
|
//println!("Initialization complete.");
|
|
|
|
|
|
|
|
//println!("");
|
|
|
|
|
|
|
|
//println!("Now it's required to add folder `{}` under git manually.", &*STORAGE_FOLDER);
|
|
|
|
|
|
|
|
//println!("Don't worry it's going to be encrypted.");
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn print_init_hint() { |
|
|
|
pub fn print_init_hint() -> io::Result<()> { |
|
|
|
println!("mps can work only when storage inited."); |
|
|
|
println!("mps can work only when storage inited."); |
|
|
|
println!("Hint: you can restore your storage if you have it already:"); |
|
|
|
println!("Hint: you can restore your storage if you have it already:"); |
|
|
|
println!(" git clone <your_storage_git_url> {}", &*STORAGE_FOLDER); |
|
|
|
println!(" git clone <your_storage_git_url> {}", Storage::get_storage_path()?); |
|
|
|
println!("to init manually your storage and config") |
|
|
|
println!("to init manually your storage and config"); |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_inited() -> bool { |
|
|
|
pub fn is_inited() -> io::Result<bool> { |
|
|
|
// TODO: check db
|
|
|
|
// TODO: check db
|
|
|
|
// TODO check git
|
|
|
|
// TODO check git
|
|
|
|
let path = Path::new(&*STORAGE_FOLDER); |
|
|
|
//let path = Path::new(&*STORAGE_FOLDER);
|
|
|
|
return path.exists(); |
|
|
|
//return path.exists();
|
|
|
|
|
|
|
|
Ok(true) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -189,7 +208,7 @@ impl Storage { |
|
|
|
let mut file = fs::OpenOptions::new() |
|
|
|
let mut file = fs::OpenOptions::new() |
|
|
|
.write(true) |
|
|
|
.write(true) |
|
|
|
.append(false) |
|
|
|
.append(false) |
|
|
|
.open(&*STORAGE_PATH)?; |
|
|
|
.open(Storage::get_storage_db_path()?)?; |
|
|
|
writeln!(file, "{}", self.encoder.get_encoded_test_passphrase()?)?; |
|
|
|
writeln!(file, "{}", self.encoder.get_encoded_test_passphrase()?)?; |
|
|
|
|
|
|
|
|
|
|
|
for item in self.items.iter() { |
|
|
|
for item in self.items.iter() { |
|
|
|