mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 01:26:04 -08:00
draw log list
This commit is contained in:
52
Cargo.lock
generated
52
Cargo.lock
generated
@@ -36,6 +36,19 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"time",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloudabi"
|
name = "cloudabi"
|
||||||
version = "0.0.3"
|
version = "0.0.3"
|
||||||
@@ -112,7 +125,7 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -221,6 +234,25 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.58"
|
version = "0.9.58"
|
||||||
@@ -436,6 +468,7 @@ dependencies = [
|
|||||||
name = "termscp"
|
name = "termscp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"crossterm 0.18.2",
|
"crossterm 0.18.2",
|
||||||
"getopts",
|
"getopts",
|
||||||
"rpassword",
|
"rpassword",
|
||||||
@@ -447,6 +480,17 @@ dependencies = [
|
|||||||
"whoami",
|
"whoami",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tui"
|
name = "tui"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
@@ -494,6 +538,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whoami"
|
name = "whoami"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ users = "0.11.0"
|
|||||||
whoami = "0.9.0"
|
whoami = "0.9.0"
|
||||||
rpassword = "5.0.0"
|
rpassword = "5.0.0"
|
||||||
unicode-width = "0.1.7"
|
unicode-width = "0.1.7"
|
||||||
|
chrono = "0.4.19"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
|
extern crate chrono;
|
||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
extern crate tui;
|
extern crate tui;
|
||||||
extern crate unicode_width;
|
extern crate unicode_width;
|
||||||
@@ -31,6 +32,7 @@ extern crate unicode_width;
|
|||||||
// locals
|
// locals
|
||||||
use super::{Activity, Context};
|
use super::{Activity, Context};
|
||||||
use crate::filetransfer::FileTransferProtocol;
|
use crate::filetransfer::FileTransferProtocol;
|
||||||
|
use crate::utils::time_to_str;
|
||||||
|
|
||||||
// File transfer
|
// File transfer
|
||||||
use crate::filetransfer::sftp_transfer::SftpFileTransfer;
|
use crate::filetransfer::sftp_transfer::SftpFileTransfer;
|
||||||
@@ -38,16 +40,16 @@ use crate::filetransfer::FileTransfer;
|
|||||||
use crate::fs::FsEntry;
|
use crate::fs::FsEntry;
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
|
use chrono::{DateTime, Local};
|
||||||
use crossterm::event::Event as InputEvent;
|
use crossterm::event::Event as InputEvent;
|
||||||
use crossterm::event::{KeyCode, KeyModifiers};
|
use crossterm::event::{KeyCode, KeyModifiers};
|
||||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io::Stdout;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use tui::{
|
use tui::{
|
||||||
backend::CrosstermBackend,
|
backend::CrosstermBackend,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Corner, Direction, Layout, Rect},
|
||||||
style::{Color, Modifier, Style},
|
style::{Color, Modifier, Style},
|
||||||
terminal::Frame,
|
terminal::Frame,
|
||||||
text::{Span, Spans, Text},
|
text::{Span, Spans, Text},
|
||||||
@@ -173,7 +175,7 @@ enum LogLevel {
|
|||||||
///
|
///
|
||||||
/// Log record entry
|
/// Log record entry
|
||||||
struct LogRecord {
|
struct LogRecord {
|
||||||
pub time: Instant,
|
pub time: DateTime<Local>,
|
||||||
pub level: LogLevel,
|
pub level: LogLevel,
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
}
|
}
|
||||||
@@ -184,7 +186,7 @@ impl LogRecord {
|
|||||||
/// Instantiates a new LogRecord
|
/// Instantiates a new LogRecord
|
||||||
pub fn new(level: LogLevel, msg: &str) -> LogRecord {
|
pub fn new(level: LogLevel, msg: &str) -> LogRecord {
|
||||||
LogRecord {
|
LogRecord {
|
||||||
time: Instant::now(),
|
time: Local::now(),
|
||||||
level: level,
|
level: level,
|
||||||
msg: String::from(msg),
|
msg: String::from(msg),
|
||||||
}
|
}
|
||||||
@@ -1480,42 +1482,43 @@ impl FileTransferActivity {
|
|||||||
.style(Style::default().fg(Color::LightYellow).add_modifier(Modifier::BOLD))
|
.style(Style::default().fg(Color::LightYellow).add_modifier(Modifier::BOLD))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// ### draw_log_list
|
/// ### draw_log_list
|
||||||
///
|
///
|
||||||
/// Draw log list
|
/// Draw log list
|
||||||
fn draw_log_list(&self) -> List {
|
fn draw_log_list(&self) -> List {
|
||||||
let events: Vec<ListItem> = self.log_records
|
let events: Vec<ListItem> = self
|
||||||
|
.log_records
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(evt, level)| {
|
.map(|record: &LogRecord| {
|
||||||
let s = match level {
|
let s = match record.level {
|
||||||
"CRITICAL" => Style::default().fg(Color::Red),
|
LogLevel::Error => Style::default().fg(Color::Red),
|
||||||
"ERROR" => Style::default().fg(Color::Magenta),
|
LogLevel::Warn => Style::default().fg(Color::Yellow),
|
||||||
"WARNING" => Style::default().fg(Color::Yellow),
|
LogLevel::Info => Style::default().fg(Color::Green),
|
||||||
"INFO" => Style::default().fg(Color::Blue),
|
};
|
||||||
_ => Style::default(),
|
let header = Spans::from(vec![
|
||||||
};
|
Span::raw("["),
|
||||||
let header = Spans::from(vec![
|
Span::styled(
|
||||||
Span::styled(format!("{:<9}", level), s),
|
format!(
|
||||||
Span::raw(" "),
|
"{:<6}",
|
||||||
Span::styled(
|
match record.level {
|
||||||
"2020-01-01 10:00:00",
|
LogLevel::Error => "ERROR",
|
||||||
Style::default().add_modifier(Modifier::ITALIC),
|
LogLevel::Warn => "WARN",
|
||||||
|
LogLevel::Info => "INFO",
|
||||||
|
}
|
||||||
),
|
),
|
||||||
]);
|
s,
|
||||||
let log = Spans::from(vec![Span::raw(evt)]);
|
),
|
||||||
ListItem::new(vec![
|
Span::raw("] "),
|
||||||
Spans::from("-".repeat(chunks[1].width as usize)),
|
Span::from(format!("{}", record.time.format("%Y-%m-%dT%H:%M:%S%Z"))),
|
||||||
header,
|
]);
|
||||||
Spans::from(""),
|
let log = Spans::from(vec![Span::from(record.msg.clone())]);
|
||||||
log,
|
ListItem::new(vec![header, log])
|
||||||
])
|
})
|
||||||
})
|
.collect();
|
||||||
.collect();
|
List::new(events)
|
||||||
let events_list = List::new(events)
|
.block(Block::default().borders(Borders::ALL).title("Log"))
|
||||||
.block(Block::default().borders(Borders::ALL).title("List"))
|
.start_corner(Corner::BottomLeft)
|
||||||
.start_corner(Corner::BottomLeft);
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
/// ### draw_footer
|
/// ### draw_footer
|
||||||
///
|
///
|
||||||
|
|||||||
20
src/utils.rs
20
src/utils.rs
@@ -24,10 +24,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
|
extern crate chrono;
|
||||||
extern crate whoami;
|
extern crate whoami;
|
||||||
|
|
||||||
use crate::filetransfer::FileTransferProtocol;
|
use crate::filetransfer::FileTransferProtocol;
|
||||||
|
|
||||||
|
use chrono::prelude::*;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
/// ### parse_remote_opt
|
/// ### parse_remote_opt
|
||||||
///
|
///
|
||||||
/// Parse remote option string. Returns in case of success a tuple made of (address, port, protocol, username)
|
/// Parse remote option string. Returns in case of success a tuple made of (address, port, protocol, username)
|
||||||
@@ -119,6 +123,16 @@ pub fn parse_remote_opt(
|
|||||||
Ok((address, port, protocol, username))
|
Ok((address, port, protocol, username))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### instant_to_str
|
||||||
|
///
|
||||||
|
/// Format a `Instant` into a time string
|
||||||
|
pub fn time_to_str(time: SystemTime, fmt: &str) -> String {
|
||||||
|
let datetime: DateTime<Local> = time.into();
|
||||||
|
// Format the datetime how you want
|
||||||
|
let newdate = datetime.to_rfc3339_opts(SecondsFormat::Secs, true);
|
||||||
|
format!("{}", datetime.format(fmt))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
@@ -175,4 +189,10 @@ mod tests {
|
|||||||
assert!(parse_remote_opt(&String::from("172.26.104.1:abc")).is_err()); // Bad port
|
assert!(parse_remote_opt(&String::from("172.26.104.1:abc")).is_err()); // Bad port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_utils_time_to_str() {
|
||||||
|
let system_time: SystemTime = SystemTime::from(SystemTime::UNIX_EPOCH);
|
||||||
|
assert_eq!(time_to_str(system_time, "%Y-%m-%d"), String::from("1970-01-01"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user