<commit_before>extern crate chrono;
#[macro_use]
extern crate clap;
extern crate fern;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate ratelimit;
extern crate regex;
extern crate reqwest;

use std::time::Duration;
use std::error::Error;
use std::io::{BufRead, BufReader, Write};
use std::fs::{File, OpenOptions};
use std::path::Path;
use clap::{App, Arg};
use reqwest::StatusCode;
use regex::Regex;

lazy_static! {
    static ref CLIENT: reqwest::Client = reqwest::Client::new();
    static ref USERNAME_REGEX: Regex = Regex::new(r"^[0-9\p{L} _\\.]{3,16}$").unwrap();
}

fn setup_logger(verbosity: u64) -> Result<(), fern::InitError> {
    fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{} [{}] [{}] {}",
                chrono::Local::now().format("%e %b %Y %H:%M:%S%.3f"),
                record.target(),
                record.level(),
                message
            ))
        })
        .level(match verbosity {
            0 | 1 => log::LogLevelFilter::Info,
            2 => log::LogLevelFilter::Debug,
            _ => log::LogLevelFilter::Trace,
        })
        .level_for("reaper", match verbosity {
            0 => log::LogLevelFilter::Info,
            1 => log::LogLevelFilter::Debug,
            _ => log::LogLevelFilter::Trace,
        })
        .chain(std::io::stdout())
        .apply()?;

    Ok(())
}

fn argparse<'a, 'b>() -> clap::App<'a, 'b> {
    App::new("Reaper")
        .version(crate_version!())
        .author("Jordan Doyle <jordan@9t9t9.com>")
        .about("Scans over a given list for available usernames on League of Legends")
        .arg(Arg::with_name("SERVER")
                .help("Sets the server to search for usernames on")
                .required(true)
                .index(1))
        .arg(Arg::with_name("INPUT")
                .help("Sets the input file to use")
                .required(true)
                .index(2))
        .arg(Arg::with_name("API KEY")
                .help("Sets the API key to use")
                .required(true)
                .index(3))
        .arg(Arg::with_name("output")
                .short("o")
                .long("output")
                .value_name("FILE")
                .help("Sets an output file to write available usernames to")
                .takes_value(true))
        .arg(Arg::with_name("verbose")
                .short("v")
                .long("verbose")
                .multiple(true)
                .help("Increases logging verbosity each use up to 3 times"))
}

fn main() {
    let args = argparse().get_matches();

    setup_logger(args.occurrences_of("verbose")).expect("Failed to initialize logging.");

    info!("Reaper booting up.");

    // all our inputs below are required fields so we can unwrap them without any worries
    let server = args.value_of("SERVER").unwrap();
    let input = Path::new(args.value_of("INPUT").unwrap());
    let api_key = args.value_of("API KEY").unwrap();

    assert!(input.exists(), "Input file doesn't exist.");

    let output = args.value_of("output");

    // output is an optional field so we check if it has a value and if it does we build a
    // new File instance and create a new Option with it
    let output_file = if output.is_some() {
        match OpenOptions::new()
            .create(true)
            .append(true)
            .open(output.unwrap())
        {
            Ok(file) => Some(file),
            Err(e) => {
                error!("Couldn't open handle to output file. {}", e);
                panic!()
            }
        }
    } else {
        None
    };

    debug!("Finished parsing arguments");

    let mut ratelimit = ratelimit::Builder::new()
        .capacity(1) // number of tokens the bucket will hold
        .quantum(1) // add one token per interval
        .interval(Duration::new(1, 0)) // add quantum tokens every 1 second
        .build();

    for line in BufReader::new(File::open(input).unwrap()).lines() {
        let username = &line.unwrap();

        if !USERNAME_REGEX.is_match(username) {
            error!(
                "The username \"{}\" isn't a valid username, skipping.",
                username
            );
            continue;
        }

        debug!("Checking if \"{}\" is available", username);

        match send_request(server, api_key, username) {
            Ok(_) => {
                info!("{} is available!", username);

                if let Some(ref mut file) = output_file.as_ref() {
                    writeln!(file, "{}", username).unwrap();
                }
            }
            Err(e) => info!("{} is not available ({})", username, e),
        }

        ratelimit.wait();
    }
}

fn send_request(server: &str, api_key: &str, username: &str) -> Result<(), Box<Error>> {
    let resp = CLIENT
        .get(&format!(
            "https://{}.api.riotgames.com/lol/summoner/v3/summoners/by-name/{}?api_key={}",
            server,
            username,
            api_key
        ))
        .send()?;

    debug!("{:?}", resp);

    if !resp.status().is_success() {
        if resp.status().eq(&StatusCode::NotFound) {
            Ok(())
        } else {
            Err(Box::from("Bad response from Riot API"))
        }
    } else {
        Err(Box::from("Username is taken"))
    }
}
<commit_msg>Update main.rs<commit_after>extern crate chrono;
#[macro_use]
extern crate clap;
extern crate fern;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate ratelimit;
extern crate regex;
extern crate reqwest;

use std::time::Duration;
use std::error::Error;
use std::io::{BufRead, BufReader, Write};
use std::fs::{File, OpenOptions};
use std::path::Path;
use clap::{App, Arg};
use reqwest::StatusCode;
use regex::Regex;

lazy_static! {
    static ref CLIENT: reqwest::Client = reqwest::Client::new();
    static ref USERNAME_REGEX: Regex = Regex::new(r"^[0-9\p{L} _\\.]{3,16}$").unwrap();
}

fn setup_logger(verbosity: u64) -> Result<(), fern::InitError> {
    fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{} [{}] [{}] {}",
                chrono::Local::now().format("%e %b %Y %H:%M:%S%.3f"),
                record.target(),
                record.level(),
                message
            ))
        })
        .level(match verbosity {
            0 | 1 => log::LogLevelFilter::Info,
            2 => log::LogLevelFilter::Debug,
            _ => log::LogLevelFilter::Trace,
        })
        .level_for("reaper", match verbosity {
            0 => log::LogLevelFilter::Info,
            1 => log::LogLevelFilter::Debug,
            _ => log::LogLevelFilter::Trace,
        })
        .chain(std::io::stdout())
        .apply()?;

    Ok(())
}

fn argparse<'a, 'b>() -> clap::App<'a, 'b> {
    App::new("Reaper")
        .version(crate_version!())
        .author("Jordan Doyle <jordan@9t9t9.com>")
        .about("Scans over a given list for available usernames on League of Legends")
        .arg(Arg::with_name("SERVER")
                .help("Sets the server to search for usernames on")
                .required(true)
                .index(1))
        .arg(Arg::with_name("INPUT")
                .help("Sets the input file to use")
                .required(true)
                .index(2))
        .arg(Arg::with_name("API KEY")
                .help("Sets the API key to use")
                .required(true)
                .index(3))
        .arg(Arg::with_name("output")
                .short("o")
                .long("output")
                .value_name("FILE")
                .help("Sets an output file to write available usernames to")
                .takes_value(true))
        .arg(Arg::with_name("verbose")
                .short("v")
                .long("verbose")
                .multiple(true)
                .help("Increases logging verbosity each use up to 3 times"))
}

fn main() {
    let args = argparse().get_matches();

    setup_logger(args.occurrences_of("verbose")).expect("Failed to initialize logging.");

    info!("Reaper booting up.");

    // all our inputs below are required fields so we can unwrap them without any worries
    let server = args.value_of("SERVER").unwrap();
    let input = Path::new(args.value_of("INPUT").unwrap());
    let api_key = args.value_of("API KEY").unwrap();

    assert!(input.exists(), "Input file doesn't exist.");

    let output = args.value_of("output");

    // output is an optional field so we check if it has a value and if it does we build a
    // new File instance and create a new Option with it
    let output_file = if output.is_some() {
        match OpenOptions::new()
            .create(true)
            .append(true)
            .open(output.unwrap())
        {
            Ok(file) => Some(file),
            Err(e) => {
                error!("Couldn't open handle to output file. {}", e);
                panic!()
            }
        }
    } else {
        None
    };

    debug!("Finished parsing arguments");

    let mut ratelimit = ratelimit::Builder::new()
        .capacity(1) // number of tokens the bucket will hold
        .quantum(1) // add one token per interval
        .interval(Duration::new(1, 0)) // add quantum tokens every 1 second
        .build();

    for line in BufReader::new(File::open(input).unwrap()).lines() {
        let username = &line.unwrap();

        if !USERNAME_REGEX.is_match(username) {
            error!(
                "The username \"{}\" isn't a valid username, skipping.",
                username
            );
            continue;
        }

        debug!("Checking if \"{}\" is available", username);

        match send_request(server, api_key, username) {
            Ok(_) => {
                info!("{} is available!", username);

                if let Some(ref mut file) = output_file.as_ref() {
                    writeln!(file, "{}", username).unwrap();
                }
            }
            Err(e) => info!("{} is not available ({})", username, e),
        }

        ratelimit.wait();
    }
}

fn send_request(server: &str, api_key: &str, username: &str) -> Result<(), Box<Error>> {
    let resp = CLIENT
        .get(&format!(
            "https://{}.api.riotgames.com/lol/summoner/v4/summoners/by-name/{}?api_key={}",
            server,
            username,
            api_key
        ))
        .send()?;

    debug!("{:?}", resp);

    if !resp.status().is_success() {
        if resp.status().eq(&StatusCode::NotFound) {
            Ok(())
        } else {
            Err(Box::from("Bad response from Riot API"))
        }
    } else {
        Err(Box::from("Username is taken"))
    }
}
<|endoftext|>


<commit_before>//! Documentation for Rust Bio Tools
use clap::{load_yaml, value_t};
use log::LevelFilter;

use clap::App;
use itertools::Itertools;
use rayon::prelude::*;
use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::path::Path;
use std::str::FromStr;

pub mod bam;
pub mod bcf;
pub mod common;
pub mod fastq;
pub mod sequences_stats;

fn main() -> Result<(), Box<dyn Error>> {
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml)
        .version(env!("CARGO_PKG_VERSION"))
        .get_matches();

    fern::Dispatch::new()
        .format(|out, message, _| out.finish(format_args!("{}", message)))
        .level(if matches.is_present("verbose") {
            LevelFilter::Debug
        } else {
            LevelFilter::Info
        })
        .chain(std::io::stderr())
        .apply()
        .unwrap();

    match matches.subcommand() {
        ("fastq-split", Some(matches)) => {
            fastq::split::split(&matches.values_of("chunks").unwrap().collect_vec())
        }
        ("fastq-filter", Some(matches)) => fastq::filter::filter(&matches.value_of("ids").unwrap()),
        ("bam-depth", Some(matches)) => bam::depth::depth(
            &matches.value_of("bam-path").unwrap(),
            value_t!(matches, "max-read-length", u32).unwrap_or(1000),
            value_t!(matches, "include-flags", u16).unwrap_or(0),
            value_t!(matches, "exclude-flags", u16).unwrap_or(4 | 256 | 512 | 1024),
            value_t!(matches, "min-mapq", u8).unwrap_or(0),
        ),
        ("vcf-to-txt", Some(matches)) => bcf::to_txt::to_txt(
            &matches
                .values_of("info")
                .map(|values| values.collect_vec())
                .unwrap_or_default(),
            &matches
                .values_of("format")
                .map(|values| values.collect_vec())
                .unwrap_or_default(),
            matches.is_present("genotypes"),
        ),
        ("vcf-match", Some(matches)) => bcf::match_variants::match_variants(
            matches.value_of("vcf").unwrap(),
            value_t!(matches, "max-dist", u32).unwrap_or(20),
            value_t!(matches, "max-len-diff", u32).unwrap_or(10),
        ),
        ("vcf-baf", Some(_)) => bcf::baf::calculate_baf(),
        ("vcf-fix-iupac-alleles", Some(_)) => bcf::fix_iupac_alleles::fix_iupac_alleles(),
        ("vcf-annotate-dgidb", Some(matches)) => bcf::annotate_dgidb::annotate_dgidb(
            &matches.value_of("vcf").unwrap(),
            matches.value_of("api-path").unwrap().to_string(),
            &matches.value_of("field").unwrap(),
            match matches.is_present("datasources") {
                true => Some(matches.values_of("datasources").unwrap().collect()),
                false => None,
            },
            value_t!(matches, "genes-per-request", usize).unwrap(),
        ),
        ("vcf-report", Some(matches)) => {
            let mut sample_calls = HashMap::new();
            let mut bam_paths = HashMap::new();
            let output_path = matches.value_of("output-path").unwrap();
            let threads = usize::from_str(matches.value_of("threads").unwrap()).unwrap();
            if !Path::new(output_path).exists() {
                fs::create_dir(Path::new(output_path)).unwrap_or_else(|_| {
                    panic!(
                        "Couldn't create output directory at {}. Please make sure the path exists.",
                        output_path
                    )
                });
            }
            let max_cells = u32::from_str(matches.value_of("max-cells").unwrap()).unwrap();
            let max_read_depth =
                u32::from_str(matches.value_of("max-read-depth").unwrap()).unwrap();
            let custom_js = matches.value_of("custom-js-template");
            let js_files = matches.values_of("custom-js-files");
            let js_files_vec = js_files
                .clone()
                .map_or_else(Vec::new, |values| values.collect());
            let js_file_names = if let Some(files) = js_files.clone() {
                files
                    .map(|f| {
                        f.split('/')
                            .collect_vec()
                            .pop()
                            .unwrap_or_else(|| {
                                panic!("Unable to extract file name from path: {:?}", f)
                            })
                            .to_owned()
                    })
                    .collect()
            } else {
                vec![]
            };
            let tsv_data = matches.value_of("tsv");
            bcf::report::embed_js(output_path, custom_js, js_files_vec)?;
            bcf::report::embed_css(output_path)?;
            bcf::report::embed_html(output_path)?;
            let fasta_path = matches.value_of("fasta").unwrap();
            let detail_path = output_path.to_owned() + "/details/";
            fs::create_dir(Path::new(&detail_path))?;
            let vcfs = matches.values_of("vcfs").unwrap();
            let bams = matches.values_of("bams").unwrap();
            let infos = matches.values_of("info");
            let formats = matches.values_of("format");
            for vcf in vcfs {
                let v: Vec<_> = vcf.split('=').collect();
                match sample_calls.insert(v[0].to_owned(), v[1].to_owned()) {
                    None => {}
                    _ => panic!("Found duplicate sample name {}. Please make sure the provided sample names are unique.", v[0].to_owned())
                }
            }
            for bam in bams {
                let b: Vec<_> = bam.split('=').collect();
                let c: Vec<_> = b[0].split(':').collect();
                let rec = bam_paths.entry(c[0].to_owned()).or_insert_with(Vec::new);
                rec.push((c[1].to_owned(), b[1].to_owned()))
            }
            let pool = rayon::ThreadPoolBuilder::new()
                .num_threads(threads)
                .build()
                .unwrap();
            pool.install(|| {
                sample_calls.par_iter().for_each(|(sample, sample_call)| {
                    bcf::report::table_report::table_report(
                        sample_call,
                        fasta_path,
                        bam_paths
                            .get(sample)
                            .unwrap_or_else(|| panic!("No bam provided for sample {}", sample)),
                        output_path,
                        sample,
                        infos.clone(),
                        formats.clone(),
                        max_read_depth,
                        js_file_names.clone(),
                    )
                    .unwrap_or_else(|_| {
                        panic!("Failed building table report for sample {}", sample)
                    });
                })
            });

            bcf::report::oncoprint::oncoprint(&sample_calls, output_path, max_cells, tsv_data)
        }
        ("vcf-split", Some(matches)) => {
            bcf::split::split(
                matches.value_of("input").unwrap(),
                &matches.values_of("output").unwrap().collect::<Vec<_>>(),
            )?;
            Ok(())
        }
        ("collapse-reads-to-fragments", Some(matches)) => match matches.subcommand() {
            ("fastq", Some(matches)) => {
                fastq::collapse_reads_to_fragments::call_consensus_reads_from_paths(
                    matches.value_of("fq1").unwrap(),
                    matches.value_of("fq2").unwrap(),
                    matches.value_of("consensus-fq1").unwrap(),
                    matches.value_of("consensus-fq2").unwrap(),
                    matches.value_of("consensus-fq3"),
                    value_t!(matches, "umi-len", usize).unwrap(),
                    value_t!(matches, "max-seq-dist", usize).unwrap(),
                    value_t!(matches, "max-umi-dist", usize).unwrap(),
                    matches.is_present("umi-on-reverse"),
                    matches.is_present("verbose-read-names"),
                    if matches.is_present("insert-size") {
                        Some(value_t!(matches, "insert-size", usize).unwrap())
                    } else {
                        None
                    },
                    if matches.is_present("std-dev") {
                        Some(value_t!(matches, "std-dev", usize).unwrap())
                    } else {
                        None
                    },
                )
            }
            ("bam", Some(matches)) => {
                bam::collapse_reads_to_fragments::call_consensus_reads_from_paths(
                    matches.value_of("bam").unwrap(),
                    matches.value_of("consensus-fq1").unwrap(),
                    matches.value_of("consensus-fq2").unwrap(),
                    matches.value_of("consensus-fq-se").unwrap(),
                    matches.value_of("skipped-bam").unwrap(),
                    matches.is_present("verbose-read-names"),
                )
            }
            _ => unreachable!(),
        },
        ("sequence-stats", Some(matches)) => sequences_stats::stats(matches.is_present("fastq")),
        // This cannot be reached, since the matches step of
        // clap assures that a valid subcommand is provided
        _ => unreachable!(),
    }
}
<commit_msg>Use ? operator<commit_after>//! Documentation for Rust Bio Tools
use clap::{load_yaml, value_t};
use log::LevelFilter;

use clap::App;
use itertools::Itertools;
use rayon::prelude::*;
use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::path::Path;
use std::str::FromStr;

pub mod bam;
pub mod bcf;
pub mod common;
pub mod fastq;
pub mod sequences_stats;

fn main() -> Result<(), Box<dyn Error>> {
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml)
        .version(env!("CARGO_PKG_VERSION"))
        .get_matches();

    fern::Dispatch::new()
        .format(|out, message, _| out.finish(format_args!("{}", message)))
        .level(if matches.is_present("verbose") {
            LevelFilter::Debug
        } else {
            LevelFilter::Info
        })
        .chain(std::io::stderr())
        .apply()
        .unwrap();

    match matches.subcommand() {
        ("fastq-split", Some(matches)) => {
            fastq::split::split(&matches.values_of("chunks").unwrap().collect_vec())
        }
        ("fastq-filter", Some(matches)) => fastq::filter::filter(&matches.value_of("ids").unwrap()),
        ("bam-depth", Some(matches)) => bam::depth::depth(
            &matches.value_of("bam-path").unwrap(),
            value_t!(matches, "max-read-length", u32).unwrap_or(1000),
            value_t!(matches, "include-flags", u16).unwrap_or(0),
            value_t!(matches, "exclude-flags", u16).unwrap_or(4 | 256 | 512 | 1024),
            value_t!(matches, "min-mapq", u8).unwrap_or(0),
        ),
        ("vcf-to-txt", Some(matches)) => bcf::to_txt::to_txt(
            &matches
                .values_of("info")
                .map(|values| values.collect_vec())
                .unwrap_or_default(),
            &matches
                .values_of("format")
                .map(|values| values.collect_vec())
                .unwrap_or_default(),
            matches.is_present("genotypes"),
        ),
        ("vcf-match", Some(matches)) => bcf::match_variants::match_variants(
            matches.value_of("vcf").unwrap(),
            value_t!(matches, "max-dist", u32).unwrap_or(20),
            value_t!(matches, "max-len-diff", u32).unwrap_or(10),
        ),
        ("vcf-baf", Some(_)) => bcf::baf::calculate_baf(),
        ("vcf-fix-iupac-alleles", Some(_)) => bcf::fix_iupac_alleles::fix_iupac_alleles(),
        ("vcf-annotate-dgidb", Some(matches)) => bcf::annotate_dgidb::annotate_dgidb(
            &matches.value_of("vcf").unwrap(),
            matches.value_of("api-path").unwrap().to_string(),
            &matches.value_of("field").unwrap(),
            match matches.is_present("datasources") {
                true => Some(matches.values_of("datasources").unwrap().collect()),
                false => None,
            },
            value_t!(matches, "genes-per-request", usize).unwrap(),
        ),
        ("vcf-report", Some(matches)) => {
            let mut sample_calls = HashMap::new();
            let mut bam_paths = HashMap::new();
            let output_path = matches.value_of("output-path").unwrap();
            let threads = usize::from_str(matches.value_of("threads").unwrap()).unwrap();
            if !Path::new(output_path).exists() {
                fs::create_dir(Path::new(output_path)).unwrap_or_else(|_| {
                    panic!(
                        "Couldn't create output directory at {}. Please make sure the path exists.",
                        output_path
                    )
                });
            }
            let max_cells = u32::from_str(matches.value_of("max-cells").unwrap()).unwrap();
            let max_read_depth =
                u32::from_str(matches.value_of("max-read-depth").unwrap()).unwrap();
            let custom_js = matches.value_of("custom-js-template");
            let js_files = matches.values_of("custom-js-files");
            let js_files_vec = js_files
                .clone()
                .map_or_else(Vec::new, |values| values.collect());
            let js_file_names = if let Some(files) = js_files.clone() {
                files
                    .map(|f| {
                        f.split('/')
                            .collect_vec()
                            .pop()
                            .unwrap_or_else(|| {
                                panic!("Unable to extract file name from path: {:?}", f)
                            })
                            .to_owned()
                    })
                    .collect()
            } else {
                vec![]
            };
            let tsv_data = matches.value_of("tsv");
            bcf::report::embed_js(output_path, custom_js, js_files_vec)?;
            bcf::report::embed_css(output_path)?;
            bcf::report::embed_html(output_path)?;
            let fasta_path = matches.value_of("fasta").unwrap();
            let detail_path = output_path.to_owned() + "/details/";
            fs::create_dir(Path::new(&detail_path))?;
            let vcfs = matches.values_of("vcfs").unwrap();
            let bams = matches.values_of("bams").unwrap();
            let infos = matches.values_of("info");
            let formats = matches.values_of("format");
            for vcf in vcfs {
                let v: Vec<_> = vcf.split('=').collect();
                match sample_calls.insert(v[0].to_owned(), v[1].to_owned()) {
                    None => {}
                    _ => panic!("Found duplicate sample name {}. Please make sure the provided sample names are unique.", v[0].to_owned())
                }
            }
            for bam in bams {
                let b: Vec<_> = bam.split('=').collect();
                let c: Vec<_> = b[0].split(':').collect();
                let rec = bam_paths.entry(c[0].to_owned()).or_insert_with(Vec::new);
                rec.push((c[1].to_owned(), b[1].to_owned()))
            }
            let pool = rayon::ThreadPoolBuilder::new()
                .num_threads(threads)
                .build()?;
            pool.install(|| {
                sample_calls.par_iter().for_each(|(sample, sample_call)| {
                    bcf::report::table_report::table_report(
                        sample_call,
                        fasta_path,
                        bam_paths
                            .get(sample)
                            .unwrap_or_else(|| panic!("No bam provided for sample {}", sample)),
                        output_path,
                        sample,
                        infos.clone(),
                        formats.clone(),
                        max_read_depth,
                        js_file_names.clone(),
                    )
                    .unwrap_or_else(|_| {
                        panic!("Failed building table report for sample {}", sample)
                    });
                })
            });

            bcf::report::oncoprint::oncoprint(&sample_calls, output_path, max_cells, tsv_data)
        }
        ("vcf-split", Some(matches)) => {
            bcf::split::split(
                matches.value_of("input").unwrap(),
                &matches.values_of("output").unwrap().collect::<Vec<_>>(),
            )?;
            Ok(())
        }
        ("collapse-reads-to-fragments", Some(matches)) => match matches.subcommand() {
            ("fastq", Some(matches)) => {
                fastq::collapse_reads_to_fragments::call_consensus_reads_from_paths(
                    matches.value_of("fq1").unwrap(),
                    matches.value_of("fq2").unwrap(),
                    matches.value_of("consensus-fq1").unwrap(),
                    matches.value_of("consensus-fq2").unwrap(),
                    matches.value_of("consensus-fq3"),
                    value_t!(matches, "umi-len", usize).unwrap(),
                    value_t!(matches, "max-seq-dist", usize).unwrap(),
                    value_t!(matches, "max-umi-dist", usize).unwrap(),
                    matches.is_present("umi-on-reverse"),
                    matches.is_present("verbose-read-names"),
                    if matches.is_present("insert-size") {
                        Some(value_t!(matches, "insert-size", usize).unwrap())
                    } else {
                        None
                    },
                    if matches.is_present("std-dev") {
                        Some(value_t!(matches, "std-dev", usize).unwrap())
                    } else {
                        None
                    },
                )
            }
            ("bam", Some(matches)) => {
                bam::collapse_reads_to_fragments::call_consensus_reads_from_paths(
                    matches.value_of("bam").unwrap(),
                    matches.value_of("consensus-fq1").unwrap(),
                    matches.value_of("consensus-fq2").unwrap(),
                    matches.value_of("consensus-fq-se").unwrap(),
                    matches.value_of("skipped-bam").unwrap(),
                    matches.is_present("verbose-read-names"),
                )
            }
            _ => unreachable!(),
        },
        ("sequence-stats", Some(matches)) => sequences_stats::stats(matches.is_present("fastq")),
        // This cannot be reached, since the matches step of
        // clap assures that a valid subcommand is provided
        _ => unreachable!(),
    }
}
<|endoftext|>


<commit_before>extern crate itertools;
use itertools::Itertools;

fn to_pig_latin(input: &str) -> String {
    input.split_whitespace()
         .map(|word| {
             let (dups, after) = word.split_at(word.find(&['a', 'e', 'i', 'o', 'u'][..]).unwrap_or(0));
             after.to_owned() + dups + "ay"
         })
         .join(" ")
}

fn main() {
    use std::env;
    use std::io;

    if env::args().len() > 1 {
        if env::args().nth(1) == Some("-h".to_string()) {
            println!("Usage: {} [-h] <string1, string2, ...>", env::args().nth(0).unwrap());
            println!("\nIf no strings are passed as parameters, the input will be read from stdin");
            println!("\n\th\tdisplay this help dialog");
        }
        else {
            for arg in env::args() {
                println!("{}", to_pig_latin(&arg));
            }
        }
    }
    else {
        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Ok(_) => println!("{}", to_pig_latin(&input)),
            _ => println!("There was an error reading from the console!"),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_to_pig_latin() {
        assert_eq!("ellohay", &to_pig_latin("hello".to_string()));
        assert_eq!("orldway", &to_pig_latin("world".to_string()));

        assert_eq!("ellohay orldway", &to_pig_latin("hello world".to_string()));
    }
}
<commit_msg>reformat<commit_after>extern crate itertools;
use itertools::Itertools;

fn to_pig_latin(input: &str) -> String {
    input
        .split_whitespace()
        .map(|word| {
                 let (dups, after) = word.split_at(word.find(&['a', 'e', 'i', 'o', 'u'][..])
                                                       .unwrap_or(0));
                 after.to_owned() + dups + "ay"
             })
        .join(" ")
}

fn main() {
    use std::env;
    use std::io;

    if env::args().len() > 1 {
        if env::args().nth(1) == Some("-h".to_string()) {
            println!("Usage: {} [-h] <string1, string2, ...>",
                     env::args().nth(0).unwrap());
            println!("\nIf no strings are passed as parameters, the input will be read from stdin");
            println!("\n\th\tdisplay this help dialog");
        } else {
            for arg in env::args() {
                println!("{}", to_pig_latin(&arg));
            }
        }
    } else {
        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Ok(_) => println!("{}", to_pig_latin(&input)),
            _ => println!("There was an error reading from the console!"),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_to_pig_latin() {
        assert_eq!("ellohay", &to_pig_latin("hello".to_string()));
        assert_eq!("orldway", &to_pig_latin("world".to_string()));

        assert_eq!("ellohay orldway", &to_pig_latin("hello world".to_string()));
    }
}

<|endoftext|>


<commit_before>extern crate chrono;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
extern crate dotenv;

use std::env;

use chrono::prelude::*;
use diesel::prelude::*;
use dotenv::dotenv;

pub mod schema {
	infer_schema!("dotenv:DATABASE_URL");
}

pub mod domain {
	use chrono;

	use super::schema::books;

	#[derive(Queryable, Identifiable, AsChangeset, Clone)]
	pub struct Book {
	    pub id : i32,
	    pub title : Option<String>,
	    pub save_date : Option<chrono::NaiveDateTime>,
	}

	#[derive(Insertable)]
	#[table_name="books"]
	pub struct NewBook<'a> {
	    pub title : Option<&'a str>,
	    pub save_date : Option<&'a chrono::NaiveDateTime>,
	}
}

fn main() {
	dotenv().ok();
    use self::schema::books::dsl::*;
	let database_url = env::var("DATABASE_URL").unwrap();
	let conn = diesel::sqlite::SqliteConnection::establish(&database_url).unwrap();
	let t = "The Lord of the Rings";
	let sd = NaiveDateTime::from_timestamp(Local::now().timestamp(), 0);
    let nb = domain::NewBook{
        title : Some(&t),
        save_date : Some(&sd)
    };
    diesel::insert(&nb).into(books).execute(&conn).unwrap();
    match books.load::<domain::Book>(&conn) {
    	Ok(vb) => {
    		for b in vb {
    			if let Some(t) = b.title {
		    		println!("{}", t);
    			}
    		}
    	},
    	Err(e) => println!("{}", e)
    }
}
<commit_msg>Print the save date too.<commit_after>extern crate chrono;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
extern crate dotenv;

use std::env;

use chrono::prelude::*;
use diesel::prelude::*;
use dotenv::dotenv;

pub mod schema {
	infer_schema!("dotenv:DATABASE_URL");
}

pub mod domain {
	use chrono;

	use super::schema::books;

	#[derive(Queryable, Identifiable, AsChangeset, Clone)]
	pub struct Book {
	    pub id : i32,
	    pub title : Option<String>,
	    pub save_date : Option<chrono::NaiveDateTime>,
	}

	#[derive(Insertable)]
	#[table_name="books"]
	pub struct NewBook<'a> {
	    pub title : Option<&'a str>,
	    pub save_date : Option<&'a chrono::NaiveDateTime>,
	}
}

fn main() {
	dotenv().ok();
    use self::schema::books::dsl::*;
	let database_url = env::var("DATABASE_URL").unwrap();
	let conn = diesel::sqlite::SqliteConnection::establish(&database_url).unwrap();
	let t = "The Lord of the Rings";
	let sd = NaiveDateTime::from_timestamp(Local::now().timestamp(), 0);
    let nb = domain::NewBook{
        title : Some(&t),
        save_date : Some(&sd)
    };
    diesel::insert(&nb).into(books).execute(&conn).unwrap();
    match books.load::<domain::Book>(&conn) {
    	Ok(vb) => {
    		for b in vb {
    			if let Some(t) = b.title {
		    		println!("{}", t);
    			}
    			if let Some(sd) = b.save_date {
		    		println!("{}", sd);
    			}
    		}
    	},
    	Err(e) => println!("{}", e)
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]

#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate nom;

extern crate bip_bencode;
extern crate bip_metainfo;
extern crate bip_utracker;
extern crate bip_util;
extern crate chrono;
extern crate hyper;
extern crate pnet;
extern crate pnet_macros_support;
extern crate pretty_env_logger;
extern crate rustyline;
extern crate url;

mod btclient;
mod packet;

mod errors {
    // Create the Error, ErrorKind, ResultExt, and Result types
    error_chain!{}
}

use bip_bencode::Bencode;
use bip_metainfo::MetainfoFile;
use bip_utracker::contact::CompactPeersV4;
use errors::*;
use chrono::{TimeZone, UTC};
use hyper::Client;
use hyper::header::Connection;
use packet::peer_pkt::{MutablePeerHandshakePacket, MutablePeerMessagePacket};
use pnet::packet::Packet;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use url::Url;

use std::fs::File;
use std::io::prelude::*;
use std::net::TcpStream;
use std::str;
use std::string::String;
use std::time::{SystemTime, UNIX_EPOCH};
use std::thread;

const HISTORY_FILE: &'static str = ".rustyline.history";
const PEER_HANDSHAKE_STRUCT_SZ: usize = 68;
const PEER_REQ_PKT_SZ: usize = 14;

/// Print file list from the torrent.
fn print_files(bytes: &[u8]) -> Result<()> {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();

    println!("File List:");
    println!("Size (bytes)\tPath");
    println!("------------\t----------------------------------------------");
    for file in info.files() {
        println!("{:12}\t{}",
                 file.length(),
                 file.paths().next().unwrap_or("<unknown>"));
    }
    Ok(())
}

/// Print general information about the torrent.
fn print_metainfo_overview(bytes: &[u8]) -> Result<()> {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();
    let info_hash_hex = metainfo.info_hash()
        .as_ref()
        .iter()
        .map(|b| format!("{:02x}", b))
        .fold(String::new(), |mut acc, nex| {
            acc.push_str(&nex);
            acc
        });
    let utc_creation_date = metainfo.creation_date().map(|c| UTC.timestamp(c, 0));

    println!("------Metainfo File Overview-----");

    println!("InfoHash: {}", info_hash_hex);
    println!("Main Tracker: {:?}", metainfo.main_tracker());
    println!("Comment: {:?}", metainfo.comment());
    println!("Creator: {:?}", metainfo.created_by());
    println!("Creation Date: {:?}", utc_creation_date);

    println!("Directory: {:?}", info.directory());
    println!("Piece Length: {:?}", info.piece_length());
    println!("Number Of Pieces: {}", info.pieces().count());
    println!("Number Of Files: {}", info.files().count());
    println!("Total File Size: {}\n",
             info.files().fold(0, |acc, nex| acc + nex.length()));

    print_files(bytes)?;
    Ok(())
}

fn connect_to_tracker(metainfo: MetainfoFile,
                      peer_id: &str,
                      port: u16)
                      -> Result<(Vec<String>, String)> {
    debug!("connecting to tracker: {:?}", metainfo.main_tracker());

    let info_hash = metainfo.info_hash();
    // TODO figure can this conversion to url-encoded form be done safely?
    let info_hash_str = unsafe { str::from_utf8_unchecked(info_hash.as_ref()) };

    // TODO this needs to be calculated based on what we have
    let total_len = metainfo.info().files().fold(0, |acc, nex| acc + nex.length());

    let mut url = Url::parse(metainfo.main_tracker().unwrap()).unwrap();
    url.query_pairs_mut()
        .append_pair("info_hash", info_hash_str)
        .append_pair("peer_id", peer_id)
        .append_pair("port", &(port.to_string()))
        // TODO parametrize this
        .append_pair("uploaded", "0")
        // TODO parametrize this
        .append_pair("downloaded", "0")
        // TODO see note on total_len above
        .append_pair("left", &(total_len.to_string()))
        .append_pair("compact", "1")
        .append_pair("event", "started")
        .append_pair("supportcrypto", "0");
    trace!("URL {:?}", url);

    let client = Client::new();
    let mut res = client.get(url).header(Connection::close()).send().unwrap();
    let mut buffer = Vec::new();
    res.read_to_end(&mut buffer).unwrap();
    debug!("{:?}", res);
    let bencode = Bencode::decode(&buffer).unwrap();
    trace!("{:?}", bencode);
    let (_, peers) = CompactPeersV4::from_bytes(bencode.dict()
            .unwrap()
            .lookup("peers")
            .unwrap()
            .bytes()
            .unwrap())
        .unwrap();
    trace!("{:?}", peers);
    let mut ip_ports: Vec<String> = Vec::new();
    debug!("Peer list received:");
    for peer in peers.iter() {
        debug!("{:?}", peer);
        ip_ports.push(peer.to_string());
    }
    Ok((ip_ports, info_hash_str.to_string()))
}

fn peer_connections(peer_ip_ports: Vec<String>, info_hash: &str, peer_id: &str) -> Result<()> {
    for peer_ip_port in peer_ip_ports {
        let peer_ip_port_cl = peer_ip_port.clone();
        let info_hash_cl = info_hash.to_string().clone();
        let peer_id_cl = peer_id.to_string().clone();
        thread::spawn(move || {
            match handshake_peer(&peer_ip_port_cl, &info_hash_cl, &peer_id_cl) {
                Ok(mut stream) => {
                    debug!("Communicating with peer {:?}", peer_ip_port_cl);
                    let mut buff = [0; PEER_HANDSHAKE_STRUCT_SZ];
                    match stream.read(&mut buff) {
                        Ok(_) => {
                            // TODO determine the below three parameters logically
                            let index = 0;
                            let begin = 0;
                            let length = 10;
                            match request_piece(stream, index, begin, length) {
                                Ok(buf_read) => {
                                    debug!("buf_read: {:?}", buf_read);
                                }
                                Err(_) => error!("Requesting piece failed!"),
                            }
                        }
                        Err(e) => error!("Reading from the stream failed! {:?}", e),
                    }
                }
                Err(_) => {
                    error!("Closing thread with peer {:?}", peer_ip_port_cl);
                }
            }
        });
    }
    Ok(())
}

fn request_piece(mut stream: TcpStream, index: u32, begin: u32, length: u32) -> Result<Vec<u8>> {
    let mut buf = vec![0u8; PEER_REQ_PKT_SZ];
    let mut peer_msg_pkt = MutablePeerMessagePacket::new(&mut buf).unwrap();
    peer_msg_pkt.set_len(13);
    peer_msg_pkt.set_id(6);
    let mut index_begin_length: Vec<u32> = Vec::new();
    index_begin_length.push(index);
    index_begin_length.push(begin);
    index_begin_length.push(length);
    let byte_arr = unsafe { std::mem::transmute::<Vec<u32>, Vec<u8>>(index_begin_length) };

    peer_msg_pkt.set_payload(&byte_arr);

    match stream.write(peer_msg_pkt.packet()) {
        Ok(_) => {
            let mut buf_read = vec![0; 2048];
            match stream.read(&mut buf_read) {
                Ok(bytes_read) => {
                    debug!("Bytes read: {:?}", bytes_read);
                    Ok(buf_read[..bytes_read].to_vec())
                }
                Err(e) => {
                    // error!("Read failed! {:?}", e);
                    bail!("Read failed! {:?}", e)
                }
            }
        }
        Err(e) => {
            bail!("Write to stream failed! {:?}", e)
            // Err("Write to stream failed!".to_owned())
        }
    }
}

fn handshake_peer(peer_ip_port: &str, info_hash: &str, peer_id: &str) -> Result<TcpStream> {
    let mut buf = vec![0u8; PEER_HANDSHAKE_STRUCT_SZ];
    let mut ph = MutablePeerHandshakePacket::new(&mut buf).unwrap();
    ph.set_pstrlen("BitTorrent protocol".len() as u8);
    ph.set_pstr(&String::from("BitTorrent protocol").into_bytes());
    ph.set_reserved(&[0; 8]);
    ph.set_info_hash(info_hash.as_bytes());
    ph.set_peer_id(peer_id.as_bytes());
    match TcpStream::connect(peer_ip_port) {
        Ok(mut stream) => {
            debug!("Connection to peer {:?} successful!", peer_ip_port);
            match stream.write(ph.packet()) {
                Ok(_) => {
                    debug!("Sending message successful!");
                    trace!("{:?}", ph.packet());
                    Ok((stream))
                }
                Err(_) => {
                    bail!("Sending message failed!")
                    // Err("Sending message failed!".to_owned())
                }
            }
        }
        Err(e) => {
            bail!("Connection to peer {:?} failed! {:?}", peer_ip_port, e)
            // Err("Connection to peer failed!".to_owned())
        }
    }
}

fn main() {
    pretty_env_logger::init();

    // See: https://brson.github.io/2016/11/30/starting-with-error-chain for explanation
    if let Err(ref e) = run() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        ::std::process::exit(1);
    }
}

fn run() -> Result<()> {
    let mut rl = Editor::<()>::new();
    if rl.load_history(HISTORY_FILE).is_err() {
        info!("No previous history!");
    }

    let now = SystemTime::now();
    let duration = now.duration_since(UNIX_EPOCH).unwrap();
    let client_id = "-bittorrent-rs-".to_owned() + &format!("{}", duration.as_secs() % 100_000);

    loop {
        let readline = rl.readline("> ");
        match readline {
            Ok(cmd) => {
                rl.add_history_entry(&cmd);

                let cmd = cmd.trim().split(' ').collect::<Vec<&str>>();

                match cmd[0] {
                    "help" | "h" => {
                        println!("Commands:
parse/p <torrent file path>      - show Metainfo File Overview
connect/c <torrent file path>    - initiate connection to tracker, and handshake with peers
showfiles/sf <torrent file path> - show files in the torrent
help/h                           - show this help");
                    }
                    "parse" | "p" => {
                        if cmd.len() != 2 {
                            error!("usage: parse <torrent file>");
                        } else {
                            let path = cmd[1];
                            debug!("MetainfoFile: {:?}", path);

                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_metainfo_overview(&bytes)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "connect" | "c" => {
                        if cmd.len() != 2 {
                            error!("usage: connect <torrent file>");
                        } else {
                            let path = cmd[1];
                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();

                                    // TODO: generate peer ID
                                    let result =
                                        connect_to_tracker(MetainfoFile::from_bytes(&bytes)
                                                               .unwrap(),
                                                           &client_id,
                                                           6882)?;
                                    // .unwrap();
                                    peer_connections(result.0, &result.1, &client_id)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "showfiles" | "sf" => {
                        if cmd.len() != 2 {
                            error!("usage: showfiles <torrent file>");
                        } else {
                            let path = cmd[1];
                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_files(&bytes)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "" => {}
                    _ => {
                        println!("invalid command, see \"help\"");
                    }
                }
            }
            Err(ReadlineError::Interrupted) |
            Err(ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                error!("Error: {:?}", err);
                break;
            }
        }
    }
    rl.save_history(HISTORY_FILE).unwrap();
    Ok(())
}
<commit_msg>Remove annoying debug trace<commit_after>#![recursion_limit = "1024"]

#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate nom;

extern crate bip_bencode;
extern crate bip_metainfo;
extern crate bip_utracker;
extern crate bip_util;
extern crate chrono;
extern crate hyper;
extern crate pnet;
extern crate pnet_macros_support;
extern crate pretty_env_logger;
extern crate rustyline;
extern crate url;

mod btclient;
mod packet;

mod errors {
    // Create the Error, ErrorKind, ResultExt, and Result types
    error_chain!{}
}

use bip_bencode::Bencode;
use bip_metainfo::MetainfoFile;
use bip_utracker::contact::CompactPeersV4;
use errors::*;
use chrono::{TimeZone, UTC};
use hyper::Client;
use hyper::header::Connection;
use packet::peer_pkt::{MutablePeerHandshakePacket, MutablePeerMessagePacket};
use pnet::packet::Packet;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use url::Url;

use std::fs::File;
use std::io::prelude::*;
use std::net::TcpStream;
use std::str;
use std::string::String;
use std::time::{SystemTime, UNIX_EPOCH};
use std::thread;

const HISTORY_FILE: &'static str = ".rustyline.history";
const PEER_HANDSHAKE_STRUCT_SZ: usize = 68;
const PEER_REQ_PKT_SZ: usize = 14;

/// Print file list from the torrent.
fn print_files(bytes: &[u8]) -> Result<()> {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();

    println!("File List:");
    println!("Size (bytes)\tPath");
    println!("------------\t----------------------------------------------");
    for file in info.files() {
        println!("{:12}\t{}",
                 file.length(),
                 file.paths().next().unwrap_or("<unknown>"));
    }
    Ok(())
}

/// Print general information about the torrent.
fn print_metainfo_overview(bytes: &[u8]) -> Result<()> {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();
    let info_hash_hex = metainfo.info_hash()
        .as_ref()
        .iter()
        .map(|b| format!("{:02x}", b))
        .fold(String::new(), |mut acc, nex| {
            acc.push_str(&nex);
            acc
        });
    let utc_creation_date = metainfo.creation_date().map(|c| UTC.timestamp(c, 0));

    println!("------Metainfo File Overview-----");

    println!("InfoHash: {}", info_hash_hex);
    println!("Main Tracker: {:?}", metainfo.main_tracker());
    println!("Comment: {:?}", metainfo.comment());
    println!("Creator: {:?}", metainfo.created_by());
    println!("Creation Date: {:?}", utc_creation_date);

    println!("Directory: {:?}", info.directory());
    println!("Piece Length: {:?}", info.piece_length());
    println!("Number Of Pieces: {}", info.pieces().count());
    println!("Number Of Files: {}", info.files().count());
    println!("Total File Size: {}\n",
             info.files().fold(0, |acc, nex| acc + nex.length()));

    print_files(bytes)?;
    Ok(())
}

fn connect_to_tracker(metainfo: MetainfoFile,
                      peer_id: &str,
                      port: u16)
                      -> Result<(Vec<String>, String)> {
    debug!("connecting to tracker: {:?}", metainfo.main_tracker());

    let info_hash = metainfo.info_hash();
    // TODO figure can this conversion to url-encoded form be done safely?
    let info_hash_str = unsafe { str::from_utf8_unchecked(info_hash.as_ref()) };

    // TODO this needs to be calculated based on what we have
    let total_len = metainfo.info().files().fold(0, |acc, nex| acc + nex.length());

    let mut url = Url::parse(metainfo.main_tracker().unwrap()).unwrap();
    url.query_pairs_mut()
        .append_pair("info_hash", info_hash_str)
        .append_pair("peer_id", peer_id)
        .append_pair("port", &(port.to_string()))
        // TODO parametrize this
        .append_pair("uploaded", "0")
        // TODO parametrize this
        .append_pair("downloaded", "0")
        // TODO see note on total_len above
        .append_pair("left", &(total_len.to_string()))
        .append_pair("compact", "1")
        .append_pair("event", "started")
        .append_pair("supportcrypto", "0");
    trace!("URL {:?}", url);

    let client = Client::new();
    let mut res = client.get(url).header(Connection::close()).send().unwrap();
    let mut buffer = Vec::new();
    res.read_to_end(&mut buffer).unwrap();
    debug!("{:?}", res);
    let bencode = Bencode::decode(&buffer).unwrap();
    trace!("{:?}", bencode);
    let (_, peers) = CompactPeersV4::from_bytes(bencode.dict()
            .unwrap()
            .lookup("peers")
            .unwrap()
            .bytes()
            .unwrap())
        .unwrap();
    trace!("{:?}", peers);
    let mut ip_ports: Vec<String> = Vec::new();
    debug!("Peer list received:");
    for peer in peers.iter() {
        debug!("{:?}", peer);
        ip_ports.push(peer.to_string());
    }
    Ok((ip_ports, info_hash_str.to_string()))
}

fn peer_connections(peer_ip_ports: Vec<String>, info_hash: &str, peer_id: &str) -> Result<()> {
    for peer_ip_port in peer_ip_ports {
        let peer_ip_port_cl = peer_ip_port.clone();
        let info_hash_cl = info_hash.to_string().clone();
        let peer_id_cl = peer_id.to_string().clone();
        thread::spawn(move || {
            match handshake_peer(&peer_ip_port_cl, &info_hash_cl, &peer_id_cl) {
                Ok(mut stream) => {
                    debug!("Communicating with peer {:?}", peer_ip_port_cl);
                    let mut buff = [0; PEER_HANDSHAKE_STRUCT_SZ];
                    match stream.read(&mut buff) {
                        Ok(_) => {
                            // TODO determine the below three parameters logically
                            let index = 0;
                            let begin = 0;
                            let length = 10;
                            match request_piece(stream, index, begin, length) {
                                Ok(buf_read) => {
                                    trace!("buf_read: {:?}", buf_read);
                                }
                                Err(_) => error!("Requesting piece failed!"),
                            }
                        }
                        Err(e) => error!("Reading from the stream failed! {:?}", e),
                    }
                }
                Err(_) => {
                    error!("Closing thread with peer {:?}", peer_ip_port_cl);
                }
            }
        });
    }
    Ok(())
}

fn request_piece(mut stream: TcpStream, index: u32, begin: u32, length: u32) -> Result<Vec<u8>> {
    let mut buf = vec![0u8; PEER_REQ_PKT_SZ];
    let mut peer_msg_pkt = MutablePeerMessagePacket::new(&mut buf).unwrap();
    peer_msg_pkt.set_len(13);
    peer_msg_pkt.set_id(6);
    let mut index_begin_length: Vec<u32> = Vec::new();
    index_begin_length.push(index);
    index_begin_length.push(begin);
    index_begin_length.push(length);
    let byte_arr = unsafe { std::mem::transmute::<Vec<u32>, Vec<u8>>(index_begin_length) };

    peer_msg_pkt.set_payload(&byte_arr);

    match stream.write(peer_msg_pkt.packet()) {
        Ok(_) => {
            let mut buf_read = vec![0; 2048];
            match stream.read(&mut buf_read) {
                Ok(bytes_read) => {
                    debug!("Bytes read: {:?}", bytes_read);
                    Ok(buf_read[..bytes_read].to_vec())
                }
                Err(e) => {
                    // error!("Read failed! {:?}", e);
                    bail!("Read failed! {:?}", e)
                }
            }
        }
        Err(e) => {
            bail!("Write to stream failed! {:?}", e)
            // Err("Write to stream failed!".to_owned())
        }
    }
}

fn handshake_peer(peer_ip_port: &str, info_hash: &str, peer_id: &str) -> Result<TcpStream> {
    let mut buf = vec![0u8; PEER_HANDSHAKE_STRUCT_SZ];
    let mut ph = MutablePeerHandshakePacket::new(&mut buf).unwrap();
    ph.set_pstrlen("BitTorrent protocol".len() as u8);
    ph.set_pstr(&String::from("BitTorrent protocol").into_bytes());
    ph.set_reserved(&[0; 8]);
    ph.set_info_hash(info_hash.as_bytes());
    ph.set_peer_id(peer_id.as_bytes());
    match TcpStream::connect(peer_ip_port) {
        Ok(mut stream) => {
            debug!("Connection to peer {:?} successful!", peer_ip_port);
            match stream.write(ph.packet()) {
                Ok(_) => {
                    debug!("Sending message successful!");
                    trace!("{:?}", ph.packet());
                    Ok((stream))
                }
                Err(_) => {
                    bail!("Sending message failed!")
                    // Err("Sending message failed!".to_owned())
                }
            }
        }
        Err(e) => {
            bail!("Connection to peer {:?} failed! {:?}", peer_ip_port, e)
            // Err("Connection to peer failed!".to_owned())
        }
    }
}

fn main() {
    pretty_env_logger::init();

    // See: https://brson.github.io/2016/11/30/starting-with-error-chain for explanation
    if let Err(ref e) = run() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        ::std::process::exit(1);
    }
}

fn run() -> Result<()> {
    let mut rl = Editor::<()>::new();
    if rl.load_history(HISTORY_FILE).is_err() {
        info!("No previous history!");
    }

    let now = SystemTime::now();
    let duration = now.duration_since(UNIX_EPOCH).unwrap();
    let client_id = "-bittorrent-rs-".to_owned() + &format!("{}", duration.as_secs() % 100_000);

    loop {
        let readline = rl.readline("> ");
        match readline {
            Ok(cmd) => {
                rl.add_history_entry(&cmd);

                let cmd = cmd.trim().split(' ').collect::<Vec<&str>>();

                match cmd[0] {
                    "help" | "h" => {
                        println!("Commands:
parse/p <torrent file path>      - show Metainfo File Overview
connect/c <torrent file path>    - initiate connection to tracker, and handshake with peers
showfiles/sf <torrent file path> - show files in the torrent
help/h                           - show this help");
                    }
                    "parse" | "p" => {
                        if cmd.len() != 2 {
                            error!("usage: parse <torrent file>");
                        } else {
                            let path = cmd[1];
                            debug!("MetainfoFile: {:?}", path);

                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_metainfo_overview(&bytes)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "connect" | "c" => {
                        if cmd.len() != 2 {
                            error!("usage: connect <torrent file>");
                        } else {
                            let path = cmd[1];
                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();

                                    // TODO: generate peer ID
                                    let result =
                                        connect_to_tracker(MetainfoFile::from_bytes(&bytes)
                                                               .unwrap(),
                                                           &client_id,
                                                           6882)?;
                                    // .unwrap();
                                    peer_connections(result.0, &result.1, &client_id)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "showfiles" | "sf" => {
                        if cmd.len() != 2 {
                            error!("usage: showfiles <torrent file>");
                        } else {
                            let path = cmd[1];
                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_files(&bytes)?;
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    "" => {}
                    _ => {
                        println!("invalid command, see \"help\"");
                    }
                }
            }
            Err(ReadlineError::Interrupted) |
            Err(ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                error!("Error: {:?}", err);
                break;
            }
        }
    }
    rl.save_history(HISTORY_FILE).unwrap();
    Ok(())
}
<|endoftext|>


<commit_before>use std::process::{Command, exit};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    let keys:Vec<String> =
        vec!["AEFB411B072836CD48FF0381AE252C284B5DBA5D".to_string(),
             "9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0".to_string(),
             "35F52A02854DCCAEC9DD5CC410443C7F54B00041".to_string()];
    let keys_clone:Vec<String> = keys.clone();
    //let mut contents:Vec<String> = vec![];
    gpg_import_keys(keys);
    let init_check:bool = gpg_init();
    if !init_check{
        println!("Update has failed, after gpg keys have been imported.");
        println!("Ensure you run update with \"sudo\", or super user privileges");
        exit(1);
    }else {
        println!("GPG Init: Task Completed Successfully!");
    }
    gpg_remove_keys(keys_clone);
    let mut contents:Vec<String> = check_pacman_conf();
    let confold:bool = create_pacman_conf_old();
    create_new_pacman_conf(contents);
    let keyring:bool = archlabs_keyring();
    let populate:bool = key_populate();
    contents = pacman_conf_final();
    create_new_pacman_conf(contents);
    println!("The automated update portion of the process has completed!");
    println!("Please visit the ArchLABs Forums:");
    println!("https://www.tapatalk.com/groups/archlabs\
    /upgrade-guide-for-existing-installations-t432.html");
    println!("To continue with the manual steps in the process...");
}

fn gpg_import_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter(){
        let keys:String =
            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;
    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());
        check = true;
    }else {
        print!("Error: ");
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}

fn gpg_remove_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter() {
        let keys:String =
            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;
    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(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        println!("Back up of \"pacman.conf\" complete!");
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    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 _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 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;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = false;
    }
    return check;
}

fn key_populate() -> bool {
    let check:bool;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    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 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>Amend Path Location<commit_after>use std::process::{Command, exit};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    let keys:Vec<String> =
        vec!["AEFB411B072836CD48FF0381AE252C284B5DBA5D".to_string(),
             "9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0".to_string(),
             "35F52A02854DCCAEC9DD5CC410443C7F54B00041".to_string()];
    let keys_clone:Vec<String> = keys.clone();
    //let mut contents:Vec<String> = vec![];
    gpg_import_keys(keys);
    let init_check:bool = gpg_init();
    if !init_check{
        println!("Update has failed, after gpg keys have been imported.");
        println!("Ensure you run update with \"sudo\", or super user privileges");
        exit(1);
    }else {
        println!("GPG Init: Task Completed Successfully!");
    }
    gpg_remove_keys(keys_clone);
    let mut contents:Vec<String> = check_pacman_conf();
    let confold:bool = create_pacman_conf_old();
    create_new_pacman_conf(contents);
    let keyring:bool = archlabs_keyring();
    let populate:bool = key_populate();
    contents = pacman_conf_final();
    create_new_pacman_conf(contents);
    println!("The automated update portion of the process has completed!");
    println!("Please visit the ArchLABs Forums:");
    println!("https://www.tapatalk.com/groups/archlabs\
    /upgrade-guide-for-existing-installations-t432.html");
    println!("To continue with the manual steps in the process...");
}

fn gpg_import_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter(){
        let keys:String =
            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;
    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());
        check = true;
    }else {
        print!("Error: ");
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}

fn gpg_remove_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter() {
        let keys:String =
            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;
    let output = Command::new("mv")
        .arg("/etc/pacman.conf")
        .arg("/etc/pacman.conf.old")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        println!("Back up of \"pacman.conf\" complete!");
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}
//This function will be called on two separate iterations
fn create_new_pacman_conf(x:Vec<String>) {
    let path = Path::new("/etc/pacman.conf");
    let display = path.display();
    // Open a file in write-only mode, returns `io::Result<File>`
    let _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("/etc/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 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;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = false;
    }
    return check;
}

fn key_populate() -> bool {
    let check:bool;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    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 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|>


<commit_before>#[macro_use(println_stderr)]
extern crate webextension_protocol as protocol;
use std::io::Write;

#[macro_use]
extern crate js;
use js::jsapi::JS_NewGlobalObject;
use js::jsapi::CompartmentOptions;
use js::jsapi::OnNewGlobalHookOption;
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use js::rust::SIMPLE_GLOBAL_CLASS;
use js::conversions::latin1_to_string;
use std::ptr;

use std::thread;
use std::sync::mpsc;
use std::fs::File;
use std::io::Read;

fn main() {

    let (tx, rx) = mpsc::channel();
    let sender = tx.clone();

    // thread reads from stdin and send messages to main thread
    thread::spawn(move || {
        loop {
            let (io_sender, io_receiver) = mpsc::channel();
            let message = match protocol::read_stdin() {
                Ok(m) => m,
                Err(_) => panic!("nothing more to read"),
            };
            sender.send((io_sender, message)).unwrap();
            let response = io_receiver.recv().unwrap();
            protocol::write_stdout(response);
        }
    });

    let rt = Runtime::new();
    let cx = rt.cx();

    let mut scriptFile = File::open("scripts/concat.js").unwrap();
    let mut script = String::new();
    scriptFile.read_to_string(&mut script);

    unsafe {
        rooted!(in(cx) let global =
            JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                               OnNewGlobalHookOption::FireOnNewGlobalHook,
                               &CompartmentOptions::default())
        );

        rooted!(in(cx) let mut rval = UndefinedValue());
        rt.evaluate_script(global.handle(), script.as_str(),
            "scripts/concat.js", 0, rval.handle_mut());

        loop {
            let (io_sender, message) = rx.recv().unwrap();

            rooted!(in(cx) let mut rval = UndefinedValue());

            let wrapped_message = "concat('".to_string() + message.as_str() + "', '');";

            rt.evaluate_script(global.handle(), wrapped_message.as_str(),
                "incomming-messsage", 1, rval.handle_mut());

            if (rval.is_string()) {
                let js_string = rval.to_string();
                let response = latin1_to_string(cx, js_string);

                io_sender.send(response).unwrap();
            }
        }
    }
}
<commit_msg>Simple http proxy<commit_after>#[macro_use(println_stderr)]
extern crate webextension_protocol as protocol;
use std::io::Write;

#[macro_use]
extern crate js;
use js::jsapi::JS_NewGlobalObject;
use js::jsapi::CompartmentOptions;
use js::jsapi::OnNewGlobalHookOption;
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use js::rust::SIMPLE_GLOBAL_CLASS;
use js::conversions::latin1_to_string;
use std::ptr;

use std::thread;
use std::sync::mpsc;
use std::fs::File;
use std::io::Read;
use std::io::{copy};
use std::net::{TcpListener, TcpStream, Shutdown};

fn main() {

    let (tx, rx) = mpsc::channel();

    let sender_for_io = tx.clone();
    // thread reads from stdin and send messages to main thread
    thread::spawn(move || {
        loop {
            let (io_sender, io_receiver) = mpsc::channel();
            let message = match protocol::read_stdin() {
                Ok(m) => m,
                Err(_) => panic!("nothing more to read"),
            };
            sender_for_io.send((io_sender, message)).unwrap();
            let response = io_receiver.recv().unwrap();
            protocol::write_stdout(response);
        }
    });

    let sender_for_http = tx.clone();
    thread::spawn(move || {
        let mut listener = TcpListener::bind("127.0.0.1:1090").unwrap();
        let socket_name = listener.local_addr().unwrap();
        println_stderr!("Listening on: {}", socket_name);

        loop {
            match listener.accept() {
                Err(e) => {
                    println_stderr!("There was an error omg {}", e)
                }
                Ok((stream, remote)) => {
                    let sender_for_http = tx.clone();
                    thread::spawn(move || {
                        println_stderr!("got a connection");
                        let mut outbound = TcpStream::connect("35.187.22.222:80").unwrap();
                        let mut client_reader = stream.try_clone().unwrap();
                        let mut client_writer = stream.try_clone().unwrap();
                        let mut socket_reader = outbound.try_clone().unwrap();
                        let mut socket_writer = outbound.try_clone().unwrap();

                        thread::spawn(move || {
                            copy(&mut client_reader, &mut socket_writer);
                            client_reader.shutdown(Shutdown::Read);
                            socket_writer.shutdown(Shutdown::Write);
                        });

                        copy(&mut socket_reader, &mut client_writer);
                        socket_reader.shutdown(Shutdown::Read);
                        client_writer.shutdown(Shutdown::Write);
                    });
                }
            }
        }
    });

    let rt = Runtime::new();
    let cx = rt.cx();

    let mut scriptFile = File::open("scripts/concat.js").unwrap();
    let mut script = String::new();
    scriptFile.read_to_string(&mut script);

    unsafe {
        rooted!(in(cx) let global =
            JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                               OnNewGlobalHookOption::FireOnNewGlobalHook,
                               &CompartmentOptions::default())
        );

        rooted!(in(cx) let mut rval = UndefinedValue());
        rt.evaluate_script(global.handle(), script.as_str(),
            "scripts/concat.js", 0, rval.handle_mut());

        loop {
            let (io_sender, message) = rx.recv().unwrap();

            rooted!(in(cx) let mut rval = UndefinedValue());

            let wrapped_message = "concat('".to_string() + message.as_str() + "', '');";

            rt.evaluate_script(global.handle(), wrapped_message.as_str(),
                "incomming-messsage", 1, rval.handle_mut());

            if (rval.is_string()) {
                let js_string = rval.to_string();
                let response = latin1_to_string(cx, js_string);

                io_sender.send(response).unwrap();
            }
        }
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[cfg(test)]
extern crate float_cmp;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate derive_error_chain;

#[macro_use]
extern crate lazy_static;

extern crate clap;
extern crate combine;
extern crate conv;
extern crate itertools;
extern crate unicode_xid;
extern crate rustyline;

mod ast;
mod eval;
mod forms;
mod lexer;
mod parser;
mod ops;
mod token;
mod repl;
mod file;
mod error;

use error::*;

quick_main!(run);

use clap::{App, Arg};

fn run<'a>() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::from_usage("-i --interactive 'Run in interactive mode'"))
        .arg(Arg::from_usage("[input] 'Input file'"))
        .get_matches();

    let mut env = ops::env();

    if let Some(file) = matches.value_of("input") {
        file::run(file, &mut env)?;
    }

    // Run REPL if -i flag supplied or no arguments
    if matches.is_present("interactive") || !matches.is_present("input") {
        repl::repl(&mut env)?;
    }
    Ok(())
}
<commit_msg>Fix cli arg parsing<commit_after>#![recursion_limit = "1024"]
#[cfg(test)]
extern crate float_cmp;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate derive_error_chain;

#[macro_use]
extern crate lazy_static;

extern crate clap;
extern crate combine;
extern crate conv;
extern crate itertools;
extern crate unicode_xid;
extern crate rustyline;

mod ast;
mod eval;
mod forms;
mod lexer;
mod parser;
mod ops;
mod token;
mod repl;
mod file;
mod error;

use error::*;

quick_main!(run);

use clap::{App, Arg};

fn run<'a>() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::from_usage("-i --interactive 'Run in interactive mode'"))
        .arg(Arg::from_usage("[input] 'Read program from file (- for stdin)'"))
        .get_matches();

    let mut env = ops::env();

    if let Some(file) = matches.value_of("input") {
        if file == "-" {

        } else {
            file::run(file, &mut env)?;
        }
    }

    // Run REPL if -i flag supplied or no arguments
    if matches.is_present("interactive") || !matches.is_present("input") {
        repl::repl(&mut env)?;
    }
    Ok(())
}
<|endoftext|>