Switch --list-meta to --list-format
This commit is contained in:
131
src/main.rs
131
src/main.rs
@@ -135,9 +135,9 @@ struct OptionsArgs {
|
|||||||
#[arg(help("Specify the directory to use for storage"))]
|
#[arg(help("Specify the directory to use for storage"))]
|
||||||
dir: Option<PathBuf>,
|
dir: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(long, env("KEEP_LIST_META"), default_value("hostname"))]
|
#[arg(long, env("KEEP_LIST_FORMAT"), default_value("id,time,size,tags,meta:hostname"))]
|
||||||
#[arg(help("A comma separated list of item metadata names to display with --list"))]
|
#[arg(help("A comma separated list of columns to display with --list"))]
|
||||||
list_meta: String,
|
list_format: String,
|
||||||
|
|
||||||
#[arg(short, long, action = clap::ArgAction::Count, conflicts_with("quiet"))]
|
#[arg(short, long, action = clap::ArgAction::Count, conflicts_with("quiet"))]
|
||||||
#[arg(help("Increase message verbosity, can be given more than once"))]
|
#[arg(help("Increase message verbosity, can be given more than once"))]
|
||||||
@@ -196,6 +196,19 @@ impl FromStr for NumberOrString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString)]
|
||||||
|
#[strum(ascii_case_insensitive)]
|
||||||
|
pub enum ColumnType {
|
||||||
|
Id,
|
||||||
|
Time,
|
||||||
|
Size,
|
||||||
|
Compression,
|
||||||
|
FileSize,
|
||||||
|
FilePath,
|
||||||
|
Tags,
|
||||||
|
Meta
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
let proj_dirs = ProjectDirs::from("gt0.ca", "Andrew Phillips", "Keep");
|
let proj_dirs = ProjectDirs::from("gt0.ca", "Andrew Phillips", "Keep");
|
||||||
|
|
||||||
@@ -489,56 +502,91 @@ fn mode_list(cmd: &mut Command, args: Args, ids: &mut Vec<i64>, tags: &Vec<Strin
|
|||||||
meta_by_item.insert(item_id, item_meta);
|
meta_by_item.insert(item_id, item_meta);
|
||||||
};
|
};
|
||||||
|
|
||||||
let meta_columns = args.options.list_meta.split(",");
|
|
||||||
|
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.set_format(*format::consts::FORMAT_CLEAN);
|
table.set_format(*format::consts::FORMAT_CLEAN);
|
||||||
|
|
||||||
let mut title_row = row!(
|
let list_format = args.options.list_format.split(",");
|
||||||
b->"ID",
|
|
||||||
b->"Time",
|
|
||||||
b->"Stream Size",
|
|
||||||
b->"Comp",
|
|
||||||
b->"File Size",
|
|
||||||
b->"Tags",
|
|
||||||
);
|
|
||||||
|
|
||||||
for name in meta_columns.clone() {
|
let mut title_row = row!();
|
||||||
title_row.add_cell(Cell::new(name).with_style(Attr::Bold));
|
|
||||||
|
for column in list_format.clone() {
|
||||||
|
let mut column_format = column.split(":").into_iter();
|
||||||
|
let column_name = column_format.next().expect("Unable to parse column name");
|
||||||
|
let column_type = ColumnType::from_str(column_name.clone()).expect(format!("Unknown column {:?}", column_name).as_str());
|
||||||
|
|
||||||
|
if column_type == ColumnType::Meta {
|
||||||
|
let meta_name = column_format.next().expect("Unable to parse metadata name for meta column");
|
||||||
|
title_row.add_cell(Cell::new(meta_name).with_style(Attr::Bold));
|
||||||
|
} else {
|
||||||
|
title_row.add_cell(Cell::new(&column_type.to_string()).with_style(Attr::Bold));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.set_titles(title_row);
|
table.set_titles(title_row);
|
||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
let item_id = item.id.unwrap();
|
let item_id = item.id.unwrap();
|
||||||
|
let tags = tags_by_item.get(&item_id).unwrap();
|
||||||
|
let meta = meta_by_item.get(&item_id).unwrap();
|
||||||
let mut item_path = data_path.clone();
|
let mut item_path = data_path.clone();
|
||||||
item_path.push(item.id.unwrap().to_string());
|
item_path.push(item.id.unwrap().to_string());
|
||||||
|
|
||||||
let id_cell = Cell::new_align(&item.id.unwrap_or(0).to_string(), Alignment::RIGHT);
|
let mut table_row = Row::new(vec![]);
|
||||||
let ts_cell = Cell::new(&item.ts.with_timezone(&Local).format("%F %T").to_string());
|
|
||||||
let size_cell = match item.size {
|
|
||||||
Some(size) => Cell::new_align(format_size(size as u64, BINARY).as_str(), Alignment::RIGHT),
|
|
||||||
None => Cell::new_align("Missing", Alignment::RIGHT).with_style(Attr::ForegroundColor(color::RED)).with_style(Attr::Bold)
|
|
||||||
};
|
|
||||||
let compression_cell = Cell::new(&item.compression);
|
|
||||||
let file_size_cell = match item_path.metadata() {
|
|
||||||
Ok(metadata) => Cell::new_align(format_size(metadata.len(), BINARY).as_str(), Alignment::RIGHT),
|
|
||||||
Err(_) => Cell::new_align("Missing", Alignment::RIGHT).with_style(Attr::ForegroundColor(color::RED)).with_style(Attr::Bold)
|
|
||||||
};
|
|
||||||
|
|
||||||
let item_tags = tags_by_item.get(&item_id).unwrap();
|
for column in list_format.clone() {
|
||||||
let tags_cell = Cell::new(&item_tags.join(" "));
|
let mut column_format = column.split(":").into_iter();
|
||||||
|
let column_name = column_format.next().expect("Unable to parse column name");
|
||||||
|
let column_type = ColumnType::from_str(column_name.clone()).expect(format!("Unknown column {:?}", column_name).as_str());
|
||||||
|
let mut meta_name: Option<&str> = None;
|
||||||
|
|
||||||
let mut table_row = Row::new(vec![id_cell,ts_cell,size_cell, compression_cell, file_size_cell, tags_cell]);
|
if column_type == ColumnType::Meta {
|
||||||
|
meta_name = column_format.next();
|
||||||
let item_meta = meta_by_item.get(&item_id).unwrap();
|
|
||||||
for name in meta_columns.clone() {
|
|
||||||
match item_meta.get(name) {
|
|
||||||
Some(value) => table_row.add_cell(Cell::new(value)),
|
|
||||||
None => table_row.add_cell(Cell::new(""))
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let column_width: usize = match column_format.next() {
|
||||||
|
Some(len) => len.parse().unwrap_or(0),
|
||||||
|
None => 0
|
||||||
|
};
|
||||||
|
|
||||||
|
let cell = match column_type {
|
||||||
|
ColumnType::Id => Cell::new_align(
|
||||||
|
truncate_column(&item.id.unwrap_or(0).to_string(), column_width),
|
||||||
|
Alignment::RIGHT),
|
||||||
|
ColumnType::Time => Cell::new(
|
||||||
|
truncate_column(&item.ts.with_timezone(&Local).format("%F %T").to_string(), column_width)),
|
||||||
|
ColumnType::Size => match item.size {
|
||||||
|
Some(size) => Cell::new_align(
|
||||||
|
truncate_column(format_size(size as u64, BINARY).as_str(), column_width),
|
||||||
|
Alignment::RIGHT),
|
||||||
|
None => match item_path.metadata() {
|
||||||
|
Ok(_) => Cell::new_align("Unknown", Alignment::RIGHT)
|
||||||
|
.with_style(Attr::ForegroundColor(color::YELLOW))
|
||||||
|
.with_style(Attr::Bold),
|
||||||
|
Err(_) => Cell::new_align("Missing", Alignment::RIGHT)
|
||||||
|
.with_style(Attr::ForegroundColor(color::RED))
|
||||||
|
.with_style(Attr::Bold)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ColumnType::Compression => Cell::new(truncate_column(&item.compression, column_width)),
|
||||||
|
ColumnType::FileSize => match item_path.metadata() {
|
||||||
|
Ok(metadata) => Cell::new_align(
|
||||||
|
truncate_column(format_size(metadata.len(), BINARY).as_str(), column_width),
|
||||||
|
Alignment::RIGHT),
|
||||||
|
Err(_) => Cell::new_align("Missing", Alignment::RIGHT)
|
||||||
|
.with_style(Attr::ForegroundColor(color::RED)).with_style(Attr::Bold)
|
||||||
|
},
|
||||||
|
ColumnType::FilePath => Cell::new(truncate_column(&item_path.clone().into_os_string().into_string().unwrap(), column_width)),
|
||||||
|
ColumnType::Tags => Cell::new(truncate_column(tags.join(" ").as_str(), column_width)),
|
||||||
|
ColumnType::Meta => match meta_name {
|
||||||
|
Some(meta_name) => match meta.get(meta_name) {
|
||||||
|
Some(meta_value) => Cell::new(truncate_column(meta_value, column_width)),
|
||||||
|
None => Cell::new("")
|
||||||
|
},
|
||||||
|
None => Cell::new("")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
table_row.add_cell(cell);
|
||||||
|
}
|
||||||
table.add_row(table_row);
|
table.add_row(table_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,3 +862,14 @@ fn get_meta_from_env() -> HashMap<String,String> {
|
|||||||
}
|
}
|
||||||
meta_env
|
meta_env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn truncate_column(s: &str, column_width: usize) -> &str {
|
||||||
|
if column_width > 0 {
|
||||||
|
match s.char_indices().nth(column_width) {
|
||||||
|
None => s,
|
||||||
|
Some((idx, _)) => &s[..idx],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user