-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
1,008 additions
and
856 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
use crate::commands::Commands; | ||
|
||
use clap::{builder::styling::AnsiColor, Parser}; | ||
|
||
#[derive(Parser, Debug)] | ||
#[clap(name = "ark-cli")] | ||
#[clap(about = "Manage ARK tag storages and indexes", styles=styles())] | ||
pub struct Cli { | ||
#[clap(subcommand)] | ||
pub command: Commands, | ||
} | ||
|
||
pub fn styles() -> clap::builder::Styles { | ||
clap::builder::Styles::styled() | ||
.header(AnsiColor::Yellow.on_default()) | ||
.usage(AnsiColor::Yellow.on_default()) | ||
.literal(AnsiColor::Green.on_default()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use std::io::Write; | ||
use std::path::PathBuf; | ||
|
||
use crate::{ | ||
create_dir_all, dir, discover_roots, home_dir, storages_exists, timestamp, | ||
AppError, CopyOptions, File, ARK_BACKUPS_PATH, ARK_FOLDER, | ||
ROOTS_CFG_FILENAME, | ||
}; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap(name = "backup", about = "Backup the ark managed folder")] | ||
pub struct Backup { | ||
#[clap(value_parser, help = "Path to the root directory")] | ||
roots_cfg: Option<PathBuf>, | ||
} | ||
|
||
impl Backup { | ||
pub fn run(&self) -> Result<(), AppError> { | ||
let timestamp = timestamp().as_secs(); | ||
let backup_dir = home_dir() | ||
.ok_or(AppError::HomeDirNotFound)? | ||
.join(ARK_BACKUPS_PATH) | ||
.join(timestamp.to_string()); | ||
|
||
if backup_dir.is_dir() { | ||
println!("Wait at least 1 second, please!"); | ||
std::process::exit(0) | ||
} | ||
|
||
println!("Preparing backup:"); | ||
let roots = discover_roots(&self.roots_cfg)?; | ||
|
||
let (valid, invalid): (Vec<PathBuf>, Vec<PathBuf>) = roots | ||
.into_iter() | ||
.partition(|root| storages_exists(root)); | ||
|
||
if !invalid.is_empty() { | ||
println!("These folders don't contain any storages:"); | ||
invalid | ||
.into_iter() | ||
.for_each(|root| println!("\t{}", root.display())); | ||
} | ||
|
||
if valid.is_empty() { | ||
println!("Nothing to backup. Bye!"); | ||
std::process::exit(0) | ||
} | ||
|
||
create_dir_all(&backup_dir).map_err(|_| { | ||
AppError::BackupCreationError( | ||
"Couldn't create backup directory!".to_owned(), | ||
) | ||
})?; | ||
|
||
let mut roots_cfg_backup = | ||
File::create(backup_dir.join(ROOTS_CFG_FILENAME))?; | ||
|
||
valid.iter().for_each(|root| { | ||
let res = writeln!(roots_cfg_backup, "{}", root.display()); | ||
if let Err(e) = res { | ||
println!("Failed to write root to backup file: {}", e); | ||
} | ||
}); | ||
|
||
println!("Performing backups:"); | ||
valid | ||
.into_iter() | ||
.enumerate() | ||
.for_each(|(i, root)| { | ||
println!("\tRoot {}", root.display()); | ||
let storage_backup = backup_dir.join(i.to_string()); | ||
|
||
let mut options = CopyOptions::new(); | ||
options.overwrite = true; | ||
options.copy_inside = true; | ||
|
||
let result = | ||
dir::copy(root.join(ARK_FOLDER), storage_backup, &options); | ||
|
||
if let Err(e) = result { | ||
println!("\t\tFailed to copy storages!\n\t\t{}", e); | ||
} | ||
}); | ||
|
||
println!("Backup created:\n\t{}", backup_dir.display()); | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use std::path::PathBuf; | ||
|
||
use crate::{monitor_index, AppError}; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap( | ||
name = "collisions", | ||
about = "Find collisions in the ark managed folder" | ||
)] | ||
pub struct Collisions { | ||
#[clap(value_parser, help = "Path to the root directory")] | ||
root_dir: Option<PathBuf>, | ||
} | ||
|
||
impl Collisions { | ||
pub fn run(&self) -> Result<(), AppError> { | ||
// FIXME: How does `monitor_index` handle `ark-cli collisions`? | ||
monitor_index(&self.root_dir, None) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use std::path::PathBuf; | ||
use std::str::FromStr; | ||
|
||
use crate::{ | ||
models::storage::Storage, models::storage::StorageType, translate_storage, | ||
AppError, Format, ResourceId, | ||
}; | ||
|
||
use data_error::ArklibError; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap(name = "append", about = "Append content to a resource")] | ||
pub struct Append { | ||
#[clap( | ||
value_parser, | ||
default_value = ".", | ||
help = "Root directory of the ark managed folder" | ||
)] | ||
root_dir: PathBuf, | ||
#[clap(help = "Storage name")] | ||
storage: String, | ||
#[clap(help = "ID of the resource to append to")] | ||
id: String, | ||
#[clap(help = "Content to append to the resource")] | ||
content: String, | ||
#[clap( | ||
short, | ||
long, | ||
value_enum, | ||
default_value = "raw", | ||
help = "Format of the resource" | ||
)] | ||
format: Option<Format>, | ||
#[clap(short, long, value_enum, help = "Storage kind of the resource")] | ||
kind: Option<StorageType>, | ||
} | ||
|
||
impl Append { | ||
pub fn run(&self) -> Result<(), AppError> { | ||
let (file_path, storage_type) = | ||
translate_storage(&Some(self.root_dir.to_owned()), &self.storage) | ||
.ok_or(AppError::StorageNotFound(self.storage.to_owned()))?; | ||
|
||
// FIXME: Why do we have `self.kind` and `self.storage`? Both are used to determine the storage type | ||
let storage_type = storage_type.unwrap_or(match self.kind { | ||
Some(t) => t, | ||
None => StorageType::File, | ||
}); | ||
|
||
let format = self.format.unwrap(); | ||
|
||
let mut storage = Storage::new(file_path, storage_type)?; | ||
|
||
let resource_id = ResourceId::from_str(&self.id) | ||
.map_err(|_e| AppError::ArklibError(ArklibError::Parse))?; | ||
|
||
storage.append(resource_id, &self.content, format)?; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
use std::path::PathBuf; | ||
use std::str::FromStr; | ||
|
||
use crate::{ | ||
models::storage::Storage, models::storage::StorageType, translate_storage, | ||
AppError, Format, ResourceId, | ||
}; | ||
|
||
use data_error::ArklibError; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap(name = "insert", about = "Insert content into a resource")] | ||
pub struct Insert { | ||
#[clap( | ||
value_parser, | ||
default_value = ".", | ||
help = "Root directory of the ark managed folder" | ||
)] | ||
root_dir: PathBuf, | ||
#[clap(help = "Storage name")] | ||
storage: String, | ||
#[clap(help = "ID of the resource to append to")] | ||
id: String, | ||
#[clap(help = "Content to append to the resource")] | ||
content: String, | ||
#[clap(short, long, value_enum, help = "Format of the resource")] | ||
format: Option<Format>, | ||
#[clap(short, long, value_enum, help = "Storage kind of the resource")] | ||
kind: Option<StorageType>, | ||
} | ||
|
||
impl Insert { | ||
pub fn run(&self) -> Result<(), AppError> { | ||
let (file_path, storage_type) = | ||
translate_storage(&Some(self.root_dir.to_owned()), &self.storage) | ||
.ok_or(AppError::StorageNotFound(self.storage.to_owned()))?; | ||
|
||
let storage_type = storage_type.unwrap_or(match self.kind { | ||
Some(t) => t, | ||
None => StorageType::File, | ||
}); | ||
|
||
let format = self.format.unwrap_or(Format::Raw); | ||
|
||
let mut storage = Storage::new(file_path, storage_type)?; | ||
|
||
let resource_id = ResourceId::from_str(&self.id) | ||
.map_err(|_e| AppError::ArklibError(ArklibError::Parse))?; | ||
|
||
storage.insert(resource_id, &self.content, format)?; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use clap::Subcommand; | ||
|
||
mod append; | ||
mod insert; | ||
mod read; | ||
mod utils; | ||
|
||
/// Available commands for the `file` subcommand | ||
#[derive(Subcommand, Debug)] | ||
pub enum File { | ||
Append(append::Append), | ||
Insert(insert::Insert), | ||
Read(read::Read), | ||
} | ||
|
||
pub use utils::{file_append, file_insert, format_file, format_line}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
use std::path::PathBuf; | ||
use std::str::FromStr; | ||
|
||
use crate::{ | ||
models::storage::Storage, models::storage::StorageType, translate_storage, | ||
AppError, ResourceId, | ||
}; | ||
|
||
use data_error::ArklibError; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap(name = "read", about = "Read content from a resource")] | ||
pub struct Read { | ||
#[clap( | ||
value_parser, | ||
default_value = ".", | ||
help = "Root directory of the ark managed folder" | ||
)] | ||
root_dir: PathBuf, | ||
#[clap(help = "Storage name")] | ||
storage: String, | ||
#[clap(help = "ID of the resource to append to")] | ||
id: String, | ||
#[clap(short, long, value_enum, help = "Storage kind of the resource")] | ||
kind: Option<StorageType>, | ||
} | ||
|
||
impl Read { | ||
pub fn run(&self) -> Result<(), AppError> { | ||
let (file_path, storage_type) = | ||
translate_storage(&Some(self.root_dir.to_owned()), &self.storage) | ||
.ok_or(AppError::StorageNotFound(self.storage.to_owned()))?; | ||
|
||
let storage_type = storage_type.unwrap_or(match self.kind { | ||
Some(t) => t, | ||
None => StorageType::File, | ||
}); | ||
|
||
let mut storage = Storage::new(file_path, storage_type)?; | ||
|
||
let resource_id = ResourceId::from_str(&self.id) | ||
.map_err(|_e| AppError::ArklibError(ArklibError::Parse))?; | ||
|
||
let output = storage.read(resource_id)?; | ||
|
||
println!("{}", output); | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use std::path::PathBuf; | ||
|
||
use crate::{commands::link::utils::create_link, provide_root, AppError}; | ||
|
||
#[derive(Clone, Debug, clap::Args)] | ||
#[clap(name = "create", about = "Create a new link")] | ||
pub struct Create { | ||
#[clap(value_parser, help = "Root directory of the ark managed folder")] | ||
root_dir: Option<PathBuf>, | ||
#[clap(help = "URL of the link")] | ||
url: Option<String>, | ||
#[clap(help = "Title of the link")] | ||
title: Option<String>, | ||
#[clap(help = "Description of the link")] | ||
desc: Option<String>, | ||
} | ||
|
||
impl Create { | ||
pub async fn run(&self) -> Result<(), AppError> { | ||
let root = provide_root(&self.root_dir)?; | ||
let url = self.url.as_ref().ok_or_else(|| { | ||
AppError::LinkCreationError("Url was not provided".to_owned()) | ||
})?; | ||
let title = self.title.as_ref().ok_or_else(|| { | ||
AppError::LinkCreationError("Title was not provided".to_owned()) | ||
})?; | ||
|
||
println!("Saving link..."); | ||
|
||
match create_link(&root, url, title, self.desc.to_owned()).await { | ||
Ok(_) => { | ||
println!("Link saved successfully!"); | ||
} | ||
Err(e) => println!("{}", e), | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.