src/tools/format.rs: move output rendering code to this new file

This commit is contained in:
Dietmar Maurer 2020-02-28 07:30:35 +01:00
parent c81b2b7c70
commit 4939255fb4
4 changed files with 69 additions and 61 deletions

View File

@ -167,16 +167,6 @@ fn complete_repository(_arg: &str, _param: &HashMap<String, String>) -> Vec<Stri
result result
} }
fn render_backup_file_list(files: &[String]) -> String {
let mut files: Vec<String> = files.iter()
.map(|v| strip_server_file_expenstion(&v))
.collect();
files.sort();
tools::join(&files, ' ')
}
fn connect(server: &str, userid: &str) -> Result<HttpClient, Error> { fn connect(server: &str, userid: &str) -> Result<HttpClient, Error> {
let fingerprint = std::env::var(ENV_VAR_PBS_FINGERPRINT).ok(); let fingerprint = std::env::var(ENV_VAR_PBS_FINGERPRINT).ok();
@ -324,15 +314,6 @@ async fn backup_image<P: AsRef<Path>>(
Ok(stats) Ok(stats)
} }
fn strip_server_file_expenstion(name: &str) -> String {
if name.ends_with(".didx") || name.ends_with(".fidx") || name.ends_with(".blob") {
name[..name.len()-5].to_owned()
} else {
name.to_owned() // should not happen
}
}
#[api( #[api(
input: { input: {
properties: { properties: {
@ -376,7 +357,7 @@ async fn list_backup_groups(param: Value) -> Result<Value, Error> {
let render_files = |_v: &Value, record: &Value| -> Result<String, Error> { let render_files = |_v: &Value, record: &Value| -> Result<String, Error> {
let item: GroupListItem = serde_json::from_value(record.to_owned())?; let item: GroupListItem = serde_json::from_value(record.to_owned())?;
Ok(render_backup_file_list(&item.files)) Ok(tools::format::render_backup_file_list(&item.files))
}; };
let options = default_table_format_options() let options = default_table_format_options()
@ -442,7 +423,7 @@ async fn list_snapshots(param: Value) -> Result<Value, Error> {
let render_files = |_v: &Value, record: &Value| -> Result<String, Error> { let render_files = |_v: &Value, record: &Value| -> Result<String, Error> {
let item: SnapshotListItem = serde_json::from_value(record.to_owned())?; let item: SnapshotListItem = serde_json::from_value(record.to_owned())?;
Ok(render_backup_file_list(&item.files)) Ok(tools::format::render_backup_file_list(&item.files))
}; };
let options = default_table_format_options() let options = default_table_format_options()
@ -1635,7 +1616,7 @@ async fn complete_server_file_name_do(param: &HashMap<String, String>) -> Vec<St
fn complete_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec<String> { fn complete_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec<String> {
complete_server_file_name(arg, param) complete_server_file_name(arg, param)
.iter() .iter()
.map(|v| strip_server_file_expenstion(&v)) .map(|v| tools::format::strip_server_file_expenstion(&v))
.collect() .collect()
} }
@ -1643,7 +1624,7 @@ fn complete_pxar_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec
complete_server_file_name(arg, param) complete_server_file_name(arg, param)
.iter() .iter()
.filter_map(|v| { .filter_map(|v| {
let name = strip_server_file_expenstion(&v); let name = tools::format::strip_server_file_expenstion(&v);
if name.ends_with(".pxar") { if name.ends_with(".pxar") {
Some(name) Some(name)
} else { } else {
@ -2178,6 +2159,11 @@ fn catalog_mgmt_cli() -> CliCommandMap {
schema: OUTPUT_FORMAT, schema: OUTPUT_FORMAT,
optional: true, optional: true,
}, },
all: {
type: Boolean,
description: "Also list stopped tasks.",
optional: true,
},
} }
} }
)] )]
@ -2190,29 +2176,28 @@ async fn task_list(param: Value) -> Result<Value, Error> {
let client = connect(repo.host(), repo.user())?; let client = connect(repo.host(), repo.user())?;
let limit = param["limit"].as_u64().unwrap_or(50) as usize; let limit = param["limit"].as_u64().unwrap_or(50) as usize;
let running = !param["all"].as_bool().unwrap_or(false);
let args = json!({ let args = json!({
"running": true, "running": running,
"start": 0, "start": 0,
"limit": limit, "limit": limit,
"userfilter": repo.user(), "userfilter": repo.user(),
"store": repo.store(), "store": repo.store(),
}); });
let result = client.get("api2/json/nodes/localhost/tasks", Some(args)).await?;
let data = &result["data"]; let mut result = client.get("api2/json/nodes/localhost/tasks", Some(args)).await?;
let mut data = result["data"].take();
if output_format == "text" { let schema = &proxmox_backup::api2::node::tasks::API_RETURN_SCHEMA_LIST_TASKS;
for item in data.as_array().unwrap() {
println!( let options = default_table_format_options()
"{} {}", .column(ColumnConfig::new("starttime").right_align(false).renderer(tools::format::render_epoch))
item["upid"].as_str().unwrap(), .column(ColumnConfig::new("endtime").right_align(false).renderer(tools::format::render_epoch))
item["status"].as_str().unwrap_or("running"), .column(ColumnConfig::new("upid"))
); .column(ColumnConfig::new("status").renderer(tools::format::render_task_status));
}
} else { format_and_print_result_full(&mut data, schema, &output_format, &options);
format_and_print_result(data, &output_format);
}
Ok(Value::Null) Ok(Value::Null)
} }

View File

@ -15,27 +15,6 @@ use proxmox_backup::client::*;
use proxmox_backup::tools::ticket::*; use proxmox_backup::tools::ticket::*;
use proxmox_backup::auth_helpers::*; use proxmox_backup::auth_helpers::*;
fn render_epoch(value: &Value, _record: &Value) -> Result<String, Error> {
if value.is_null() { return Ok(String::new()); }
let text = match value.as_i64() {
Some(epoch) => {
Local.timestamp(epoch, 0).format("%c").to_string()
}
None => {
value.to_string()
}
};
Ok(text)
}
fn render_status(value: &Value, record: &Value) -> Result<String, Error> {
if record["endtime"].is_null() {
Ok(value.as_str().unwrap_or("running").to_string())
} else {
Ok(value.as_str().unwrap_or("unknown").to_string())
}
}
async fn view_task_result( async fn view_task_result(
client: HttpClient, client: HttpClient,
result: Value, result: Value,
@ -287,10 +266,10 @@ async fn task_list(param: Value) -> Result<Value, Error> {
let options = TableFormatOptions::new() let options = TableFormatOptions::new()
.noborder(false) .noborder(false)
.noheader(false) .noheader(false)
.column(ColumnConfig::new("starttime").right_align(false).renderer(render_epoch)) .column(ColumnConfig::new("starttime").right_align(false).renderer(tools::format::render_epoch))
.column(ColumnConfig::new("endtime").right_align(false).renderer(render_epoch)) .column(ColumnConfig::new("endtime").right_align(false).renderer(tools::format::render_epoch))
.column(ColumnConfig::new("upid")) .column(ColumnConfig::new("upid"))
.column(ColumnConfig::new("status").renderer(render_status)); .column(ColumnConfig::new("status").renderer(tools::format::render_task_status));
format_and_print_result_full(&mut data, schema, &output_format, &options); format_and_print_result_full(&mut data, schema, &output_format, &options);

View File

@ -23,6 +23,7 @@ pub mod async_io;
pub mod borrow; pub mod borrow;
pub mod daemon; pub mod daemon;
pub mod fs; pub mod fs;
pub mod format;
pub mod lru_cache; pub mod lru_cache;
pub mod runtime; pub mod runtime;
pub mod ticket; pub mod ticket;

43
src/tools/format.rs Normal file
View File

@ -0,0 +1,43 @@
use failure::*;
use serde_json::Value;
use chrono::{Local, TimeZone};
pub fn strip_server_file_expenstion(name: &str) -> String {
if name.ends_with(".didx") || name.ends_with(".fidx") || name.ends_with(".blob") {
name[..name.len()-5].to_owned()
} else {
name.to_owned() // should not happen
}
}
pub fn render_backup_file_list(files: &[String]) -> String {
let mut files: Vec<String> = files.iter()
.map(|v| strip_server_file_expenstion(&v))
.collect();
files.sort();
super::join(&files, ' ')
}
pub fn render_epoch(value: &Value, _record: &Value) -> Result<String, Error> {
if value.is_null() { return Ok(String::new()); }
let text = match value.as_i64() {
Some(epoch) => {
Local.timestamp(epoch, 0).format("%c").to_string()
}
None => {
value.to_string()
}
};
Ok(text)
}
pub fn render_task_status(value: &Value, record: &Value) -> Result<String, Error> {
if record["endtime"].is_null() {
Ok(value.as_str().unwrap_or("running").to_string())
} else {
Ok(value.as_str().unwrap_or("unknown").to_string())
}
}