summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-02-06 00:55:10 +0100
committerrabite <rabite@posteo.de>2019-02-06 00:55:10 +0100
commit8c2c1c0bab46518ea95e8eaf400faaddad1ef93d (patch)
tree6c25ef733dea9b3ba903be17b6dacbdfe0f4f20a
parent09b50562ece43e6b8dc202def224b521268ad875 (diff)
show file stats at bottom
-rw-r--r--Cargo.toml4
-rw-r--r--src/file_browser.rs11
-rw-r--r--src/files.rs101
-rw-r--r--src/main.rs2
-rw-r--r--src/term.rs18
-rw-r--r--src/widget.rs14
-rw-r--r--src/window.rs24
7 files changed, 144 insertions, 30 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 71f9304..b97e5f6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,4 +13,6 @@ alphanumeric-sort = "1.0.6"
lscolors = { version = "0.5.0", features = [ "ansi_term" ] }
mime-detective = "*"
rayon = "1.0.3"
-dirs-2 = "1.1.0" \ No newline at end of file
+dirs-2 = "1.1.0"
+users = "0.8"
+chrono = "0.4" \ No newline at end of file
diff --git a/src/file_browser.rs b/src/file_browser.rs
index aa23b22..1de948d 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -181,6 +181,17 @@ impl Widget for FileBrowser {
let sized_path = crate::term::sized_string(&pretty_path, xsize);
sized_path
}
+ fn render_footer(&self) -> String {
+ let file = self.selected_file();
+ let permissions = file.pretty_print_permissions();
+
+ let user = file.pretty_user().unwrap_or("NOUSER".into());
+ let group = file.pretty_group().unwrap_or("NOGROUP".into());
+
+ let mtime = file.pretty_mtime();
+
+ format!("{} {}:{} {}", permissions, user, group, mtime)
+ }
fn refresh(&mut self) {
self.columns.refresh();
}
diff --git a/src/files.rs b/src/files.rs
index 0c836ab..0f0f373 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -1,11 +1,13 @@
use std::cmp::{Ord, Ordering};
use std::error::Error;
use std::ops::Index;
+use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
-use std::time::SystemTime;
use lscolors::LsColors;
use mime_detective;
+use users;
+use chrono::TimeZone;
lazy_static! {
@@ -55,17 +57,20 @@ impl Files {
let files: Vec<_> = direntries?
.iter()
.map(|file| {
- //let file = file?;
+ //let file = file?;
let name = file.file_name();
let name = name.to_string_lossy();
let kind = get_kind(&file);
let path = file.path();
let meta = file.metadata().unwrap();
+ let mode = meta.mode();
let size = meta.len();
- let mtime = meta.modified().unwrap();
-
- let color = get_color(&path, &meta);
- File::new(&name, path, kind, size as usize, mtime, color)
+ let mtime = meta.mtime();
+ let user = meta.uid();
+ let group = meta.gid();
+ let color = get_color(&path, &meta);
+ File::new(&name, path, kind, size as usize, mtime, color, mode,
+ user, group)
})
.collect();
@@ -165,10 +170,11 @@ pub struct File {
pub path: PathBuf,
pub size: Option<usize>,
pub kind: Kind,
- pub mtime: SystemTime,
+ pub mtime: i64,
pub color: Option<lscolors::Color>,
- // owner: Option<String>,
- // group: Option<String>,
+ pub mode: u32,
+ pub user: u32,
+ pub group: u32,
// flags: Option<String>,
}
@@ -178,8 +184,11 @@ impl File {
path: PathBuf,
kind: Kind,
size: usize,
- mtime: SystemTime,
+ mtime: i64,
color: Option<lscolors::Color>,
+ mode: u32,
+ user: u32,
+ group: u32
) -> File {
File {
name: name.to_string(),
@@ -187,7 +196,10 @@ impl File {
size: Some(size),
kind: kind,
mtime: mtime,
- color: color
+ color: color,
+ mode: mode,
+ user: user,
+ group: group
// owner: None,
// group: None,
// flags: None,
@@ -202,11 +214,17 @@ impl File {
.unwrap_or("/".to_string());
let kind = Kind::Directory; //get_kind(&path);
- let meta = &path.metadata().unwrap();
+ let meta = &path.metadata()?;
let size = meta.len();
- let mtime = meta.modified().unwrap();
+ let user = meta.uid();
+ let group = meta.gid();
let color = get_color(&path, meta);
- Ok(File::new(&name, pathbuf, kind, size as usize, mtime, color))
+ let mode = meta.mode();
+ let mtime = meta.mtime();
+ Ok(
+ File::new(&name, pathbuf, kind, size as usize, mtime, color, mode, user
+ , group)
+ )
}
pub fn new_placeholder(path: &Path) -> Result<File, Box<Error>> {
@@ -266,4 +284,59 @@ impl File {
pub fn path(&self) -> PathBuf {
self.path.clone()
}
+
+ pub fn pretty_print_permissions(&self) -> String {
+ let perms: usize = format!("{:o}", self.mode).parse().unwrap();
+ let perms: usize = perms % 800;
+ let perms = format!("{}", perms);
+
+ let r = format!("{}r", crate::term::color_green());
+ let w = format!("{}w", crate::term::color_yellow());
+ let x = format!("{}x", crate::term::color_red());
+ let n = format!("{}-", crate::term::highlight_color());
+
+ let perms = perms.chars().map(|c| match c.to_string().parse().unwrap() {
+ 1 => format!("{}{}{}", n,n,x),
+ 2 => format!("{}{}{}", n,w,n),
+ 3 => format!("{}{}{}", n,w,x),
+ 4 => format!("{}{}{}", r,n,n),
+ 5 => format!("{}{}{}", r,n,x),
+ 6 => format!("{}{}{}", r,w,n),
+ 7 => format!("{}{}{}", r,w,x),
+ _ => format!("---")
+ }).collect();
+
+ perms
+ }
+
+ pub fn pretty_user(&self) -> Option<String> {
+ let uid = self.user;
+ let file_user = users::get_user_by_uid(uid)?;
+ let cur_user = users::get_current_username()?;
+ let color =
+ if file_user.name() == cur_user {
+ crate::term::color_green()
+ } else {
+ crate::term::color_yellow() };
+ Some(format!("{}{}", color, file_user.name().to_string_lossy()))
+ }
+
+ pub fn pretty_group(&self) -> Option<String> {
+ let gid = self.group;
+ let file_group = users::get_group_by_gid(gid)?;
+ let cur_group = users::get_current_groupname()?;
+ let color =
+ if file_group.name() == cur_group {
+ crate::term::color_green()
+ } else {
+ crate::term::color_yellow() };
+ Some(format!("{}{}", color, file_group.name().to_string_lossy()))
+ }
+
+ pub fn pretty_mtime(&self) -> String {
+ //let time = chrono::DateTime::from_timestamp(self.mtime, 0);
+ let time: chrono::DateTime<chrono::Local>
+ = chrono::Local.timestamp(self.mtime, 0);
+ time.format("%F %R").to_string()
+ }
}
diff --git a/src/main.rs b/src/main.rs
index 24550d2..c4a0cb6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,8 @@ extern crate lazy_static;
extern crate alphanumeric_sort;
extern crate dirs_2;
extern crate lscolors;
+extern crate users;
+extern crate chrono;
extern crate mime_detective;
extern crate rayon;
diff --git a/src/term.rs b/src/term.rs
index bbd8806..950a410 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -55,6 +55,18 @@ pub fn normal_color() -> String {
)
}
+pub fn color_red() -> String {
+ format!("{}", termion::color::Fg(termion::color::Red))
+}
+
+pub fn color_yellow() -> String {
+ format!("{}", termion::color::Fg(termion::color::Yellow))
+}
+
+pub fn color_green() -> String {
+ format!("{}", termion::color::Fg(termion::color::Green))
+}
+
pub fn from_lscolor(color: &lscolors::Color) -> String {
match color {
lscolors::Color::Black => format!("{}", termion::color::Fg(termion::color::Black)),
@@ -69,9 +81,9 @@ pub fn from_lscolor(color: &lscolors::Color) -> String {
}
}
-pub fn cursor_left(n: u16) -> String {
- format!("{}", termion::cursor::Left(n))
-}
+// pub fn cursor_left(n: u16) -> String {
+// format!("{}", termion::cursor::Left(n))
+// }
pub fn gotoy(y: u16) -> String {
format!("{}", termion::cursor::Goto(1, y))
diff --git a/src/widget.rs b/src/widget.rs
index 02103fc..465d625 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -13,6 +13,7 @@ pub trait Widget: PartialEq {
fn get_coordinates(&self) -> &Coordinates;
fn set_coordinates(&mut self, coordinates: &Coordinates);
fn render_header(&self) -> String;
+ fn render_footer(&self) -> String { "".into() }
fn on_event(&mut self, event: Event) {
match event {
@@ -65,6 +66,19 @@ pub trait Widget: PartialEq {
)
}
+ fn get_footer_drawlist(&mut self) -> String {
+ let xsize = self.get_coordinates().xsize();
+ let ypos = crate::term::ysize();
+ format!(
+ "{}{}{:xsize$}{}{}",
+ crate::term::goto_xy(1, ypos),
+ crate::term::header_color(),
+ " ",
+ crate::term::goto_xy(1, ypos),
+ self.render_footer(),
+ xsize = xsize as usize)
+ }
+
fn get_clearlist(&self) -> String {
let (xpos, ypos) = self.get_position().position();
let (xsize, ysize) = self.get_size().size();
diff --git a/src/window.rs b/src/window.rs
index a06c276..6033c71 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -50,28 +50,28 @@ where
}
pub fn draw(&mut self) {
- let output = self.widget.get_drawlist() + &self.widget.get_header_drawlist();
+ let output = self.widget.get_drawlist() + &self.widget.get_header_drawlist()
+ + &self.widget.get_footer_drawlist();
self.screen.write(output.as_ref()).unwrap();
self.screen.flush().unwrap();
- Self::draw_status();
}
- pub fn show_status(status: &str) {
- show_status(status);
- }
+ // pub fn show_status(status: &str) {
+ // show_status(status);
+ // }
- pub fn draw_status() {
- draw_status();
- }
+ // pub fn draw_status() {
+ // draw_status();
+ // }
- pub fn clear_status() {
- Self::show_status("");
- }
+ // pub fn clear_status() {
+ // Self::show_status("");
+ // }
pub fn handle_input(&mut self) {
for event in stdin().events() {
- Self::clear_status();
+ //Self::clear_status();
let event = event.unwrap();
self.widget.on_event(event);
self.draw();