<commit_before>extern crate rustc_serialize;
#[macro_use]
extern crate aws_abacus;
#[macro_use]
extern crate log;
extern crate walkdir;
extern crate env_logger;
extern crate docopt;
use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
extern crate chrono;
use chrono::{DateTime, UTC};
use aws_abacus::elb_log_files::ParsingResult;
use std::collections::HashMap;
extern crate urlparse;
use urlparse::{Url, urlparse};
use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

fn main() {
    env_logger::init().unwrap();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let log_location = &path::Path::new(&args.arg_log_location);
    debug!("Running summary on {}.", log_location.to_str().unwrap());

    let start: Option<DateTime<UTC>> = if args.flag_benchmark {
        Some(UTC::now())
    } else {
        None
    };

    let mut filenames = Vec::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();
            debug!("Found {} files.", num_files);

            let number_of_records = elb_log_files::process_files(&filenames, &mut |parsing_result: ParsingResult| {
                parsing_result_handler(parsing_result, &mut agg);
            });
            debug!("Processed {} records in {} files.", number_of_records, num_files);

            for (aggregate, total) in &agg {
                println!(
                    "{},{},{},{}",
                    aggregate.system_name,
                    aggregate.day,
                    aggregate.client_address,
                    total
                );
            };

            match start {
                Some(s) => {
                    let end = UTC::now();
                    let time = end - s;
                    println!("Processed {} files having {} records in {} milliseconds and produced {} aggregates.",
                        num_files,
                        number_of_records,
                        time.num_milliseconds(),
                        agg.len()
                    );
                },
                None => {},
            };

            std::process::exit(0);
        },

        Err(e) => {
            println_stderr!("The following error occurred while trying to get the list of files. {}", e);
            std::process::exit(1);
        },
    };
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct AggregateELBRecord {
    day: String,
    client_address: String,
    system_name: String,
}

fn parsing_result_handler(parsing_result: ParsingResult, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    match parsing_result {
        Ok(elb_record) => {
            let url = urlparse(&elb_record.request_url);
            let aer = AggregateELBRecord {
                day: elb_record.timestamp.format("%Y-%m-%d").to_string(),
                client_address: elb_record.client_address.ip().to_string(),
                system_name: parse_system_name(&url).unwrap_or("UNDEFINED_SYSTEM".to_owned()),
            };
            aggregate_record(aer, aggregation);
        },

        Err(errors) => {
            println_stderr!("{}", errors.record);
        }
    }
}

fn parse_system_name(url: &Url) -> Option<String> {
    url.get_parsed_query().map( |query_map|
        query_map.get("system").map( |systems|
            systems[0].clone()
        )
    ).unwrap_or_else( || None )
}

fn aggregate_record(aggregate_record: AggregateELBRecord, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    let total = aggregation.entry(aggregate_record).or_insert(0);
    *total += 1;
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug | -b | --benchmark) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
    flag_benchmark: bool,
}

#[cfg(test)]
mod tests {

    use std::collections::HashMap;
    use ::AggregateELBRecord;
    use ::aggregate_record;

    const TEST_RECORD: &'static str = "2015-08-15T23:43:05.302180Z elb-name 172.16.1.6:54814 \
    172.16.1.5:9000 0.000039 0.145507 0.00003 200 200 0 7582 \
    \"GET http://some.domain.com:80/path0/path1?param0=p0&param1=p1 HTTP/1.1\"\
    ";

    #[test]
	fn inserting_two_records_with_different_values_creates_two_entries_each_recorded_once() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8880
        };

        let ar1 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg.len(), 2);
        for (_, total) in agg {
            assert_eq!(total, 1)
        }
	}

    #[test]
	fn inserting_two_records_with_the_same_values_increases_the_total_correctly() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        let ar1 = ar0.clone();
        let ar3 = ar0.clone();

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg[&ar3], 2);
	}
}
<commit_msg>Cleaned up the tests after all of the recent changes.<commit_after>extern crate rustc_serialize;
#[macro_use]
extern crate aws_abacus;
#[macro_use]
extern crate log;
extern crate walkdir;
extern crate env_logger;
extern crate docopt;
use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
extern crate chrono;
use chrono::{DateTime, UTC};
use aws_abacus::elb_log_files::ParsingResult;
use std::collections::HashMap;
extern crate urlparse;
use urlparse::{Url, urlparse};
use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

fn main() {
    env_logger::init().unwrap();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let log_location = &path::Path::new(&args.arg_log_location);
    debug!("Running summary on {}.", log_location.to_str().unwrap());

    let start: Option<DateTime<UTC>> = if args.flag_benchmark {
        Some(UTC::now())
    } else {
        None
    };

    let mut filenames = Vec::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();
            debug!("Found {} files.", num_files);

            let number_of_records = elb_log_files::process_files(&filenames, &mut |parsing_result: ParsingResult| {
                parsing_result_handler(parsing_result, &mut agg);
            });
            debug!("Processed {} records in {} files.", number_of_records, num_files);

            for (aggregate, total) in &agg {
                println!(
                    "{},{},{},{}",
                    aggregate.system_name,
                    aggregate.day,
                    aggregate.client_address,
                    total
                );
            };

            match start {
                Some(s) => {
                    let end = UTC::now();
                    let time = end - s;
                    println!("Processed {} files having {} records in {} milliseconds and produced {} aggregates.",
                        num_files,
                        number_of_records,
                        time.num_milliseconds(),
                        agg.len()
                    );
                },
                None => {},
            };

            std::process::exit(0);
        },

        Err(e) => {
            println_stderr!("The following error occurred while trying to get the list of files. {}", e);
            std::process::exit(1);
        },
    };
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct AggregateELBRecord {
    day: String,
    client_address: String,
    system_name: String,
}

fn parsing_result_handler(parsing_result: ParsingResult, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    match parsing_result {
        Ok(elb_record) => {
            let url = urlparse(&elb_record.request_url);
            let aer = AggregateELBRecord {
                day: elb_record.timestamp.format("%Y-%m-%d").to_string(),
                client_address: elb_record.client_address.ip().to_string(),
                system_name: parse_system_name(&url).unwrap_or("UNDEFINED_SYSTEM".to_owned()),
            };
            aggregate_record(aer, aggregation);
        },

        Err(errors) => {
            println_stderr!("{}", errors.record);
        }
    }
}

fn parse_system_name(url: &Url) -> Option<String> {
    url.get_parsed_query().map( |query_map|
        query_map.get("system").map( |systems|
            systems[0].clone()
        )
    ).unwrap_or_else( || None )
}

fn aggregate_record(aggregate_record: AggregateELBRecord, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    let total = aggregation.entry(aggregate_record).or_insert(0);
    *total += 1;
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug | -b | --benchmark) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
    flag_benchmark: bool,
}

#[cfg(test)]
mod tests {

    use std::collections::HashMap;
    use ::AggregateELBRecord;
    use ::aggregate_record;

    const TEST_RECORD: &'static str = "2015-08-15T23:43:05.302180Z elb-name 172.16.1.6:54814 \
    172.16.1.5:9000 0.000039 0.145507 0.00003 200 200 0 7582 \
    \"GET http://some.domain.com:80/path0/path1?param0=p0&param1=p1 HTTP/1.1\"\
    ";

    #[test]
	fn inserting_two_records_with_different_values_creates_two_entries_each_recorded_once() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
        };

        let ar1 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys2".to_owned(),
        };

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg.len(), 2);
        for (_, total) in agg {
            assert_eq!(total, 1)
        }
	}

    #[test]
	fn inserting_two_records_with_the_same_values_increases_the_total_correctly() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
        };

        let ar1 = ar0.clone();
        let ar3 = ar0.clone();

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg[&ar3], 2);
	}
}
<|endoftext|>


<commit_before>

mod curses;

use std::ffi::CString;

use curses::*;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        let mut c = getch();

        /* while c != final {
            if c == up then
                x++
            cursor_move( 10, 10 );
        */

        refresh();
        getch();
        endwin();
    }
}
<commit_msg>movement<commit_after>

mod curses;

use std::ffi::CString;

use curses::*;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        keypad();
        noecho();

        let mut c = getch();

        while c as u8 as char != 'q' {
            if c as u8 as char == 'j' {
                y+=1;
                cursor_move( y, x );
            } else if c as u8 as char == 'k' {
                y-=1;
                cursor_move( y, x );
            } else if c as u8 as char == 'l' {
               x+=1;
               cursor_move( y, x );
            } else if c as u8 as char == 'h' {
               x-=1;
               cursor_move( y, x );
            }
            refresh();
            c = getch();
        }

        endwin();
    }
}

<|endoftext|>


<commit_before>//! cargo-outdated
//! A subcommand for cargo that checks if your dependencies are up-to-date

#![deny(bare_trait_objects, anonymous_parameters, elided_lifetimes_in_paths)]

#[macro_use]
mod macros;
mod cargo_ops;
mod cli;
mod error;

use cargo::core::shell::Verbosity;
use cargo::core::Workspace;
use cargo::ops::needs_custom_http_transport;
use cargo::util::important_paths::find_root_manifest_for_wd;
use cargo::util::{CargoResult, CliError, Config};

use crate::{
    cargo_ops::{ElaborateWorkspace, TempProject},
    cli::{Format, Options},
    error::OutdatedError,
};

fn main() {
    env_logger::init();
    let options = cli::parse();

    let mut config = match Config::default() {
        Ok(cfg) => cfg,
        Err(e) => {
            let mut shell = cargo::core::Shell::new();
            cargo::exit_with_error(e.into(), &mut shell)
        }
    };

    // Only use a custom transport if any HTTP options are specified,
    // such as proxies or custom certificate authorities. The custom
    // transport, however, is not as well battle-tested.
    // See cargo-outdated issue #197 and
    // https://github.com/rust-lang/cargo/blob/master/src/bin/cargo/main.rs#L181
    // fn init_git_transports()
    if let Ok(true) = needs_custom_http_transport(&config) {
        if let Ok(handle) = cargo::ops::http_handle(&config) {
            unsafe {
                git2_curl::register(handle);
            }
        }
    }

    let exit_code = options.exit_code;
    let result = execute(options, &mut config);
    match result {
        Err(e) => {
            config.shell().set_verbosity(Verbosity::Normal);
            let cli_error = CliError::new(e, 1);
            cargo::exit_with_error(cli_error, &mut *config.shell())
        }
        Ok(i) => {
            if i > 0 {
                std::process::exit(exit_code);
            } else {
                std::process::exit(0);
            }
        }
    }
}

/// executes the cargo-outdate command with the cargo configuration and options
pub fn execute(options: Options, config: &mut Config) -> CargoResult<i32> {
    // Check if $CARGO_HOME is set before capturing the config environment
    // if it is, set it in the configure options
    let cargo_home_path = std::env::var_os("CARGO_HOME").map(std::path::PathBuf::from);

    // enabling nightly features
    config.nightly_features_allowed = true;

    config.configure(
        options
            .verbose
            .try_into()
            .expect("--verbose used too many times"),
        options.quiet,
        Some(&options.color.to_string().to_ascii_lowercase()),
        options.frozen(),
        options.locked(),
        options.offline,
        &cargo_home_path,
        &[],
        &[],
    )?;
    debug!(config, format!("options: {:?}", options));

    verbose!(config, "Parsing...", "current workspace");
    // the Cargo.toml that we are actually working on
    let mut manifest_abspath: std::path::PathBuf;
    let curr_manifest = if let Some(ref manifest_path) = options.manifest_path {
        manifest_abspath = manifest_path.into();
        if manifest_abspath.is_relative() {
            verbose!(config, "Resolving...", "absolute path of manifest");
            manifest_abspath = std::env::current_dir()?.join(manifest_path);
        }
        manifest_abspath
    } else {
        find_root_manifest_for_wd(config.cwd())?
    };
    let curr_workspace = Workspace::new(&curr_manifest, config)?;
    verbose!(config, "Resolving...", "current workspace");
    if options.verbose == 0 {
        config.shell().set_verbosity(Verbosity::Quiet);
    }
    let ela_curr = ElaborateWorkspace::from_workspace(&curr_workspace, &options)?;
    if options.verbose > 0 {
        config.shell().set_verbosity(Verbosity::Verbose);
    } else {
        config.shell().set_verbosity(Verbosity::Normal);
    }

    verbose!(config, "Parsing...", "compat workspace");
    let compat_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    compat_proj.write_manifest_semver(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "compat workspace");
    compat_proj.cargo_update()?;
    verbose!(config, "Resolving...", "compat workspace");
    let compat_workspace = compat_proj.workspace.borrow();
    let ela_compat = ElaborateWorkspace::from_workspace(
        compat_workspace
            .as_ref()
            .ok_or(OutdatedError::CannotElaborateWorkspace)?,
        &options,
    )?;

    verbose!(config, "Parsing...", "latest workspace");
    let latest_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    latest_proj.write_manifest_latest(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "latest workspace");
    latest_proj.cargo_update()?;
    verbose!(config, "Resolving...", "latest workspace");
    let latest_workspace = latest_proj.workspace.borrow();
    let ela_latest = ElaborateWorkspace::from_workspace(
        latest_workspace
            .as_ref()
            .ok_or(OutdatedError::CannotElaborateWorkspace)?,
        &options,
    )?;

    if ela_curr.workspace_mode {
        let mut sum = 0;
        match options.format {
            Format::List => verbose!(config, "Printing...", "Package status in list format"),
            Format::Json => verbose!(config, "Printing...", "Package status in json format"),
        }

        for member in ela_curr.workspace.members() {
            ela_curr.resolve_status(
                &ela_compat,
                &ela_latest,
                &options,
                config,
                member.package_id(),
            )?;
            match options.format {
                Format::List => {
                    sum += ela_curr.print_list(&options, member.package_id(), sum > 0)?;
                }
                Format::Json => {
                    sum += ela_curr.print_json(&options, member.package_id())?;
                }
            }
        }
        if sum == 0 {
            println!("All dependencies are up to date, yay!");
        }
        Ok(sum)
    } else {
        verbose!(config, "Resolving...", "package status");
        let root = ela_curr.determine_root(&options)?;
        ela_curr.resolve_status(&ela_compat, &ela_latest, &options, config, root)?;
        verbose!(config, "Printing...", "list format");
        let mut count = 0;

        match options.format {
            Format::List => {
                count = ela_curr.print_list(&options, root, false)?;
            }
            Format::Json => {
                ela_curr.print_json(&options, root)?;
            }
        }

        Ok(count)
    }
}
<commit_msg>fix: remove non-json line when run in workspace mode.<commit_after>//! cargo-outdated
//! A subcommand for cargo that checks if your dependencies are up-to-date

#![deny(bare_trait_objects, anonymous_parameters, elided_lifetimes_in_paths)]

#[macro_use]
mod macros;
mod cargo_ops;
mod cli;
mod error;

use cargo::core::shell::Verbosity;
use cargo::core::Workspace;
use cargo::ops::needs_custom_http_transport;
use cargo::util::important_paths::find_root_manifest_for_wd;
use cargo::util::{CargoResult, CliError, Config};

use crate::{
    cargo_ops::{ElaborateWorkspace, TempProject},
    cli::{Format, Options},
    error::OutdatedError,
};

fn main() {
    env_logger::init();
    let options = cli::parse();

    let mut config = match Config::default() {
        Ok(cfg) => cfg,
        Err(e) => {
            let mut shell = cargo::core::Shell::new();
            cargo::exit_with_error(e.into(), &mut shell)
        }
    };

    // Only use a custom transport if any HTTP options are specified,
    // such as proxies or custom certificate authorities. The custom
    // transport, however, is not as well battle-tested.
    // See cargo-outdated issue #197 and
    // https://github.com/rust-lang/cargo/blob/master/src/bin/cargo/main.rs#L181
    // fn init_git_transports()
    if let Ok(true) = needs_custom_http_transport(&config) {
        if let Ok(handle) = cargo::ops::http_handle(&config) {
            unsafe {
                git2_curl::register(handle);
            }
        }
    }

    let exit_code = options.exit_code;
    let result = execute(options, &mut config);
    match result {
        Err(e) => {
            config.shell().set_verbosity(Verbosity::Normal);
            let cli_error = CliError::new(e, 1);
            cargo::exit_with_error(cli_error, &mut *config.shell())
        }
        Ok(i) => {
            if i > 0 {
                std::process::exit(exit_code);
            } else {
                std::process::exit(0);
            }
        }
    }
}

/// executes the cargo-outdate command with the cargo configuration and options
pub fn execute(options: Options, config: &mut Config) -> CargoResult<i32> {
    // Check if $CARGO_HOME is set before capturing the config environment
    // if it is, set it in the configure options
    let cargo_home_path = std::env::var_os("CARGO_HOME").map(std::path::PathBuf::from);

    // enabling nightly features
    config.nightly_features_allowed = true;

    config.configure(
        options
            .verbose
            .try_into()
            .expect("--verbose used too many times"),
        options.quiet,
        Some(&options.color.to_string().to_ascii_lowercase()),
        options.frozen(),
        options.locked(),
        options.offline,
        &cargo_home_path,
        &[],
        &[],
    )?;
    debug!(config, format!("options: {:?}", options));

    verbose!(config, "Parsing...", "current workspace");
    // the Cargo.toml that we are actually working on
    let mut manifest_abspath: std::path::PathBuf;
    let curr_manifest = if let Some(ref manifest_path) = options.manifest_path {
        manifest_abspath = manifest_path.into();
        if manifest_abspath.is_relative() {
            verbose!(config, "Resolving...", "absolute path of manifest");
            manifest_abspath = std::env::current_dir()?.join(manifest_path);
        }
        manifest_abspath
    } else {
        find_root_manifest_for_wd(config.cwd())?
    };
    let curr_workspace = Workspace::new(&curr_manifest, config)?;
    verbose!(config, "Resolving...", "current workspace");
    if options.verbose == 0 {
        config.shell().set_verbosity(Verbosity::Quiet);
    }
    let ela_curr = ElaborateWorkspace::from_workspace(&curr_workspace, &options)?;
    if options.verbose > 0 {
        config.shell().set_verbosity(Verbosity::Verbose);
    } else {
        config.shell().set_verbosity(Verbosity::Normal);
    }

    verbose!(config, "Parsing...", "compat workspace");
    let compat_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    compat_proj.write_manifest_semver(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "compat workspace");
    compat_proj.cargo_update()?;
    verbose!(config, "Resolving...", "compat workspace");
    let compat_workspace = compat_proj.workspace.borrow();
    let ela_compat = ElaborateWorkspace::from_workspace(
        compat_workspace
            .as_ref()
            .ok_or(OutdatedError::CannotElaborateWorkspace)?,
        &options,
    )?;

    verbose!(config, "Parsing...", "latest workspace");
    let latest_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    latest_proj.write_manifest_latest(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "latest workspace");
    latest_proj.cargo_update()?;
    verbose!(config, "Resolving...", "latest workspace");
    let latest_workspace = latest_proj.workspace.borrow();
    let ela_latest = ElaborateWorkspace::from_workspace(
        latest_workspace
            .as_ref()
            .ok_or(OutdatedError::CannotElaborateWorkspace)?,
        &options,
    )?;

    if ela_curr.workspace_mode {
        let mut sum = 0;
        match options.format {
            Format::List => verbose!(config, "Printing...", "Package status in list format"),
            Format::Json => verbose!(config, "Printing...", "Package status in json format"),
        }

        for member in ela_curr.workspace.members() {
            ela_curr.resolve_status(
                &ela_compat,
                &ela_latest,
                &options,
                config,
                member.package_id(),
            )?;
            match options.format {
                Format::List => {
                    sum += ela_curr.print_list(&options, member.package_id(), sum > 0)?;
                }
                Format::Json => {
                    sum += ela_curr.print_json(&options, member.package_id())?;
                }
            }
        }
        if sum == 0 && matches!(options.format, Format::List) {
            println!("All dependencies are up to date, yay!");
        }
        Ok(sum)
    } else {
        verbose!(config, "Resolving...", "package status");
        let root = ela_curr.determine_root(&options)?;
        ela_curr.resolve_status(&ela_compat, &ela_latest, &options, config, root)?;
        verbose!(config, "Printing...", "list format");
        let mut count = 0;

        match options.format {
            Format::List => {
                count = ela_curr.print_list(&options, root, false)?;
            }
            Format::Json => {
                ela_curr.print_json(&options, root)?;
            }
        }

        Ok(count)
    }
}
<|endoftext|>


<commit_before>extern crate bspl;
extern crate tempfile;
extern crate rustyline;

use rustyline::error::ReadlineError;
use rustyline::Editor;
use tempfile::NamedTempFile;
use bspl::constants::VERSION;
use bspl::lexer::Lexer;
use bspl::parser::Parser;
use bspl::evaluator::Evaluator;
use bspl::error::{ParserError, EvaluatorError};

fn prelude() {
    println!("bspl {}", VERSION);
    println!("Bit-Shift-Print Loop");
    println!("Type 'help', or 'license' for more information.");
}

fn error_message(width: usize, msg: &'static str) {
    println!("{caret:>width$}\n.. {}", msg, caret = "^", width = width);
}

fn display_results(x: &Vec<String>) {
    for r in x {
        println!(".. {}", r);
    }

    let y = x.last().unwrap();
    println!(".. Dec: {}", y);
    let h: i32 = y.parse().unwrap();
    println!(".. Hex: 0x{:x}", h);
    println!(".. Bin: 0b{:b}", h);

}

fn repl() {
    let mut repl = Editor::<()>::new();
    let prompt = "=> ";
    let tmp_file = NamedTempFile::new().unwrap();
    let _ = repl.load_history(tmp_file.path());

    let mut lexer = Lexer::new();
    let mut parser = Parser::default();
    let mut evaluator = Evaluator::default();

    loop {
        match repl.readline(prompt) {
            Ok(line) => {
                repl.add_history_entry(&line);
                match parser.parse(lexer.analyze(&line)) {
                    Ok(parsed_tokens) => {
                        match evaluator.evaluate(parsed_tokens) {
                            Ok(result) => {
                                display_results(&result);
                            }
                            Err(EvaluatorError::MissingArgument(position)) => {
                                error_message(position + prompt.len() + 1, "Missing Argument");
                            }
                            _ => continue,
                        }
                    }
                    Err(ParserError::IllegalOperator(position)) => {
                        error_message(position + prompt.len() + 1, "Illegal Operator");
                    }
                    Err(ParserError::MissingOpeningBracket(position)) => {
                        error_message(position + prompt.len() + 1, "Missing Opening Bracket");
                    }
                    Err(ParserError::MissingClosingBracket(position)) => {
                        error_message(position + prompt.len() + 1, "Missing Closing Bracket");
                    }
                }
            }
            Err(ReadlineError::Eof) => break,
            Err(ReadlineError::Interrupted) => {
                println!("Type 'exit' or press Ctrl-D to leave bspl");
                continue;
            }
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }

        }
        repl.save_history(tmp_file.path()).unwrap();
    }
}

pub fn main() {
    prelude();
    repl();
}
<commit_msg>Refactor pretty print function<commit_after>extern crate bspl;
extern crate tempfile;
extern crate rustyline;

use rustyline::error::ReadlineError;
use rustyline::Editor;
use tempfile::NamedTempFile;
use bspl::constants::VERSION;
use bspl::lexer::Lexer;
use bspl::parser::Parser;
use bspl::evaluator::Evaluator;
use bspl::error::{ParserError, EvaluatorError};

fn prelude() {
    println!("bspl {}", VERSION);
    println!("Bit-Shift-Print Loop");
    println!("Type 'help', or 'license' for more information.");
}

fn error_message(width: usize, msg: &'static str) {
    println!("{caret:>width$}\n.. {}", msg, caret = "^", width = width);
}

fn display_results(results: &Vec<String>) {
    for result in results {
        println!(".. {}", result);
    }

    let final_result: i32 = results.last().unwrap().parse().unwrap();
    println!(".. Dec: {}", final_result);
    println!(".. Hex: 0x{:x}", final_result);
    println!(".. Bin: 0b{:b}", final_result);
}

fn repl() {
    let mut repl = Editor::<()>::new();
    let prompt = "=> ";
    let tmp_file = NamedTempFile::new().unwrap();
    let _ = repl.load_history(tmp_file.path());

    let mut lexer = Lexer::new();
    let mut parser = Parser::default();
    let mut evaluator = Evaluator::default();

    loop {
        match repl.readline(prompt) {
            Ok(line) => {
                repl.add_history_entry(&line);
                match parser.parse(lexer.analyze(&line)) {
                    Ok(parsed_tokens) => {
                        match evaluator.evaluate(parsed_tokens) {
                            Ok(result) => {
                                display_results(&result);
                            }
                            Err(EvaluatorError::MissingArgument(position)) => {
                                error_message(position + prompt.len() + 1, "Missing Argument");
                            }
                            _ => continue,
                        }
                    }
                    Err(ParserError::IllegalOperator(position)) => {
                        error_message(position + prompt.len() + 1, "Illegal Operator");
                    }
                    Err(ParserError::MissingOpeningBracket(position)) => {
                        error_message(position + prompt.len() + 1, "Missing Opening Bracket");
                    }
                    Err(ParserError::MissingClosingBracket(position)) => {
                        error_message(position + prompt.len() + 1, "Missing Closing Bracket");
                    }
                }
            }
            Err(ReadlineError::Eof) => break,
            Err(ReadlineError::Interrupted) => {
                println!("Type 'exit' or press Ctrl-D to leave bspl");
                continue;
            }
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }

        }
        repl.save_history(tmp_file.path()).unwrap();
    }
}

pub fn main() {
    prelude();
    repl();
}
<|endoftext|>


<commit_before>extern crate crypto;
extern crate env_logger;
extern crate futures;
extern crate getopts;
extern crate librespot;
#[macro_use]
extern crate log;
extern crate rpassword;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_signal;
extern crate url;

use crypto::digest::Digest;
use crypto::sha1::Sha1;
use env_logger::LogBuilder;
use futures::sync::mpsc::UnboundedReceiver;
use futures::{Async, Future, Poll, Stream};
use std::env;
use std::io::{self, stderr, Write};
use std::mem;
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
use tokio_core::reactor::{Core, Handle};
use tokio_io::IoStream;
use url::Url;

use librespot::core::authentication::{get_credentials, Credentials};
use librespot::core::cache::Cache;
use librespot::core::config::{ConnectConfig, DeviceType, SessionConfig};
use librespot::core::session::Session;
use librespot::core::version;

use librespot::connect::discovery::{discovery, DiscoveryStream};
use librespot::connect::spirc::{Spirc, SpircTask};
use librespot::playback::audio_backend::{self, Sink, BACKENDS};
use librespot::playback::config::{Bitrate, PlayerConfig};
use librespot::playback::mixer::{self, Mixer};
use librespot::playback::player::{Player, PlayerEvent};

mod player_event_handler;
use player_event_handler::run_program_on_events;

fn device_id(name: &str) -> String {
    let mut h = Sha1::new();
    h.input_str(name);
    h.result_str()
}

fn usage(program: &str, opts: &getopts::Options) -> String {
    let brief = format!("Usage: {} [options]", program);
    opts.usage(&brief)
}

fn setup_logging(verbose: bool) {
    let mut builder = LogBuilder::new();
    match env::var("RUST_LOG") {
        Ok(config) => {
            builder.parse(&config);
            builder.init().unwrap();

            if verbose {
                warn!("`--verbose` flag overidden by `RUST_LOG` environment variable");
            }
        }
        Err(_) => {
            if verbose {
                builder.parse("mdns=info,librespot=trace");
            } else {
                builder.parse("mdns=info,librespot=info");
            }
            builder.init().unwrap();
        }
    }
}

fn list_backends() {
    println!("Available Backends : ");
    for (&(name, _), idx) in BACKENDS.iter().zip(0..) {
        if idx == 0 {
            println!("- {} (default)", name);
        } else {
            println!("- {}", name);
        }
    }
}

#[derive(Clone)]
struct Setup {
    backend: fn(Option<String>) -> Box<Sink>,
    device: Option<String>,

    mixer: fn() -> Box<Mixer>,

    cache: Option<Cache>,
    player_config: PlayerConfig,
    session_config: SessionConfig,
    connect_config: ConnectConfig,
    credentials: Option<Credentials>,
    enable_discovery: bool,
    zeroconf_port: u16,
    player_event_program: Option<String>,
}

fn setup(args: &[String]) -> Setup {
    let mut opts = getopts::Options::new();
    opts.optopt(
        "c",
        "cache",
        "Path to a directory where files will be cached.",
        "CACHE",
    ).optflag("", "disable-audio-cache", "Disable caching of the audio data.")
        .reqopt("n", "name", "Device name", "NAME")
        .optopt("", "device-type", "Displayed device type", "DEVICE_TYPE")
        .optopt(
            "b",
            "bitrate",
            "Bitrate (96, 160 or 320). Defaults to 160",
            "BITRATE",
        )
        .optopt(
            "",
            "onevent",
            "Run PROGRAM when playback is about to begin.",
            "PROGRAM",
        )
        .optflag("v", "verbose", "Enable verbose output")
        .optopt("u", "username", "Username to sign in with", "USERNAME")
        .optopt("p", "password", "Password", "PASSWORD")
        .optopt("", "proxy", "HTTP proxy to use when connecting", "PROXY")
        .optflag("", "disable-discovery", "Disable discovery mode")
        .optopt(
            "",
            "backend",
            "Audio backend to use. Use '?' to list options",
            "BACKEND",
        )
        .optopt(
            "",
            "device",
            "Audio device to use. Use '?' to list options if using portaudio",
            "DEVICE",
        )
        .optopt("", "mixer", "Mixer to use", "MIXER")
        .optopt(
            "",
            "initial-volume",
            "Initial volume in %, once connected (must be from 0 to 100)",
            "VOLUME",
        )
        .optopt(
            "",
            "zeroconf-port",
            "The port the internal server advertised over zeroconf uses.",
            "ZEROCONF_PORT",
        )
        .optflag(
            "",
            "enable-volume-normalisation",
            "Play all tracks at the same volume",
        )
        .optopt(
            "",
            "normalisation-pregain",
            "Pregain (dB) applied by volume normalisation",
            "PREGAIN",
        )
        .optflag(
            "",
            "linear-volume",
            "increase volume linear instead of logarithmic.",
        );

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            writeln!(stderr(), "error: {}\n{}", f.to_string(), usage(&args[0], &opts)).unwrap();
            exit(1);
        }
    };

    let verbose = matches.opt_present("verbose");
    setup_logging(verbose);

    info!(
        "librespot {} ({}). Built on {}. Build ID: {}",
        version::short_sha(),
        version::commit_date(),
        version::short_now(),
        version::build_id()
    );

    let backend_name = matches.opt_str("backend");
    if backend_name == Some("?".into()) {
        list_backends();
        exit(0);
    }

    let backend = audio_backend::find(backend_name).expect("Invalid backend");

    let device = matches.opt_str("device");

    let mixer_name = matches.opt_str("mixer");
    let mixer = mixer::find(mixer_name.as_ref()).expect("Invalid mixer");

    let initial_volume = matches
        .opt_str("initial-volume")
        .map(|volume| {
            let volume = volume.parse::<i32>().unwrap();
            if volume < 0 || volume > 100 {
                panic!("Initial volume must be in the range 0-100");
            }
            volume * 0xFFFF / 100
        })
        .unwrap_or(0x8000);

    let zeroconf_port = matches
        .opt_str("zeroconf-port")
        .map(|port| port.parse::<u16>().unwrap())
        .unwrap_or(0);

    let name = matches.opt_str("name").unwrap();
    let use_audio_cache = !matches.opt_present("disable-audio-cache");

    let cache = matches
        .opt_str("c")
        .map(|cache_location| Cache::new(PathBuf::from(cache_location), use_audio_cache));

    let credentials = {
        let cached_credentials = cache.as_ref().and_then(Cache::credentials);

        let password = |username: &String| -> String {
            write!(stderr(), "Password for {}: ", username).unwrap();
            stderr().flush().unwrap();
            rpassword::read_password().unwrap()
        };

        get_credentials(
            matches.opt_str("username"),
            matches.opt_str("password"),
            cached_credentials,
            password,
        )
    };

    let session_config = {
        let device_id = device_id(&name);

        SessionConfig {
            user_agent: version::version_string(),
            device_id: device_id,
            proxy: matches.opt_str("proxy").or(std::env::var("http_proxy").ok()).map(
                |s| {
                    match Url::parse(&s) {
                Ok(url) => {
                    if url.host().is_none() || url.port().is_none() {
                        panic!("Invalid proxy url, only urls on the format \"http://host:port\" are allowed");
                    }

                    if url.scheme() != "http" {
                        panic!("Only unsecure http:// proxies are supported");
                    }
                    url
                },
                Err(err) => panic!("Invalid proxy url: {}, only urls on the format \"http://host:port\" are allowed", err)
            }
                },
            ),
        }
    };

    let player_config = {
        let bitrate = matches
            .opt_str("b")
            .as_ref()
            .map(|bitrate| Bitrate::from_str(bitrate).expect("Invalid bitrate"))
            .unwrap_or(Bitrate::default());

        PlayerConfig {
            bitrate: bitrate,
            normalisation: matches.opt_present("enable-volume-normalisation"),
            normalisation_pregain: matches
                .opt_str("normalisation-pregain")
                .map(|pregain| pregain.parse::<f32>().expect("Invalid pregain float value"))
                .unwrap_or(PlayerConfig::default().normalisation_pregain),
        }
    };

    let connect_config = {
        let device_type = matches
            .opt_str("device-type")
            .as_ref()
            .map(|device_type| DeviceType::from_str(device_type).expect("Invalid device type"))
            .unwrap_or(DeviceType::default());

        ConnectConfig {
            name: name,
            device_type: device_type,
            volume: initial_volume,
            linear_volume: matches.opt_present("linear-volume"),
        }
    };

    let enable_discovery = !matches.opt_present("disable-discovery");

    Setup {
        backend: backend,
        cache: cache,
        session_config: session_config,
        player_config: player_config,
        connect_config: connect_config,
        credentials: credentials,
        device: device,
        enable_discovery: enable_discovery,
        zeroconf_port: zeroconf_port,
        mixer: mixer,
        player_event_program: matches.opt_str("onevent"),
    }
}

struct Main {
    cache: Option<Cache>,
    player_config: PlayerConfig,
    session_config: SessionConfig,
    connect_config: ConnectConfig,
    backend: fn(Option<String>) -> Box<Sink>,
    device: Option<String>,
    mixer: fn() -> Box<Mixer>,
    handle: Handle,

    discovery: Option<DiscoveryStream>,
    signal: IoStream<()>,

    spirc: Option<Spirc>,
    spirc_task: Option<SpircTask>,
    connect: Box<Future<Item = Session, Error = io::Error>>,

    shutdown: bool,

    player_event_channel: Option<UnboundedReceiver<PlayerEvent>>,
    player_event_program: Option<String>,
}

impl Main {
    fn new(handle: Handle, setup: Setup) -> Main {
        let mut task = Main {
            handle: handle.clone(),
            cache: setup.cache,
            session_config: setup.session_config,
            player_config: setup.player_config,
            connect_config: setup.connect_config,
            backend: setup.backend,
            device: setup.device,
            mixer: setup.mixer,

            connect: Box::new(futures::future::empty()),
            discovery: None,
            spirc: None,
            spirc_task: None,
            shutdown: false,
            signal: Box::new(tokio_signal::ctrl_c(&handle).flatten_stream()),

            player_event_channel: None,
            player_event_program: setup.player_event_program,
        };

        if setup.enable_discovery {
            let config = task.connect_config.clone();
            let device_id = task.session_config.device_id.clone();

            task.discovery = Some(discovery(&handle, config, device_id, setup.zeroconf_port).unwrap());
        }

        if let Some(credentials) = setup.credentials {
            task.credentials(credentials);
        }

        task
    }

    fn credentials(&mut self, credentials: Credentials) {
        let config = self.session_config.clone();
        let handle = self.handle.clone();

        let connection = Session::connect(config, credentials, self.cache.clone(), handle);

        self.connect = connection;
        self.spirc = None;
        let task = mem::replace(&mut self.spirc_task, None);
        if let Some(task) = task {
            self.handle.spawn(task);
        }
    }
}

impl Future for Main {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        loop {
            let mut progress = false;

            if let Some(Async::Ready(Some(creds))) = self.discovery.as_mut().map(|d| d.poll().unwrap()) {
                if let Some(ref spirc) = self.spirc {
                    spirc.shutdown();
                }
                self.credentials(creds);

                progress = true;
            }

            if let Async::Ready(session) = self.connect.poll().unwrap() {
                self.connect = Box::new(futures::future::empty());
                let device = self.device.clone();
                let mixer = (self.mixer)();
                let player_config = self.player_config.clone();
                let connect_config = self.connect_config.clone();

                let audio_filter = mixer.get_audio_filter();
                let backend = self.backend;
                let (player, event_channel) =
                    Player::new(player_config, session.clone(), audio_filter, move || {
                        (backend)(device)
                    });

                let (spirc, spirc_task) = Spirc::new(connect_config, session, player, mixer);
                self.spirc = Some(spirc);
                self.spirc_task = Some(spirc_task);
                self.player_event_channel = Some(event_channel);

                progress = true;
            }

            if let Async::Ready(Some(())) = self.signal.poll().unwrap() {
                trace!("Ctrl-C received");
                if !self.shutdown {
                    if let Some(ref spirc) = self.spirc {
                        spirc.shutdown();
                    }
                    self.shutdown = true;
                } else {
                    return Ok(Async::Ready(()));
                }

                progress = true;
            }

            if let Some(ref mut spirc_task) = self.spirc_task {
                if let Async::Ready(()) = spirc_task.poll().unwrap() {
                    if self.shutdown {
                        return Ok(Async::Ready(()));
                    } else {
                        panic!("Spirc shut down unexpectedly");
                    }
                }
            }

            if let Some(ref mut player_event_channel) = self.player_event_channel {
                if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() {
                    if let Some(ref program) = self.player_event_program {
                        run_program_on_events(event, program);
                    }
                }
            }

            if !progress {
                return Ok(Async::NotReady);
            }

            if self.shutdown {
                return Ok(Async::Ready(()));
            }
        }
    }
}

fn main() {
    if env::var("RUST_BACKTRACE").is_err() {
        env::set_var("RUST_BACKTRACE", "full")
    }
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let args: Vec<String> = std::env::args().collect();

    core.run(Main::new(handle, setup(&args))).unwrap()
}
<commit_msg>reverse #212 since it does not address the real problem (#213)<commit_after>extern crate crypto;
extern crate env_logger;
extern crate futures;
extern crate getopts;
extern crate librespot;
#[macro_use]
extern crate log;
extern crate rpassword;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_signal;
extern crate url;

use crypto::digest::Digest;
use crypto::sha1::Sha1;
use env_logger::LogBuilder;
use futures::sync::mpsc::UnboundedReceiver;
use futures::{Async, Future, Poll, Stream};
use std::env;
use std::io::{self, stderr, Write};
use std::mem;
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
use tokio_core::reactor::{Core, Handle};
use tokio_io::IoStream;
use url::Url;

use librespot::core::authentication::{get_credentials, Credentials};
use librespot::core::cache::Cache;
use librespot::core::config::{ConnectConfig, DeviceType, SessionConfig};
use librespot::core::session::Session;
use librespot::core::version;

use librespot::connect::discovery::{discovery, DiscoveryStream};
use librespot::connect::spirc::{Spirc, SpircTask};
use librespot::playback::audio_backend::{self, Sink, BACKENDS};
use librespot::playback::config::{Bitrate, PlayerConfig};
use librespot::playback::mixer::{self, Mixer};
use librespot::playback::player::{Player, PlayerEvent};

mod player_event_handler;
use player_event_handler::run_program_on_events;

fn device_id(name: &str) -> String {
    let mut h = Sha1::new();
    h.input_str(name);
    h.result_str()
}

fn usage(program: &str, opts: &getopts::Options) -> String {
    let brief = format!("Usage: {} [options]", program);
    opts.usage(&brief)
}

fn setup_logging(verbose: bool) {
    let mut builder = LogBuilder::new();
    match env::var("RUST_LOG") {
        Ok(config) => {
            builder.parse(&config);
            builder.init().unwrap();

            if verbose {
                warn!("`--verbose` flag overidden by `RUST_LOG` environment variable");
            }
        }
        Err(_) => {
            if verbose {
                builder.parse("mdns=info,librespot=trace");
            } else {
                builder.parse("mdns=info,librespot=info");
            }
            builder.init().unwrap();
        }
    }
}

fn list_backends() {
    println!("Available Backends : ");
    for (&(name, _), idx) in BACKENDS.iter().zip(0..) {
        if idx == 0 {
            println!("- {} (default)", name);
        } else {
            println!("- {}", name);
        }
    }
}

#[derive(Clone)]
struct Setup {
    backend: fn(Option<String>) -> Box<Sink>,
    device: Option<String>,

    mixer: fn() -> Box<Mixer>,

    cache: Option<Cache>,
    player_config: PlayerConfig,
    session_config: SessionConfig,
    connect_config: ConnectConfig,
    credentials: Option<Credentials>,
    enable_discovery: bool,
    zeroconf_port: u16,
    player_event_program: Option<String>,
}

fn setup(args: &[String]) -> Setup {
    let mut opts = getopts::Options::new();
    opts.optopt(
        "c",
        "cache",
        "Path to a directory where files will be cached.",
        "CACHE",
    ).optflag("", "disable-audio-cache", "Disable caching of the audio data.")
        .reqopt("n", "name", "Device name", "NAME")
        .optopt("", "device-type", "Displayed device type", "DEVICE_TYPE")
        .optopt(
            "b",
            "bitrate",
            "Bitrate (96, 160 or 320). Defaults to 160",
            "BITRATE",
        )
        .optopt(
            "",
            "onevent",
            "Run PROGRAM when playback is about to begin.",
            "PROGRAM",
        )
        .optflag("v", "verbose", "Enable verbose output")
        .optopt("u", "username", "Username to sign in with", "USERNAME")
        .optopt("p", "password", "Password", "PASSWORD")
        .optopt("", "proxy", "HTTP proxy to use when connecting", "PROXY")
        .optflag("", "disable-discovery", "Disable discovery mode")
        .optopt(
            "",
            "backend",
            "Audio backend to use. Use '?' to list options",
            "BACKEND",
        )
        .optopt(
            "",
            "device",
            "Audio device to use. Use '?' to list options if using portaudio",
            "DEVICE",
        )
        .optopt("", "mixer", "Mixer to use", "MIXER")
        .optopt(
            "",
            "initial-volume",
            "Initial volume in %, once connected (must be from 0 to 100)",
            "VOLUME",
        )
        .optopt(
            "",
            "zeroconf-port",
            "The port the internal server advertised over zeroconf uses.",
            "ZEROCONF_PORT",
        )
        .optflag(
            "",
            "enable-volume-normalisation",
            "Play all tracks at the same volume",
        )
        .optopt(
            "",
            "normalisation-pregain",
            "Pregain (dB) applied by volume normalisation",
            "PREGAIN",
        )
        .optflag(
            "",
            "linear-volume",
            "increase volume linear instead of logarithmic.",
        );

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            writeln!(stderr(), "error: {}\n{}", f.to_string(), usage(&args[0], &opts)).unwrap();
            exit(1);
        }
    };

    let verbose = matches.opt_present("verbose");
    setup_logging(verbose);

    info!(
        "librespot {} ({}). Built on {}. Build ID: {}",
        version::short_sha(),
        version::commit_date(),
        version::short_now(),
        version::build_id()
    );

    let backend_name = matches.opt_str("backend");
    if backend_name == Some("?".into()) {
        list_backends();
        exit(0);
    }

    let backend = audio_backend::find(backend_name).expect("Invalid backend");

    let device = matches.opt_str("device");

    let mixer_name = matches.opt_str("mixer");
    let mixer = mixer::find(mixer_name.as_ref()).expect("Invalid mixer");

    let initial_volume = matches
        .opt_str("initial-volume")
        .map(|volume| {
            let volume = volume.parse::<i32>().unwrap();
            if volume < 0 || volume > 100 {
                panic!("Initial volume must be in the range 0-100");
            }
            volume * 0xFFFF / 100
        })
        .unwrap_or(0x8000);

    let zeroconf_port = matches
        .opt_str("zeroconf-port")
        .map(|port| port.parse::<u16>().unwrap())
        .unwrap_or(0);

    let name = matches.opt_str("name").unwrap();
    let use_audio_cache = !matches.opt_present("disable-audio-cache");

    let cache = matches
        .opt_str("c")
        .map(|cache_location| Cache::new(PathBuf::from(cache_location), use_audio_cache));

    let credentials = {
        let cached_credentials = cache.as_ref().and_then(Cache::credentials);

        let password = |username: &String| -> String {
            write!(stderr(), "Password for {}: ", username).unwrap();
            stderr().flush().unwrap();
            rpassword::read_password().unwrap()
        };

        get_credentials(
            matches.opt_str("username"),
            matches.opt_str("password"),
            cached_credentials,
            password,
        )
    };

    let session_config = {
        let device_id = device_id(&name);

        SessionConfig {
            user_agent: version::version_string(),
            device_id: device_id,
            proxy: matches.opt_str("proxy").or(std::env::var("http_proxy").ok()).map(
                |s| {
                    match Url::parse(&s) {
                Ok(url) => {
                    if url.host().is_none() || url.port().is_none() {
                        panic!("Invalid proxy url, only urls on the format \"http://host:port\" are allowed");
                    }

                    if url.scheme() != "http" {
                        panic!("Only unsecure http:// proxies are supported");
                    }
                    url
                },
                Err(err) => panic!("Invalid proxy url: {}, only urls on the format \"http://host:port\" are allowed", err)
            }
                },
            ),
        }
    };

    let player_config = {
        let bitrate = matches
            .opt_str("b")
            .as_ref()
            .map(|bitrate| Bitrate::from_str(bitrate).expect("Invalid bitrate"))
            .unwrap_or(Bitrate::default());

        PlayerConfig {
            bitrate: bitrate,
            normalisation: matches.opt_present("enable-volume-normalisation"),
            normalisation_pregain: matches
                .opt_str("normalisation-pregain")
                .map(|pregain| pregain.parse::<f32>().expect("Invalid pregain float value"))
                .unwrap_or(PlayerConfig::default().normalisation_pregain),
        }
    };

    let connect_config = {
        let device_type = matches
            .opt_str("device-type")
            .as_ref()
            .map(|device_type| DeviceType::from_str(device_type).expect("Invalid device type"))
            .unwrap_or(DeviceType::default());

        ConnectConfig {
            name: name,
            device_type: device_type,
            volume: initial_volume,
            linear_volume: matches.opt_present("linear-volume"),
        }
    };

    let enable_discovery = !matches.opt_present("disable-discovery");

    Setup {
        backend: backend,
        cache: cache,
        session_config: session_config,
        player_config: player_config,
        connect_config: connect_config,
        credentials: credentials,
        device: device,
        enable_discovery: enable_discovery,
        zeroconf_port: zeroconf_port,
        mixer: mixer,
        player_event_program: matches.opt_str("onevent"),
    }
}

struct Main {
    cache: Option<Cache>,
    player_config: PlayerConfig,
    session_config: SessionConfig,
    connect_config: ConnectConfig,
    backend: fn(Option<String>) -> Box<Sink>,
    device: Option<String>,
    mixer: fn() -> Box<Mixer>,
    handle: Handle,

    discovery: Option<DiscoveryStream>,
    signal: IoStream<()>,

    spirc: Option<Spirc>,
    spirc_task: Option<SpircTask>,
    connect: Box<Future<Item = Session, Error = io::Error>>,

    shutdown: bool,

    player_event_channel: Option<UnboundedReceiver<PlayerEvent>>,
    player_event_program: Option<String>,
}

impl Main {
    fn new(handle: Handle, setup: Setup) -> Main {
        let mut task = Main {
            handle: handle.clone(),
            cache: setup.cache,
            session_config: setup.session_config,
            player_config: setup.player_config,
            connect_config: setup.connect_config,
            backend: setup.backend,
            device: setup.device,
            mixer: setup.mixer,

            connect: Box::new(futures::future::empty()),
            discovery: None,
            spirc: None,
            spirc_task: None,
            shutdown: false,
            signal: Box::new(tokio_signal::ctrl_c(&handle).flatten_stream()),

            player_event_channel: None,
            player_event_program: setup.player_event_program,
        };

        if setup.enable_discovery {
            let config = task.connect_config.clone();
            let device_id = task.session_config.device_id.clone();

            task.discovery = Some(discovery(&handle, config, device_id, setup.zeroconf_port).unwrap());
        }

        if let Some(credentials) = setup.credentials {
            task.credentials(credentials);
        }

        task
    }

    fn credentials(&mut self, credentials: Credentials) {
        let config = self.session_config.clone();
        let handle = self.handle.clone();

        let connection = Session::connect(config, credentials, self.cache.clone(), handle);

        self.connect = connection;
        self.spirc = None;
        let task = mem::replace(&mut self.spirc_task, None);
        if let Some(task) = task {
            self.handle.spawn(task);
        }
    }
}

impl Future for Main {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        loop {
            let mut progress = false;

            if let Some(Async::Ready(Some(creds))) = self.discovery.as_mut().map(|d| d.poll().unwrap()) {
                if let Some(ref spirc) = self.spirc {
                    spirc.shutdown();
                }
                self.credentials(creds);

                progress = true;
            }

            if let Async::Ready(session) = self.connect.poll().unwrap() {
                self.connect = Box::new(futures::future::empty());
                let device = self.device.clone();
                let mixer = (self.mixer)();
                let player_config = self.player_config.clone();
                let connect_config = self.connect_config.clone();

                let audio_filter = mixer.get_audio_filter();
                let backend = self.backend;
                let (player, event_channel) =
                    Player::new(player_config, session.clone(), audio_filter, move || {
                        (backend)(device)
                    });

                let (spirc, spirc_task) = Spirc::new(connect_config, session, player, mixer);
                self.spirc = Some(spirc);
                self.spirc_task = Some(spirc_task);
                self.player_event_channel = Some(event_channel);

                progress = true;
            }

            if let Async::Ready(Some(())) = self.signal.poll().unwrap() {
                trace!("Ctrl-C received");
                if !self.shutdown {
                    if let Some(ref spirc) = self.spirc {
                        spirc.shutdown();
                    }
                    self.shutdown = true;
                } else {
                    return Ok(Async::Ready(()));
                }

                progress = true;
            }

            if let Some(ref mut spirc_task) = self.spirc_task {
                if let Async::Ready(()) = spirc_task.poll().unwrap() {
                    if self.shutdown {
                        return Ok(Async::Ready(()));
                    } else {
                        panic!("Spirc shut down unexpectedly");
                    }
                }
            }

            if let Some(ref mut player_event_channel) = self.player_event_channel {
                if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() {
                    if let Some(ref program) = self.player_event_program {
                        run_program_on_events(event, program);
                    }
                }
            }

            if !progress {
                return Ok(Async::NotReady);
            }
        }
    }
}

fn main() {
    if env::var("RUST_BACKTRACE").is_err() {
        env::set_var("RUST_BACKTRACE", "full")
    }
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let args: Vec<String> = std::env::args().collect();

    core.run(Main::new(handle, setup(&args))).unwrap()
}
<|endoftext|>


<commit_before>//    Copyright 2017 Vector Creations Limited
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

// extern crate base64;
// extern crate blake2_rfc;
#[macro_use]
extern crate clap;
extern crate humansize;
extern crate linear_map;
extern crate rusqlite;
extern crate twox_hash;
extern crate walkdir;
extern crate indicatif;

// use blake2_rfc::blake2b::Blake2b;
use humansize::{FileSize, file_size_opts as options};
use clap::{App, Arg};
use linear_map::LinearMap;
use std::io;
use std::io::Read;
use std::fs::File;
use std::hash::Hasher;
use std::collections::BTreeMap;
use std::path::PathBuf;
use walkdir::WalkDir;

fn copy<R: io::Read, W: Hasher>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
    let mut buf = [0; 64 * 1024];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write(&buf[..len]);
        written += len as u64;
    }
}

fn to_hash(path: &PathBuf) -> u64 {
    let mut file = File::open(path).unwrap();
    let mut hasher = twox_hash::XxHash::default();
    copy(&mut file, &mut hasher).unwrap();
    hasher.finish()
}

fn read_file(path: &PathBuf) -> Vec<u8> {
    let mut file = File::open(path).unwrap();
    let mut vec = Vec::new();
    file.read_to_end(&mut vec).unwrap();
    vec
}

fn partition_by<I, F, R>(paths: I, f: F) -> LinearMap<R, Vec<PathBuf>>
    where I: Iterator<Item=PathBuf>, F: Fn(&PathBuf) -> R, R: Eq
{
    let mut map = LinearMap::with_capacity(paths.size_hint().0);
    for path in paths {
        let key = f(&path);
        map.entry(key).or_insert_with(Vec::new).push(path);
    }
    map
}

const DB_TABLE_SCHEMA: &'static str = r#"
CREATE TABLE files (
    hash BIGINT NOT NULL,
    path TEXT NOT NULL,
    size BIGINT NOT NULL
);
"#;

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!("\n"))
        .arg(Arg::with_name("media_directory")
            .help("The location of the media store")
            .index(1)
            .required(true))
        .get_matches();

    let path = matches.value_of("media_directory").unwrap();

    println!("Creating DB...");

    let db = rusqlite::Connection::open_in_memory().expect("failed to open sqlite db");
    db.execute_batch(DB_TABLE_SCHEMA).expect("failed to create db schema");

    let mut paths_by_size = BTreeMap::new();
    let mut total_files = 0;
    let mut total_size = 0;

    println!("Walking fs...");

    let pb = indicatif::ProgressBar::new_spinner();

    for entry in WalkDir::new(path) {
        let entry = entry.unwrap();
        if !entry.file_type().is_file() {
            continue
        }

        let file_size = entry.metadata().unwrap().len() as usize;
        paths_by_size.entry(file_size).or_insert_with(Vec::new).push(entry.path().to_owned());

        total_files += 1;
        total_size += file_size;

        pb.inc(1);
        if total_files % 100 == 0 {
            // println!("Handled {} files", total_files);
            // pb.set_message(&format!("Handled {} files", total_files));
        }
        pb.set_message(&format!("Handled {} files", total_files));
    }

    pb.finish_and_clear();

    println!("Handled {} files", total_files);
    println!();

     let pb = indicatif::ProgressBar::new(total_size as u64);

    let mut total_wasted_size = 0;

    for (file_size, paths) in paths_by_size {
        if paths.len() == 1 {
            pb.inc(file_size as u64);
            continue
        }

        let by_hash = partition_by(paths.into_iter(), to_hash);

        for (hash, paths) in by_hash {
            if paths.len() == 1 {
                pb.inc(file_size as u64);
                continue
            }

            let by_contents = partition_by(paths.into_iter(), read_file);

            for (_, paths) in by_contents {
                if paths.len() == 1 {
                    pb.inc(file_size as u64);
                    continue
                }

                // print!("Duplicate {} paths (hash: {})\n", paths.len(), hash);
                for path in &paths {
                    db.execute("INSERT INTO files (hash, path, size) VALUES (?, ?, ?)", &[&(hash as i64), &path.to_str().unwrap(), &(file_size as i64)]).expect("failed to write to db");
                    // print!("  {}\n", path.display());
                }

                let wasted = file_size * (paths.len() - 1);
                // print!(
                //     " Size: {}. Wasting {}.\n",
                //     file_size.file_size(options::CONVENTIONAL).unwrap(),
                //     wasted.file_size(options::CONVENTIONAL).unwrap(),
                // );

                total_wasted_size += wasted;

                pb.inc((file_size * paths.len()) as u64);
            }
        }
    }

    pb.finish();

    println!();
    println!("Total wasted size: {}", total_wasted_size.file_size(options::CONVENTIONAL).unwrap());

    let mut disk_db = rusqlite::Connection::open("media_store_sizes.db").expect("failed to open sqlite db");
    let backup = rusqlite::backup::Backup::new(&db, &mut disk_db).expect("failed to create backup");
    backup.run_to_completion(5, std::time::Duration::from_millis(0), None).expect("failed to write to disk");
}
<commit_msg>Output total size<commit_after>//    Copyright 2017 Vector Creations Limited
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

// extern crate base64;
// extern crate blake2_rfc;
#[macro_use]
extern crate clap;
extern crate humansize;
extern crate linear_map;
extern crate rusqlite;
extern crate twox_hash;
extern crate walkdir;
extern crate indicatif;

// use blake2_rfc::blake2b::Blake2b;
use humansize::{FileSize, file_size_opts as options};
use clap::{App, Arg};
use linear_map::LinearMap;
use std::io;
use std::io::Read;
use std::fs::File;
use std::hash::Hasher;
use std::collections::BTreeMap;
use std::path::PathBuf;
use walkdir::WalkDir;

fn copy<R: io::Read, W: Hasher>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
    let mut buf = [0; 64 * 1024];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write(&buf[..len]);
        written += len as u64;
    }
}

fn to_hash(path: &PathBuf) -> u64 {
    let mut file = File::open(path).unwrap();
    let mut hasher = twox_hash::XxHash::default();
    copy(&mut file, &mut hasher).unwrap();
    hasher.finish()
}

fn read_file(path: &PathBuf) -> Vec<u8> {
    let mut file = File::open(path).unwrap();
    let mut vec = Vec::new();
    file.read_to_end(&mut vec).unwrap();
    vec
}

fn partition_by<I, F, R>(paths: I, f: F) -> LinearMap<R, Vec<PathBuf>>
    where I: Iterator<Item=PathBuf>, F: Fn(&PathBuf) -> R, R: Eq
{
    let mut map = LinearMap::with_capacity(paths.size_hint().0);
    for path in paths {
        let key = f(&path);
        map.entry(key).or_insert_with(Vec::new).push(path);
    }
    map
}

const DB_TABLE_SCHEMA: &'static str = r#"
CREATE TABLE files (
    hash BIGINT NOT NULL,
    path TEXT NOT NULL,
    size BIGINT NOT NULL
);
"#;

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!("\n"))
        .arg(Arg::with_name("media_directory")
            .help("The location of the media store")
            .index(1)
            .required(true))
        .get_matches();

    let path = matches.value_of("media_directory").unwrap();

    println!("Creating DB...");

    let db = rusqlite::Connection::open_in_memory().expect("failed to open sqlite db");
    db.execute_batch(DB_TABLE_SCHEMA).expect("failed to create db schema");

    let mut paths_by_size = BTreeMap::new();
    let mut total_files = 0;
    let mut total_size = 0;

    println!("Walking fs...");

    let pb = indicatif::ProgressBar::new_spinner();

    for entry in WalkDir::new(path) {
        let entry = entry.unwrap();
        if !entry.file_type().is_file() {
            continue
        }

        let file_size = entry.metadata().unwrap().len() as usize;
        paths_by_size.entry(file_size).or_insert_with(Vec::new).push(entry.path().to_owned());

        total_files += 1;
        total_size += file_size;

        pb.inc(1);
        if total_files % 100 == 0 {
            // println!("Handled {} files", total_files);
            // pb.set_message(&format!("Handled {} files", total_files));
        }
        pb.set_message(&format!("Handled {} files", total_files));
    }

    pb.finish_and_clear();

    println!("Handled {} files", total_files);
    println!();

     let pb = indicatif::ProgressBar::new(total_size as u64);

    let mut total_wasted_size = 0;

    for (file_size, paths) in paths_by_size {
        if paths.len() == 1 {
            pb.inc(file_size as u64);
            continue
        }

        let by_hash = partition_by(paths.into_iter(), to_hash);

        for (hash, paths) in by_hash {
            if paths.len() == 1 {
                pb.inc(file_size as u64);
                continue
            }

            let by_contents = partition_by(paths.into_iter(), read_file);

            for (_, paths) in by_contents {
                if paths.len() == 1 {
                    pb.inc(file_size as u64);
                    continue
                }

                // print!("Duplicate {} paths (hash: {})\n", paths.len(), hash);
                for path in &paths {
                    db.execute("INSERT INTO files (hash, path, size) VALUES (?, ?, ?)", &[&(hash as i64), &path.to_str().unwrap(), &(file_size as i64)]).expect("failed to write to db");
                    // print!("  {}\n", path.display());
                }

                let wasted = file_size * (paths.len() - 1);
                // print!(
                //     " Size: {}. Wasting {}.\n",
                //     file_size.file_size(options::CONVENTIONAL).unwrap(),
                //     wasted.file_size(options::CONVENTIONAL).unwrap(),
                // );

                total_wasted_size += wasted;

                pb.inc((file_size * paths.len()) as u64);
            }
        }
    }

    pb.finish();

    println!();
    println!("Total wasted size: {}", total_wasted_size.file_size(options::CONVENTIONAL).unwrap());
    println!("Total size: {}", total_size.file_size(options::CONVENTIONAL).unwrap());

    let mut disk_db = rusqlite::Connection::open("media_store_sizes.db").expect("failed to open sqlite db");
    let backup = rusqlite::backup::Backup::new(&db, &mut disk_db).expect("failed to create backup");
    backup.run_to_completion(5, std::time::Duration::from_millis(0), None).expect("failed to write to disk");
}
<|endoftext|>


<commit_before>extern crate regex;
//use regex::Regex;
//use std::env;
use std::process::{Command};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    //Rewrite to Main is needed.
    // This is needed for the end user to know what is happening.
    let mut holder:Vec<String> = vec![];
    let mut hold:Vec<String> = vec![];
    /*let pass = "PASS!";
    let fail = "FAIL!";
    let key_one = gpg_import_key_one();
    let key_two = gpg_import_key_two();
    let key_three = gpg_import_key_three();

    if key_one && key_two && key_three{
        println!("1st Key Import {}", pass);
        println!("2nd Key Import {}", pass);
        println!("3rd Key Import {}", pass);
    }else if !key_one {
        println!("1st Key Import {}", fail);
        exit(1);
    }else if key_one &! key_two{
        println!("2nd Key Import {}", fail);
        exit(1);
    }else if key_one && key_two &!key_three {
        println!("3rd Key Import {}", fail);
        exit(1);
    }

    let init_check = gpg_init();

    if init_check {
        println!("Pacman Key Init {}", pass);
    }else {
        println!("Pacman Key Init {}", fail);
    }*/
    //modify_pacman_conf();
    holder =  check_pacman_conf();
    check_pacman_conf();
    let check_one = create_pacman_conf_old();;
    println!("Created backup of \"/etc/pacman.conf:\" {}", check_one);
    create_new_pacman_conf(holder);
    hold = pacman_conf_final();
    create_new_pacman_conf(hold);

}

fn gpg_import_key_one() -> bool{
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("--receive-keys")
        .arg("AEFB411B072836CD48FF0381AE252C284B5DBA5D")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_import_key_two() -> bool{
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("--receive-keys")
        .arg("9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_import_key_three() -> bool{
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("--receive-keys")
        .arg("35F52A02854DCCAEC9DD5CC410443C7F54B00041")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_init() -> bool{
    let check:bool = true;
    let output = Command::new("pacman-key")
        .arg("--init")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_remove_key_one() -> bool{
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("-r")
        .arg("AEFB411B072836CD48FF0381AE252C284B5DBA5D")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_remove_key_two() -> bool{
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("-r")
        .arg("9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_remove_key_three() -> bool {
    let check:bool = true;
    let output = Command::new("gpg")
        .arg("-r")
        .arg("35F52A02854DCCAEC9DD5CC410443C7F54B00041")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn create_pacman_conf_old() -> bool{
    let check:bool = true;
    let output = Command::new("mv")
        .arg("out/pacman.conf")
        .arg("out/pacman.conf.old")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}
//This function will be called on two separate iterations
fn create_new_pacman_conf(x:Vec<String>) {
    let path = Path::new("out/pacman.conf");
    let display = path.display();
    // Open a file in write-only mode, returns `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(file) => file,
    };

    let mut f = OpenOptions::new()
        .write(true)
        .append(true)
        .open("out/pacman.conf")
        .unwrap();
    for item in x.iter(){
        if let Err(e) =
        writeln!(f, "{}",item.to_string()){
            println!("{}", e);
        }
    }
}

fn check_pacman_conf() ->Vec<String> {

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "#[archlabs_repo]".to_string();
    let check_str_two:String =
        "[archlabs_repo]".to_string();
    let check_str_three:String =
        "#SigLevel = Never".to_string();
    let check_str_four:String =
        "SigLevel = Never".to_string();
    let check_str_five:String =
        "#Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_six:String =
        "Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_seven:String =
        "#Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();
    let check_str_eight:String =
        "Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();

    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_two);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_three) {
                let str_replace =
                    line.replace(&check_str_three, &check_str_four);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_five) {
                let str_replace =
                    line.replace(&check_str_five, &check_str_six);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_seven) {
                let str_replace =
                    line.replace(&check_str_seven, &check_str_eight);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}

fn archlabs_keyring() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn key_populate() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn pacman_conf_final() -> Vec<String>{

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "[archlabs_repo]".to_string();
    let check_str_two:String =
        "SigLevel = Never".to_string();
    let check_str_three:String =
        "SigLevel = Optional TrustAll".to_string();
    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_one);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_two) {
                let str_replace =
                    line.replace(&check_str_two, &check_str_three);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}<commit_msg>Streamline FNs<commit_after>use std::process::{Command};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    //Rewrite to Main is needed.
    // This is needed for the end user to know what is happening.
    let keys:Vec<String> =
        vec!["AEFB411B072836CD48FF0381AE252C284B5DBA5D".to_string(),
             "9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0".to_string(),
             "35F52A02854DCCAEC9DD5CC410443C7F54B00041".to_string()];
    let mut keys_clone:Vec<String> = vec![];
    keys_clone = keys.clone();
    let mut holder:Vec<String> = vec![];
    let mut hold:Vec<String> = vec![];
    /*let pass = "PASS!";
    let fail = "FAIL!";
    let key_one = gpg_import_key_one();
    let key_two = gpg_import_key_two();
    let key_three = gpg_import_key_three();

    if key_one && key_two && key_three{
        println!("1st Key Import {}", pass);
        println!("2nd Key Import {}", pass);
        println!("3rd Key Import {}", pass);
    }else if !key_one {
        println!("1st Key Import {}", fail);
        exit(1);
    }else if key_one &! key_two{
        println!("2nd Key Import {}", fail);
        exit(1);
    }else if key_one && key_two &!key_three {
        println!("3rd Key Import {}", fail);
        exit(1);
    }

    let init_check = gpg_init();

    if init_check {
        println!("Pacman Key Init {}", pass);
    }else {
        println!("Pacman Key Init {}", fail);
    }*/
    //modify_pacman_conf();
    //holder =  check_pacman_conf();
    //check_pacman_conf();
    //let check_one = create_pacman_conf_old();
    //println!("Created backup of \"/etc/pacman.conf:\" {}", check_one);
    //create_new_pacman_conf(holder);
    //hold = pacman_conf_final();
    //create_new_pacman_conf(hold);
    gpg_import_keys(keys);
    gpg_remove_keys(keys_clone);
}

fn gpg_import_keys(k:Vec<String>) {

    let mut keys:String = String::new();
    let mut check:i8 = 0;
    for item in k.iter(){
        keys = item.to_string();

        let output = Command::new("gpg")
            .arg("--receive-keys")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");
        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not imported");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were imported successfully.");
    }
}

fn gpg_init() -> bool{
    let check:bool = true;
    let output = Command::new("pacman-key")
        .arg("--init")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        print!("Success: ");
        println!("{}", String::from_utf8(output.stdout).unwrap());
    }else {
        print!("Error: ");
        println!("{}", String::from_utf8(output.stderr).unwrap());
    }
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_remove_keys(k:Vec<String>) {

    let mut keys:String = String::new();
    let mut check:i8 = 0;
    for item in k.iter() {
        keys = item.to_string();

        let output =
            Command::new("pacman-key")
            .arg("-r")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");

        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not removed!");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were removed successfully.");
    }
}

fn create_pacman_conf_old() -> bool{
    let check:bool = true;
    let output = Command::new("mv")
        .arg("out/pacman.conf")
        .arg("out/pacman.conf.old")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}
//This function will be called on two separate iterations
fn create_new_pacman_conf(x:Vec<String>) {
    let path = Path::new("out/pacman.conf");
    let display = path.display();
    // Open a file in write-only mode, returns `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(file) => file,
    };

    let mut f = OpenOptions::new()
        .write(true)
        .append(true)
        .open("out/pacman.conf")
        .unwrap();
    for item in x.iter(){
        if let Err(e) =
        writeln!(f, "{}",item.to_string()){
            println!("{}", e);
        }
    }
}

fn check_pacman_conf() ->Vec<String> {

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "#[archlabs_repo]".to_string();
    let check_str_two:String =
        "[archlabs_repo]".to_string();
    let check_str_three:String =
        "#SigLevel = Never".to_string();
    let check_str_four:String =
        "SigLevel = Never".to_string();
    let check_str_five:String =
        "#Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_six:String =
        "Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_seven:String =
        "#Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();
    let check_str_eight:String =
        "Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();

    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_two);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_three) {
                let str_replace =
                    line.replace(&check_str_three, &check_str_four);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_five) {
                let str_replace =
                    line.replace(&check_str_five, &check_str_six);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_seven) {
                let str_replace =
                    line.replace(&check_str_seven, &check_str_eight);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}

fn archlabs_keyring() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn key_populate() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn pacman_conf_final() -> Vec<String>{

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "[archlabs_repo]".to_string();
    let check_str_two:String =
        "SigLevel = Never".to_string();
    let check_str_three:String =
        "SigLevel = Optional TrustAll".to_string();
    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_one);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_two) {
                let str_replace =
                    line.replace(&check_str_two, &check_str_three);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}<|endoftext|>