extern crate ansi_term;
extern crate docopt;
extern crate regex;
extern crate rustc_serialize;
use std::fs;
use std::io;
use std::thread;
use std::io::Write;
use std::process::Command;
use std::time::Duration;
use ansi_term::Style;
use ansi_term::Colour::Red;
use docopt::{Docopt, Error};
use regex::Regex;
const USAGE: &'static str = "
blerp filters local or remote files or resources.
Usage:
blerp [options] [<path>...]
blerp (--help | --version)
Options:
-a Attack mode
-b Suppress bees
-— Flags use em dashes
-c Count number of arguments
-d Pipes output to debug.exe
-D Deprecated
-e Execute something
-f Fun mode
-g Use Google
-h Check whether input halts
-i Ignore case (lower)
-I Ignore case (upper)
-jk Kidding
-n Behavior not defined
-o Overwrite
-O Opposite day
-p Set true Pope; accepts \"Rome\" or \"Avignon\"
-q Quiet mode; output is printed to stdout instead of being spoken aloud
-r Randomize arguments
-R Run recursively on http://*
-s Follow symbolic links symbolically
-S Stealth mode
-t Tumble dry
-u UTF-8 mode; otherwise defaults to ANSEL
-U Update (default: Facebook)
-v Verbose; alias to find / -exec cat {}
-V Set version number
-y Yikes
";
#[derive(Debug)]
pub struct Blerp {
arguments: Vec<String>,
suppress_bees: bool,
count_args: bool,
deprecated: bool,
fun_mode: bool,
use_google: bool,
check_if_halts: bool,
opposite_day: bool,
quiet_mode: bool,
stealth_mode: bool,
}
impl Blerp {
pub fn new<S>(argv: Vec<S>) -> Result<Self, Error> where S: AsRef<str> {
let version = Some(format!("blerp {}", env!("CARGO_PKG_VERSION")));
let docopt = try!(Docopt::new(USAGE));
let argvmap = try!(docopt.argv(argv).options_first(true).version(version).parse());
let blerp = Blerp {
arguments: argvmap.get_vec("<path>").iter().map(|a| a.to_string()).collect::<Vec<String>>(),
suppress_bees: argvmap.get_bool("-b"),
count_args: argvmap.get_bool("-c"),
deprecated: argvmap.get_bool("-D"),
fun_mode: argvmap.get_bool("-f"),
use_google: argvmap.get_bool("-g"),
check_if_halts: argvmap.get_bool("-h"),
opposite_day: argvmap.get_bool("-O"),
quiet_mode: argvmap.get_bool("-q"),
stealth_mode: argvmap.get_bool("-S"),
};
return Ok(blerp);
}
pub fn run(&self) -> Result<(), &str> {
if self.use_google {
let engine = if self.opposite_day {
"https://duckduckgo.com/"
} else {
"https://www.google.com/search"
};
let url = format!("{}?q={}", engine, self.arguments.join("+"));
if Command::new("open").arg(url).output().is_err() {
return Err("Failed to open URL in browser.");
}
}
if self.count_args {
println!("Number of arguments: {}", self.arguments.len());
}
if self.deprecated {
println!("{}", Red.paint("Use of the `-D` option is deprecated."));
}
if self.fun_mode {
println!("{}", Style::new().blink().bold().paint("Fun mode!"));
}
let mut files: Vec<String> = Vec::new();
for path in fs::read_dir("./").unwrap() {
if path.as_ref().unwrap().metadata().unwrap().is_file() {
files.push(path.unwrap().file_name().into_string().unwrap());
}
}
for arg in self.arguments.clone() {
let re = Regex::new(&arg).unwrap();
files.retain(|f| re.is_match(f));
}
let mut style = Style::new();
if self.stealth_mode {
if self.opposite_day {
style = style.bold();
} else {
style = style.dimmed();
}
}
let say_cmd: Option<&str>;
if Command::new("say").spawn().is_ok() {
say_cmd = Some("say");
} else if Command::new("espeak").spawn().is_ok() {
say_cmd = Some("espeak");
} else {
say_cmd = None;
if self.quiet_mode && self.opposite_day {
println!("`say` and `espeak` are unavailable. Defaulting to quiet mode.");
}
}
for mut file in files {
if self.suppress_bees {
file = file.replace("B", "Ƀ").replace("b", "ƀ");
}
if self.quiet_mode && self.opposite_day && say_cmd.is_some() {
Command::new(say_cmd.unwrap()).arg(file).output().unwrap();
} else {
println!("{}", style.paint(file));
}
}
if self.check_if_halts {
if self.opposite_day {
println!("Input halts.");
} else {
print!("Checking whether input halts");
let mut delay = Duration::from_secs(1);
let mut next = delay;
loop {
io::stdout().flush().expect("Couldn't flush stdout");
print!(".");
thread::sleep(delay);
let tmp = delay + next;
delay = next;
next = tmp;
}
}
}
return Ok(());
}
}