aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-client
diff options
context:
space:
mode:
authorEllie Huxtable <e@elm.sh>2021-04-20 21:53:07 +0100
committerGitHub <noreply@github.com>2021-04-20 20:53:07 +0000
commita21737e2b7f8d1e426726bdd7536033f299d476a (patch)
treee940afdff9c145d25d9a2895fd44a77d70719a2e /atuin-client
parentSwitch to Warp + SQLx, use async, switch to Rust stable (#36) (diff)
downloadatuin-a21737e2b7f8d1e426726bdd7536033f299d476a.zip
Use cargo workspaces (#37)
* Switch to Cargo workspaces Breaking things into "client", "server" and "common" makes managing the codebase much easier! client - anything running on a user's machine for adding history server - handles storing/syncing history and running a HTTP server common - request/response API definitions, common utils, etc * Update dockerfile
Diffstat (limited to '')
-rw-r--r--atuin-client/Cargo.toml40
-rw-r--r--atuin-client/config.toml (renamed from config.toml)19
-rw-r--r--atuin-client/src/api_client.rs (renamed from src/local/api_client.rs)9
-rw-r--r--atuin-client/src/database.rs (renamed from src/local/database.rs)0
-rw-r--r--atuin-client/src/encryption.rs (renamed from src/local/encryption.rs)4
-rw-r--r--atuin-client/src/history.rs (renamed from src/local/history.rs)2
-rw-r--r--atuin-client/src/import.rs (renamed from src/local/import.rs)0
-rw-r--r--atuin-client/src/lib.rs (renamed from src/local/mod.rs)7
-rw-r--r--atuin-client/src/settings.rs (renamed from src/settings.rs)59
-rw-r--r--atuin-client/src/sync.rs (renamed from src/local/sync.rs)19
10 files changed, 83 insertions, 76 deletions
diff --git a/atuin-client/Cargo.toml b/atuin-client/Cargo.toml
new file mode 100644
index 00000000..06c96a9a
--- /dev/null
+++ b/atuin-client/Cargo.toml
@@ -0,0 +1,40 @@
+[package]
+name = "atuin-client"
+version = "0.1.0"
+authors = ["Ellie Huxtable <ellie@elliehuxtable.com>"]
+edition = "2018"
+license = "MIT"
+description = "client library for atuin"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+atuin-common = { path = "../atuin-common", version = "0.1.0" }
+
+log = "0.4"
+fern = {version = "0.6.0", features = ["colored"] }
+chrono = { version = "0.4", features = ["serde"] }
+eyre = "0.6"
+directories = "3"
+uuid = { version = "0.8", features = ["v4"] }
+indicatif = "0.15.0"
+whoami = "1.1.2"
+chrono-english = "0.1.4"
+config = "0.11"
+serde_derive = "1.0.125"
+serde = "1.0.125"
+serde_json = "1.0.64"
+rmp-serde = "0.15.4"
+sodiumoxide = "0.2.6"
+reqwest = { version = "0.11", features = ["blocking", "json"] }
+base64 = "0.13.0"
+parse_duration = "2.1.1"
+rand = "0.8.3"
+rust-crypto = "^0.2"
+tokio = { version = "1", features = ["full"] }
+async-trait = "0.1.49"
+urlencoding = "1.1.1"
+humantime = "2.1.0"
+rusqlite= { version = "0.25", features = ["bundled"] }
+itertools = "0.10.0"
+shellexpand = "2"
diff --git a/config.toml b/atuin-client/config.toml
index fe776d6e..33e5b545 100644
--- a/config.toml
+++ b/atuin-client/config.toml
@@ -1,8 +1,3 @@
-# A'tuin example config
-
-# This section specifies the config for a local client,
-# ie where your shell history is on your local machine
-[local]
## where to store your database, default is your system data directory
## mac: ~/Library/Application Support/com.elliehuxtable.atuin/history.db
## linux: ~/.local/share/atuin/history.db
@@ -27,17 +22,3 @@
## address of the sync server
# sync_address = "https://api.atuin.sh"
-
-# This section configures the sync server, if you decide to host your own
-[server]
-## host to bind, can also be passed via CLI args
-# host = "127.0.0.1"
-
-## port to bind, can also be passed via CLI args
-# port = 8888
-
-## whether to allow anyone to register an account
-# open_registration = false
-
-## URI for postgres (using development creds here)
-# db_uri="postgres://username:password@localhost/atuin"
diff --git a/src/local/api_client.rs b/atuin-client/src/api_client.rs
index 1b64a295..db2802c3 100644
--- a/src/local/api_client.rs
+++ b/atuin-client/src/api_client.rs
@@ -4,10 +4,11 @@ use reqwest::header::{HeaderMap, AUTHORIZATION};
use reqwest::Url;
use sodiumoxide::crypto::secretbox;
-use crate::api::{AddHistoryRequest, CountResponse, SyncHistoryResponse};
-use crate::local::encryption::decrypt;
-use crate::local::history::History;
-use crate::utils::hash_str;
+use atuin_common::api::{AddHistoryRequest, CountResponse, SyncHistoryResponse};
+use atuin_common::utils::hash_str;
+
+use crate::encryption::decrypt;
+use crate::history::History;
pub struct Client<'a> {
sync_addr: &'a str,
diff --git a/src/local/database.rs b/atuin-client/src/database.rs
index abc22bb8..abc22bb8 100644
--- a/src/local/database.rs
+++ b/atuin-client/src/database.rs
diff --git a/src/local/encryption.rs b/atuin-client/src/encryption.rs
index 3c1699e3..37153f94 100644
--- a/src/local/encryption.rs
+++ b/atuin-client/src/encryption.rs
@@ -15,7 +15,7 @@ use std::path::PathBuf;
use eyre::{eyre, Result};
use sodiumoxide::crypto::secretbox;
-use crate::local::history::History;
+use crate::history::History;
use crate::settings::Settings;
#[derive(Debug, Serialize, Deserialize)]
@@ -26,7 +26,7 @@ pub struct EncryptedHistory {
// Loads the secret key, will create + save if it doesn't exist
pub fn load_key(settings: &Settings) -> Result<secretbox::Key> {
- let path = settings.local.key_path.as_str();
+ let path = settings.key_path.as_str();
if PathBuf::from(path).exists() {
let bytes = std::fs::read(path)?;
diff --git a/src/local/history.rs b/atuin-client/src/history.rs
index 1712f8b9..7f607784 100644
--- a/src/local/history.rs
+++ b/atuin-client/src/history.rs
@@ -3,7 +3,7 @@ use std::hash::{Hash, Hasher};
use chrono::Utc;
-use crate::command::uuid_v4;
+use atuin_common::utils::uuid_v4;
// Any new fields MUST be Optional<>!
#[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/src/local/import.rs b/atuin-client/src/import.rs
index 3b0b2a69..3b0b2a69 100644
--- a/src/local/import.rs
+++ b/atuin-client/src/import.rs
diff --git a/src/local/mod.rs b/atuin-client/src/lib.rs
index 9fe31292..1207bfdb 100644
--- a/src/local/mod.rs
+++ b/atuin-client/src/lib.rs
@@ -1,6 +1,13 @@
+#[macro_use]
+extern crate log;
+
+#[macro_use]
+extern crate serde_derive;
+
pub mod api_client;
pub mod database;
pub mod encryption;
pub mod history;
pub mod import;
+pub mod settings;
pub mod sync;
diff --git a/src/settings.rs b/atuin-client/src/settings.rs
index 5325610e..e28963c0 100644
--- a/src/settings.rs
+++ b/atuin-client/src/settings.rs
@@ -12,7 +12,7 @@ use parse_duration::parse;
pub const HISTORY_PAGE_SIZE: i64 = 100;
#[derive(Clone, Debug, Deserialize)]
-pub struct Local {
+pub struct Settings {
pub dialect: String,
pub auto_sync: bool,
pub sync_address: String,
@@ -26,7 +26,7 @@ pub struct Local {
pub session_token: String,
}
-impl Local {
+impl Settings {
pub fn save_sync_time() -> Result<()> {
let sync_time_path = ProjectDirs::from("com", "elliehuxtable", "atuin")
.ok_or_else(|| eyre!("could not determine key file location"))?;
@@ -66,28 +66,12 @@ impl Local {
match parse(self.sync_frequency.as_str()) {
Ok(d) => {
let d = chrono::Duration::from_std(d).unwrap();
- Ok(Utc::now() - Local::last_sync()? >= d)
+ Ok(Utc::now() - Settings::last_sync()? >= d)
}
Err(e) => Err(eyre!("failed to check sync: {}", e)),
}
}
-}
-#[derive(Clone, Debug, Deserialize)]
-pub struct Server {
- pub host: String,
- pub port: u16,
- pub db_uri: String,
- pub open_registration: bool,
-}
-
-#[derive(Clone, Debug, Deserialize)]
-pub struct Settings {
- pub local: Local,
- pub server: Server,
-}
-
-impl Settings {
pub fn new() -> Result<Self> {
let config_dir = ProjectDirs::from("com", "elliehuxtable", "atuin").unwrap();
let config_dir = config_dir.config_dir();
@@ -103,8 +87,6 @@ impl Settings {
config_file
};
- // create the config file if it does not exist
-
let mut s = Config::new();
let db_path = ProjectDirs::from("com", "elliehuxtable", "atuin")
@@ -122,18 +104,13 @@ impl Settings {
.data_dir()
.join("session");
- s.set_default("local.db_path", db_path.to_str())?;
- s.set_default("local.key_path", key_path.to_str())?;
- s.set_default("local.session_path", session_path.to_str())?;
- s.set_default("local.dialect", "us")?;
- s.set_default("local.auto_sync", true)?;
- s.set_default("local.sync_frequency", "5m")?;
- s.set_default("local.sync_address", "https://api.atuin.sh")?;
-
- s.set_default("server.host", "127.0.0.1")?;
- s.set_default("server.port", 8888)?;
- s.set_default("server.open_registration", false)?;
- s.set_default("server.db_uri", "default_uri")?;
+ s.set_default("db_path", db_path.to_str())?;
+ s.set_default("key_path", key_path.to_str())?;
+ s.set_default("session_path", session_path.to_str())?;
+ s.set_default("dialect", "us")?;
+ s.set_default("auto_sync", true)?;
+ s.set_default("sync_frequency", "5m")?;
+ s.set_default("sync_address", "https://api.atuin.sh")?;
if config_file.exists() {
s.merge(ConfigFile::with_name(config_file.to_str().unwrap()))?;
@@ -146,24 +123,24 @@ impl Settings {
s.merge(Environment::with_prefix("atuin").separator("_"))?;
// all paths should be expanded
- let db_path = s.get_str("local.db_path")?;
+ let db_path = s.get_str("db_path")?;
let db_path = shellexpand::full(db_path.as_str())?;
- s.set("local.db_path", db_path.to_string())?;
+ s.set("db_path", db_path.to_string())?;
- let key_path = s.get_str("local.key_path")?;
+ let key_path = s.get_str("key_path")?;
let key_path = shellexpand::full(key_path.as_str())?;
- s.set("local.key_path", key_path.to_string())?;
+ s.set("key_path", key_path.to_string())?;
- let session_path = s.get_str("local.session_path")?;
+ let session_path = s.get_str("session_path")?;
let session_path = shellexpand::full(session_path.as_str())?;
- s.set("local.session_path", session_path.to_string())?;
+ s.set("session_path", session_path.to_string())?;
// Finally, set the auth token
if Path::new(session_path.to_string().as_str()).exists() {
let token = std::fs::read_to_string(session_path.to_string())?;
- s.set("local.session_token", token.trim())?;
+ s.set("session_token", token.trim())?;
} else {
- s.set("local.session_token", "not logged in")?;
+ s.set("session_token", "not logged in")?;
}
s.try_into()
diff --git a/src/local/sync.rs b/atuin-client/src/sync.rs
index e0feb759..0ca8d3a6 100644
--- a/src/local/sync.rs
+++ b/atuin-client/src/sync.rs
@@ -3,11 +3,12 @@ use std::convert::TryInto;
use chrono::prelude::*;
use eyre::Result;
-use crate::local::api_client;
-use crate::local::database::Database;
-use crate::local::encryption::{encrypt, load_key};
-use crate::settings::{Local, Settings, HISTORY_PAGE_SIZE};
-use crate::{api::AddHistoryRequest, utils::hash_str};
+use atuin_common::{api::AddHistoryRequest, utils::hash_str};
+
+use crate::api_client;
+use crate::database::Database;
+use crate::encryption::{encrypt, load_key};
+use crate::settings::{Settings, HISTORY_PAGE_SIZE};
// Currently sync is kinda naive, and basically just pages backwards through
// history. This means newly added stuff shows up properly! We also just use
@@ -33,7 +34,7 @@ async fn sync_download(
let mut last_sync = if force {
Utc.timestamp_millis(0)
} else {
- Local::last_sync()?
+ Settings::last_sync()?
};
let mut last_timestamp = Utc.timestamp_millis(0);
@@ -124,8 +125,8 @@ async fn sync_upload(
pub async fn sync(settings: &Settings, force: bool, db: &mut (impl Database + Send)) -> Result<()> {
let client = api_client::Client::new(
- settings.local.sync_address.as_str(),
- settings.local.session_token.as_str(),
+ settings.sync_address.as_str(),
+ settings.session_token.as_str(),
load_key(settings)?,
);
@@ -135,7 +136,7 @@ pub async fn sync(settings: &Settings, force: bool, db: &mut (impl Database + Se
debug!("sync downloaded {}", download.0);
- Local::save_sync_time()?;
+ Settings::save_sync_time()?;
Ok(())
}