summaryrefslogtreecommitdiffstats
path: root/atuin-client
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@elliehuxtable.com>2024-04-18 16:41:28 +0100
committerGitHub <noreply@github.com>2024-04-18 16:41:28 +0100
commit95cc472037fcb3207b510e67f1a44af4e2a2cae9 (patch)
treefc1d3e71d8e0bdb806370e4144fd6f373bcc9c5e /atuin-client
parent176eae02f7f855ef40a4461caca61d530486113f (diff)
chore: move crates into crates/ dir (#1958)
I'd like to tidy up the root a little, and it's nice to have all the rust crates in one place
Diffstat (limited to 'atuin-client')
-rw-r--r--atuin-client/Cargo.toml73
-rw-r--r--atuin-client/config.toml210
-rw-r--r--atuin-client/migrations/20210422143411_create_history.sql16
-rw-r--r--atuin-client/migrations/20220505083406_create-events.sql11
-rw-r--r--atuin-client/migrations/20220806155627_interactive_search_index.sql6
-rw-r--r--atuin-client/migrations/20230315220114_drop-events.sql2
-rw-r--r--atuin-client/migrations/20230319185725_deleted_at.sql2
-rw-r--r--atuin-client/record-migrations/20230531212437_create-records.sql16
-rw-r--r--atuin-client/record-migrations/20231127090831_create-store.sql15
-rw-r--r--atuin-client/src/api_client.rs415
-rw-r--r--atuin-client/src/database.rs1128
-rw-r--r--atuin-client/src/encryption.rs430
-rw-r--r--atuin-client/src/history.rs517
-rw-r--r--atuin-client/src/history/builder.rs99
-rw-r--r--atuin-client/src/history/store.rs410
-rw-r--r--atuin-client/src/import/bash.rs218
-rw-r--r--atuin-client/src/import/fish.rs179
-rw-r--r--atuin-client/src/import/mod.rs111
-rw-r--r--atuin-client/src/import/nu.rs67
-rw-r--r--atuin-client/src/import/nu_histdb.rs113
-rw-r--r--atuin-client/src/import/resh.rs140
-rw-r--r--atuin-client/src/import/xonsh.rs233
-rw-r--r--atuin-client/src/import/xonsh_sqlite.rs217
-rw-r--r--atuin-client/src/import/zsh.rs229
-rw-r--r--atuin-client/src/import/zsh_histdb.rs247
-rw-r--r--atuin-client/src/kv.rs265
-rw-r--r--atuin-client/src/lib.rs21
-rw-r--r--atuin-client/src/ordering.rs32
-rw-r--r--atuin-client/src/record/encryption.rs373
-rw-r--r--atuin-client/src/record/mod.rs6
-rw-r--r--atuin-client/src/record/sqlite_store.rs641
-rw-r--r--atuin-client/src/record/store.rs60
-rw-r--r--atuin-client/src/record/sync.rs607
-rw-r--r--atuin-client/src/secrets.rs59
-rw-r--r--atuin-client/src/settings.rs784
-rw-r--r--atuin-client/src/settings/dotfiles.rs6
-rw-r--r--atuin-client/src/sync.rs210
-rw-r--r--atuin-client/src/utils.rs14
-rw-r--r--atuin-client/tests/data/xonsh-history.sqlitebin12288 -> 0 bytes
-rw-r--r--atuin-client/tests/data/xonsh/xonsh-82eafbf5-9f43-489a-80d2-61c7dc6ef542.json12
-rw-r--r--atuin-client/tests/data/xonsh/xonsh-de16af90-9148-4461-8df3-5b5659c6420d.json12
41 files changed, 0 insertions, 8206 deletions
diff --git a/atuin-client/Cargo.toml b/atuin-client/Cargo.toml
deleted file mode 100644
index c8ca74ae..00000000
--- a/atuin-client/Cargo.toml
+++ /dev/null
@@ -1,73 +0,0 @@
-[package]
-name = "atuin-client"
-edition = "2021"
-description = "client library for atuin"
-
-rust-version = { workspace = true }
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[features]
-default = ["sync"]
-sync = ["urlencoding", "reqwest", "sha2", "hex"]
-check-update = []
-
-[dependencies]
-atuin-common = { path = "../atuin-common", version = "18.2.0" }
-
-log = { workspace = true }
-base64 = { workspace = true }
-time = { workspace = true, features = ["macros", "formatting"] }
-clap = { workspace = true }
-eyre = { workspace = true }
-directories = { workspace = true }
-uuid = { workspace = true }
-whoami = { workspace = true }
-interim = { workspace = true }
-config = { workspace = true }
-serde = { workspace = true }
-serde_json = { workspace = true }
-parse_duration = "2.1.1"
-async-trait = { workspace = true }
-itertools = { workspace = true }
-rand = { workspace = true }
-shellexpand = "3"
-sqlx = { workspace = true, features = ["sqlite", "regexp"] }
-minspan = "0.1.1"
-regex = "1.10.4"
-serde_regex = "1.1.0"
-fs-err = { workspace = true }
-sql-builder = "3"
-memchr = "2.5"
-rmp = { version = "0.8.11" }
-typed-builder = { workspace = true }
-tokio = { workspace = true }
-semver = { workspace = true }
-thiserror = { workspace = true }
-futures = "0.3"
-crypto_secretbox = "0.1.1"
-generic-array = { version = "0.14", features = ["serde"] }
-serde_with = "3.5.1"
-
-# encryption
-rusty_paseto = { version = "0.6.0", default-features = false }
-rusty_paserk = { version = "0.3.0", default-features = false, features = [
- "v4",
- "serde",
-] }
-
-# sync
-urlencoding = { version = "2.1.0", optional = true }
-reqwest = { workspace = true, optional = true }
-hex = { version = "0.4", optional = true }
-sha2 = { version = "0.10", optional = true }
-indicatif = "0.17.7"
-
-[dev-dependencies]
-tokio = { version = "1", features = ["full"] }
-pretty_assertions = { workspace = true }
diff --git a/atuin-client/config.toml b/atuin-client/config.toml
deleted file mode 100644
index 415fd441..00000000
--- a/atuin-client/config.toml
+++ /dev/null
@@ -1,210 +0,0 @@
-## where to store your database, default is your system data directory
-## linux/mac: ~/.local/share/atuin/history.db
-## windows: %USERPROFILE%/.local/share/atuin/history.db
-# db_path = "~/.history.db"
-
-## where to store your encryption key, default is your system data directory
-## linux/mac: ~/.local/share/atuin/key
-## windows: %USERPROFILE%/.local/share/atuin/key
-# key_path = "~/.key"
-
-## where to store your auth session token, default is your system data directory
-## linux/mac: ~/.local/share/atuin/session
-## windows: %USERPROFILE%/.local/share/atuin/session
-# session_path = "~/.session"
-
-## date format used, either "us" or "uk"
-# dialect = "us"
-
-## default timezone to use when displaying time
-## either "l", "local" to use the system's current local timezone, or an offset
-## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]"
-## for example: "+9", "-05", "+03:30", "-01:23:45", etc.
-# timezone = "local"
-
-## enable or disable automatic sync
-# auto_sync = true
-
-## enable or disable automatic update checks
-# update_check = true
-
-## address of the sync server
-# sync_address = "https://api.atuin.sh"
-
-## how often to sync history. note that this is only triggered when a command
-## is ran, so sync intervals may well be longer
-## set it to 0 to sync after every command
-# sync_frequency = "10m"
-
-## which search mode to use
-## possible values: prefix, fulltext, fuzzy, skim
-# search_mode = "fuzzy"
-
-## which filter mode to use
-## possible values: global, host, session, directory
-# filter_mode = "global"
-
-## With workspace filtering enabled, Atuin will filter for commands executed
-## in any directory within a git repository tree (default: false)
-# workspaces = false
-
-## which filter mode to use when atuin is invoked from a shell up-key binding
-## the accepted values are identical to those of "filter_mode"
-## leave unspecified to use same mode set in "filter_mode"
-# filter_mode_shell_up_key_binding = "global"
-
-## which search mode to use when atuin is invoked from a shell up-key binding
-## the accepted values are identical to those of "search_mode"
-## leave unspecified to use same mode set in "search_mode"
-# search_mode_shell_up_key_binding = "fuzzy"
-
-## which style to use
-## possible values: auto, full, compact
-# style = "auto"
-
-## the maximum number of lines the interface should take up
-## set it to 0 to always go full screen
-# inline_height = 0
-
-## Invert the UI - put the search bar at the top , Default to `false`
-# invert = false
-
-## enable or disable showing a preview of the selected command
-## useful when the command is longer than the terminal width and is cut off
-# show_preview = false
-
-## enable or disable automatic preview. It shows a preview, if the command is
-## longer than the width of the terminal. It respects max_preview_height.
-## (default: true)
-# show_preview_auto = true
-
-## what to do when the escape key is pressed when searching
-## possible values: return-original, return-query
-# exit_mode = "return-original"
-
-## possible values: emacs, subl
-# word_jump_mode = "emacs"
-
-## characters that count as a part of a word
-# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
-
-## number of context lines to show when scrolling by pages
-# scroll_context_lines = 1
-
-## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts
-## alt-0 .. alt-9
-# ctrl_n_shortcuts = false
-
-## default history list format - can also be specified with the --format arg
-# history_format = "{time}\t{command}\t{duration}"
-
-## prevent commands matching any of these regexes from being written to history.
-## Note that these regular expressions are unanchored, i.e. if they don't start
-## with ^ or end with $, they'll match anywhere in the command.
-## For details on the supported regular expression syntax, see
-## https://docs.rs/regex/latest/regex/#syntax
-# history_filter = [
-# "^secret-cmd",
-# "^innocuous-cmd .*--secret=.+",
-# ]
-
-## prevent commands run with cwd matching any of these regexes from being written
-## to history. Note that these regular expressions are unanchored, i.e. if they don't
-## start with ^ or end with $, they'll match anywhere in CWD.
-## For details on the supported regular expression syntax, see
-## https://docs.rs/regex/latest/regex/#syntax
-# cwd_filter = [
-# "^/very/secret/area",
-# ]
-
-## Configure the maximum height of the preview to show.
-## Useful when you have long scripts in your history that you want to distinguish
-## by more than the first few lines.
-# max_preview_height = 4
-
-## Configure whether or not to show the help row, which includes the current Atuin
-## version (and whether an update is available), a keymap hint, and the total
-## amount of commands in your history.
-# show_help = true
-
-## Configure whether or not to show tabs for search and inspect
-# show_tabs = true
-
-## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include
-## 1. AWS key id
-## 2. Github pat (old and new)
-## 3. Slack oauth tokens (bot, user)
-## 4. Slack webhooks
-## 5. Stripe live/test keys
-# secrets_filter = true
-
-## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command. Press tab to return to the shell and edit.
-# This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
-enter_accept = true
-
-## Defaults to "emacs". This specifies the keymap on the startup of `atuin
-## search`. If this is set to "auto", the startup keymap mode in the Atuin
-## search is automatically selected based on the shell's keymap where the
-## keybinding is defined. If this is set to "emacs", "vim-insert", or
-## "vim-normal", the startup keymap mode in the Atuin search is forced to be
-## the specified one.
-# keymap_mode = "auto"
-
-## Cursor style in each keymap mode. If specified, the cursor style is changed
-## in entering the cursor shape. Available values are "default" and
-## "{blink,steady}-{block,underline,bar}".
-# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
-
-# network_connect_timeout = 5
-# network_timeout = 5
-
-## Timeout (in seconds) for acquiring a local database connection (sqlite)
-# local_timeout = 5
-
-## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc.
-## Alternatively, set env NO_MOTION=true
-# prefers_reduced_motion = false
-
-[stats]
-## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl
-# common_subcommands = [
-# "apt",
-# "cargo",
-# "composer",
-# "dnf",
-# "docker",
-# "git",
-# "go",
-# "ip",
-# "kubectl",
-# "nix",
-# "nmcli",
-# "npm",
-# "pecl",
-# "pnpm",
-# "podman",
-# "port",
-# "systemctl",
-# "tmux",
-# "yarn",
-# ]
-
-## Set commands that should be totally stripped and ignored from stats
-# common_prefix = ["sudo"]
-
-## Set commands that will be completely ignored from stats
-# ignored_commands = [
-# "cd",
-# "ls",
-# "vi"
-# ]
-
-[keys]
-# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry.
-# scroll_exits = false
-
-[sync]
-# Enable sync v2 by default
-# This ensures that sync v2 is enabled for new installs only
-# In a later release it will become the default across the board
-records = true
diff --git a/atuin-client/migrations/20210422143411_create_history.sql b/atuin-client/migrations/20210422143411_create_history.sql
deleted file mode 100644
index 1f3f8686..00000000
--- a/atuin-client/migrations/20210422143411_create_history.sql
+++ /dev/null
@@ -1,16 +0,0 @@
--- Add migration script here
-create table if not exists history (
- id text primary key,
- timestamp integer not null,
- duration integer not null,
- exit integer not null,
- command text not null,
- cwd text not null,
- session text not null,
- hostname text not null,
-
- unique(timestamp, cwd, command)
-);
-
-create index if not exists idx_history_timestamp on history(timestamp);
-create index if not exists idx_history_command on history(command);
diff --git a/atuin-client/migrations/20220505083406_create-events.sql b/atuin-client/migrations/20220505083406_create-events.sql
deleted file mode 100644
index f6cafeba..00000000
--- a/atuin-client/migrations/20220505083406_create-events.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-create table if not exists events (
- id text primary key,
- timestamp integer not null,
- hostname text not null,
- event_type text not null,
-
- history_id text not null
-);
-
--- Ensure there is only ever one of each event type per history item
-create unique index history_event_idx ON events(event_type, history_id);
diff --git a/atuin-client/migrations/20220806155627_interactive_search_index.sql b/atuin-client/migrations/20220806155627_interactive_search_index.sql
deleted file mode 100644
index b5770e62..00000000
--- a/atuin-client/migrations/20220806155627_interactive_search_index.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Interactive search filters by command then by the max(timestamp) for that
--- command. Create an index that covers those
-create index if not exists idx_history_command_timestamp on history(
- command,
- timestamp
-);
diff --git a/atuin-client/migrations/20230315220114_drop-events.sql b/atuin-client/migrations/20230315220114_drop-events.sql
deleted file mode 100644
index fe3cae17..00000000
--- a/atuin-client/migrations/20230315220114_drop-events.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-drop table events;
diff --git a/atuin-client/migrations/20230319185725_deleted_at.sql b/atuin-client/migrations/20230319185725_deleted_at.sql
deleted file mode 100644
index 6c422abc..00000000
--- a/atuin-client/migrations/20230319185725_deleted_at.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-alter table history add column deleted_at integer;
diff --git a/atuin-client/record-migrations/20230531212437_create-records.sql b/atuin-client/record-migrations/20230531212437_create-records.sql
deleted file mode 100644
index 4f4b304a..00000000
--- a/atuin-client/record-migrations/20230531212437_create-records.sql
+++ /dev/null
@@ -1,16 +0,0 @@
--- Add migration script here
-create table if not exists records (
- id text primary key,
- parent text unique, -- null if this is the first one
- host text not null,
-
- timestamp integer not null,
- tag text not null,
- version text not null,
- data blob not null,
- cek blob not null
-);
-
-create index host_idx on records (host);
-create index tag_idx on records (tag);
-create index host_tag_idx on records (host, tag);
diff --git a/atuin-client/record-migrations/20231127090831_create-store.sql b/atuin-client/record-migrations/20231127090831_create-store.sql
deleted file mode 100644
index 53d78860..00000000
--- a/atuin-client/record-migrations/20231127090831_create-store.sql
+++ /dev/null
@@ -1,15 +0,0 @@
--- Add migration script here
-create table if not exists store (
- id text primary key, -- globally unique ID
-
- idx integer, -- incrementing integer ID unique per (host, tag)
- host text not null, -- references the host row
- tag text not null,
-
- timestamp integer not null,
- version text not null,
- data blob not null,
- cek blob not null
-);
-
-create unique index record_uniq ON store(host, tag, idx);
diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs
deleted file mode 100644
index f31a796e..00000000
--- a/atuin-client/src/api_client.rs
+++ /dev/null
@@ -1,415 +0,0 @@
-use std::collections::HashMap;
-use std::env;
-use std::time::Duration;
-
-use eyre::{bail, Result};
-use reqwest::{
- header::{HeaderMap, AUTHORIZATION, USER_AGENT},
- Response, StatusCode, Url,
-};
-
-use atuin_common::{
- api::{
- AddHistoryRequest, ChangePasswordRequest, CountResponse, DeleteHistoryRequest,
- ErrorResponse, LoginRequest, LoginResponse, MeResponse, RegisterResponse, StatusResponse,
- SyncHistoryResponse,
- },
- record::RecordStatus,
-};
-use atuin_common::{
- api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ATUIN_VERSION},
- record::{EncryptedData, HostId, Record, RecordIdx},
-};
-
-use semver::Version;
-use time::format_description::well_known::Rfc3339;
-use time::OffsetDateTime;
-
-use crate::{history::History, sync::hash_str, utils::get_host_user};
-
-static APP_USER_AGENT: &str = concat!("atuin/", env!("CARGO_PKG_VERSION"),);
-
-pub struct Client<'a> {
- sync_addr: &'a str,
- client: reqwest::Client,
-}
-
-pub async fn register(
- address: &str,
- username: &str,
- email: &str,
- password: &str,
-) -> Result<RegisterResponse> {
- let mut map = HashMap::new();
- map.insert("username", username);
- map.insert("email", email);
- map.insert("password", password);
-
- let url = format!("{address}/user/{username}");
- let resp = reqwest::get(url).await?;
-
- if resp.status().is_success() {
- bail!("username already in use");
- }
-
- let url = format!("{address}/register");
- let client = reqwest::Client::new();
- let resp = client
- .post(url)
- .header(USER_AGENT, APP_USER_AGENT)
- .header(ATUIN_HEADER_VERSION, ATUIN_CARGO_VERSION)
- .json(&map)
- .send()
- .await?;
-
- if !ensure_version(&resp)? {
- bail!("could not register user due to version mismatch");
- }
-
- if !resp.status().is_success() {
- let error = resp.json::<ErrorResponse>().await?;
- bail!("failed to register user: {}", error.reason);
- }
-
- let session = resp.json::<RegisterResponse>().await?;
- Ok(session)
-}
-
-pub async fn login(address: &str, req: LoginRequest) -> Result<LoginResponse> {
- let url = format!("{address}/login");
- let client = reqwest::Client::new();
-
- let resp = client
- .post(url)
- .header(USER_AGENT, APP_USER_AGENT)
- .json(&req)
- .send()
- .await?;
-
- if !ensure_version(&resp)? {
- bail!("could not login due to version mismatch");
- }
-
- if resp.status() != reqwest::StatusCode::OK {
- let error = resp.json::<ErrorResponse>().await?;
- bail!("invalid login details: {}", error.reason);
- }
-
- let session = resp.json::<LoginResponse>().await?;
- Ok(session)
-}
-
-#[cfg(feature = "check-update")]
-pub async fn latest_version() -> Result<Version> {
- use atuin_common::api::IndexResponse;
-
- let url = "https://api.atuin.sh";
- let client = reqwest::Client::new();
-
- let resp = client
- .get(url)
- .header(USER_AGENT, APP_USER_AGENT)
- .send()
- .await?;
-
- if resp.status() != reqwest::StatusCode::OK {
- let error = resp.json::<ErrorResponse>().await?;
- bail!("failed to check latest version: {}", error.reason);
- }
-
- let index = resp.json::<IndexResponse>().await?;
- let version = Version::parse(index.version.as_str())?;
-
- Ok(version)
-}
-
-pub fn ensure_version(response: &Response) -> Result<bool> {
- let version = response.headers().get(ATUIN_HEADER_VERSION);
-
- let version = if let Some(version) = version {
- match version.to_str() {
- Ok(v) => Version::parse(v),
- Err(e) => bail!("failed to parse server version: {:?}", e),
- }
- } else {
- // if there is no version header, then the newest this server can possibly be is 17.1.0
- Version::parse("17.1.0")
- }?;
-
- // If the client is newer than the server
- if version.major < ATUIN_VERSION.major {
- println!("Atuin version mismatch! In order to successfully sync, the server needs to run a newer version of Atuin");
- println!("Client: {}", ATUIN_CARGO_VERSION);
- println!("Server: {}", version);
-
- return Ok(false);
- }
-
- Ok(true)
-}
-
-async fn handle_resp_error(resp: Response) -> Result<Response> {
- let status = resp.status();
-
- if status == StatusCode::SERVICE_UNAVAILABLE {
- bail!(
- "Service unavailable: check https://status.atuin.sh (or get in touch with your host)"
- );
- }
-
- if !status.is_success() {
- if let Ok(error) = resp.json::<ErrorResponse>().await {
- let reason = error.reason;
-
- if status.is_client_error() {
- bail!("Could not fetch history, client error {status}: {reason}.")
- }
-
- bail!("There was an error with the atuin sync service, server error {status}: {reason}.\nIf the problem persists, contact the host")
- }
-
- bail!("There was an error with the atuin sync service: Status {status:?}.\nIf the problem persists, contact the host")
- }
-
- Ok(resp)
-}
-
-impl<'a> Client<'a> {
- pub fn new(
- sync_addr: &'a str,
- session_token: &str,
- connect_timeout: u64,
- timeout: u64,
- ) -> Result<Self> {
- let mut headers = HeaderMap::new();
- headers.insert(AUTHORIZATION, format!("Token {session_token}").parse()?);
-
- // used for semver server check
- headers.insert(ATUIN_HEADER_VERSION, ATUIN_CARGO_VERSION.parse()?);
-
- Ok(Client {
- sync_addr,
- client: reqwest::Client::builder()
- .user_agent(APP_USER_AGENT)
- .default_headers(headers)
- .connect_timeout(Duration::new(connect_timeout, 0))
- .timeout(Duration::new(timeout, 0))
- .build()?,
- })
- }
-
- pub async fn count(&self) -> Result<i64> {
- let url = format!("{}/sync/count", self.sync_addr);
- let url = Url::parse(url.as_str())?;
-
- let resp = self.client.get(url).send().await?;
- let resp = handle_resp_error(resp).await?;
-
- if !ensure_version(&resp)? {
- bail!("could not sync due to version mismatch");
- }
-
- if resp.status() != StatusCode::OK {
- bail!("failed to get count (are you logged in?)");
- }
-
- let count = resp.json::<CountResponse>().await?;
-
- Ok(count.count)
- }
-
- pub async fn status(&self) -> Result<StatusResponse> {
- let url = format!("{}/sync/status", self.sync_addr);
- let url = Url::parse(url.as_str())?;
-
- let resp = self.client.get(url).send().await?;
- let resp = handle_resp_error(resp).await?;
-
- if !ensure_version(&resp)? {
- bail!("could not sync due to version mismatch");
- }
-
- let status = resp.json::<StatusResponse>().await?;
-
- Ok(status)
- }
-
- pub async fn me(&self) -> Result<MeResponse> {
- let url = format!("{}/api/v0/me", self.sync_addr);
- let url = Url::parse(url.as_str())?;
-
- let resp = self.client.get(url).send().await?;
- let resp = handle_resp_error(resp).await?;
-
- let status = resp.json::<MeResponse>().await?;
-
- Ok(status)
- }
-
- pub async fn get_history(
- &self,
- sync_ts: OffsetDateTime,
- history_ts: OffsetDateTime,
- host: Option<String>,
- ) -> Result<SyncHistoryResponse> {
- let host = host.unwrap_or_else(|| hash_str(&get_host_user()));
-
- let url = format!(
- "{}/sync/history?sync_ts={}&history_ts={}&host={}",
- self.sync_addr,
- urlencoding::encode(sync_ts.format(&Rfc3339)?.as_str()),
- urlencoding::encode(history_ts.format(&Rfc3339)?.as_str()),
- host,
- );
-
- let resp = self.client.get(url).send().await?;
- let resp = handle_resp_error(resp).await?;