Start working on automatic file history

This commit is contained in:
timvisee 2018-04-19 00:52:59 +02:00
parent ca616f6167
commit 6da2e5ca2a
No known key found for this signature in database
GPG key ID: 109CBA0BF74036C2
7 changed files with 151 additions and 2 deletions

View file

@ -26,3 +26,6 @@ ffsend-api = { version = "*", path = "../api" }
open = "1"
pbr = "1"
rpassword = "2.0"
serde = "1.0"
serde_derive = "1.0"
toml = "0.4"

15
cli/history.toml Normal file
View file

@ -0,0 +1,15 @@
[[files]]
id = "462aad1de5"
time = "2018-04-18T22:45:01.121174527Z"
host = "http://localhost:8081/"
url = "http://localhost:8081/download/462aad1de5/"
secret = [244, 53, 118, 229, 172, 83, 160, 232, 231, 244, 119, 59, 193, 11, 114, 78]
owner_token = "07734e9bfc8fc7d59873"
[[files]]
id = "d0ef8edb0a"
time = "2018-04-18T22:45:06.934834655Z"
host = "http://localhost:8081/"
url = "http://localhost:8081/download/d0ef8edb0a/"
secret = [7, 190, 112, 142, 31, 59, 95, 158, 167, 57, 12, 120, 224, 150, 88, 94]
owner_token = "3e17d911164114ff3973"

View file

@ -1,5 +1,5 @@
use std::fs::File;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use clap::ArgMatches;
@ -11,6 +11,7 @@ use ffsend_api::reqwest::Client;
use cmd::matcher::{Matcher, MainMatcher, UploadMatcher};
use error::ActionError;
use history::History;
use progress::ProgressBar;
use util::{
ErrorHintsBuilder,
@ -124,6 +125,18 @@ impl<'a> Upload<'a> {
println!("Download URL: {}", url);
println!("Owner token: {}", file.owner_token().unwrap());
// Update the history manager, load it first
// TODO: complete this implementation
let history_path = PathBuf::from("./history.toml");
match History::load_or_new(history_path) {
Ok(mut history) => {
// Add the file, and save
history.add(file.clone());
history.save();
},
Err(err) => println!("TODO: PRINT LOAD ERROR HERE"),
}
// Open the URL in the browser
if matcher_upload.open() {
if let Err(err) = open_url(url.clone()) {

102
cli/src/history.rs Normal file
View file

@ -0,0 +1,102 @@
extern crate toml;
use std::fs;
use std::io::Read;
use std::path::PathBuf;
use ffsend_api::file::remote_file::RemoteFile;
#[derive(Serialize, Deserialize)]
pub struct History {
/// The file history.
files: Vec<RemoteFile>,
/// Whether the list of files has changed.
#[serde(skip)]
changed: bool,
/// An optional path to automatically save the history to.
#[serde(skip)]
autosave: Option<PathBuf>,
}
impl History {
/// Construct a new history.
/// A path may be given to automatically save the history to once changed.
pub fn new(autosave: Option<PathBuf>) -> Self {
let mut history = History::default();
history.autosave = autosave;
history
}
/// Load the history from the given file.
/// If the file doesn't exist, create a new empty history instance.
///
/// Autosaving will be enabled, and will save to the given file path.
pub fn load_or_new(file: PathBuf) -> Result<Self, ()> {
if file.is_file() {
Self::load(file)
} else {
Ok(Self::new(Some(file)))
}
}
/// Load the history from the given file.
pub fn load(path: PathBuf) -> Result<Self, ()> {
// Read the file to a string
// TODO: handle error
let data = fs::read_to_string(path.clone()).unwrap();
// Parse the data, set the autosave path
let mut history: Self = toml::from_str(&data).unwrap();
history.autosave = Some(path);
Ok(history)
}
/// Save the history to the internal autosave file.
pub fn save(&mut self) -> Result<(), ()> {
// Build the data
// TODO: handle error
let data = toml::to_string(self).unwrap();
// Write to a file
// TODO: handle error
fs::write(self.autosave.as_ref().unwrap(), data).unwrap();
// There are no new changes, set the flag
self.changed = false;
Ok(())
}
/// Add the given remote file to the history.
pub fn add(&mut self, file: RemoteFile) {
self.files.push(file);
self.changed = true;
}
/// Get all files.
pub fn files(&self) -> &Vec<RemoteFile> {
&self.files
}
}
impl Drop for History {
fn drop(&mut self) {
// Automatically save if enabled and something was changed
if self.autosave.is_some() && self.changed {
self.save();
}
}
}
impl Default for History {
fn default() -> Self {
Self {
files: Vec::new(),
changed: false,
autosave: None,
}
}
}

View file

@ -7,10 +7,14 @@ extern crate failure;
extern crate failure_derive;
extern crate ffsend_api;
extern crate rpassword;
extern crate serde;
#[macro_use]
extern crate serde_derive;
mod action;
mod cmd;
mod error;
mod history;
mod host;
mod progress;
mod util;