Skip to content

Commit

Permalink
feat: allow specifying exactly which db file to sync with
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikBjare committed May 15, 2023
1 parent 49b2026 commit 72993e7
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 11 deletions.
4 changes: 2 additions & 2 deletions aw-datastore/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl DatastoreWorker {
Ok((req, res_sender)) => (req, res_sender),
Err(_) => {
// All references to responder is gone, quit
info!("DB worker quitting");
debug!("DB worker quitting");
self.quit = true;
break;
}
Expand Down Expand Up @@ -205,7 +205,7 @@ impl DatastoreWorker {
break;
};
}
info!("DB Worker thread finished");
debug!("DB Worker thread finished");
}

fn handle_request(
Expand Down
24 changes: 23 additions & 1 deletion aw-sync/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extern crate serde_json;

use std::error::Error;
use std::path::Path;
use std::path::PathBuf;

use chrono::{DateTime, Datelike, TimeZone, Utc};
use clap::{Parser, Subcommand};
Expand All @@ -41,10 +42,15 @@ struct Opts {
/// Convenience option for using the default testing host and port.
#[clap(long)]
testing: bool,
/// Path to sync directory.
/// Full path to sync directory.
/// If not specified, exit.
#[clap(long)]
sync_dir: String,
/// Full path to sync db file
/// Useful for syncing buckets from a specific db file in the sync directory.
/// Must be a valid absolute path to a file in the sync directory.
#[clap(long)]
sync_db: Option<String>,
}

#[derive(Subcommand)]
Expand Down Expand Up @@ -90,6 +96,10 @@ fn main() -> Result<(), Box<dyn Error>> {
};
info!("Using sync dir: {}", sync_directory.display());

if let Some(sync_db) = &opts.sync_db {
info!("Using sync db: {}", sync_db);
}

let port = if opts.testing && opts.port == DEFAULT_PORT {
"5666"
} else {
Expand Down Expand Up @@ -121,8 +131,20 @@ fn main() -> Result<(), Box<dyn Error>> {
.as_ref()
.map(|b| b.split(',').map(|s| s.to_string()).collect());

let sync_db: Option<PathBuf> = opts.sync_db.as_ref().map(|db| {
let db_path = Path::new(db);
if !db_path.is_absolute() {
panic!("Sync db path must be absolute");
}
if !db_path.starts_with(sync_directory) {
panic!("Sync db path must be in sync directory");
}
db_path.to_path_buf()
});

let sync_spec = sync::SyncSpec {
path: sync_directory.to_path_buf(),
path_db: sync_db,
buckets: buckets_vec,
start,
};
Expand Down
33 changes: 28 additions & 5 deletions aw-sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub enum SyncMode {
pub struct SyncSpec {
/// Path of sync folder
pub path: PathBuf,
/// Path of sync db
/// If None, will use all
pub path_db: Option<PathBuf>,
/// Bucket IDs to sync
pub buckets: Option<Vec<String>>,
/// Start of time range to sync
Expand All @@ -43,6 +46,7 @@ impl Default for SyncSpec {
let path = Path::new("/tmp/aw-sync").to_path_buf();
SyncSpec {
path,
path_db: None,
buckets: None,
start: None,
}
Expand All @@ -60,7 +64,11 @@ pub fn sync_run(client: AwClient, sync_spec: &SyncSpec, mode: SyncMode) -> Resul

// FIXME: Bad device_id assumption?
let ds_localremote = setup_local_remote(sync_spec.path.as_path(), device_id)?;
let remote_dbfiles = find_remotes_nonlocal(sync_spec.path.as_path(), device_id);
let remote_dbfiles = find_remotes_nonlocal(
sync_spec.path.as_path(),
device_id,
sync_spec.path_db.as_ref(),
);

// Log if remotes found
// TODO: Only log remotes of interest
Expand Down Expand Up @@ -127,7 +135,7 @@ pub fn list_buckets(client: &AwClient, sync_directory: &Path) -> Result<(), Stri
let device_id = info.device_id.as_str();
let ds_localremote = setup_local_remote(sync_directory, device_id)?;

let remote_dbfiles = find_remotes_nonlocal(sync_directory, device_id);
let remote_dbfiles = find_remotes_nonlocal(sync_directory, device_id, None);
info!("Found remotes: {:?}", remote_dbfiles);

// TODO: Check for compatible remote db version before opening
Expand Down Expand Up @@ -177,11 +185,15 @@ fn find_remotes(sync_directory: &Path) -> std::io::Result<Vec<PathBuf>> {
}

/// Returns a list of all remotes, excluding local ones
fn find_remotes_nonlocal(sync_directory: &Path, device_id: &str) -> Vec<PathBuf> {
fn find_remotes_nonlocal(
sync_directory: &Path,
device_id: &str,
sync_db: Option<&PathBuf>,
) -> Vec<PathBuf> {
let remotes_all = find_remotes(sync_directory).unwrap();
// Filter out own remote
remotes_all
.into_iter()
// Filter out own remote
.filter(|path| {
!(path
.clone()
Expand All @@ -190,6 +202,14 @@ fn find_remotes_nonlocal(sync_directory: &Path, device_id: &str) -> Vec<PathBuf>
.unwrap()
.contains(device_id))
})
// If sync_db is Some, return only remotes in that path
.filter(|path| {
if let Some(sync_db) = sync_db {
path.starts_with(sync_db)
} else {
true
}
})
.collect()
}

Expand Down Expand Up @@ -231,7 +251,10 @@ fn get_or_create_sync_bucket(
serde_json::json!(bucket_from.hostname),
);
ds_to.create_bucket(&bucket_new).unwrap();
ds_to.get_bucket(new_id.as_str()).unwrap()
match ds_to.get_bucket(new_id.as_str()) {
Ok(bucket) => bucket,
Err(e) => panic!("{e:?}"),
}
}
Err(e) => panic!("{e:?}"),
}
Expand Down
23 changes: 20 additions & 3 deletions aw-sync/test-sync-pull.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ SYNCROOTDIR="$HOME/ActivityWatchSync"
function sync_host() {
host=$1
SYNCDIR="$SYNCROOTDIR/$host"
for db in $(ls $SYNCDIR/*/*.db); do
AWSYNCPARAMS="--port $PORT --sync-dir $SYNCDIR"
dbs=$(find $SYNCDIR -name "*.db")
for db in $dbs; do
# workaround to avoid trying to sync empty database files (size 45056)
if [ "$(stat -c%s $db)" -lt 50000 ]; then
continue
fi

AWSYNCPARAMS="--port $PORT --sync-dir $SYNCDIR --sync-db $db"
BUCKETS="aw-watcher-window_$host,aw-watcher-afk_$host"

echo "Syncing $db to $host"
Expand All @@ -45,7 +51,18 @@ if [ -z "$host" ]; then
echo "Syncing all hosts"
sleep 0.5
# For each host in the sync directory, pull the data from each database file using aw-sync
for host in $(ls $SYNCROOTDIR); do
# Use `find` to get all directories in the sync directory
hostnames=$(find $SYNCROOTDIR -maxdepth 1 -type d -exec basename {} \;)
# filter out "erb-m2.local"
hostnames=$(echo $hostnames | tr ' ' '\n' | grep -v "erb-m2.local")
# filter out folder not containing subfolders with .db files
for host in $hostnames; do
if [ ! "$(find $SYNCROOTDIR/$host -name "*.db")" ]; then
hostnames=$(echo $hostnames | tr ' ' '\n' | grep -v $host)
fi
done
# Sync each host, file-by-file
for host in $hostnames; do
sync_host $host
done
else
Expand Down

0 comments on commit 72993e7

Please sign in to comment.