use std::{env, fs, fs::DirEntry, io, process::Command};
extern crate dirs;
extern crate ravenlib;
#[macro_use]
extern crate log;
extern crate clap_verbosity_flag;
#[macro_use]
extern crate structopt;
use structopt::StructOpt;
#[macro_use]
extern crate human_panic;
pub mod args;
use args::*;
use dirs::home_dir;
use ravenlib::{config::*, daemon::*, ravenserver::*, themes::*};
fn main() {
#[cfg(not(debug_assertions))]
setup_panic!();
if check_init() {
init().unwrap();
}
interpet_args();
}
fn interpet_args() {
let r = Raven::from_args();
use Cycle::*;
use Manage::*;
use Raven::*;
check_themes().unwrap();
let conf = get_config().unwrap();
match r {
Load { theme, verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
run_theme(&load_theme(theme).unwrap()).unwrap();
}
New { name, verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
new_theme(name).unwrap()
}
Modify {
name,
editor,
verbose,
} => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
modify_file(conf.editing, name, editor)
}
Delete { name, verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
del_theme(name).unwrap()
}
Edit { name, verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
edit(name).unwrap();
}
Key {
key,
value,
verbose,
} => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
key_value(key, value, conf.editing).unwrap()
}
ManageO { .. } => {
match r {
ManageO(Export { name, verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
export(name, check_tmp()).unwrap();
}
ManageO(Import { name, verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
import(name).unwrap()
}
ManageO(Publish { name, verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
upload_theme(name).unwrap();
}
ManageO(Create {
name,
pass1,
pass2,
verbose,
}) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
create_user(name, pass1, pass2).unwrap();
}
ManageO(Unpublish { name, verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
unpublish_theme(name).unwrap()
}
ManageO(Login {
name,
pass,
verbose,
}) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
login_user(name, pass).unwrap()
}
ManageO(Logout { verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
logout().unwrap()
}
ManageO(DUser { pass, verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
delete_user(pass).unwrap()
}
_ => println!("Well, this shouldn't be happening"),
};
}
CycleD { .. } => {
let running = check_daemon().unwrap();
match r {
CycleD(Check { verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
if running {
println!("Cycle daemon running.");
} else {
println!("Cycle daemon not running.");
}
}
CycleD(Start { verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
if !running {
start_daemon().unwrap();
} else {
println!("Cycle daemon already running.");
}
}
CycleD(Stop { verbose }) => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
if running {
stop_daemon().unwrap();
} else {
println!("Cycle daemon not running.");
}
}
_ => {
println!("Not a possible command.");
}
}
}
Info { verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
print_info(conf.editing)
}
Refresh { verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
refresh_theme(conf.last).unwrap();
}
Install {
name,
force,
verbose,
} => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
download_theme(name, force).unwrap();
}
Add {
name,
option,
verbose,
} => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
add_to_theme(conf.editing, option, name).unwrap()
}
Rm { name, verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
rm_from_theme(conf.editing, name).unwrap()
}
Menu { verbose } => {
verbose
.setup_env_logger("raven")
.expect("Couldn't set up logger");
show_menu(conf.menu_command)
}
};
}
fn print_info<N>(editing: N)
where
N: Into<String>,
{
let editing = editing.into();
info!("Reading in themes");
let options = fs::read_dir(get_home() + "/.config/raven/themes/" + &editing)
.expect("Couldn't read themes")
.collect::<Vec<io::Result<DirEntry>>>()
.into_iter()
.map(|x| proc_path(x.unwrap()))
.filter(|x| x != "theme.json")
.collect::<Vec<String>>();
println!("Current configured options for {}", editing);
for option in options {
println!("{}", option);
}
println!("All themes: ");
let themes = get_themes().unwrap();
for t in themes {
println!("{}", t);
}
}
fn modify_file<N>(editing: N, file: N, editor: Option<N>)
where
N: Into<String>,
{
if editor.is_none() {
let editor = env::var_os("EDITOR");
if editor.is_none() {
error!("Could not fetch $EDITOR from your OS.");
std::process::exit(64);
}
}
let editor = editor.unwrap().into();
let path = get_home() + "/.config/raven/themes/" + &editing.into() + "/" + &file.into();
info!("Started editor {:?} at {}", editor, path);
Command::new(editor)
.arg(path)
.spawn()
.expect("Couldn't run $EDITOR");
}
fn show_menu<N>(menu_command: N)
where
N: Into<String>,
{
let mut theme_list = String::new();
let mut entries = get_themes().unwrap();
entries.sort_by(|a, b| a.cmp(&b));
let mut i = 0;
for entry in entries {
if entry.chars().count() > 0 {
if i > 0 {
theme_list.push_str("\n");
}
theme_list.push_str(&entry);
i += 1;
}
}
info!("Starting menu command");
let output = Command::new("sh")
.arg("-c")
.arg(String::from("echo '") + &theme_list + "' | " + &menu_command.into())
.output()
.expect("Failed to run menu.");
info!("Menu command stopped. Parsing into theme name.");
let int_output = String::from_utf8_lossy(&output.stdout);
if int_output.len() > 0 {
info!("loading selected theme");
let theme = load_theme(int_output.trim());
if theme.is_err() {
error!("Could not load in theme data. Does it exist?");
} else {
run_theme(&theme.unwrap()).unwrap();
}
} else {
println!("Theme not selected.");
}
}
fn get_home() -> String {
return String::from(home_dir().unwrap().to_str().unwrap());
}
fn proc_path(path: DirEntry) -> String {
let base = path.file_name().into_string().unwrap();
return base;
}