<commit_before>//! Implementation of a simple uTP client and server.
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate utp;
extern crate getopts;
extern crate daemonize;

use daemonize::{Daemonize};
use std::process;
use std::process::Command;
use std::thread;
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
use std::net;
use std::str;
use std::env;
use std::fs::File;
use std::path::Path;
use getopts::Options;

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options] REMOTE-LOCATION", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    use utp::{UtpStream, UtpListener, UtpSocket};
    use std::io::{stdin, stdout, stderr, Read, Write};

    // This example may run in either server or client mode.
    // Using an enum tends to make the code cleaner and easier to read.
    enum Mode {Server, Client}

    // Start logging
    env_logger::init().expect("Error starting logger");

    // Fetch arguments
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("o", "", "set output file name", "NAME");
    opts.optflag("s", "server", "server mode");
    opts.optflag("p", "port-range", "server listening port range");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    // Parse the mode argument
    let mode: Mode = match matches.opt_present("s") {
        true => Mode::Server,
        false => Mode::Client
    };

    match mode {
        Mode::Server => {
            // Create a listening stream
            let addr = "0.0.0.0:55000";
            let mut stream = UtpStream::bind(&addr).expect("Error binding stream");

            let mut f = File::open(input).unwrap();
            println!("{}", addr);

            let daemonize = Daemonize::new();

            let mut writer = stdout();
            let _ = writeln!(&mut stderr(), "Serving on {}", addr);

            // Create a reasonably sized buffer
            let mut payload = vec![0; 1024 * 1024];

            let mut startmagic = vec![0; 1];
            match stream.read(&mut startmagic) {
                Ok(1) => {
                    println!("got the magic.");
                }
                _ => {
                    panic!("uh oh.");
                }
            }

            // match daemonize.start() {
            //     Ok(_) => { let _ = writeln!(&mut stderr(), "daemonized"); }
            //     Err(e) => { let _ = writeln!(&mut stderr(), "RWRWARWARARRR"); }
            // }

            let mut total = 0;
            // Create a reasonably sized buffer
            let mut payload = vec![0; 1300];
            loop {
                match stream.write(&payload) {
                    Ok(written) => { print!("."); }
                    Err(e) => { panic!("{}", e); }
                }
            }
            // loop {
            //     match f.read(&mut payload) {
            //         Ok(read) => {
            //             println!("file read {}", read);
            //             match stream.write(&payload[0..read]) {
            //                 Ok(written) => {
            //                     total += written;
            //                     println!("written {}", total);
            //                 },
            //                 Err(e) => {
            //                     stream.close().expect("Error closing stream");
            //                     panic!("{}", e);
            //                 }
            //             }
            //         },
            //         Err(e) => {
            //             stream.close().expect("Error closing stream");
            //             panic!("{}", e);
            //         }
            //     }
            // }
            stream.close().expect("Error closing stream");
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(":").collect();
            let addr: String = sections[0].to_owned();
            let path: String = sections[1].to_owned();
            let cmd = format!("~/bin/shoop -s {}", path);
            println!("addr: {}, path: {}, cmd: {}", addr, path, cmd);

            // let output = Command::new("ssh")
            //                      .arg(addr.to_owned())
            //                      .arg(cmd)
            //                      .output()
            //                      .unwrap_or_else(|e| {
            //                          panic!("failed to execute process: {}", e);
            //                      });
            // let udp_addr = String::from_utf8_lossy(&output.stdout).trim().to_owned();
            //
            // // Create a stream and try to connect to the remote address
            // println!("shoop server told us to connect to {}", udp_addr);
            let mut stream = UtpStream::connect("144.76.81.4:55000").expect("Error connecting to remote peer");
            println!("initted.");

            // let mut f = File::create("outfile").unwrap();
            // println!("created file.");
            // Create a reasonably sized buffer
            let mut payload = vec![0; 1024 * 1024];

            stream.write(b"\x01");
            println!("write magic byte.");

            let mut total = 0;
            loop {
                match stream.read(&mut payload) {
                    Ok(0) => {
                        println!("EOF");
                        break
                    },
                    Ok(read) => {
                        total += read;
                        println!("read {}", total);
                        // f.write_all(&payload[0..read-1]);
                    },
                    Err(e) => {
                        stream.close().expect("Error closing stream");
                        panic!("{:?}", e);
                    }
                }
            }

            // Explicitly close the stream.
            stream.close().expect("Error closing stream");
        }
    }
}

<commit_msg>just try udp?<commit_after>//! Implementation of a simple uTP client and server.
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate utp;
extern crate getopts;
extern crate daemonize;

use daemonize::{Daemonize};
use std::process;
use std::process::Command;
use std::thread;
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr, UdpSocket};
use std::net;
use std::str;
use std::env;
use std::fs::File;
use std::path::Path;
use getopts::Options;

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options] REMOTE-LOCATION", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    use utp::{UtpStream, UtpListener, UtpSocket};
    use std::io::{stdin, stdout, stderr, Read, Write};

    // This example may run in either server or client mode.
    // Using an enum tends to make the code cleaner and easier to read.
    enum Mode {Server, Client}

    // Start logging
    env_logger::init().expect("Error starting logger");

    // Fetch arguments
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("o", "", "set output file name", "NAME");
    opts.optflag("s", "server", "server mode");
    opts.optflag("p", "port-range", "server listening port range");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    // Parse the mode argument
    let mode: Mode = match matches.opt_present("s") {
        true => Mode::Server,
        false => Mode::Client
    };

    match mode {
        Mode::Server => {
            // Create a listening stream
            let addr = "0.0.0.0:55000";
            let mut stream = UdpSocket::bind(&addr).expect("Error binding stream");

            let mut f = File::open(input).unwrap();
            println!("{}", addr);

            let daemonize = Daemonize::new();

            let mut writer = stdout();
            let _ = writeln!(&mut stderr(), "Serving on {}", addr);

            // Create a reasonably sized buffer
            let mut payload = vec![0; 1024 * 1024];

            let mut startmagic = vec![0; 1];
            let (amount_read, sender_address) = stream.recv_from(&mut startmagic).unwrap();
            println!("got {} magic byte(s) from {:?}.", amount_read, sender_address);

            // match daemonize.start() {
            //     Ok(_) => { let _ = writeln!(&mut stderr(), "daemonized"); }
            //     Err(e) => { let _ = writeln!(&mut stderr(), "RWRWARWARARRR"); }
            // }

            let mut total = 0;
            // Create a reasonably sized buffer
            let mut payload = vec![0; 1300];
            loop {
                match stream.send_to(&payload, sender_address) {
                    Ok(written) => { print!("."); }
                    Err(e) => { panic!("{}", e); }
                }
            }
            // loop {
            //     match f.read(&mut payload) {
            //         Ok(read) => {
            //             println!("file read {}", read);
            //             match stream.write(&payload[0..read]) {
            //                 Ok(written) => {
            //                     total += written;
            //                     println!("written {}", total);
            //                 },
            //                 Err(e) => {
            //                     stream.close().expect("Error closing stream");
            //                     panic!("{}", e);
            //                 }
            //             }
            //         },
            //         Err(e) => {
            //             stream.close().expect("Error closing stream");
            //             panic!("{}", e);
            //         }
            //     }
            // }
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(":").collect();
            let addr: String = sections[0].to_owned();
            let path: String = sections[1].to_owned();
            let cmd = format!("~/bin/shoop -s {}", path);
            println!("addr: {}, path: {}, cmd: {}", addr, path, cmd);

            // let output = Command::new("ssh")
            //                      .arg(addr.to_owned())
            //                      .arg(cmd)
            //                      .output()
            //                      .unwrap_or_else(|e| {
            //                          panic!("failed to execute process: {}", e);
            //                      });
            // let udp_addr = String::from_utf8_lossy(&output.stdout).trim().to_owned();
            //
            // // Create a stream and try to connect to the remote address
            // println!("shoop server told us to connect to {}", udp_addr);
            let mut stream = UdpSocket::bind("0.0.0.0:0").expect("Error connecting to remote peer");
            println!("initted.");

            // let mut f = File::create("outfile").unwrap();
            // println!("created file.");
            // Create a reasonably sized buffer
            let mut payload = vec![0; 1024 * 1024];
            stream.connect("144.76.81.4:55000");
            stream.send(b"\x01");
            println!("write magic byte.");

            let mut total = 0;
            loop {
                match stream.recv(&mut payload) {
                    Ok(0) => {
                        println!("EOF");
                        break
                    },
                    Ok(read) => {
                        total += read;
                        println!("read {}", total);
                        // f.write_all(&payload[0..read-1]);
                    },
                    Err(e) => {
                        panic!("{:?}", e);
                    }
                }
            }

            // Explicitly close the stream.
        }
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate peresil;

mod parser;
mod machine;

use std::fs::File;
use std::io::prelude::*;
use std::collections::BTreeMap;

use parser::Parser;
use machine::{Input, Output, Registers, Tile, Machine};

fn append_string(input: &mut Input, s: &str) {
    input.extend(s.chars().map(Tile::Letter));
}

fn append_zero_terminated_string(input: &mut Input, s: &str) {
    append_string(input, s);
    input.push(Tile::num(0));
}

// Given two zero-terminated words, output the word that is first in
// alphabetical order
fn level_36() -> (Input, Registers, Output) {
    let mut input = Vec::new();
    append_zero_terminated_string(&mut input, "aab");
    append_zero_terminated_string(&mut input, "aaa");

    let mut registers = BTreeMap::new();
    registers.insert(23, Tile::num(0));
    registers.insert(24, Tile::num(10));

    let mut output = Vec::new();
    append_string(&mut output, "aaa");

    (input, registers, output)
}

// Given numbers, output the digits of the numbers
fn level_38() -> (Input, Registers, Output) {
    let input = [33, 505, 7, 979].iter().cloned().map(Tile::num).collect();

    let mut registers = BTreeMap::new();
    registers.insert(9, Tile::num(0));
    registers.insert(10, Tile::num(10));
    registers.insert(11, Tile::num(100));

    let output = [3, 3, 5, 0, 5, 7, 9, 7, 9].iter().cloned().map(Tile::num).collect();

    (input, registers, output)
}

fn report_parsing_error(s: &str, offset: usize, errors: &[parser::Error]) {
    let upto = &s[..offset];
    let leading_nl = upto.rfind("\n").map(|x| x + 1).unwrap_or(0);
    let after = &s[offset..];
    let trailing_nl = after.find("\n").map(|x| x - 1).unwrap_or(after.len()) + offset;

    let line = &s[leading_nl..trailing_nl];
    let inner_offset = offset - leading_nl;

    println!("Error occured while parsing:");
    println!("{}", line);
    for _ in 0..inner_offset { print!(" ") }
    println!("^");
    println!("{:?}", errors);
}

fn main() {
    let level = ::std::env::args().nth(1).expect("level").parse().expect("level number");
    let fname = ::std::env::args().nth(2).expect("filename");
    let mut f = File::open(fname).expect("File?");

    let mut s = String::new();
    f.read_to_string(&mut s).expect("read");

    let t = Parser::new(&s);

    let p = match t.collect() {
        Ok(p) => p,
        Err((offset, errors)) => {
            report_parsing_error(&s, offset, &errors);
            return;
        },
    };

    let (input, registers, output) = match level {
        36 => level_36(),
        38 => level_38(),
        _ => panic!("Unknown level {}", level),
    };
    let mut m = Machine::new(p, input, registers);

    match m.run() {
        Ok(..) => {
            let actual_output = m.into_output();
            println!("Program completed");
            if actual_output == output {
                println!("Output matched!");
            } else {
                println!("Output did not match");
                println!("Expected: {:?}", output);
                println!("Got:      {:?}", actual_output);
            }
        },
        Err(e) => {
            println!("Program failed");
            println!("{:?}", e);
        }
    }
}
<commit_msg>Add level 37<commit_after>#[macro_use]
extern crate peresil;

mod parser;
mod machine;

use std::fs::File;
use std::io::prelude::*;
use std::collections::BTreeMap;

use parser::Parser;
use machine::{Input, Output, Registers, Tile, Machine};

fn append_string(input: &mut Input, s: &str) {
    input.extend(s.chars().map(Tile::Letter));
}

fn append_zero_terminated_string(input: &mut Input, s: &str) {
    append_string(input, s);
    input.push(Tile::num(0));
}

// Given two zero-terminated words, output the word that is first in
// alphabetical order
fn level_36() -> (Input, Registers, Output) {
    let mut input = Vec::new();
    append_zero_terminated_string(&mut input, "aab");
    append_zero_terminated_string(&mut input, "aaa");

    let mut registers = BTreeMap::new();
    registers.insert(23, Tile::num(0));
    registers.insert(24, Tile::num(10));

    let mut output = Vec::new();
    append_string(&mut output, "aaa");

    (input, registers, output)
}

fn level_37() -> (Input, Registers, Output) {
    let input = [0, 23].iter().cloned().map(Tile::num).collect();

    let mut registers = BTreeMap::new();
    let z = [
        (0, 'e', 13),
        (3, 'c', 23),
        (10, 'p', 20),
        (13, 's', 3),
        (20, 'e', -1),
        (23, 'a', 10),
    ];
    for &(idx, c, v) in &z {
        registers.insert(idx, Tile::Letter(c));
        registers.insert(idx + 1, Tile::num(v));
    }

    let mut output = Vec::new();
    append_string(&mut output, "escapeape");

    (input, registers, output)
}

// Given numbers, output the digits of the numbers
fn level_38() -> (Input, Registers, Output) {
    let input = [33, 505, 7, 979].iter().cloned().map(Tile::num).collect();

    let mut registers = BTreeMap::new();
    registers.insert(9, Tile::num(0));
    registers.insert(10, Tile::num(10));
    registers.insert(11, Tile::num(100));

    let output = [3, 3, 5, 0, 5, 7, 9, 7, 9].iter().cloned().map(Tile::num).collect();

    (input, registers, output)
}

fn report_parsing_error(s: &str, offset: usize, errors: &[parser::Error]) {
    let upto = &s[..offset];
    let leading_nl = upto.rfind("\n").map(|x| x + 1).unwrap_or(0);
    let after = &s[offset..];
    let trailing_nl = after.find("\n").map(|x| x - 1).unwrap_or(after.len()) + offset;

    let line = &s[leading_nl..trailing_nl];
    let inner_offset = offset - leading_nl;

    println!("Error occured while parsing:");
    println!("{}", line);
    for _ in 0..inner_offset { print!(" ") }
    println!("^");
    println!("{:?}", errors);
}

fn main() {
    let level = ::std::env::args().nth(1).expect("level").parse().expect("level number");
    let fname = ::std::env::args().nth(2).expect("filename");
    let mut f = File::open(fname).expect("File?");

    let mut s = String::new();
    f.read_to_string(&mut s).expect("read");

    let t = Parser::new(&s);

    let p = match t.collect() {
        Ok(p) => p,
        Err((offset, errors)) => {
            report_parsing_error(&s, offset, &errors);
            return;
        },
    };

    let (input, registers, output) = match level {
        36 => level_36(),
        37 => level_37(),
        38 => level_38(),
        _ => panic!("Unknown level {}", level),
    };
    let mut m = Machine::new(p, input, registers);

    match m.run() {
        Ok(..) => {
            let actual_output = m.into_output();
            println!("Program completed");
            if actual_output == output {
                println!("Output matched!");
            } else {
                println!("Output did not match");
                println!("Expected: {:?}", output);
                println!("Got:      {:?}", actual_output);
            }
        },
        Err(e) => {
            println!("Program failed");
            println!("{:?}", e);
        }
    }
}
<|endoftext|>


<commit_before>mod git;
mod remotes;

use clap::{App, Arg};
use log::{debug, info};
use std::process;

/// Get the `origin` remote
fn get_origin() -> String {
    git::get_repo_info("remote.origin.url")
}

/// Check out the branch corresponding to the MR ID
fn checkout_mr(mr_id: i64) {
    info!("Getting MR: {}", mr_id);
    let origin = get_origin();
    let mut remote = match remotes::get_remote(&origin) {
        Ok(x) => x,
        Err(error) => panic!(
            "There was a problem finding the remote Git repo: {:?}",
            error
        ),
    };
    debug!("Found remote: {}", remote);
    let branch_name = remote.get_req_branch(mr_id);
    debug!("Got branch name: {}", branch_name);
    match git::checkout_branch(&branch_name) {
        Ok(_) => {
            info!("Done!");
        }
        Err(error) => {
            eprintln!("There was an error checking out the branch: {:?}", &error);
            process::exit(1)
        }
    };
}

/// Do the thing
fn main() {
    let _ = env_logger::try_init();
    let matches = App::new("git-req")
        .version("0.1")
        .author("Aru Sahni <arusahni@gmail.com>")
        .about(
            "Switch between merge/pull requests in your GitLab/GitHub repositories with just the request ID.",
        )
        .arg(Arg::with_name("REQUEST_ID").required(true).index(1))
        .get_matches();
    checkout_mr(matches.value_of("REQUEST_ID").unwrap().parse().unwrap());
}
<commit_msg>Add a crate level docstring to trigger CI builds.<commit_after>///! GIT REQ!
mod git;
mod remotes;

use clap::{App, Arg};
use log::{debug, info};
use std::process;

/// Get the `origin` remote
fn get_origin() -> String {
    git::get_repo_info("remote.origin.url")
}

/// Check out the branch corresponding to the MR ID
fn checkout_mr(mr_id: i64) {
    info!("Getting MR: {}", mr_id);
    let origin = get_origin();
    let mut remote = match remotes::get_remote(&origin) {
        Ok(x) => x,
        Err(error) => panic!(
            "There was a problem finding the remote Git repo: {:?}",
            error
        ),
    };
    debug!("Found remote: {}", remote);
    let branch_name = remote.get_req_branch(mr_id);
    debug!("Got branch name: {}", branch_name);
    match git::checkout_branch(&branch_name) {
        Ok(_) => {
            info!("Done!");
        }
        Err(error) => {
            eprintln!("There was an error checking out the branch: {:?}", &error);
            process::exit(1)
        }
    };
}

/// Do the thing
fn main() {
    let _ = env_logger::try_init();
    let matches = App::new("git-req")
        .version("0.1")
        .author("Aru Sahni <arusahni@gmail.com>")
        .about(
            "Switch between merge/pull requests in your GitLab/GitHub repositories with just the request ID.",
        )
        .arg(Arg::with_name("REQUEST_ID").required(true).index(1))
        .get_matches();
    checkout_mr(matches.value_of("REQUEST_ID").unwrap().parse().unwrap());
}
<|endoftext|>


<commit_before>//Copyright (c) 2016, Ruslan Baratov, Alex Frappier Lachapelle
//All rights reserved.

use std::error::Error;
use std::fs;
use std::fs::OpenOptions;
use std::path::{Path, PathBuf};
use std::str::FromStr;

extern crate clap;
use clap::{Arg, App};

#[macro_use]
extern crate log;
use log::LogLevelFilter;

extern crate hyper;

mod commands;
mod config;
mod logger;
mod webhooks;

include!("logger_macros.rs");

////////////////////////////////////////////////////////////
//                          Funcs                         //
////////////////////////////////////////////////////////////

//Utils
//NOTE: No logging here, these functions fire before logger is initialized
fn file_path_validator(file_path: String) -> Result<(), String> {
    match OpenOptions::new().read(true).write(true).create(true).open(Path::new(&file_path)) {
        Ok(_)    => Ok(()),
        Err(err) => {Err(format!("Cannot open file \"{}\" due to an error: \"{}\"", file_path.as_str(), err.description()))}
    }
}

fn dir_path_validator(dir_path: String) -> Result<(), String> {

    //Check if it's even a directory.
    match fs::metadata(&dir_path) {
        Ok(metadata) => {
            if !metadata.is_dir() {
                let mut err_string = "\"".to_string();
                err_string.push_str(dir_path.as_str());
                err_string.push_str("\" is not a directory.");
                return Err(err_string);
            }
        },
        Err(err)     => {
            let mut err_string = "Failed to acquire metadata for \"".to_string();
            err_string.push_str(dir_path.as_str());
            err_string.push_str("\": ");
            err_string.push_str(err.description());
            return Err(err_string);
        }
    }

    //Test if we can write a file to this directory
    let mut counter = 0;
    loop {
        //Generate a file name.
        let mut tmp_file_path:     String = dir_path.clone();
        let     tmp_file_name:     String = format!("ab{}ba.tmp", counter);
        let     tmp_file_path_buf: PathBuf;
        tmp_file_path.push_str(tmp_file_name.as_str());
        tmp_file_path_buf = PathBuf::from(&tmp_file_path);

        //If file does not exist, check if we can create it with r/w permissions.
        if !tmp_file_path_buf.exists() {
            match OpenOptions::new().read(true).write(true).create(true).open(&tmp_file_path_buf.as_path()) {
                Ok(_)    => {
                    match fs::remove_file(&tmp_file_path_buf) {
                        Ok(_)    => return Ok(()),
                        Err(err) => {
                            let mut err_string = "Failed to delete temporary file: \"".to_string();
                            err_string.push_str(&tmp_file_path);
                            err_string.push_str("\": ");
                            err_string.push_str(err.description());
                            return Err(err_string);
                        }
                    }
                }
                Err(err) => {
                    let mut err_string = "Invalid directory: \"".to_string();
                    err_string.push_str(err.description());
                    err_string.push_str("\"");
                    return Err(err_string);
                }
            }
        }
        counter += 1;
    }
}

fn max_log_level_validator(max_log_level: String) -> Result<(), String> {
    match &max_log_level.to_lowercase()[..] {
        "off"   => return Ok(()),
        "error" => return Ok(()),
        "warn"  => return Ok(()),
        "info"  => return Ok(()),
        "debug" => return Ok(()),
        "trace" => return Ok(()),
        _       => return Err(String::from("Invalid log level"))
    }
}

fn log_size_validator(log_size: String) -> Result<(), String> {
    match u64::from_str(&log_size[..]) {
        Ok(_)    => return Ok(()),
        Err(err) => return Err(format!("Failed to parse the log size: {}", err.description()))
    }
}

////////////////////////////////////////////////////////////
//                          Main                          //
////////////////////////////////////////////////////////////

fn main() {

    let hunterbot_version = "0.1.0";
    let matches           = App::new("HunterBot")
    .version(hunterbot_version)
    .arg(Arg::with_name("CONFIG")
        .short("c")
        .long("config")
        .help("Sets a custom file path for the config.")
        .validator(file_path_validator)
        .takes_value(true))
    .arg(Arg::with_name("LOG")
        .short("l")
        .long("log-dir")
        .help("Sets a custom directory path for the log.")
        .validator(dir_path_validator)
        .takes_value(true))
    .arg(Arg::with_name("MAXLOGLEVEL")
        .short("m")
        .long("max-log-level")
        .help("Sets the maximum logging level, \"Info\" is the default, valid values are (in increasing order): error, warn, info, debug, trace.")
        .validator(max_log_level_validator)
        .takes_value(true))
    .arg(Arg::with_name("LOGSIZE")
        .short("s")
        .long("log-size")
        .help("Sets the maximum log file (in MB) before being rotated.")
        .validator(log_size_validator)
        .takes_value(true))
    .get_matches();

    let hunterbot_config_path = matches.value_of("CONFIG").unwrap_or("./HunterBotConfig.toml");
    let hunterbot_log_dir     = matches.value_of("LOG").unwrap_or("./");
    let log_size              = u64::from_str(matches.value_of("LOGSIZE").unwrap_or("5")).unwrap();
    let max_log_level         = match matches.value_of("MAXLOGLEVEL").unwrap_or("info") {
        "error" => LogLevelFilter::Error,
        "warn"  => LogLevelFilter::Warn,
        "info"  => LogLevelFilter::Info,
        "debug" => LogLevelFilter::Debug,
        "trace" => LogLevelFilter::Trace,
        _       => LogLevelFilter::Error
    };

    //Start logger
    let (logger, rx) = logger::Logger::new(&max_log_level);
    match logger::Logger::init(logger, max_log_level) {
        Ok(())   => (),
        Err(err) => {panic!("Failed to initialize the logger: {}", err);}
    }
    logger::Logger::process_logs(rx, PathBuf::from(hunterbot_log_dir), log_size);

    thread_info!("Logger booted.");
    thread_debug!("matches: {:?}", matches);
    thread_debug!("hunterbot_config_path: {}", hunterbot_config_path);
    thread_debug!("hunterbot_log_dir: {}", hunterbot_log_dir);
    thread_debug!("log_size: {}", log_size);
    thread_debug!("max_log_level: {}", max_log_level);

    //Load config
    let mut config = config::ConfigHandler::new();

    thread_info!("Opening config...");
    match config.load(&hunterbot_config_path.to_string()) {
        Ok(())   => {thread_info!("Success!");}
        Err(err) => {thread_crash!("Error loading the config: {}", err);}
    }

    config.validate();

    //Setup webhooks
    webhooks::register(&mut config);

    //Listen for/process webhooks
    webhooks::listen(&mut config);
}
<commit_msg>Removed "off" log level from log level validation<commit_after>//Copyright (c) 2016, Ruslan Baratov, Alex Frappier Lachapelle
//All rights reserved.

use std::error::Error;
use std::fs;
use std::fs::OpenOptions;
use std::path::{Path, PathBuf};
use std::str::FromStr;

extern crate clap;
use clap::{Arg, App};

#[macro_use]
extern crate log;
use log::LogLevelFilter;

extern crate hyper;

mod commands;
mod config;
mod logger;
mod webhooks;

include!("logger_macros.rs");

////////////////////////////////////////////////////////////
//                          Funcs                         //
////////////////////////////////////////////////////////////

//Utils
//NOTE: No logging here, these functions fire before logger is initialized
fn file_path_validator(file_path: String) -> Result<(), String> {
    match OpenOptions::new().read(true).write(true).create(true).open(Path::new(&file_path)) {
        Ok(_)    => Ok(()),
        Err(err) => {Err(format!("Cannot open file \"{}\" due to an error: \"{}\"", file_path.as_str(), err.description()))}
    }
}

fn dir_path_validator(dir_path: String) -> Result<(), String> {

    //Check if it's even a directory.
    match fs::metadata(&dir_path) {
        Ok(metadata) => {
            if !metadata.is_dir() {
                let mut err_string = "\"".to_string();
                err_string.push_str(dir_path.as_str());
                err_string.push_str("\" is not a directory.");
                return Err(err_string);
            }
        },
        Err(err)     => {
            let mut err_string = "Failed to acquire metadata for \"".to_string();
            err_string.push_str(dir_path.as_str());
            err_string.push_str("\": ");
            err_string.push_str(err.description());
            return Err(err_string);
        }
    }

    //Test if we can write a file to this directory
    let mut counter = 0;
    loop {
        //Generate a file name.
        let mut tmp_file_path:     String = dir_path.clone();
        let     tmp_file_name:     String = format!("ab{}ba.tmp", counter);
        let     tmp_file_path_buf: PathBuf;
        tmp_file_path.push_str(tmp_file_name.as_str());
        tmp_file_path_buf = PathBuf::from(&tmp_file_path);

        //If file does not exist, check if we can create it with r/w permissions.
        if !tmp_file_path_buf.exists() {
            match OpenOptions::new().read(true).write(true).create(true).open(&tmp_file_path_buf.as_path()) {
                Ok(_)    => {
                    match fs::remove_file(&tmp_file_path_buf) {
                        Ok(_)    => return Ok(()),
                        Err(err) => {
                            let mut err_string = "Failed to delete temporary file: \"".to_string();
                            err_string.push_str(&tmp_file_path);
                            err_string.push_str("\": ");
                            err_string.push_str(err.description());
                            return Err(err_string);
                        }
                    }
                }
                Err(err) => {
                    let mut err_string = "Invalid directory: \"".to_string();
                    err_string.push_str(err.description());
                    err_string.push_str("\"");
                    return Err(err_string);
                }
            }
        }
        counter += 1;
    }
}

fn max_log_level_validator(max_log_level: String) -> Result<(), String> {
    match &max_log_level.to_lowercase()[..] {
        "error" => return Ok(()),
        "warn"  => return Ok(()),
        "info"  => return Ok(()),
        "debug" => return Ok(()),
        "trace" => return Ok(()),
        _       => return Err(String::from("Invalid log level"))
    }
}

fn log_size_validator(log_size: String) -> Result<(), String> {
    match u64::from_str(&log_size[..]) {
        Ok(_)    => return Ok(()),
        Err(err) => return Err(format!("Failed to parse the log size: {}", err.description()))
    }
}

////////////////////////////////////////////////////////////
//                          Main                          //
////////////////////////////////////////////////////////////

fn main() {

    let hunterbot_version = "0.1.0";
    let matches           = App::new("HunterBot")
    .version(hunterbot_version)
    .arg(Arg::with_name("CONFIG")
        .short("c")
        .long("config")
        .help("Sets a custom file path for the config.")
        .validator(file_path_validator)
        .takes_value(true))
    .arg(Arg::with_name("LOG")
        .short("l")
        .long("log-dir")
        .help("Sets a custom directory path for the log.")
        .validator(dir_path_validator)
        .takes_value(true))
    .arg(Arg::with_name("MAXLOGLEVEL")
        .short("m")
        .long("max-log-level")
        .help("Sets the maximum logging level, \"Info\" is the default, valid values are (in increasing order): error, warn, info, debug, trace.")
        .validator(max_log_level_validator)
        .takes_value(true))
    .arg(Arg::with_name("LOGSIZE")
        .short("s")
        .long("log-size")
        .help("Sets the maximum log file (in MB) before being rotated.")
        .validator(log_size_validator)
        .takes_value(true))
    .get_matches();

    let hunterbot_config_path = matches.value_of("CONFIG").unwrap_or("./HunterBotConfig.toml");
    let hunterbot_log_dir     = matches.value_of("LOG").unwrap_or("./");
    let log_size              = u64::from_str(matches.value_of("LOGSIZE").unwrap_or("5")).unwrap();
    let max_log_level         = match matches.value_of("MAXLOGLEVEL").unwrap_or("info") {
        "error" => LogLevelFilter::Error,
        "warn"  => LogLevelFilter::Warn,
        "info"  => LogLevelFilter::Info,
        "debug" => LogLevelFilter::Debug,
        "trace" => LogLevelFilter::Trace,
        _       => LogLevelFilter::Error
    };

    //Start logger
    let (logger, rx) = logger::Logger::new(&max_log_level);
    match logger::Logger::init(logger, max_log_level) {
        Ok(())   => (),
        Err(err) => {panic!("Failed to initialize the logger: {}", err);}
    }
    logger::Logger::process_logs(rx, PathBuf::from(hunterbot_log_dir), log_size);

    thread_info!("Logger booted.");
    thread_debug!("matches: {:?}", matches);
    thread_debug!("hunterbot_config_path: {}", hunterbot_config_path);
    thread_debug!("hunterbot_log_dir: {}", hunterbot_log_dir);
    thread_debug!("log_size: {}", log_size);
    thread_debug!("max_log_level: {}", max_log_level);

    //Load config
    let mut config = config::ConfigHandler::new();

    thread_info!("Opening config...");
    match config.load(&hunterbot_config_path.to_string()) {
        Ok(())   => {thread_info!("Success!");}
        Err(err) => {thread_crash!("Error loading the config: {}", err);}
    }

    config.validate();

    //Setup webhooks
    webhooks::register(&mut config);

    //Listen for/process webhooks
    webhooks::listen(&mut config);
}
<|endoftext|>


<commit_before>extern crate serde_json;
extern crate clap;

use serde_json::Value;
use serde_json::Deserializer;
use std::io::{self, Write};
use clap::{App, Arg};
use std::fs;
use std::result;
use std::error::Error;
use std::vec::Vec;
use std::string::String;

type Result<T> = result::Result<T, Box<Error>>;

fn run() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about("Extract JSON elements from a stream via JSON Pointers")
        .arg(Arg::with_name("INPUT")
            .short("i")
            .long("input")
            .takes_value(true)
            .help("input file to use if not receiving on stdin"))
        .arg(Arg::with_name("POINTER")
            .required(true)
            .multiple(true)
            .help("JSON Pointer expressions to match on input"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap_or("-");
    let rdr: Box<io::Read> = match input {
        "-" => Box::new(io::stdin()),
        _ => Box::new(try!(fs::File::open(input))),
    };

    let mut pointers = Vec::new();
    // unwrap is safe as POINTER is required
    for p in matches.values_of("POINTER").unwrap() {
        pointers.push(p);
    }

    let iter = Deserializer::from_reader(rdr).into_iter::<Value>();
    for rv in iter {
        let v: Value = try!(rv);
        let mut line = String::new();
        for p in &pointers {
            line.push_str(&render(v.pointer(p).unwrap_or(&Value::Null)));
            line.push('\t');
        }
        line.pop();
        println!("{}", line);
    }
    Ok(())
}

fn main() {
    match run() {
        Ok(_) => {}
        Err(e) => {
            writeln!(&mut io::stderr(), "error: {}", e).unwrap();
            std::process::exit(1);
        }
    }
}

fn render(v: &Value) -> String {
    match v {
        &Value::Null => String::new(),
        &Value::Bool(ref b) => format!("{}", b),
        &Value::Number(ref b) => format!("{}", b),
        &Value::String(ref s) => format!("{}", s),
        &Value::Array(_) => format!("{}", v),
        &Value::Object(_) => format!("{}", v),
    }
}
<commit_msg>Configurable Delimiter<commit_after>extern crate serde_json;
extern crate clap;

use serde_json::Value;
use serde_json::Deserializer;
use std::io::{self, Write};
use clap::{App, Arg};
use std::fs;
use std::result;
use std::error::Error;
use std::vec::Vec;
use std::string::String;

type Result<T> = result::Result<T, Box<Error>>;

fn run() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about("Extract JSON elements from a stream via JSON Pointers")
        .arg(Arg::with_name("INPUT")
            .short("i")
            .long("input")
            .takes_value(true)
            .help("input file to use if not receiving on stdin"))
        .arg(Arg::with_name("DELIMITER")
            .short("d")
            .long("delimiter")
            .takes_value(true)
            .help("delimiter between output values, default is tab"))
        .arg(Arg::with_name("POINTER")
            .required(true)
            .multiple(true)
            .help("JSON Pointer expressions to match on input"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap_or("-");
    let rdr: Box<io::Read> = match input {
        "-" => Box::new(io::stdin()),
        _ => Box::new(try!(fs::File::open(input))),
    };

    let delim = matches.value_of("DELIMITER").unwrap_or("\t");

    let mut pointers = Vec::new();
    // unwrap is safe as POINTER is required
    for p in matches.values_of("POINTER").unwrap() {
        pointers.push(p);
    }

    let iter = Deserializer::from_reader(rdr).into_iter::<Value>();
    for rv in iter {
        let v = try!(rv);
        let mut line = String::new();
        for p in &pointers {
            line.push_str(&render(v.pointer(p).unwrap_or(&Value::Null)));
            line.push_str(delim);
        }
        line.pop(); // remove the final tab
        println!("{}", line);
    }
    Ok(())
}

fn main() {
    match run() {
        Ok(_) => {}
        Err(e) => {
            writeln!(&mut io::stderr(), "error: {}", e).unwrap();
            std::process::exit(1);
        }
    }
}

fn render(v: &Value) -> String {
    match v {
        &Value::Null => String::new(),
        &Value::Bool(ref b) => format!("{}", b),
        &Value::Number(ref b) => format!("{}", b),
        &Value::String(ref s) => format!("{}", s),
        &Value::Array(_) => format!("{}", v),
        &Value::Object(_) => format!("{}", v),
    }
}
<|endoftext|>


<commit_before>use clap::{AppSettings, Parser};

fn main() {
    let args = Args::parse();
    let files = match get_corpus_files(&args.files) {
        Ok(files) => files,
        Err(error) => {
            eprintln!("{}", error);
            std::process::exit(1);
        }
    };
    let gen_passphrase_options = markovpass::GenPassphraseOptions {
        files,
        number: args.number,
        min_entropy: args.min_entropy,
        ngram_length: args.ngram_length,
        min_word_length: args.min_word_length,
    };
    let passphrases = match markovpass::gen_passphrases(&gen_passphrase_options) {
        Ok(passphrases) => passphrases,
        Err(error) => {
            eprintln!("{}", error);
            std::process::exit(1);
        }
    };

    for (passphrase, entropy) in passphrases {
        if args.show_entropy {
            println!("{} <{}>", passphrase, entropy);
        } else {
            println!("{}", passphrase);
        }
    }
}

#[derive(Parser, Debug, Clone)]
#[clap(version, about, setting = AppSettings::DeriveDisplayOrder)]
struct Args {
    /// Files to use as markov chain input corpus. Use '-' to read from stdin
    #[clap(value_parser)]
    pub files: Vec<String>,

    /// Number of passphrases to generate
    #[clap(short = 'n', value_parser, default_value_t = 1)]
    pub number: usize,

    /// Minimum entropy
    #[clap(short = 'e', value_parser, default_value_t = 60.0)]
    pub min_entropy: f64,

    /// Ngram length
    #[clap(short = 'l', value_parser, default_value_t = 3)]
    pub ngram_length: usize,

    /// Minimum word length for corpus
    #[clap(short = 'w', value_parser, default_value_t = 5)]
    pub min_word_length: usize,

    /// Print the entropy for each passphrase
    #[clap(long, value_parser, default_value_t = false)]
    pub show_entropy: bool,
}

fn get_corpus_files(files: &[String]) -> std::io::Result<Vec<std::path::PathBuf>> {
    match files {
        [] => get_data_files(),
        [x] if x == "-" => Ok(vec![]),
        _ => Ok(files.iter().map(|f| f.into()).collect()),
    }
}

fn get_data_files() -> std::io::Result<Vec<std::path::PathBuf>> {
    let mut data_dirs = directories::ProjectDirs::from_path("markovpass".into())
        .map(|pds| vec![pds.data_dir().to_path_buf()])
        .unwrap_or_else(|| vec![]);
    if cfg!(target_os = "linux") {
        data_dirs.extend(
            std::env::var("XDG_DATA_DIRS")
                .unwrap_or("/usr/local/share/:/usr/share/".to_string())
                .split(":")
                .map(|s| std::path::PathBuf::from(s).join("markovpass")),
        );
    }
    for dir in &data_dirs {
        if dir.exists() {
            let entries = std::fs::read_dir(dir)?.collect::<Result<Vec<_>, _>>()?;
            let paths: Vec<_> = entries
                .into_iter()
                .map(|entry| entry.path())
                .filter(|path| path.is_file())
                .collect();
            if !paths.is_empty() {
                return Ok(paths);
            }
        }
    }
    Err(std::io::Error::new(
        std::io::ErrorKind::NotFound,
        format!(
            "No corpus data found in any of {}.",
            data_dirs
                .iter()
                .map(|p| p.to_string_lossy())
                .collect::<Vec<_>>()
                .join(", ")
        ),
    ))
}
<commit_msg>Fix clippy complaints<commit_after>use clap::{AppSettings, Parser};

fn main() {
    let args = Args::parse();
    let files = match get_corpus_files(&args.files) {
        Ok(files) => files,
        Err(error) => {
            eprintln!("{}", error);
            std::process::exit(1);
        }
    };
    let gen_passphrase_options = markovpass::GenPassphraseOptions {
        files,
        number: args.number,
        min_entropy: args.min_entropy,
        ngram_length: args.ngram_length,
        min_word_length: args.min_word_length,
    };
    let passphrases = match markovpass::gen_passphrases(&gen_passphrase_options) {
        Ok(passphrases) => passphrases,
        Err(error) => {
            eprintln!("{}", error);
            std::process::exit(1);
        }
    };

    for (passphrase, entropy) in passphrases {
        if args.show_entropy {
            println!("{} <{}>", passphrase, entropy);
        } else {
            println!("{}", passphrase);
        }
    }
}

#[derive(Parser, Debug, Clone)]
#[clap(version, about, setting = AppSettings::DeriveDisplayOrder)]
struct Args {
    /// Files to use as markov chain input corpus. Use '-' to read from stdin
    #[clap(value_parser)]
    pub files: Vec<String>,

    /// Number of passphrases to generate
    #[clap(short = 'n', value_parser, default_value_t = 1)]
    pub number: usize,

    /// Minimum entropy
    #[clap(short = 'e', value_parser, default_value_t = 60.0)]
    pub min_entropy: f64,

    /// Ngram length
    #[clap(short = 'l', value_parser, default_value_t = 3)]
    pub ngram_length: usize,

    /// Minimum word length for corpus
    #[clap(short = 'w', value_parser, default_value_t = 5)]
    pub min_word_length: usize,

    /// Print the entropy for each passphrase
    #[clap(long, value_parser, default_value_t = false)]
    pub show_entropy: bool,
}

fn get_corpus_files(files: &[String]) -> std::io::Result<Vec<std::path::PathBuf>> {
    match files {
        [] => get_data_files(),
        [x] if x == "-" => Ok(vec![]),
        _ => Ok(files.iter().map(|f| f.into()).collect()),
    }
}

fn get_data_files() -> std::io::Result<Vec<std::path::PathBuf>> {
    let mut data_dirs = directories::ProjectDirs::from_path("markovpass".into())
        .map(|pds| vec![pds.data_dir().to_path_buf()])
        .unwrap_or_else(Vec::new);
    if cfg!(target_os = "linux") {
        data_dirs.extend(
            std::env::var("XDG_DATA_DIRS")
                .unwrap_or_else(|_| "/usr/local/share/:/usr/share/".to_string())
                .split(':')
                .map(|s| std::path::PathBuf::from(s).join("markovpass")),
        );
    }
    for dir in &data_dirs {
        if dir.exists() {
            let entries = std::fs::read_dir(dir)?.collect::<Result<Vec<_>, _>>()?;
            let paths: Vec<_> = entries
                .into_iter()
                .map(|entry| entry.path())
                .filter(|path| path.is_file())
                .collect();
            if !paths.is_empty() {
                return Ok(paths);
            }
        }
    }
    Err(std::io::Error::new(
        std::io::ErrorKind::NotFound,
        format!(
            "No corpus data found in any of {}.",
            data_dirs
                .iter()
                .map(|p| p.to_string_lossy())
                .collect::<Vec<_>>()
                .join(", ")
        ),
    ))
}
<|endoftext|>


<commit_before>extern crate xml;

use std::fs::File;
use std::io::{BufReader, Read};
use std::sync::RwLock;

use xml::{Event, Parser, Element};

// mod doc;

fn indent(size: usize) -> String {
    const INDENT: &'static str = "    ";
    (0..size)
        .map(|_| INDENT)
        .fold(String::with_capacity(size * INDENT.len()), |r, s| r + s)
}

fn main() {
    let mut file = File::open("tests/documents/testrect.svg").unwrap();
    //    let file = BufReader::new(file);

    let mut file_string = String::new();
    if let Err(err) = file.read_to_string(&mut file_string) {
        println!("Reading failed: {}", err);
        std::process::exit(1);
    };
    let mut parser = Parser::new();

    parser.feed_str(&file_string);
    for event in parser {
        match event.unwrap() {
            Event::ElementStart(tag) => println!("<{}>", tag.name),
            Event::ElementEnd(tag) => println!("</{}>", tag.name),
            _ => (),
        }
    }

    //    let reader = parserconfig::new()
    //        .whitespace_to_characters(true)
    //        .ignore_comments(true)
    //        .create_reader(bufreader::new(file));
    //
    //    let document = rwlock::new(doc::document::document::new());
    //
    //    let mut depth = 0;
    //    for e in reader {
    //        match e {
    //            ok(xmlEvent::StartDocument { version, encoding, standalone }) => {
    //                document.write().unwrap().set_version(version);
    //                document.write().unwrap().set_encoding(&encoding);
    //                document.write().unwrap().set_standalone(standalone.unwrap_or_default());
    //            }
    //            Ok(XmlEventa:EndDocument) => {
    //                println!("End");
    //            }
    //            Ok(XmlEvent::StartElement { name, attributes, namespace }) => {
    //                let node = doc::node::Node::new(0,
    //                                                attributes,
    //                                                doc::node::NodeType::Element {
    //                                                    elem_type: doc::node::ElementType::Rect,
    //                                                });
    //                document.write().unwrap().add(node);
    //                println!("{}+{}", indent(depth), name);
    //                depth += 1;
    //            }
    //            Ok(XmlEvent::EndElement { name }) => {
    //                depth -= 1;
    //                println!("{}-{}", indent(depth), name);
    //            }
    //            Ok(XmlEvent::CData(data)) => {
    //                println!("{}", data);
    //            }
    //            Ok(XmlEvent::Characters(data)) => {
    //                println!("{}", data);
    //            }
    //            Ok(XmlEvent::ProcessingInstruction { name, data }) => {
    //                println!("{} {}", name, data.unwrap_or_default());
    //            }
    //            Err(e) => {
    //                println!("Error: {}", e);
    //                break;
    //            }
    //            _ => {}
    //        }
    //    }
}
<commit_msg>Added UI components back in. Borrowing from a conrod example.<commit_after>#[macro_use]
extern crate conrod;
extern crate xml;
extern crate piston_window;
extern crate find_folder;

use std::fs::File;
use std::io::Read;

use conrod::{Theme, Widget};
use piston_window::*;

use xml::{Parser, ElementBuilder};

/// Conrod is backend agnostic. Here, we define the `piston_window` backend to use for our `Ui`.
type Backend = (piston_window::G2dTexture<'static>, piston_window::Glyphs);
type Ui = conrod::Ui<Backend>;
type UiCell<'a> = conrod::UiCell<'a, Backend>;

// mod doc;

fn main() {

    let mut file = File::open("tests/documents/testrect.svg").unwrap();

    let mut file_string = String::new();
    if let Err(err) = file.read_to_string(&mut file_string) {
        println!("Reading failed: {}", err);
        std::process::exit(1);
    };
    let mut parser = Parser::new();
    let mut eb = ElementBuilder::new();

    parser.feed_str(&file_string);
    let doc = parser.filter_map(|x| eb.handle_event(x));

    // Construct the window.
    let mut window: PistonWindow = WindowSettings::new("Inkrust", [720, 360])
                                       .opengl(piston_window::OpenGL::V3_2)
                                       .samples(4)
                                       .exit_on_esc(true)
                                       .build()
                                       .unwrap();

    // Construct our `Ui`.
    let mut ui = {
        let assets = find_folder::Search::KidsThenParents(3, 5)
                         .for_folder("assets")
                         .unwrap();
        let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
        let theme = Theme::default();
        let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.clone()).unwrap();
        Ui::new(glyph_cache, theme)
    };

    window.set_ups(60);

    for elem in doc {
        let e = elem.unwrap();

        println!("{}", e);
    }

    // Poll events from the window.
    while let Some(event) = window.next() {
        ui.handle_event(event.clone());
        event.update(|_| ui.set_widgets(set_ui));
        window.draw_2d(&event, |c, g| ui.draw_if_changed(c, g));
    }

    // Declare the `WidgetId`s and instantiate the widgets.
    fn set_ui(ref mut ui: UiCell) {
        use conrod::{Canvas, Circle, Line, Oval, PointPath, Polygon, Positionable, Rectangle};
        use std::iter::once;

        // Generate a unique const `WidgetId` for each widget.
        widget_ids!{
	        CANVAS,
	        LINE,
	        POINT_PATH,
	        RECTANGLE_FILL,
	        RECTANGLE_OUTLINE,
	        TRAPEZOID,
	        OVAL_FILL,
	        OVAL_OUTLINE,
	        CIRCLE,
	    };

        // The background canvas upon which we'll place our widgets.
        Canvas::new().pad(80.0).set(CANVAS, ui);

        Line::centred([-40.0, -40.0], [40.0, 40.0]).top_left_of(CANVAS).set(LINE, ui);

        let left = [-40.0, -40.0];
        let top = [0.0, 40.0];
        let right = [40.0, -40.0];
        let points = once(left).chain(once(top)).chain(once(right));
        PointPath::centred(points).down(80.0).set(POINT_PATH, ui);

        Rectangle::fill([80.0, 80.0]).down(80.0).set(RECTANGLE_FILL, ui);

        Rectangle::outline([80.0, 80.0]).down(80.0).set(RECTANGLE_OUTLINE, ui);

        let bl = [-40.0, -40.0];
        let tl = [-20.0, 40.0];
        let tr = [20.0, 40.0];
        let br = [40.0, -40.0];
        let points = once(bl).chain(once(tl)).chain(once(tr)).chain(once(br));
        Polygon::centred_fill(points).right_from(LINE, 80.0).set(TRAPEZOID, ui);

        Oval::fill([40.0, 80.0]).down(80.0).align_middle_x().set(OVAL_FILL, ui);

        Oval::outline([80.0, 40.0]).down(100.0).align_middle_x().set(OVAL_OUTLINE, ui);

        Circle::fill(40.0).down(100.0).align_middle_x().set(CIRCLE, ui);
    }
}
<|endoftext|>


<commit_before>extern crate yaml_rust;
extern crate csv;
extern crate tina;

mod config;

use std::env;
use std::sync::Arc;

use tina::*;
use config::*;

fn main()
{
	let args: Vec<String> = env::args().collect();

	let conf_path = args.get(1).map(|s| s.as_str()).unwrap_or("tina.yaml");

	let conf = match Config::load_config(conf_path) {
		Err(err) => {
			println!("Error while loading config ({:?})", err);
			return;
		},
		Ok(c) => c
	};

	let tw_fn = |eews: &[Arc<EEW>], latest: Arc<EEW>, tw: &mut TwitterClient| {

		if let Some(out) = ja_format_eew_short(&latest, eews.iter().rev().nth(1).map(|e| e.as_ref())) {
			tw.output(&out, None);
		}
	};

	let stdout_fn = |_: &[Arc<EEW>], latest: Arc<EEW>, stdout_logger: &mut StdoutLogger| {

		let out = format_eew_full(&latest);
		stdout_logger.output(&out);
	};

	let wni_client = WNIClient::new(conf.wni_id.clone(), conf.wni_password.clone());
	let mut cons: Vec<Connector> = Vec::new();

	cons.push(Connector::new(stdout_fn, StdoutLogger::new()));
	println!("Use: Stdout");

	if conf.twitter.is_some() {
		let t = &conf.twitter.unwrap();
		let tc = TwitterClient::new(
			t.consumer_token.clone(), t.consumer_secret.clone(),
			t.access_token.clone(), t.access_secret.clone());
		cons.push(Connector::new(tw_fn, tc));
		println!("Use: Twitter");
	}

	loop {

		let mut connection = match wni_client.connect() {
			Ok(v) => v,
			Err(e) => {
				println!("ConnectionError: {:?}", e);
				continue;
			}
		};

		loop {

			let eew = match connection.wait_for_telegram(&conf.epicenter_dict, &conf.area_dict) {
				Err(e) => {
					println!("StreamingError: {:?}", e);
					break;
				},
				Ok(eew) => Arc::new(eew)
			};

			for e in cons.iter() {
				e.emit(eew.clone());
			}
		}
	}
}
<commit_msg>Implement in_reply_to feature<commit_after>extern crate yaml_rust;
extern crate csv;
extern crate tina;

mod config;

use std::env;
use std::sync::Arc;

use tina::*;
use config::*;

fn main()
{
	let args: Vec<String> = env::args().collect();

	let conf_path = args.get(1).map(|s| s.as_str()).unwrap_or("tina.yaml");

	let conf = match Config::load_config(conf_path) {
		Err(err) => {
			println!("Error while loading config ({:?})", err);
			return;
		},
		Ok(c) => c
	};

	let tw_fn = |eews: &[Arc<EEW>], latest: Arc<EEW>, state: &mut (TwitterClient, LimitedQueue<(String, u64)>)| {

		let (ref tw, ref mut q) = *state;

		let out = match ja_format_eew_short(&latest, eews.iter().rev().nth(1).map(|e| e.as_ref())) {
			Some(out) => out,
			None => return
		};

		let prev_tw_id_opt = q.iter().find(|x| x.0 == latest.id).map(|x| x.1);

		if let Some(tw_id) = tw.output(&out, prev_tw_id_opt) {

			if prev_tw_id_opt == None {
				q.push((latest.id.clone(), tw_id));
			} else {
				q.iter_mut().find(|x| x.0 == latest.id).unwrap().1 = tw_id;
			}
		}
	};

	let stdout_fn = |_: &[Arc<EEW>], latest: Arc<EEW>, stdout_logger: &mut StdoutLogger| {

		let out = format_eew_full(&latest);
		stdout_logger.output(&out);
	};

	let wni_client = WNIClient::new(conf.wni_id.clone(), conf.wni_password.clone());
	let mut cons: Vec<Connector> = Vec::new();

	cons.push(Connector::new(stdout_fn, StdoutLogger::new()));
	println!("Use: Stdout");

	if conf.twitter.is_some() {
		let t = &conf.twitter.unwrap();
		let tc = TwitterClient::new(
			t.consumer_token.clone(), t.consumer_secret.clone(),
			t.access_token.clone(), t.access_secret.clone());
		let q = LimitedQueue::with_allocation(16);
		cons.push(Connector::new(tw_fn, (tc, q)));
		println!("Use: Twitter");
	}

	loop {

		let mut connection = match wni_client.connect() {
			Ok(v) => v,
			Err(e) => {
				println!("ConnectionError: {:?}", e);
				continue;
			}
		};

		loop {

			let eew = match connection.wait_for_telegram(&conf.epicenter_dict, &conf.area_dict) {
				Err(e) => {
					println!("StreamingError: {:?}", e);
					break;
				},
				Ok(eew) => Arc::new(eew)
			};

			for e in cons.iter() {
				e.emit(eew.clone());
			}
		}
	}
}
<|endoftext|>


<commit_before>// Worklog is for recording your hours.
//

extern crate chrono;
extern crate csv;
extern crate clap;
extern crate rustc_serialize;

mod error;
mod timeclock;
mod util;

use chrono::*;
use clap::{Arg, ArgGroup, App};
use error::WorklogError;
use std::env;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::PathBuf;
use timeclock::Direction;
use timeclock::now;

#[cfg(target_family = "unix")]
static CSV_FILE_NAME: &'static str = ".worklog.csv";
#[cfg(target_family = "windows")]
static CSV_FILE_NAME: &'static str = "worklog.csv";

// TODO This belongs in a config file somewhere
const WEEKSTART: i64 = Weekday::Sat as i64;

fn print_csv_entries<R: Read>(file: R) -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    for rec in csv_entries {
        println!("{}", rec);
    }
    Ok(())
}

fn print_full_summary<R: Read>(file: R,
                               rounding: util::Rounding)
                               -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    let records = timeclock::collect_date_records(csv_entries);

    let mut total_hours: f64 = 0.0;
    for rec in records {
        let hours = util::round(rec.seconds(), rounding) / 3600.0;
        total_hours += hours;
        println!("{} {:.2} {}", rec.date().format("%F"), hours, rec.memo());
    }

    println!("Total Hours: {:.2}", total_hours);
    Ok(())
}

fn print_short_summary<R: Read>(file: R,
                                since: Date<FixedOffset>,
                                rounding: util::Rounding)
                                -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    let records = timeclock::collect_date_records(csv_entries);

    let mut total_hours: f64 = 0.0;
    for rec in records {
        if rec.date() >= since {
            let hours = util::round(rec.seconds(), rounding) / 3600.0;
            total_hours += hours;
            println!("{} {:.2} {}", rec.date().format("%F"), hours, rec.memo());
        }
    }

    println!("Total Hours: {:.2}", total_hours);
    Ok(())
}

/// Get the path for the csv data file
fn get_csv_path() -> Result<PathBuf, WorklogError> {
    let mut data_path = match env::home_dir() {
        Some(path) => path,
        None => {
            return Err(env::VarError::NotPresent).map_err(WorklogError::Env)
        }
    };

    data_path.push(CSV_FILE_NAME);
    Ok(data_path)
}

fn main0() -> Result<(), WorklogError> {
    // Using std env macro rather than depending on clap's. No difference
    // as far as I can tell.
    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("[in] -i, --in 'Record an In entry'"))
        .arg(Arg::from_usage("[out] -o, --out 'Record an Out entry'"))
        .arg(Arg::from_usage("[time] -t, --time <TIME> 'time'")
            .default_value("now")
            .requires("inout"))
        .arg(Arg::from_usage("[memo] -m, --memo <MEMO> 'Memo for the entry'")
            .default_value("")
            .requires("inout"))
        .arg(Arg::from_usage("[summary] -s, --summary 'Print a summary'")
            .conflicts_with("inout"))
        .arg(Arg::from_usage("[log] -l, --log 'Print the full log'")
            .conflicts_with("inout"))
        .arg(Arg::from_usage("[round] -r, --round 'Round totals up to the next quarter hour'")
            .conflicts_with("inout"))
        .group(ArgGroup::with_name("inout").args(&["in", "out"]))
        .get_matches();

    let csv_path = try!(get_csv_path());

    let mut csv_file = try!(OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open(csv_path));

    let rounding = {
        if matches.is_present("round") {
            // round up in 15min intervals
            util::Rounding::Up(900.0)
        } else {
            util::Rounding::None
        }
    };

    if matches.is_present("in") || matches.is_present("out") {
        let dir = if matches.is_present("in") {
            Direction::In
        } else {
            Direction::Out
        };

        let time = matches.value_of("time").unwrap();
        let time = try!(util::parse_multi_time_fmt(&time));

        let memo = matches.value_of("memo").unwrap().to_owned();
        timeclock::mark_time(dir, time, memo, &mut csv_file);

        println!("Clocked {:#} at {}", dir, time.format("%F %I:%M %P"));

    } else if matches.is_present("summary") {
        try!(print_full_summary(&csv_file, rounding));

    } else if matches.is_present("log") {
        try!(print_csv_entries(&csv_file));

    } else {
        let today = now().date();
        let weekday = today.weekday() as i64;
        let days_back = (7 - WEEKSTART + weekday) % 7;
        let start_date = today - Duration::days(days_back);
        try!(print_short_summary(&csv_file, start_date, rounding));
    }

    Ok(())
}

fn main() {
    match main0() {
        Ok(_) => {}
        Err(err) => {
            let _ = writeln!(&mut std::io::stderr(), "Error: {}", err);
        }
    };
}
<commit_msg>Fixed unnecessary required args<commit_after>// Worklog is for recording your hours.
//

extern crate chrono;
extern crate csv;
extern crate clap;
extern crate rustc_serialize;

mod error;
mod timeclock;
mod util;

use chrono::*;
use clap::{Arg, ArgGroup, App};
use error::WorklogError;
use std::env;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::PathBuf;
use timeclock::Direction;
use timeclock::now;

#[cfg(target_family = "unix")]
static CSV_FILE_NAME: &'static str = ".worklog.csv";
#[cfg(target_family = "windows")]
static CSV_FILE_NAME: &'static str = "worklog.csv";

// TODO This belongs in a config file somewhere
const WEEKSTART: i64 = Weekday::Sat as i64;

fn print_csv_entries<R: Read>(file: R) -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    for rec in csv_entries {
        println!("{}", rec);
    }
    Ok(())
}

fn print_full_summary<R: Read>(file: R,
                               rounding: util::Rounding)
                               -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    let records = timeclock::collect_date_records(csv_entries);

    let mut total_hours: f64 = 0.0;
    for rec in records {
        let hours = util::round(rec.seconds(), rounding) / 3600.0;
        total_hours += hours;
        println!("{} {:.2} {}", rec.date().format("%F"), hours, rec.memo());
    }

    println!("Total Hours: {:.2}", total_hours);
    Ok(())
}

fn print_short_summary<R: Read>(file: R,
                                since: Date<FixedOffset>,
                                rounding: util::Rounding)
                                -> Result<(), WorklogError> {
    let csv_entries = try!(timeclock::read_timesheet(file));
    let records = timeclock::collect_date_records(csv_entries);

    let mut total_hours: f64 = 0.0;
    for rec in records {
        if rec.date() >= since {
            let hours = util::round(rec.seconds(), rounding) / 3600.0;
            total_hours += hours;
            println!("{} {:.2} {}", rec.date().format("%F"), hours, rec.memo());
        }
    }

    println!("Total Hours: {:.2}", total_hours);
    Ok(())
}

/// Get the path for the csv data file
fn get_csv_path() -> Result<PathBuf, WorklogError> {
    let mut data_path = match env::home_dir() {
        Some(path) => path,
        None => {
            return Err(env::VarError::NotPresent).map_err(WorklogError::Env)
        }
    };

    data_path.push(CSV_FILE_NAME);
    Ok(data_path)
}

fn main0() -> Result<(), WorklogError> {
    // Using std env macro rather than depending on clap's. No difference
    // as far as I can tell.
    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("[in] -i, --in 'Record an In entry'"))
        .arg(Arg::from_usage("[out] -o, --out 'Record an Out entry'"))
        .arg(Arg::from_usage("[time] -t, --time <TIME> 'time'")
            // Using default + required triggers needing the other option.
            // removing the requires() for now as work around
            .default_value("now"))
        .arg(Arg::from_usage("[memo] -m, --memo <MEMO> 'Memo for the entry'")
            .default_value(""))
        .arg(Arg::from_usage("[summary] -s, --summary 'Print a summary'")
            .conflicts_with("inout"))
        .arg(Arg::from_usage("[log] -l, --log 'Print the full log'")
            .conflicts_with("inout"))
        .arg(Arg::from_usage("[round] -r, --round 'Round totals up to the next quarter hour'")
            .conflicts_with("inout"))
        .group(ArgGroup::with_name("inout").args(&["in", "out"]))
        .get_matches();

    let csv_path = try!(get_csv_path());

    let mut csv_file = try!(OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open(csv_path));

    let rounding = {
        if matches.is_present("round") {
            // round up in 15min intervals
            util::Rounding::Up(900.0)
        } else {
            util::Rounding::None
        }
    };

    if matches.is_present("in") || matches.is_present("out") {
        let dir = if matches.is_present("in") {
            Direction::In
        } else {
            Direction::Out
        };

        let time = matches.value_of("time").unwrap();
        let time = try!(util::parse_multi_time_fmt(&time));

        let memo = matches.value_of("memo").unwrap().to_owned();
        timeclock::mark_time(dir, time, memo, &mut csv_file);

        println!("Clocked {:#} at {}", dir, time.format("%F %I:%M %P"));

    } else if matches.is_present("summary") {
        try!(print_full_summary(&csv_file, rounding));

    } else if matches.is_present("log") {
        try!(print_csv_entries(&csv_file));

    } else {
        let today = now().date();
        let weekday = today.weekday() as i64;
        let days_back = (7 - WEEKSTART + weekday) % 7;
        let start_date = today - Duration::days(days_back);
        try!(print_short_summary(&csv_file, start_date, rounding));
    }

    Ok(())
}

fn main() {
    match main0() {
        Ok(_) => {}
        Err(err) => {
            let _ = writeln!(&mut std::io::stderr(), "Error: {}", err);
        }
    };
}
<|endoftext|>


<commit_before>use std::cmp::min;

fn main() {
    let bv = [0, 1, 0, 1];
    println!("rank:{:?}", rank_mock(&bv, 0));
    println!("select:{:?}", select_mock(&bv, 1));
}

fn rank_mock(bv: &[u8], idx: usize) -> usize {
    let mut ret = 0;
    let len = min(bv.len(), idx);

    for i in 0..len {
        if bv[i]==1 {
            ret = ret + 1;
        }
    }

    ret
}

fn select_mock(bv: &[u8], idx: usize) -> usize {
    let mut cnt = 0;
    for i in 0..bv.len() {
        if bv[i]==1 {
            cnt = cnt+1;
        }
        if cnt==idx+1 {
            return i;
        }
    }
    return 0;
}

#[test]
fn rank_test() {
    let bv = [0,1,0,1];
    assert_eq!(rank_mock(&bv, 0), 0);
    assert_eq!(rank_mock(&bv, 1), 0);
    assert_eq!(rank_mock(&bv, 2), 1);
    assert_eq!(rank_mock(&bv, 3), 1);
    assert_eq!(rank_mock(&bv, 4), 2);
    assert_eq!(rank_mock(&bv, 5), 2);
}

#[test]
fn select_test() {
    let bv = [0,1,0,1];
    assert_eq!(select_mock(&bv, 0), 1);
    assert_eq!(select_mock(&bv, 1), 3);
    assert_eq!(select_mock(&bv, 2), 0);
}
<commit_msg>rankの実装<commit_after>use std::cmp::min;
use std::vec::Vec;

fn main() {
    let bv = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0];
    let fid = Fid::new(&bv);
    println!("{:?}", fid.big_blocks);
    println!("{:?}", fid.small_blocks);
    println!("{:?}", fid.rank(10));
}

struct Fid<'a> {
    raw: &'a [u8]
    ,big_block_size: usize
    ,big_blocks: Vec<usize>
    ,small_block_size: usize
    ,small_blocks: Vec<usize>
}

impl<'a> Fid<'a> {
    fn new(bv: &[u8]) -> Fid{
        let mut ret = Fid {
            raw: bv
            ,big_block_size: 0
            ,big_blocks: Vec::new()
            ,small_block_size: 0
            ,small_blocks: Vec::new()
        };
        ret.build();
        ret
    }

    fn build(&mut self) {
        let n = self.raw.len();
        let big_block_size = (n as f64).log2().powi(2).floor() as usize; // (lg(n))^2
        let small_block_size = ((n as f64)/2.0).floor() as usize; // lg(n)/2
        self.big_block_size = big_block_size;
        self.small_block_size = small_block_size;

        let mut cntb = 0;
        let mut cnts = 0;
        for i in 0..n {
            if i%big_block_size==0 {
                self.big_blocks.push(cntb);
            }
            if i%small_block_size==0 {
                let s = cnts - self.big_blocks.last().unwrap();
                self.small_blocks.push(s);
            }
            if self.raw[i]==1 {
                cntb = cntb + 1;
                cnts = cnts + 1;
            }
        }
    }

    fn rank(&self, idx: usize) -> usize {
        let mut rank = 0;

        let p = idx % self.big_block_size;
        let pos = min((idx-p)/self.big_block_size, self.big_blocks.len()-1);
        rank += self.big_blocks[pos];

        let sp = p % self.small_block_size;
        let spos = pos/self.small_block_size + (p-sp)/self.small_block_size;
        rank += self.small_blocks[spos];

        for i in (pos*self.big_block_size+spos*self.small_block_size)..min(idx,self.raw.len()) {
            if self.raw[i]== 1 {
                rank += 1;
            }
        }
        rank
    }
}

fn rank_mock(bv: &[u8], idx: usize) -> usize {
    let mut ret = 0;
    let len = min(bv.len(), idx);

    for i in 0..len {
        if bv[i]==1 {
            ret = ret + 1;
        }
    }

    ret
}

fn select_mock(bv: &[u8], idx: usize) -> usize {
    let mut cnt = 0;
    for i in 0..bv.len() {
        if bv[i]==1 {
            cnt = cnt+1;
        }
        if cnt==idx+1 {
            return i;
        }
    }
    return 0;
}

#[test]
fn rank_test() {
    let bv = [0,1,0,1];
    let fid = Fid::new(&bv);

    assert_eq!(rank_mock(&bv, 0), 0);
    assert_eq!(rank_mock(&bv, 1), 0);
    assert_eq!(rank_mock(&bv, 2), 1);
    assert_eq!(rank_mock(&bv, 3), 1);
    assert_eq!(rank_mock(&bv, 4), 2);
    assert_eq!(rank_mock(&bv, 5), 2);

    assert_eq!(rank_mock(&bv, 0), fid.rank(0));
    assert_eq!(rank_mock(&bv, 1), fid.rank(1));
    assert_eq!(rank_mock(&bv, 2), fid.rank(2));
    assert_eq!(rank_mock(&bv, 3), fid.rank(3));
    assert_eq!(rank_mock(&bv, 4), fid.rank(4));
    assert_eq!(rank_mock(&bv, 5), fid.rank(5));
}

#[test]
fn select_test() {
    let bv = [0,1,0,1];
    assert_eq!(select_mock(&bv, 0), 1);
    assert_eq!(select_mock(&bv, 1), 3);
    assert_eq!(select_mock(&bv, 2), 0);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

use clap::{App, Arg};
use std::path::PathBuf;

fn main() {
    // Use the clap crate to handle argument parsing.
    let version = crate_version!();
    let program = App::new("to")
                    .about("Bookmark directories")
                    .version(version)
                    .author("Jason Campbell <jason@artifact.sh>")
                    .arg(Arg::with_name("name")
                        .help("Name of the bookamrk")
                        .index(1))
                    .arg(Arg::with_name("directory")
                        .help("Path of the bookamrk")
                        .index(2));

    // Take the matches from clap and convert them into name, directory, and
    // action.
    let operation = parse(program);
}

struct Operation {
    name: String,
    directory: PathBuf,
}

fn parse(cli: clap::App) -> Operation {
    let matches = cli.get_matches();

    if let Some(name) = matches.value_of("name") {
        println!("A name was passed in: {}", name);
    }

    if let Some(directory) = matches.value_of("directory") {
        println!("A name was passed in: {}", directory);
    }

    return Operation{ name: "foo".to_string(), directory: PathBuf::from(".")}
}
<commit_msg>Matching matches.<commit_after>#[macro_use]
extern crate clap;

use clap::{App, Arg};
use std::path::PathBuf;

fn main() {
    // Use the clap crate to handle argument parsing.
    let version = crate_version!();
    let program = App::new("to")
                    .about("Bookmark directories")
                    .version(version)
                    .author("Jason Campbell <jason@artifact.sh>")
                    .arg(Arg::with_name("name")
                        .help("Name of the bookamrk")
                        .index(1))
                    .arg(Arg::with_name("directory")
                        .help("Path of the bookamrk")
                        .index(2));

    // Take the matches from clap and convert them into name, directory, and
    // action.
    parse(program);

}

struct Operation {
    name: String,
    directory: PathBuf,
}

fn parse(cli: clap::App) -> Operation {
    let matches = cli.get_matches();

    let name = match matches.value_of("name") {
        Some(name) => { name.to_string() },
        None => { "foo".to_string() },
    };

    if let Some(directory) = matches.value_of("directory") {
        println!("A name was passed in: {}", directory);
    }

    return Operation{ name: name, directory: PathBuf::from(".")}
}
<|endoftext|>


<commit_before>#[macro_use] extern crate lazy_static;
extern crate deploy;
extern crate dotenv;
extern crate pencil;

use deploy::*;
use dotenv::dotenv;
use pencil::{Pencil, Response, Request, PencilResult};
use std::env;
use std::path::Path;
use std::process::{Stdio, Command};
use std::thread;

lazy_static! {
  pub static ref SECRET: String = env::var("TENJAVA_DEPLOY_SECRET").expect("missing TENJAVA_DEPLOY_SECRET");
  pub static ref PROD_REPO: String = env::var("TENJAVA_WEBSITE_REPO").expect("mssing TENJAVA_WEBSITE_PROD_REPO");
  pub static ref DEV_REPO: String = env::var("TENJAVA_WEBSITE_REPO").expect("mssing TENJAVA_WEBSITE_DEV_REPO");
}

fn deploy_webhook(r: &mut Request) -> PencilResult {
  println!("receiving a deploy request");
  let (signature, event) = {
    let headers = r.headers();
    let signature: &XHubSignature = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing a signature header");
        println!("  done");
        let mut res = Response::new("missing a signature header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    let event: &XGitHubEvent = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing an event header");
        println!("  done");
        let mut res = Response::new("missing an event header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    (signature.clone(), event.clone())
  };
  if *event != "push" {
    println!("  it was not a push event");
    println!("  done");
    return Ok("not a push event, but thanks anyway".into());
  }
  let signature_check = match deploy::check_signature(r, &signature, &SECRET) {
    Ok(x) => x,
    Err(e) => {
      println!("  an error occurred while checking the signature: {}", e);
      println!("  done");
      let mut res = Response::new(format!("an error occurred while checking signature: {}", e));
      res.status_code = 500;
      return Ok(res);
    }
  };
  if !signature_check {
    println!("  it had an invalid signature");
    println!("  done");
    let mut res = Response::new("invalid signature");
    res.status_code = 401;
    return Ok(res);
  }
  println!("  everything checks out");
  println!("  checking branch");
  let branch = match deploy::get_branch(r) {
    Ok(b) => b,
    Err(e) => {
      println!("  an error occurred while checking branch: {}", e);
      println!("  done");
      let mut res = Response::new(format!("couldn't get branch: {}", e));
      res.status_code = 401;
      return Ok(res);
    }
  };
  println!("  spawning update thread");
  update_repo(&branch);
  println!("  thread spawned");
  println!("  done");
  println!("");
  Ok("deploy initiated".into())
}

fn update_repo(branch: &Branch) {
  let repo_path = match *branch {
    Branch::Master => &*PROD_REPO,
    Branch::Dev => &*DEV_REPO
  };
  thread::spawn(move || {
    let status = Command::new("git")
      .arg("pull")
      .stdout(Stdio::null())
      .current_dir(Path::new(repo_path))
      .status()
      .expect("could not start git");
    if !status.success() {
      match status.code() {
        Some(code) => {
          println!("git exited with code {}", code);
        },
        None => {
          println!("git exited with an unknown status code");
        }
      }
    } else {
      println!("git exited successfully")
    }
  });
}

fn inner() -> i32 {
  // load up env
  dotenv().ok();

  // check env
  if (&*SECRET).is_empty() {
    println!("oops, no TENJAVA_DEPLOY_SECRET was specified");
    return 1;
  }
  if (&*PROD_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_PROD_REPO was specified");
    return 1;
  }
  if (&*DEV_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_DEV_REPO was specified");
    return 1;
  }
  let mut app = Pencil::new("/static");
  app.post("/deploy", "deploy", deploy_webhook);
  app.run("0.0.0.0:32260");
  0
}

fn main() {
  let exit_code = inner();
  std::process::exit(exit_code);
}
<commit_msg>fix: correct typo<commit_after>#[macro_use] extern crate lazy_static;
extern crate deploy;
extern crate dotenv;
extern crate pencil;

use deploy::*;
use dotenv::dotenv;
use pencil::{Pencil, Response, Request, PencilResult};
use std::env;
use std::path::Path;
use std::process::{Stdio, Command};
use std::thread;

lazy_static! {
  pub static ref SECRET: String = env::var("TENJAVA_DEPLOY_SECRET").expect("missing TENJAVA_DEPLOY_SECRET");
  pub static ref PROD_REPO: String = env::var("TENJAVA_WEBSITE_REPO").expect("missing TENJAVA_WEBSITE_PROD_REPO");
  pub static ref DEV_REPO: String = env::var("TENJAVA_WEBSITE_REPO").expect("missing TENJAVA_WEBSITE_DEV_REPO");
}

fn deploy_webhook(r: &mut Request) -> PencilResult {
  println!("receiving a deploy request");
  let (signature, event) = {
    let headers = r.headers();
    let signature: &XHubSignature = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing a signature header");
        println!("  done");
        let mut res = Response::new("missing a signature header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    let event: &XGitHubEvent = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing an event header");
        println!("  done");
        let mut res = Response::new("missing an event header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    (signature.clone(), event.clone())
  };
  if *event != "push" {
    println!("  it was not a push event");
    println!("  done");
    return Ok("not a push event, but thanks anyway".into());
  }
  let signature_check = match deploy::check_signature(r, &signature, &SECRET) {
    Ok(x) => x,
    Err(e) => {
      println!("  an error occurred while checking the signature: {}", e);
      println!("  done");
      let mut res = Response::new(format!("an error occurred while checking signature: {}", e));
      res.status_code = 500;
      return Ok(res);
    }
  };
  if !signature_check {
    println!("  it had an invalid signature");
    println!("  done");
    let mut res = Response::new("invalid signature");
    res.status_code = 401;
    return Ok(res);
  }
  println!("  everything checks out");
  println!("  checking branch");
  let branch = match deploy::get_branch(r) {
    Ok(b) => b,
    Err(e) => {
      println!("  an error occurred while checking branch: {}", e);
      println!("  done");
      let mut res = Response::new(format!("couldn't get branch: {}", e));
      res.status_code = 401;
      return Ok(res);
    }
  };
  println!("  spawning update thread");
  update_repo(&branch);
  println!("  thread spawned");
  println!("  done");
  println!("");
  Ok("deploy initiated".into())
}

fn update_repo(branch: &Branch) {
  let repo_path = match *branch {
    Branch::Master => &*PROD_REPO,
    Branch::Dev => &*DEV_REPO
  };
  thread::spawn(move || {
    let status = Command::new("git")
      .arg("pull")
      .stdout(Stdio::null())
      .current_dir(Path::new(repo_path))
      .status()
      .expect("could not start git");
    if !status.success() {
      match status.code() {
        Some(code) => {
          println!("git exited with code {}", code);
        },
        None => {
          println!("git exited with an unknown status code");
        }
      }
    } else {
      println!("git exited successfully")
    }
  });
}

fn inner() -> i32 {
  // load up env
  dotenv().ok();

  // check env
  if (&*SECRET).is_empty() {
    println!("oops, no TENJAVA_DEPLOY_SECRET was specified");
    return 1;
  }
  if (&*PROD_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_PROD_REPO was specified");
    return 1;
  }
  if (&*DEV_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_DEV_REPO was specified");
    return 1;
  }
  let mut app = Pencil::new("/static");
  app.post("/deploy", "deploy", deploy_webhook);
  app.run("0.0.0.0:32260");
  0
}

fn main() {
  let exit_code = inner();
  std::process::exit(exit_code);
}
<|endoftext|>


<commit_before>
#![feature(io)]

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::sync::{Arc, Mutex };
use std::sync::mpsc::{ channel, Sender, Receiver };
use std::thread;

// State Function
struct StateFn<E: std::error::Error> {
    f: fn(l: &Lex<E>)->Option<StateFn<E>>
}

#[derive(Debug)]
struct Pos {
    line: u64,
    col: u64
}

impl Pos {
    fn new()->Pos {
        Pos {
            line: 0,
            col: 0
        }
    }
}

#[derive(Debug)]
enum TokenType {
    Integer,
    Operator
}

#[derive(Debug)]
struct Token {
    pos: Pos,
    typ: TokenType,
    val: String
}

trait Lex<E: std::error::Error> {
    fn next(&self)->Result<char, E>;
    fn emit(&self);
}

// State Machine
struct Lexer<R: io::Read+Send> {
    pos: Pos,
    buf: Arc<Mutex<io::Chars<R>>>,
    state: StateFn<io::CharsError>,
    send: Option<Sender<Token>>
}

fn start_state<E: std::error::Error>(l: &Lex<E>)->Option<StateFn<E>> {
    l.emit();
    None
}

impl<R: io::Read+Send+'static> Lexer<R> {
    fn new(reader: R)->Lexer<R> {
        Lexer {
            pos: Pos::new(),
            buf: Arc::new(Mutex::new(reader.chars())),
            state: StateFn {
                f: start_state
            },
            send: None
        }
    }

    fn lex(mut self)->(thread::JoinHandle<()>, Receiver<Token>) {
        let (tx, rx) = channel();
        self.send = Some(tx);
        (thread::spawn(move || {
            loop {
                match (self.state.f)(&self) {
                    Some(s) => { self.state = s; }
                    None => { return }
                }
            }
        }), rx)
    }
}

impl<R: io::Read+Send> Lex<io::CharsError> for Lexer<R> {
    fn next(&self)->Result<char, io::CharsError> {
        self.buf.lock().unwrap().next().unwrap()
    }

    fn emit(&self) {
        self.send.as_ref().unwrap().send(Token{
            pos: Pos::new(),
            typ: TokenType::Integer,
            val: "Test".to_string()
        }).unwrap();
    }
}

fn main() {
    let lexer = Lexer::new(BufReader::new(File::open("src.f").unwrap()));
    let (th, rx) = lexer.lex();
    println!("{:?}", rx.recv().unwrap());
    th.join().unwrap();
}
<commit_msg>update<commit_after>
#![feature(io)]

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::sync::{Arc, Mutex };
use std::sync::mpsc::{ channel, Sender, Receiver };
use std::thread;

// State Function
struct StateFn<E: std::error::Error>(fn(l: &Lex<E>)->Option<StateFn<E>>);

#[derive(Debug)]
struct Pos {
    line: u64,
    col: u64
}

impl Pos {
    fn new()->Pos {
        Pos {
            line: 0,
            col: 0
        }
    }
}

#[derive(Debug)]
enum TokenType {
    Integer,
    Operator
}

#[derive(Debug)]
struct Token {
    pos: Pos,
    typ: TokenType,
    val: String
}

trait Lex<E: std::error::Error> {
    fn next(&self)->Result<char, E>;
    fn emit(&self);
}

// State Machine
struct Lexer<R: io::Read+Send> {
    pos: Pos,
    buf: Arc<Mutex<io::Chars<R>>>,
    state: StateFn<io::CharsError>,
    send: Option<Sender<Token>>
}

fn start_state<E: std::error::Error>(l: &Lex<E>)->Option<StateFn<E>> {
    l.emit();
    None
}

impl<R: io::Read+Send+'static> Lexer<R> {
    fn new(reader: R)->Lexer<R> {
        Lexer {
            pos: Pos::new(),
            buf: Arc::new(Mutex::new(reader.chars())),
            state: StateFn(start_state),
            send: None
        }
    }

    fn lex(mut self)->(thread::JoinHandle<()>, Receiver<Token>) {
        let (tx, rx) = channel();
        self.send = Some(tx);
        (thread::spawn(move || {
            loop {
                match (self.state.0)(&self) {
                    Some(s) => { self.state = s; }
                    None => { return }
                }
            }
        }), rx)
    }
}

impl<R: io::Read+Send> Lex<io::CharsError> for Lexer<R> {
    fn next(&self)->Result<char, io::CharsError> {
        self.buf.lock().unwrap().next().unwrap()
    }

    fn emit(&self) {
        self.send.as_ref().unwrap().send(Token{
            pos: Pos::new(),
            typ: TokenType::Integer,
            val: "Test".to_string()
        }).unwrap();
    }
}

fn main() {
    let lexer = Lexer::new(BufReader::new(File::open("src.f").unwrap()));
    let (th, rx) = lexer.lex();
    println!("{:?}", rx.recv().unwrap());
    th.join().unwrap();
}
<|endoftext|>