refactor: move mode_list to src/modes/list.rs and update imports
This commit is contained in:
@@ -38,6 +38,7 @@ pub mod db;
|
||||
//pub mod item;
|
||||
|
||||
use compression::CompressionType;
|
||||
use modes::list::mode_list;
|
||||
|
||||
|
||||
extern crate term;
|
||||
@@ -309,7 +310,7 @@ fn main() -> Result<(), Error> {
|
||||
crate::modes::get::mode_get(&mut cmd, args, ids, tags, &mut conn, data_path)?
|
||||
}
|
||||
KeepModes::Diff => mode_diff(&mut cmd, args, ids, tags, &mut conn, data_path)?,
|
||||
KeepModes::List => mode_list(&mut cmd, args, ids, tags, &mut conn, data_path)?,
|
||||
KeepModes::List => mode_list::mode_list(&mut cmd, args, ids, tags, &mut conn, data_path)?,
|
||||
KeepModes::Update => {
|
||||
crate::modes::update::mode_update(&mut cmd, args, ids, tags, &mut conn, data_path)?
|
||||
}
|
||||
|
||||
218
src/modes/list.rs
Normal file
218
src/modes/list.rs
Normal file
@@ -0,0 +1,218 @@
|
||||
use anyhow::{anyhow, Error, Result};
|
||||
use clap::Command;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::compression::CompressionType;
|
||||
use crate::db::{get_item, get_item_last, get_items, get_items_matching};
|
||||
use crate::modes::common::{format_size, get_format_box_chars_no_border_line_separator};
|
||||
use crate::modes::common::{string_column, size_column};
|
||||
use crate::modes::common::ColumnType;
|
||||
use is_terminal::IsTerminal;
|
||||
use prettytable::format::TableFormat;
|
||||
use prettytable::row;
|
||||
use prettytable::{Attr, Cell, Row, Table};
|
||||
|
||||
pub fn mode_list(
|
||||
cmd: &mut Command,
|
||||
args: crate::Args,
|
||||
ids: &mut Vec<i64>,
|
||||
tags: &Vec<String>,
|
||||
conn: &mut Connection,
|
||||
data_path: PathBuf,
|
||||
) -> Result<()> {
|
||||
if !ids.is_empty() {
|
||||
cmd.error(
|
||||
ErrorKind::InvalidValue,
|
||||
"ID given, you can only supply tags when using --list",
|
||||
)
|
||||
.exit();
|
||||
}
|
||||
|
||||
let mut meta: HashMap<String, String> = HashMap::new();
|
||||
for item in args.item.meta.iter() {
|
||||
let item = item.clone();
|
||||
meta.insert(item.key, item.value);
|
||||
}
|
||||
|
||||
let items = match tags.is_empty() && meta.is_empty() {
|
||||
true => get_items(conn)?,
|
||||
false => get_items_matching(conn, tags, &meta)?,
|
||||
};
|
||||
|
||||
debug!("MAIN: Items: {:?}", items);
|
||||
|
||||
let mut tags_by_item: HashMap<i64, Vec<String>> = HashMap::new();
|
||||
let mut meta_by_item: HashMap<i64, HashMap<String, String>> = HashMap::new();
|
||||
|
||||
for item in items.iter() {
|
||||
let item_id = item.id.unwrap();
|
||||
|
||||
let item_tags: Vec<String> = get_item_tags(conn, item)?
|
||||
.into_iter()
|
||||
.map(|x| x.name)
|
||||
.collect();
|
||||
tags_by_item.insert(item_id, item_tags);
|
||||
|
||||
let mut item_meta: HashMap<String, String> = HashMap::new();
|
||||
|
||||
for meta in get_item_meta(conn, item)? {
|
||||
item_meta.insert(meta.name.clone(), meta.value);
|
||||
}
|
||||
meta_by_item.insert(item_id, item_meta);
|
||||
}
|
||||
|
||||
let mut table = Table::new();
|
||||
table.set_format(*format::consts::FORMAT_CLEAN);
|
||||
|
||||
let list_format = args.options.list_format.split(",");
|
||||
|
||||
let mut title_row = row!();
|
||||
|
||||
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)
|
||||
.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);
|
||||
|
||||
for item in items {
|
||||
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();
|
||||
item_path.push(item.id.unwrap().to_string());
|
||||
|
||||
let mut table_row = Row::new(vec![]);
|
||||
|
||||
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)
|
||||
.expect(format!("Unknown column {:?}", column_name).as_str());
|
||||
let mut meta_name: Option<&str> = None;
|
||||
|
||||
if column_type == ColumnType::Meta {
|
||||
meta_name = column_format.next();
|
||||
}
|
||||
|
||||
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(
|
||||
&string_column(item.id.unwrap_or(0).to_string(), column_width),
|
||||
Alignment::RIGHT,
|
||||
),
|
||||
ColumnType::Time => Cell::new(&string_column(
|
||||
item.ts.with_timezone(&Local).format("%F %T").to_string(),
|
||||
column_width,
|
||||
)),
|
||||
ColumnType::Size => match item.size {
|
||||
Some(size) => Cell::new_align(
|
||||
&size_column(size as u64, args.options.human_readable, 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(&string_column(item.compression.to_string(), column_width))
|
||||
}
|
||||
ColumnType::FileSize => match item_path.metadata() {
|
||||
Ok(metadata) => Cell::new_align(
|
||||
&size_column(
|
||||
metadata.len() as u64,
|
||||
args.options.human_readable,
|
||||
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(&string_column(
|
||||
item_path.clone().into_os_string().into_string().unwrap(),
|
||||
column_width,
|
||||
)),
|
||||
ColumnType::Tags => Cell::new(&string_column(tags.join(" "), column_width)),
|
||||
ColumnType::Meta => match meta_name {
|
||||
Some(meta_name) => match meta.get(meta_name) {
|
||||
Some(meta_value) => {
|
||||
Cell::new(&string_column(meta_value.to_string(), column_width))
|
||||
}
|
||||
None => Cell::new(""),
|
||||
},
|
||||
None => Cell::new(""),
|
||||
},
|
||||
};
|
||||
table_row.add_cell(cell);
|
||||
}
|
||||
table.add_row(table_row);
|
||||
}
|
||||
|
||||
table.printstd();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// These helper functions are needed for the mode_list function
|
||||
pub fn get_item_tags(conn: &Connection, item: &Item) -> Result<Vec<Tag>> {
|
||||
debug!("DB: Getting tags for item: {:?}", item);
|
||||
let mut statement = conn
|
||||
.prepare_cached("SELECT id, name FROM tags WHERE id=?1 ORDER BY name ASC")
|
||||
.context("Problem preparing SQL statement")?;
|
||||
let mut rows = statement.query([item.id])?;
|
||||
|
||||
let mut tags = Vec::new();
|
||||
|
||||
while let Some(row) = rows.next()? {
|
||||
tags.push(Tag {
|
||||
id: row.get(0)?,
|
||||
name: row.get(1)?,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(tags)
|
||||
}
|
||||
|
||||
pub fn get_item_meta(conn: &Connection, item: &Item) -> Result<Vec<Meta>> {
|
||||
debug!("DB: Getting item meta: {:?}", item);
|
||||
let mut statement = conn
|
||||
.prepare_cached("SELECT id, name, value FROM metas WHERE id=?1 ORDER BY name ASC")
|
||||
.context("Problem preparing SQL statement")?;
|
||||
let mut rows = statement.query([item.id])?;
|
||||
|
||||
let mut metas = Vec::new();
|
||||
|
||||
while let Some(row) = rows.next()? {
|
||||
metas.push(Meta {
|
||||
id: row.get(0)?,
|
||||
name: row.get(1)?,
|
||||
value: row.get(2)?,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(metas)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ pub mod common;
|
||||
pub mod delete;
|
||||
pub mod get;
|
||||
pub mod info;
|
||||
pub mod list;
|
||||
pub mod save;
|
||||
pub mod status;
|
||||
pub mod update;
|
||||
|
||||
Reference in New Issue
Block a user