use std::cmp::{Ord, Ordering};
use std::collections::{HashMap, HashSet};
use std::ops::Index;
use std::fs::Metadata;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, RwLock};
use std::sync::mpsc::Sender;
use std::hash::{Hash, Hasher};
use std::str::FromStr;
use lscolors::LsColors;
use tree_magic;
use users::{get_current_username,
get_current_groupname,
get_user_by_uid,
get_group_by_gid};
use chrono::TimeZone;
use failure::Error;
use rayon::{ThreadPool, ThreadPoolBuilder};
use alphanumeric_sort::compare_str;
use mime_guess;
use pathbuftools::PathBufTools;
use async_value::{Async, Stale};
use crate::fail::{HResult, HError, ErrorLog};
use crate::dirty::{AsyncDirtyBit, DirtyBit, Dirtyable};
use crate::widget::Events;
use crate::icon::Icons;
use crate::fscache::FsEvent;
lazy_static! {
static ref COLORS: LsColors = LsColors::from_env().unwrap_or_default();
static ref TAGS: RwLock<(bool, Vec<PathBuf>)> = RwLock::new((false, vec![]));
static ref ICONS: Icons = Icons::new();
}
fn make_pool(sender: Option<Sender<Events>>) -> ThreadPool {
let sender = Arc::new(Mutex::new(sender));
ThreadPoolBuilder::new()
.num_threads(8)
.exit_handler(move |thread_num| {
if thread_num == 0 {
if let Ok(lock) = sender.lock() {
if let Some(sender) = lock.as_ref() {
sender.send(Events::WidgetReady).ok();
}
}
}
})
.build()
.expect("Failed to create thread pool")
}
pub fn load_tags() -> HResult<()> {
std::thread::spawn(|| -> HResult<()> {
let tag_path = crate::paths::tagfile_path()?;
if !tag_path.exists() {
import_tags().log();
}
let tags = std::fs::read_to_string(tag_path)?;
let mut tags = tags.lines()
.map(|f|
PathBuf::from(f))
.collect::<Vec<PathBuf>>();
let mut tag_lock = TAGS.write()?;
tag_lock.0 = true;
tag_lock.1.append(&mut tags);
Ok(())
});
Ok(())
}
pub fn import_tags() -> HResult<()> {
let mut ranger_tags = crate::paths::ranger_path()?;
ranger_tags.push("tagged");
if ranger_tags.exists() {
let tag_path = crate::paths::tagfile_path()?;
std::fs::copy(