<commit_before>extern crate rustyline;
extern crate serde;
extern crate serde_json;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use rustyline::completion::Completer;
use std::env::args;
use std::path::PathBuf;
use std::process::Command;
use std::env::home_dir;
use std::fs::create_dir;
use std::fs::File;
use std::collections::HashMap;

struct BashCompleter{
    command: String,
}

impl Completer for BashCompleter {
    fn complete(&self, line: &str, pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        let words: Vec<&str> = line.split(" ").collect();
        let last_word = words.iter().nth(words.len()-1).unwrap();
        let count_words = words.len();

        let script = format!(
                    // COMP_WORDS must be specified in a bash context because normal environment
                    // variables can't be arrays
                    "
                    COMP_CWORD={}
                    COMP_POINT={}
                    COMP_LINE=\"{} {}\"
                    COMP_WORDS=({} {})
                    _xfunc git _git
                    printf \"%s\\n\" \"${{COMPREPLY[@]}}\"
                    ",
                    count_words,
                    pos + self.command.len() + 1,
                    self.command,
                    line,
                    self.command,
                    line,
                );
        let completion_result = Command::new("bash")
            .args(vec![
                "-lic",
                script.as_str(),
            ])
            .output();
        let completion_str = match completion_result {
            Ok(completion_string) => String::from_utf8(completion_string.stdout).unwrap(),
            Err(err) => {
                return Err(ReadlineError::Io(err));
            },
        };

        let word_len = last_word.len();
        let completions: Vec<String> = completion_str.split("\n").map(|s| s.to_string()).collect();

        Ok((pos-word_len, completions))
    }
}

fn main() {
    // TODO use a real arg parser
    let program = args().nth(1).expect("no program specified");

    let mut line_editor = Editor::<BashCompleter>::new();
    line_editor.set_completer(Some(BashCompleter{command: program.to_string()}));

    let (history_file_option, prompts_config_path_option) = match home_dir() {
        Some(home) => {
            let config_dir: PathBuf = [home, PathBuf::from(".tpol")].iter().collect();
            if !config_dir.exists() {
                println!("creating config dir at {}", config_dir.to_str().unwrap());
                create_dir(&config_dir).unwrap();
            }

            (
                {
                    let history_dir: PathBuf = [&config_dir, &PathBuf::from("history")].iter().collect();
                    if !history_dir.exists() {
                        println!("creating history dir at {}", history_dir.to_str().unwrap());
                        create_dir(&history_dir).unwrap();
                    }

                    let command_history: PathBuf = [history_dir, PathBuf::from(&program)].iter().collect();
                    if !command_history.exists() {
                        println!("creating history file for {} at {}", &program, command_history.to_str().unwrap());
                        let _ = File::create(&command_history).unwrap();
                    }

                    Some(command_history)
                },
                {
                    let prompts_config_path: PathBuf = [&config_dir, &PathBuf::from("prompts.json")].iter().collect();
                    Some(prompts_config_path)
                },
            )
        }
        None => (None, None)
    };

    if let Some(ref history_file) = history_file_option.clone() {
        if let Err(err) = line_editor.load_history(history_file) {
            eprintln!("Warning: error while trying to load history file {}: {}", history_file.to_str().unwrap(), err);
        }
    } else {
        eprintln!("Warning: can't find home directory, no history will be saved");
    }

    let program_to_prompt_string_command = match prompts_config_path_option {
        Some(prompts_config_path) => {
            File::open(prompts_config_path)
                .map(|file| {
                    let prompts_config: HashMap<String, String> = serde_json::from_reader(file)
                        .unwrap_or(HashMap::new());
                    prompts_config
                })
                .unwrap_or(HashMap::new())
        }
        None => HashMap::new(),
    };

    let prompt_string_command_option = program_to_prompt_string_command.get(&program);

    loop {
        let prompt_string = match prompt_string_command_option.as_ref() {
            Some(ref command) => {
                match Command::new("bash").args(vec!["-lic", command]).output() {
                    Ok(output) => String::from_utf8(output.stdout).unwrap(),
                    Err(_) => {
                        // TODO log error
                        "".to_string()
                    }
                }
            },
            None => "".to_string(),
        };

        let line_result = line_editor.readline(format!("{}>{} ", prompt_string, &program).as_str());
        match line_result {
            Ok(line) => {
                if line == "" || line == "!" {
                    // ignore empty commands
                } else {
                    let mut command = if line.starts_with("!") {
                        let parts = line.split(" ");
                        let command = &parts.clone().nth(0).unwrap()[1..];
                        let args: Vec<&str> = parts.skip(1).collect();
                        let mut command = Command::new(command);
                        command.args(args);
                        command
                    } else {
                        let mut command = Command::new(&program);
                        // TODO deal with quoted strings
                        command.args(line.trim().split(" ").collect::<Vec<&str>>());
                        command
                    };
                    let mut process_result = command.spawn();
                    match process_result {
                        Ok(mut process) => {
                            // TODO maybe display return code?
                            let _ = process.wait();
                            // TODO maybe only save in history if it's successful?
                            line_editor.add_history_entry(&line);
                        },
                        Err(err) => println!("error while trying to run command: {:?}", err),
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                break;
            },
            Err(ReadlineError::Eof) => {
                break;
            },
            Err(err) => {
                eprintln!("{:?}", err);
                break;
            }
        }
    }

    if let Some(ref history_file) = history_file_option {
        if let Err(err) = line_editor.save_history(history_file) {
            eprintln!("Warning: error while trying to load history file {}: {}", history_file.to_str().unwrap(), err);
        }
    }
}
<commit_msg>trim space on prompt_string<commit_after>extern crate rustyline;
extern crate serde;
extern crate serde_json;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use rustyline::completion::Completer;
use std::env::args;
use std::path::PathBuf;
use std::process::Command;
use std::env::home_dir;
use std::fs::create_dir;
use std::fs::File;
use std::collections::HashMap;

struct BashCompleter{
    command: String,
}

impl Completer for BashCompleter {
    fn complete(&self, line: &str, pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        let words: Vec<&str> = line.split(" ").collect();
        let last_word = words.iter().nth(words.len()-1).unwrap();
        let count_words = words.len();

        let script = format!(
                    // COMP_WORDS must be specified in a bash context because normal environment
                    // variables can't be arrays
                    "
                    COMP_CWORD={}
                    COMP_POINT={}
                    COMP_LINE=\"{} {}\"
                    COMP_WORDS=({} {})
                    _xfunc git _git
                    printf \"%s\\n\" \"${{COMPREPLY[@]}}\"
                    ",
                    count_words,
                    pos + self.command.len() + 1,
                    self.command,
                    line,
                    self.command,
                    line,
                );
        let completion_result = Command::new("bash")
            .args(vec![
                "-lic",
                script.as_str(),
            ])
            .output();
        let completion_str = match completion_result {
            Ok(completion_string) => String::from_utf8(completion_string.stdout).unwrap(),
            Err(err) => {
                return Err(ReadlineError::Io(err));
            },
        };

        let word_len = last_word.len();
        let completions: Vec<String> = completion_str.split("\n").map(|s| s.to_string()).collect();

        Ok((pos-word_len, completions))
    }
}

fn main() {
    // TODO use a real arg parser
    let program = args().nth(1).expect("no program specified");

    let mut line_editor = Editor::<BashCompleter>::new();
    line_editor.set_completer(Some(BashCompleter{command: program.to_string()}));

    let (history_file_option, prompts_config_path_option) = match home_dir() {
        Some(home) => {
            let config_dir: PathBuf = [home, PathBuf::from(".tpol")].iter().collect();
            if !config_dir.exists() {
                println!("creating config dir at {}", config_dir.to_str().unwrap());
                create_dir(&config_dir).unwrap();
            }

            (
                {
                    let history_dir: PathBuf = [&config_dir, &PathBuf::from("history")].iter().collect();
                    if !history_dir.exists() {
                        println!("creating history dir at {}", history_dir.to_str().unwrap());
                        create_dir(&history_dir).unwrap();
                    }

                    let command_history: PathBuf = [history_dir, PathBuf::from(&program)].iter().collect();
                    if !command_history.exists() {
                        println!("creating history file for {} at {}", &program, command_history.to_str().unwrap());
                        let _ = File::create(&command_history).unwrap();
                    }

                    Some(command_history)
                },
                {
                    let prompts_config_path: PathBuf = [&config_dir, &PathBuf::from("prompts.json")].iter().collect();
                    Some(prompts_config_path)
                },
            )
        }
        None => (None, None)
    };

    if let Some(ref history_file) = history_file_option.clone() {
        if let Err(err) = line_editor.load_history(history_file) {
            eprintln!("Warning: error while trying to load history file {}: {}", history_file.to_str().unwrap(), err);
        }
    } else {
        eprintln!("Warning: can't find home directory, no history will be saved");
    }

    let program_to_prompt_string_command = match prompts_config_path_option {
        Some(prompts_config_path) => {
            File::open(prompts_config_path)
                .map(|file| {
                    let prompts_config: HashMap<String, String> = serde_json::from_reader(file)
                        .unwrap_or(HashMap::new());
                    prompts_config
                })
                .unwrap_or(HashMap::new())
        }
        None => HashMap::new(),
    };

    let prompt_string_command_option = program_to_prompt_string_command.get(&program);

    loop {
        let prompt_string = match prompt_string_command_option.as_ref() {
            Some(ref command) => {
                match Command::new("bash").args(vec!["-lic", command]).output() {
                    Ok(output) => String::from_utf8(output.stdout).unwrap(),
                    Err(_) => {
                        // TODO log error
                        "".to_string()
                    }
                }
            },
            None => "".to_string(),
        };

        let line_result = line_editor.readline(format!("{}>{} ", prompt_string.trim(), &program).as_str());
        match line_result {
            Ok(line) => {
                if line == "" || line == "!" {
                    // ignore empty commands
                } else {
                    let mut command = if line.starts_with("!") {
                        let parts = line.split(" ");
                        let command = &parts.clone().nth(0).unwrap()[1..];
                        let args: Vec<&str> = parts.skip(1).collect();
                        let mut command = Command::new(command);
                        command.args(args);
                        command
                    } else {
                        let mut command = Command::new(&program);
                        // TODO deal with quoted strings
                        command.args(line.trim().split(" ").collect::<Vec<&str>>());
                        command
                    };
                    let mut process_result = command.spawn();
                    match process_result {
                        Ok(mut process) => {
                            // TODO maybe display return code?
                            let _ = process.wait();
                            // TODO maybe only save in history if it's successful?
                            line_editor.add_history_entry(&line);
                        },
                        Err(err) => println!("error while trying to run command: {:?}", err),
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                break;
            },
            Err(ReadlineError::Eof) => {
                break;
            },
            Err(err) => {
                eprintln!("{:?}", err);
                break;
            }
        }
    }

    if let Some(ref history_file) = history_file_option {
        if let Err(err) = line_editor.save_history(history_file) {
            eprintln!("Warning: error while trying to load history file {}: {}", history_file.to_str().unwrap(), err);
        }
    }
}
<|endoftext|>


<commit_before>extern crate ghoti;
extern crate getopts;

use getopts::Options;
use ghoti::correction;
use std::env;

fn print_usage(opts: Options) {
    let usage = "Usage: ghoti [options] <word>";
    print!("{}", opts.usage(usage));
}

fn main() {
    // Set up CLI options
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("v", "version", "print version info");

    // Ignore the first element of env::args() (program name)
    let args: Vec<String> = env::args().skip(1).collect();
    let matches = opts.parse(&args).unwrap();

    // Iterate through CLI flags
    if matches.opt_present("version") {
        println!("ghoti {}", env!("CARGO_PKG_VERSION"));
        return;
    } else if matches.opt_present("help") || matches.free.is_empty() {
        print_usage(opts);
        return;
    }

    println!("{}", correction(&matches.free[0]));
}
<commit_msg>Convert input to lowercase before correcting<commit_after>extern crate ghoti;
extern crate getopts;

use getopts::Options;
use ghoti::correction;
use std::env;

fn print_usage(opts: Options) {
    let usage = "Usage: ghoti [options] <word>";
    print!("{}", opts.usage(usage));
}

fn main() {
    // Set up CLI options
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("v", "version", "print version info");

    // Ignore the first element of env::args() (program name)
    let args: Vec<String> = env::args().skip(1).collect();
    let matches = opts.parse(&args).unwrap();

    // Iterate through CLI flags
    if matches.opt_present("version") {
        println!("ghoti {}", env!("CARGO_PKG_VERSION"));
        return;
    } else if matches.opt_present("help") || matches.free.is_empty() {
        print_usage(opts);
        return;
    }

    let word = matches.free[0].to_lowercase();
    println!("{}", correction(&word));
}
<|endoftext|>


<commit_before>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: MPL-2.0
//

#[macro_use]
extern crate log;
extern crate stderrlog;
#[macro_use]
extern crate structopt;
extern crate updatehub;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(
    name = "updatehub",
    author = "O.S. Systems Software LTDA. <contact@ossystems.com.br>",
    about = "A generic and safe Firmware Over-The-Air agent."
)]
#[structopt(raw(version = "updatehub::build_info::version()"))]
struct Opt {
    /// Increase the verboseness level
    #[structopt(short = "v", long = "verbose", parse(from_occurrences))]
    verbose: u8,
}

fn run() -> updatehub::Result<()> {
    let opt = Opt::from_args();

    stderrlog::new()
        .verbosity(opt.verbose as usize + 1)
        .init()?;

    info!(
        "Starting UpdateHub Agent {}",
        updatehub::build_info::version()
    );

    let settings = updatehub::settings::Settings::new().load()?;
    let runtime_settings = updatehub::runtime_settings::RuntimeSettings::new()
        .load(&settings.storage.runtime_settings)?;
    let firmware = updatehub::firmware::Metadata::new(&settings.firmware.metadata_path)?;

    updatehub::states::StateMachine::new(settings, runtime_settings, firmware).run();

    Ok(())
}

fn main() {
    if let Err(ref e) = run() {
        error!("{}", e);
        e.iter_causes()
            .skip(1)
            .for_each(|e| error!(" caused by: {}\n", e));

        std::process::exit(1);
    }
}
<commit_msg>main: Avoid a trivial casting<commit_after>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: MPL-2.0
//

#[macro_use]
extern crate log;
extern crate stderrlog;
#[macro_use]
extern crate structopt;
extern crate updatehub;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(
    name = "updatehub",
    author = "O.S. Systems Software LTDA. <contact@ossystems.com.br>",
    about = "A generic and safe Firmware Over-The-Air agent."
)]
#[structopt(raw(version = "updatehub::build_info::version()"))]
struct Opt {
    /// Increase the verboseness level
    #[structopt(short = "v", long = "verbose", parse(from_occurrences))]
    verbose: usize,
}

fn run() -> updatehub::Result<()> {
    let opt = Opt::from_args();

    stderrlog::new().verbosity(opt.verbose + 1).init()?;

    info!(
        "Starting UpdateHub Agent {}",
        updatehub::build_info::version()
    );

    let settings = updatehub::settings::Settings::new().load()?;
    let runtime_settings = updatehub::runtime_settings::RuntimeSettings::new()
        .load(&settings.storage.runtime_settings)?;
    let firmware = updatehub::firmware::Metadata::new(&settings.firmware.metadata_path)?;

    updatehub::states::StateMachine::new(settings, runtime_settings, firmware).run();

    Ok(())
}

fn main() {
    if let Err(ref e) = run() {
        error!("{}", e);
        e.iter_causes()
            .skip(1)
            .for_each(|e| error!(" caused by: {}\n", e));

        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate nix;
extern crate colored;

mod util;
mod stats;
mod filesystems;

use std::cmp;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::process;
use nix::sys::statvfs::vfs::Statvfs;
use colored::*;
use std::env;
use getopts::Options;

use util::{iec, bargraph};
use stats::Stats;
use filesystems::pseudo_filesystems;

const FS_SPEC: usize = 0;
const FS_FILE: usize = 1;
const FS_VFSTYPE: usize = 2;

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("a", "all", "display all filesystems");
    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(e) => { panic!(e); },
    };

    let file = match File::open("/proc/mounts") {
        Ok(f)  => f,
        Err(e) => {
            println!("Error: Could not open /proc/mounts - {}", e);
            process::exit(1);
        },
    };
    let reader = BufReader::new(&file);

    let excludes = pseudo_filesystems();

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if !matches.opt_present("a") && excludes.contains(fields[FS_VFSTYPE]) {
                    continue;
                }
                let statvfs = match Statvfs::for_path(fields[FS_FILE]) {
                    Ok(s) => s,
                    Err(err) => {
                        println!("Error: {}", err);
                        continue;
                    },
                };
                let size = statvfs.f_blocks * statvfs.f_bsize;
                let avail = statvfs.f_bavail * statvfs.f_bsize;
                if size == 0 && !matches.opt_present("a") {
                    continue;
                }
                let s = Stats::new(fields[FS_SPEC], size, avail, fields[FS_FILE]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            },
            Err(err) => println!("Error: {}", err),
        }
    }

    stats.sort();

    let headers = ["Filesystem", "Size", "Used", "Avail", "Use%", "", "Mounted on"];
    let headers: Vec<ColoredString> = headers.into_iter().map(|x| x.yellow()).collect();
    println!("{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {}",
             headers[0], headers[1], headers[2], headers[3],
             headers[4], headers[5], headers[6], width = max_width);

    for stat in stats {
        let fs = if stat.is_network() {
            stat.filesystem.cyan()
        } else {
            stat.filesystem.normal()
        };
        println!("{:width$} {:>5} {:>5} {:>5} {:>5.1} {:20} {}",
                 fs, iec(stat.size), iec(stat.used), iec(stat.avail),
                 stat.percent, bargraph(stat.percent), stat.mount, width = max_width);
    }

}
<commit_msg>Remove NaN from output.<commit_after>extern crate getopts;
extern crate nix;
extern crate colored;

mod util;
mod stats;
mod filesystems;

use std::cmp;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::process;
use nix::sys::statvfs::vfs::Statvfs;
use colored::*;
use std::env;
use getopts::Options;

use util::{iec, bargraph};
use stats::Stats;
use filesystems::pseudo_filesystems;

const FS_SPEC: usize = 0;
const FS_FILE: usize = 1;
const FS_VFSTYPE: usize = 2;

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("a", "all", "display all filesystems");
    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(e) => { panic!(e); },
    };

    let file = match File::open("/proc/mounts") {
        Ok(f)  => f,
        Err(e) => {
            println!("Error: Could not open /proc/mounts - {}", e);
            process::exit(1);
        },
    };
    let reader = BufReader::new(&file);

    let excludes = pseudo_filesystems();

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if !matches.opt_present("a") && excludes.contains(fields[FS_VFSTYPE]) {
                    continue;
                }
                let statvfs = match Statvfs::for_path(fields[FS_FILE]) {
                    Ok(s) => s,
                    Err(err) => {
                        println!("Error: {}", err);
                        continue;
                    },
                };
                let size = statvfs.f_blocks * statvfs.f_bsize;
                let avail = statvfs.f_bavail * statvfs.f_bsize;
                if size == 0 && !matches.opt_present("a") {
                    continue;
                }
                let s = Stats::new(fields[FS_SPEC], size, avail, fields[FS_FILE]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            },
            Err(err) => println!("Error: {}", err),
        }
    }

    stats.sort();

    let headers = ["Filesystem", "Size", "Used", "Avail", "Use%", "", "Mounted on"];
    let headers: Vec<ColoredString> = headers.into_iter().map(|x| x.yellow()).collect();
    println!("{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {}",
             headers[0], headers[1], headers[2], headers[3],
             headers[4], headers[5], headers[6], width = max_width);

    for stat in stats {
        let fs = if stat.is_network() {
            stat.filesystem.cyan()
        } else {
            stat.filesystem.normal()
        };
        let percent = if stat.percent.is_nan() {
            "    -".to_string()
        } else {
            format!("{:>5.1}", stat.percent)
        };
        println!("{:width$} {:>5} {:>5} {:>5} {} {:20} {}",
                 fs, iec(stat.size), iec(stat.used), iec(stat.avail),
                 percent, bargraph(stat.percent), stat.mount, width = max_width);
    }

}
<|endoftext|>


<commit_before>extern crate actix;
extern crate actix_web;
extern crate env_logger;
#[macro_use]
extern crate rust_embed;
extern crate futures;
extern crate json;
extern crate mime_guess;
extern crate r2d2;
extern crate r2d2_sqlite;
extern crate rusqlite;
extern crate serde;
extern crate serde_derive;
extern crate serde_json;
extern crate time;

use self::actix::prelude::*;
use actix_web::http::{header, Method};
use actix_web::{server, App, Body, HttpRequest, HttpResponse};
use futures::future::Future;
use mime_guess::guess_mime_type;
use r2d2_sqlite::SqliteConnectionManager;
use std::sync::Arc;

mod api;
mod db;
mod geoip;
use self::db::{DbExecutor, LogVisit};
use self::geoip::{GeoIPExecutor, LookupIP};

#[derive(RustEmbed)]
#[folder = "frontend/out/"]
struct Asset;

fn handle_embedded_file(path: &str) -> HttpResponse {
    let canonical_path = if path.is_empty() {
        "index.html"
    } else if path == "resume" || path == "resume/" {
        "resume/index.html"
    } else {
        path
    };
    match Asset::get(canonical_path) {
        Some(content) => HttpResponse::Ok()
            .header(
                header::CONTENT_TYPE,
                guess_mime_type(canonical_path).as_ref(),
            )
            .body(Body::from_slice(content.as_ref())),
        None => HttpResponse::NotFound().body("404 Not Found"),
    }
}

struct State {
    db: Addr<DbExecutor>,
    geoip: Addr<GeoIPExecutor>,
}

fn handle_static(req: HttpRequest<Arc<State>>) -> HttpResponse {
    handle_embedded_file(&req.path()[1..])
}

fn handle_resume(req: HttpRequest<Arc<State>>) -> HttpResponse {
    use std::net::{AddrParseError, IpAddr, SocketAddr};

    let timestamp = time::now().to_timespec();
    let state = req.state().clone();
    match req.connection_info().remote() {
        Some(remote_host) => {
            let ip: Option<IpAddr> = {
                let socket_remote: Result<SocketAddr, AddrParseError> = remote_host.parse();
                let ipaddr_remote: Result<IpAddr, AddrParseError> = remote_host.parse();
                match socket_remote {
                    Ok(socket_remote) => { Some(socket_remote.ip()) }
                    _ => ipaddr_remote.ok()
                }
            };

            match ip {
                Some(ip) => {
                    let ip: String = ip.to_string();
                    let ft = state
                        .geoip
                        .send(LookupIP {
                            address: ip.clone(),
                        })
                        .and_then(move |res| {
                            let msg = match res {
                                Ok(ref location) => LogVisit {
                                    ipaddr: ip,
                                    time: timestamp,
                                    location: location.location,
                                },

                                Err(_) => LogVisit {
                                    ipaddr: ip,
                                    time: timestamp,
                                    location: (0.0, 0.0),
                                },
                            };
                            state.db.send(msg)
                        })
                        .map(|_| ())
                        .map_err(|_| ());
                    req.server_settings().cpu_pool().spawn(ft).forget();
                }
                _ => { println!("Failed to parse {}", remote_host); }
            };
        }
        _ => {
            println!("no remote");
        }
    };

    handle_embedded_file("static/resume.pdf")
}

fn main() {
    ::std::env::set_var("RUST_LOG", "actix_web=debug");

    let geoip_api_key = api::GEOIP_KEY.to_string();

    let sys = actix::System::new("website");
    let manager = SqliteConnectionManager::file("resume-logs.sqlite");
    let pool = r2d2::Pool::new(manager).unwrap();
    let db_addr = SyncArbiter::start(1, move || DbExecutor::new(pool.clone()));
    let geoip_addr = Arbiter::start(|_| GeoIPExecutor::new(geoip_api_key));

    server::new(move || {
        App::with_state(Arc::new(State {
            db: db_addr.clone(),
            geoip: geoip_addr.clone(),
        }))
        .route("/resume.pdf", Method::GET, handle_resume)
        .route("/{_:.*}", Method::GET, handle_static)
    })
    .bind("0.0.0.0:8000")
    .unwrap()
    .run();

    let _ = sys.run();
}
<commit_msg>Resolve next.js exported html files<commit_after>extern crate actix;
extern crate actix_web;
extern crate env_logger;
#[macro_use]
extern crate rust_embed;
extern crate futures;
extern crate json;
extern crate mime_guess;
extern crate r2d2;
extern crate r2d2_sqlite;
extern crate rusqlite;
extern crate serde;
extern crate serde_derive;
extern crate serde_json;
extern crate time;

use self::actix::prelude::*;
use actix_web::http::{header, Method};
use actix_web::{server, App, Body, HttpRequest, HttpResponse};
use futures::future::Future;
use mime_guess::guess_mime_type;
use r2d2_sqlite::SqliteConnectionManager;
use std::sync::Arc;
use std::path::Path;

mod api;
mod db;
mod geoip;
use self::db::{DbExecutor, LogVisit};
use self::geoip::{GeoIPExecutor, LookupIP};

#[derive(RustEmbed)]
#[folder = "frontend/out/"]
struct Asset;

fn handle_embedded_file(path: &str) -> HttpResponse {
    let (mime_type, content) = match Asset::get(path) {
        Some(content) => (guess_mime_type(path), Some(content)),
        None => {
            let path = Path::new(path).join("index.html");
            (guess_mime_type(&path), Asset::get(&path.to_string_lossy()))
        }
    };

    match content {
        Some(content) => HttpResponse::Ok()
            .header(
                header::CONTENT_TYPE,
                mime_type.as_ref(),
            )
            .header(header::CACHE_CONTROL, "7200")
            .body(Body::from_slice(content.as_ref())),
        None => HttpResponse::NotFound().body("404 Not Found"),
    }
}

struct State {
    db: Addr<DbExecutor>,
    geoip: Addr<GeoIPExecutor>,
}

fn handle_static(req: HttpRequest<Arc<State>>) -> HttpResponse {
    handle_embedded_file(&req.path()[1..])
}

fn handle_resume(req: HttpRequest<Arc<State>>) -> HttpResponse {
    use std::net::{AddrParseError, IpAddr, SocketAddr};

    let timestamp = time::now().to_timespec();
    let state = req.state().clone();
    match req.connection_info().remote() {
        Some(remote_host) => {
            let ip: Option<IpAddr> = {
                let socket_remote: Result<SocketAddr, AddrParseError> = remote_host.parse();
                let ipaddr_remote: Result<IpAddr, AddrParseError> = remote_host.parse();
                match socket_remote {
                    Ok(socket_remote) => { Some(socket_remote.ip()) }
                    _ => ipaddr_remote.ok()
                }
            };

            match ip {
                Some(ip) => {
                    let ip: String = ip.to_string();
                    let ft = state
                        .geoip
                        .send(LookupIP {
                            address: ip.clone(),
                        })
                        .and_then(move |res| {
                            let msg = match res {
                                Ok(ref location) => LogVisit {
                                    ipaddr: ip,
                                    time: timestamp,
                                    location: location.location,
                                },

                                Err(_) => LogVisit {
                                    ipaddr: ip,
                                    time: timestamp,
                                    location: (0.0, 0.0),
                                },
                            };
                            state.db.send(msg)
                        })
                        .map(|_| ())
                        .map_err(|_| ());
                    req.server_settings().cpu_pool().spawn(ft).forget();
                }
                _ => { println!("Failed to parse {}", remote_host); }
            };
        }
        _ => {
            println!("no remote");
        }
    };

    handle_embedded_file("static/resume.pdf")
}

fn main() {
    ::std::env::set_var("RUST_LOG", "actix_web=debug");

    let geoip_api_key = api::GEOIP_KEY.to_string();

    let sys = actix::System::new("website");
    let manager = SqliteConnectionManager::file("resume-logs.sqlite");
    let pool = r2d2::Pool::new(manager).unwrap();
    let db_addr = SyncArbiter::start(1, move || DbExecutor::new(pool.clone()));
    let geoip_addr = Arbiter::start(|_| GeoIPExecutor::new(geoip_api_key));

    server::new(move || {
        App::with_state(Arc::new(State {
            db: db_addr.clone(),
            geoip: geoip_addr.clone(),
        }))
        .route("/resume.pdf", Method::GET, handle_resume)
        .route("/{_:.*}", Method::GET, handle_static)
    })
    .bind("0.0.0.0:8000")
    .unwrap()
    .run();

    let _ = sys.run();
}
<|endoftext|>


<commit_before>// Copyright (c) Björn Edström <be@bjrn.se> 2015.
// See LICENSE for details.

extern crate chrono;
extern crate crypto;
extern crate getopts;
extern crate num;
extern crate rustc_serialize;

mod timmy;

use chrono::datetime::DateTime;
use chrono::offset::utc::UTC;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use getopts::Options;
use num::bigint::BigUint;
use rustc_serialize::base64::{STANDARD, ToBase64, FromBase64};
use rustc_serialize::json::{self};
use std::env;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io;
use std::net::TcpStream;
use std::process::exit;

use timmy::rsa::*;
use timmy::util::*;
use timmy::tls::*;
use timmy::x509::*;

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

#[derive(RustcDecodable, RustcEncodable, Debug)]
struct JsonOutput {
    blob: String,
    certificates: Vec<String>,
    signature: String
}

fn verify(blob: &Vec<u8>, cert0: &Vec<u8>, signature: &Vec<u8>) -> i32 {
    // Parse certificates
    let cert = X509Certificate::new(cert0.clone());
    let parsed_cert = cert.parse().unwrap(); // XXX unwrap

    // Check if certificate expired.
    let utc_now: DateTime<UTC> = UTC::now();
    let cert_still_valid = utc_now >= parsed_cert.validity.0 && utc_now <= parsed_cert.validity.1;
    if !cert_still_valid {
        println_stderr!("ERROR! Signature verification FAILURE: Certificate has expired.");
        return 1;
    }

    match parsed_cert.key {
        PublicKey::RSA(rsa_n, rsa_e) => {

            // Perform RSA signature operation
            let signature_int = BigUint::from_bytes_be(&signature);
            let sig_op = rsa_encrypt(&signature_int, &rsa_e,  &rsa_n);

            // Fix up PKCS1.5 blob
            let mut raw_pkcs1_ = sig_op.to_bytes_be();
            raw_pkcs1_.insert(0, 0x00);
            let raw_pkcs1 = raw_pkcs1_;

            // Construct our own PKCS 1.5 blob to compare against
            let tls_hash = weird_tls_hash(&blob);
            let constructed_pkcs1 = make_pkcs1_sig_padding(&rsa_n, &tls_hash);

            let valid_signature = crypto_compare(&constructed_pkcs1, &raw_pkcs1);

            if valid_signature {
                // Signature is valid, parse out fields from blob.
                let mut tls = TLSHandshake::new();
                tls.client_random = blob[0..32].iter().cloned().collect();
                tls.server_random = blob[32..64].iter().cloned().collect();

                // Validate signed timestamp against certificate validity period.
                let unix_timestamp = tls.get_unix_timestamp();
                let ts = timestamp_to_datetime(unix_timestamp);
                let valid_dates = ts >= parsed_cert.validity.0 && ts <= parsed_cert.validity.1;

                if valid_dates {
                    // Success!
                    println!("Signature verification SUCCESS.");
                    println!("Warning! Signature only verified against first X509 certificate.");
                    println!("Please verify yourself that the certificate chain is valid.");
                    println!("");
                    println!("{} Signed SHA-256 {} at {:?} (Unix Timestamp: {})",
                             parsed_cert.subject,
                             to_hex_string(&tls.client_random), ts, unix_timestamp);
                } else {
                    println!("ERROR! Signature verification FAILURE: Invalid timestamp.");
                    return 1;
                }

            } else {
                println!("ERROR! Signature verification FAILURE.");
                return 1;
            }
        }
    }

    0
}

fn sign(server: &String, port: &u16, hash_buf: &[u8; 32]) -> i32 {
    // Construct our special ClientHello message and send it to the server.
    let conn_str = format!("{}:{}", server, port);
    let mut tcpconn = TcpStream::connect(&conn_str[..]).unwrap();

    let mut ch = SimpleBinaryWriter::new();
    create_special_client_hello(&mut ch, &hash_buf);

    match tcpconn.write(&ch.buf) {
        Err(_) => {
            println_stderr!("ERROR! Failed to write to server.");
            return 1;
        }
        Ok(_) => {}
    }

    // Parse the response.
    let mut pars = BinaryParser::new(&mut tcpconn);
    let mut tls = TLSHandshake::new();

    tls.client_random.extend(hash_buf[0..32].iter());

    tls.parse_server_hello(&mut pars);
    tls.parse_certificates(&mut pars);
    tls.parse_server_key_exchange(&mut pars);

    // Extract timestamp and perform checks on it.
    let unix_timestamp = tls.get_unix_timestamp();
    let ts = timestamp_to_datetime(unix_timestamp);

    let utc_now: DateTime<UTC> = UTC::now();
    let utc_now_ts = utc_now.timestamp() as u32;

    if unix_timestamp < utc_now_ts - 3600 || unix_timestamp > utc_now_ts + 3600 {
        println_stderr!("ERROR! Server responded with invalid time! Aborting.");
        return 1;
    }

    // Output banner and result JSON blob.
    println_stderr!("{} signed SHA-256 {} at {:?} (Unix Timestamp: {})",
                    server, to_hex_string(&hash_buf[0..32].iter().cloned().collect()), ts, unix_timestamp);

    let json_output = JsonOutput {
        blob: tls.signed_blob.to_base64(STANDARD),
        signature: tls.signature.to_base64(STANDARD),
        certificates: tls.certs.iter().map(
            |c| c.buf.to_base64(STANDARD)
            ).collect(),
    };

    println!("{}", json::encode(&json_output).unwrap());

    0
}

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

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();

    opts.optopt("V", "verify", "verify signature object", "PATH");
    opts.optopt("S", "sign", "input file to sign [-]", "PATH");
    opts.optopt("H", "host", "set server for signing [www.google.com]", "HOSTNAME");
    opts.optopt("p", "port", "set port for --server [443]", "PORT");

    opts.optflag("h", "help", "print this help menu");

    let parse_result = opts.parse(&args[1..]);

    if let Err(f) = parse_result {
        println_stderr!("ERROR: {}", f.to_string());
        return;
    }

    let matches = parse_result.unwrap();

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

    // parse "host"
    let server = if matches.opt_present("H") {
        matches.opt_str("H").unwrap()
    } else {
        "www.google.com".to_string()
    };

    // parse "port"
    let port: u16 = if matches.opt_present("p") {
        let port_str = matches.opt_str("p").unwrap();
        match port_str.parse() {
            Ok(p) => p,
            Err(_) => {
                print_usage(&program, opts);
                return;
            }
        }
    } else {
        443
    };

    if !matches.opt_present("V") {
        // sign

        // parse "file" and hash it
        let mut hasher = Sha256::new();

        if matches.opt_present("S") {
            let path = matches.opt_str("S").unwrap();
            let mut file_handle = match File::open(path) {
                Ok(f) => f,
                Err(s) => {
                    println_stderr!("Reading file failed: {}", s);
                    exit(1);
                }
            };

            hash_content(&mut file_handle, &mut hasher);
        } else {
            hash_content(&mut io::stdin(), &mut hasher);
        };

        let mut hash_buf: [u8; 32] = [0; 32];
        hasher.result(&mut hash_buf);

        let ret = sign(&server, &port, &hash_buf);

        exit(ret);
    } else {
        // verify

        let path = matches.opt_str("V").unwrap();
        let mut contents: Vec<u8> = Vec::new();
        let file_handle = File::open(path) ;
        file_handle.unwrap().read_to_end(&mut contents).unwrap();

        let filestr = String::from_utf8(contents).unwrap();

        let json_blob: JsonOutput = json::decode(&filestr).unwrap();

        let blob = json_blob.blob.from_base64().unwrap();
        let cert0 = json_blob.certificates[0].from_base64().unwrap();
        let signature = json_blob.signature.from_base64().unwrap();

        let ret = verify(&blob, &cert0, &signature);

        exit(ret);
    }
}
<commit_msg>Improve main.rs error handling.<commit_after>// Copyright (c) Björn Edström <be@bjrn.se> 2015.
// See LICENSE for details.

extern crate chrono;
extern crate crypto;
extern crate getopts;
extern crate num;
extern crate rustc_serialize;

mod timmy;

use chrono::datetime::DateTime;
use chrono::offset::utc::UTC;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use getopts::Options;
use num::bigint::BigUint;
use rustc_serialize::base64::{STANDARD, ToBase64, FromBase64};
use rustc_serialize::json::{self};
use std::env;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io;
use std::net::TcpStream;
use std::process::exit;

use timmy::rsa::*;
use timmy::util::*;
use timmy::tls::*;
use timmy::x509::*;

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

#[derive(RustcDecodable, RustcEncodable, Debug)]
struct JsonOutput {
    blob: String,
    certificates: Vec<String>,
    signature: String
}

fn verify(blob: &Vec<u8>, cert0: &Vec<u8>, signature: &Vec<u8>) -> i32 {
    // Parse certificates
    let cert = X509Certificate::new(cert0.clone());
    let parsed_cert = cert.parse().unwrap(); // XXX unwrap

    // Check if certificate expired.
    let utc_now: DateTime<UTC> = UTC::now();
    let cert_still_valid = utc_now >= parsed_cert.validity.0 && utc_now <= parsed_cert.validity.1;
    if !cert_still_valid {
        println_stderr!("ERROR! Signature verification FAILURE: Certificate has expired.");
        return 1;
    }

    match parsed_cert.key {
        PublicKey::RSA(rsa_n, rsa_e) => {

            // Perform RSA signature operation
            let signature_int = BigUint::from_bytes_be(&signature);
            let sig_op = rsa_encrypt(&signature_int, &rsa_e,  &rsa_n);

            // Fix up PKCS1.5 blob
            let mut raw_pkcs1_ = sig_op.to_bytes_be();
            raw_pkcs1_.insert(0, 0x00);
            let raw_pkcs1 = raw_pkcs1_;

            // Construct our own PKCS 1.5 blob to compare against
            let tls_hash = weird_tls_hash(&blob);
            let constructed_pkcs1 = make_pkcs1_sig_padding(&rsa_n, &tls_hash);

            let valid_signature = crypto_compare(&constructed_pkcs1, &raw_pkcs1);

            if valid_signature {
                // Signature is valid, parse out fields from blob.
                let mut tls = TLSHandshake::new();
                tls.client_random = blob[0..32].iter().cloned().collect();
                tls.server_random = blob[32..64].iter().cloned().collect();

                // Validate signed timestamp against certificate validity period.
                let unix_timestamp = tls.get_unix_timestamp();
                let ts = timestamp_to_datetime(unix_timestamp);
                let valid_dates = ts >= parsed_cert.validity.0 && ts <= parsed_cert.validity.1;

                if valid_dates {
                    // Success!
                    println!("Signature verification SUCCESS.");
                    println!("Warning! Signature only verified against first X509 certificate.");
                    println!("Please verify yourself that the certificate chain is valid.");
                    println!("");
                    println!("{} Signed SHA-256 {} at {:?} (Unix Timestamp: {})",
                             parsed_cert.subject,
                             to_hex_string(&tls.client_random), ts, unix_timestamp);
                } else {
                    println!("ERROR! Signature verification FAILURE: Invalid timestamp.");
                    return 1;
                }

            } else {
                println!("ERROR! Signature verification FAILURE.");
                return 1;
            }
        }
    }

    0
}

fn sign(server: &String, port: &u16, hash_buf: &[u8; 32]) -> i32 {
    // Construct our special ClientHello message and send it to the server.
    let conn_str = format!("{}:{}", server, port);
    let mut tcpconn = TcpStream::connect(&conn_str[..]).unwrap();

    let mut ch = SimpleBinaryWriter::new();
    create_special_client_hello(&mut ch, &hash_buf);

    match tcpconn.write(&ch.buf) {
        Err(_) => {
            println_stderr!("ERROR! Failed to write to server.");
            return 1;
        }
        Ok(_) => {}
    }

    // Parse the response.
    let mut pars = BinaryParser::new(&mut tcpconn);
    let mut tls = TLSHandshake::new();

    tls.client_random.extend(hash_buf[0..32].iter());

    tls.parse_server_hello(&mut pars);
    tls.parse_certificates(&mut pars);
    tls.parse_server_key_exchange(&mut pars);

    // Extract timestamp and perform checks on it.
    let unix_timestamp = tls.get_unix_timestamp();
    let ts = timestamp_to_datetime(unix_timestamp);

    let utc_now: DateTime<UTC> = UTC::now();
    let utc_now_ts = utc_now.timestamp() as u32;

    if unix_timestamp < utc_now_ts - 3600 || unix_timestamp > utc_now_ts + 3600 {
        println_stderr!("ERROR! Server responded with invalid time! Aborting.");
        return 1;
    }

    // Output banner and result JSON blob.
    println_stderr!("{} signed SHA-256 {} at {:?} (Unix Timestamp: {})",
                    server, to_hex_string(&hash_buf[0..32].iter().cloned().collect()), ts, unix_timestamp);

    let json_output = JsonOutput {
        blob: tls.signed_blob.to_base64(STANDARD),
        signature: tls.signature.to_base64(STANDARD),
        certificates: tls.certs.iter().map(
            |c| c.buf.to_base64(STANDARD)
            ).collect(),
    };

    println!("{}", json::encode(&json_output).unwrap());

    0
}

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

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();

    opts.optopt("V", "verify", "verify signature object", "PATH");
    opts.optopt("S", "sign", "input file to sign [-]", "PATH");
    opts.optopt("H", "host", "set server for signing [www.google.com]", "HOSTNAME");
    opts.optopt("p", "port", "set port for --server [443]", "PORT");

    opts.optflag("h", "help", "print this help menu");

    let parse_result = opts.parse(&args[1..]);

    if let Err(f) = parse_result {
        println_stderr!("ERROR: {}", f.to_string());
        return;
    }

    let matches = parse_result.unwrap();

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

    // parse "host"
    let server = if matches.opt_present("H") {
        matches.opt_str("H").unwrap()
    } else {
        "www.google.com".to_string()
    };

    // parse "port"
    let port: u16 = if matches.opt_present("p") {
        let port_str = matches.opt_str("p").unwrap();
        match port_str.parse() {
            Ok(p) => p,
            Err(_) => {
                print_usage(&program, opts);
                return;
            }
        }
    } else {
        443
    };

    if !matches.opt_present("V") {
        // sign

        // parse "file" and hash it
        let mut hasher = Sha256::new();

        if matches.opt_present("S") {
            let path = matches.opt_str("S").unwrap();
            let mut file_handle = match File::open(path) {
                Ok(f) => f,
                Err(s) => {
                    println_stderr!("Reading file failed: {}", s);
                    exit(1);
                }
            };

            hash_content(&mut file_handle, &mut hasher);
        } else {
            hash_content(&mut io::stdin(), &mut hasher);
        };

        let mut hash_buf: [u8; 32] = [0; 32];
        hasher.result(&mut hash_buf);

        let ret = sign(&server, &port, &hash_buf);

        exit(ret);
    } else {
        // verify

        let path = matches.opt_str("V").unwrap();
        let mut contents: Vec<u8> = Vec::new();

        let mut file_handle = match File::open(path) {
                Ok(f) => f,
                Err(s) => {
                    println_stderr!("Reading file failed: {}", s);
                    exit(1);
                }
            };

        file_handle.read_to_end(&mut contents).unwrap();

        let filestr = String::from_utf8(contents).unwrap();

        let json_blob: JsonOutput = json::decode(&filestr).unwrap();

        let blob = json_blob.blob.from_base64().unwrap();
        let cert0 = json_blob.certificates[0].from_base64().unwrap();
        let signature = json_blob.signature.from_base64().unwrap();

        let ret = verify(&blob, &cert0, &signature);

        exit(ret);
    }
}
<|endoftext|>


<commit_before>extern crate kernel32;
extern crate user32;
extern crate winapi;
extern crate libc;
extern crate gdi32;

use winapi::windef::HWND;
use winapi::windef::HMENU;
use winapi::windef::HBRUSH;
use winapi::minwindef::HINSTANCE;

use winapi::minwindef::UINT;
use winapi::minwindef::DWORD;
use winapi::minwindef::WPARAM;
use winapi::minwindef::LPARAM;
use winapi::minwindef::LRESULT;
use winapi::winnt::LPCWSTR;

use winapi::winuser::WS_OVERLAPPEDWINDOW;
use winapi::winuser::WS_VISIBLE;
use winapi::winuser::WNDCLASSW;
use winapi::winuser::CF_BITMAP;

use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

const g_class_name: str = "winshot";

// Rectangle represents screen coordinates
struct Rectangle {
	x: i32,
	y: i32,
	x2: i32,
	y2: i32,
}

// convert normal string to wide string
#[allow(dead_code)]
fn to_wstring(str: &str) -> *const u16 {
	let v: Vec<u16> = OsStr::new(str).encode_wide() . chain(Some(0).into_iter()).collect();
	v.as_ptr()
}

// This is our window message handler function. Currently,
// it only processes the WM_DESTROY message to exit our window properly on close event.
#[allow(dead_code)]
pub unsafe extern "system" fn window_proc(h_wnd: HWND, msg: UINT, w_param: WPARAM, l_param: LPARAM) -> LRESULT {
	if msg == winapi::winuser::WM_DESTROY {
		user32::PostQuitMessage(0);
	}

	match msg {
		winapi::winuser::WM_DESTROY => user32::PostQuitMessage(0),
		winapi::winuser::WM_MOUSEMOVE => 0 as LRESULT,
		winapi::winuser::WM_LBUTTONDOWN => 0 as LRESULT,
		winapi::winuser::WM_LBUTTONUP => 0 as LRESULT,
		_ => user32::DefWindowProcW(h_wnd, msg, w_param, l_param),
	}
}

// The following function hides the Console Window since we are building a GUI application.
#[allow(dead_code)]
fn hide_console_window() {
	let window = unsafe {
		kernel32::GetConsoleWindow()
	};

	if window != std::ptr::null_mut() {
		unsafe {
			user32::ShowWindow(window, winapi::SW_HIDE)
		};
	}
}

fn normalize_coords(rect: Rectangle) -> Rectangle {
    let Rectangle{mut x, mut y, mut x2, mut y2} = rect;

    if x > x2 {
        let tmp = x;
        x = x2;
        x2 = tmp;
    }
    if y > y2 {
        let tmp = y;
        y = y2;
        y2 = tmp;
    }

    Rectangle{x: x, y: y, x2: x2, y2: y2}
}

fn get_screen_rect() -> Rectangle {
	Rectangle{
		x /* left */: user32::GetSystemMetrics(winapi::winuser::SM_XVIRTUALSCREEN),
		y /* top */: user32::GetSystemMetrics(winapi::winuser::SM_YVIRTUALSCREEN),
		x2 /* right */: user32::GetSystemMetrics(winapi::winuser::SM_CXVIRTUALSCREEN) + x,
		y2 /* bottom */: user32::GetSystemMetrics(winapi::winuser::SM_CYVIRTUALSCREEN) + y,
	}
}

fn capture_screen_clipboard(hwnd: HWND, rect: mut Rectangle) -> bool {
	// normalize coordinates
	rect = normalize_coords(rect);
	let w = rect.x2 - rect.x;
	let h = rect.y2 - rect.y;

	let screen_dc = user32::GetDC(0 as HWND);
	let shot_dc = gdi32::CreateCompatibleDC(screen_dc);
	let shot_bitmap = gdi32::CreateCompatibleBitmap(screen_dc, w, h);
	let old_obj = gdi32::SelectObject(shot_dc, shot_bitmap);

	if !gdi32::BitBlt(shot_dc, 0, 0, w, h, screen_dc, rect.x, rect.y, 0 as DWORD) {
		println!("{:?}", "BitBlt failed? Perhaps.");
		false
	}

	let mut ret = false;
	if user32::OpenClipboard(hwnd) {
		if user32::EmptyClipboard() {
			if user32::SetClipboardData(CF_BITMAP, shot_bitmap) {
				ret = true;
			}
			user32::CloseClipboard();
		}
	} else {
		println!("{:?}", "could not open clipboard");
	}

	// Clean up
	gdi32::DeleteDC(shot_dc);
	gdi32::DeleteDC(screen_dc);
	gdi32::SelectObject(shot_dc, old_obj);

	return ret;
}

fn main() {
	unsafe {
		let hInstance = kernel32::GetModuleHandle(0 as LPCWSTR);
		let m_class_name = to_wstring(g_class_name);
		let wnd = WNDCLASSW {
			hInstance: hInstance,
			lpszClassName: m_class_name,
			lpszMenuName: 0 as LPCWSTR,
			lpfnWndProc: Some(window_proc),
			cbClsExtra: 0,
			cbWndExtra: 0,
			style: winapi::winuser::CS_HREDRAW | winapi::winuser::CS_VREDRAW,
			hbrBackground: 0,
			hCursor: user32::LoadCursorW(0 as HINSTANCE, winapi::winuser::IDC_CROSS),
			hIcon: user32::LoadIconW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
		};

		user32::RegisterClassW(&wnd);
		let rect = get_screen_rect();
		let exstyle = winapi::winuser::WS_EX_TRANSPARENT;
		let style = winapi::winuser::WS_POPUP;

		let win = user32::CreateWindowEx(exstyle,
			m_class_name,
			m_class_name,
			style,
			// dimensions
			0, 0, rect.x2, rect.y2,
			0, // no parent
			0, // no menu
			hInstance, // module_instance
			0 as LPARAM,
		);

		user32::ShowWindow(win, winapi::winuser::SW_SHOW);
		user32::ShowWindow(win, winapi::winuser::SW_SHOWMAXIMIZED);
		user32::SetForegroundWindow(win);

		capture_screen_clipboard(win, Rectangle{
			x: 0,
			y: 0,
			x2: 200,
			y2: 200,
		});
		user32::DestroyWindow(win);
	}
}

// fn main() {
// 	// Here our unsafe code goes
// 	unsafe {
// 		// First we hide the console window
// 		hide_console_window();

// 		// Then we initialize the WNDCLASS structure
// 		let m_class_name = to_wstring(g_class_name);
// 		let wnd = WNDCLASSW {
// 			hInstance: 0 as HINSTANCE,
// 			lpszClassName = m_class_name,
// 			lpszMenuName: 0 as LPCWSTR,
// 			lpfnWndProc: Some(window_proc),

// 			style: winapi::winuser::CS_HREDRAW | winapi::winuser::CS_VREDRAW,

// 			cbClsExtra: 0,
// 			cbWndExtra: 0,

// 			hIcon: user32::LoadIconW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
// 			hCursor: user32::LoadCursorW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
// 			hbrBackground: 16 as HBRUSH,

// 		};

// 		// Register our class
// 		user32::RegisterClassW(&wnd);

// 		let h_wnd_desktop = user32::GetDesktopWindow();

// 		user32::CreateWindowExA(0, "my_window".as_ptr() as *mut _,
// 			"Simple Window".as_ptr() as *mut _, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
// 			0, 0, 400, 400, h_wnd_desktop, 0 as HMENU, 0 as HINSTANCE,
// 			std::ptr::null_mut());

// 		let mut msg = winapi::winuser::MSG {
// 			hwnd: 0 as HWND,
// 			message: 0 as UINT,
// 			wParam: 0 as WPARAM,
// 			lParam: 0 as LPARAM,
// 			time: 0 as DWORD,
// 			pt : winapi::windef::POINT{ x: 0, y: 0, },
// 		};

// 		// Kick off the application loop
// 		loop {
// 			let pm = user32::PeekMessageW(&mut msg, 0 as HWND, 0, 0, winapi::winuser::PM_REMOVE);

// 			if pm == 0 {
// 				continue;
// 			}

// 			if msg.message == winapi::winuser::WM_QUIT {
// 				break;
// 			}

// 			user32::TranslateMessage(&mut msg);
// 			user32::DispatchMessageW(&mut msg);
// 		}
// 	}
// }<commit_msg>Cleaning<commit_after>extern crate kernel32;
extern crate user32;
extern crate winapi;
extern crate libc;
extern crate gdi32;

use winapi::windef::HWND;
use winapi::windef::HMENU;
use winapi::windef::HBRUSH;
use winapi::minwindef::HINSTANCE;

use winapi::minwindef::UINT;
use winapi::minwindef::DWORD;
use winapi::minwindef::WPARAM;
use winapi::minwindef::LPARAM;
use winapi::minwindef::LRESULT;
use winapi::winnt::LPCWSTR;

use winapi::winuser::WS_OVERLAPPEDWINDOW;
use winapi::winuser::WS_VISIBLE;
use winapi::winuser::WNDCLASSW;
use winapi::winuser::CF_BITMAP;

use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

const g_class_name: &'static str = "winshot";

// Rectangle represents screen coordinates
struct Rectangle {
	x: i32,
	y: i32,
	x2: i32,
	y2: i32,
}

// convert normal string to wide string
#[allow(dead_code)]
fn to_wstring(str: &str) -> *const u16 {
	let v: Vec<u16> = OsStr::new(str).encode_wide() . chain(Some(0).into_iter()).collect();
	v.as_ptr()
}

// This is our window message handler function. Currently,
// it only processes the WM_DESTROY message to exit our window properly on close event.
#[allow(dead_code)]
pub unsafe extern "system" fn window_proc(h_wnd: HWND, msg: UINT, w_param: WPARAM, l_param: LPARAM) -> LRESULT {
	if msg == winapi::winuser::WM_DESTROY {
		user32::PostQuitMessage(0);
	}

	match msg {
		winapi::winuser::WM_DESTROY => user32::PostQuitMessage(0),
		winapi::winuser::WM_MOUSEMOVE => 0 as LRESULT,
		winapi::winuser::WM_LBUTTONDOWN => 0 as LRESULT,
		winapi::winuser::WM_LBUTTONUP => 0 as LRESULT,
		_ => user32::DefWindowProcW(h_wnd, msg, w_param, l_param),
	}
}

// The following function hides the Console Window since we are building a GUI application.
#[allow(dead_code)]
fn hide_console_window() {
	let window = unsafe {
		kernel32::GetConsoleWindow()
	};

	if window != std::ptr::null_mut() {
		unsafe {
			user32::ShowWindow(window, winapi::SW_HIDE)
		};
	}
}

fn normalize_coords(rect: Rectangle) -> Rectangle {
    let Rectangle{mut x, mut y, mut x2, mut y2} = rect;

    if x > x2 {
        let tmp = x;
        x = x2;
        x2 = tmp;
    }
    if y > y2 {
        let tmp = y;
        y = y2;
        y2 = tmp;
    }

    Rectangle{x: x, y: y, x2: x2, y2: y2}
}

fn get_screen_rect() -> Rectangle {
	Rectangle{
		x /* left */: user32::GetSystemMetrics(winapi::winuser::SM_XVIRTUALSCREEN),
		y /* top */: user32::GetSystemMetrics(winapi::winuser::SM_YVIRTUALSCREEN),
		x2 /* right */: user32::GetSystemMetrics(winapi::winuser::SM_CXVIRTUALSCREEN) + user32::GetSystemMetrics(winapi::winuser::SM_XVIRTUALSCREEN),
		y2 /* bottom */: user32::GetSystemMetrics(winapi::winuser::SM_CYVIRTUALSCREEN) + user32::GetSystemMetrics(winapi::winuser::SM_CYVIRTUALSCREEN),
	}
}

fn capture_screen_clipboard(hwnd: HWND, mut rect: Rectangle) -> bool {
	// normalize coordinates
	let rect = normalize_coords(rect);
	let w = rect.x2 - rect.x;
	let h = rect.y2 - rect.y;

	let screen_dc = user32::GetDC(0 as HWND);
	let shot_dc = gdi32::CreateCompatibleDC(screen_dc);
	let shot_bitmap = gdi32::CreateCompatibleBitmap(screen_dc, w, h);
	let old_obj = gdi32::SelectObject(shot_dc, shot_bitmap);

	if !gdi32::BitBlt(shot_dc, 0, 0, w, h, screen_dc, rect.x, rect.y, 0 as DWORD) {
		println!("{:?}", "BitBlt failed? Perhaps.");
		false
	}

	let mut ret = false;
	if user32::OpenClipboard(hwnd) {
		if user32::EmptyClipboard() {
			if user32::SetClipboardData(CF_BITMAP, shot_bitmap) {
				ret = true;
			}
			user32::CloseClipboard();
		}
	} else {
		println!("{:?}", "could not open clipboard");
	}

	// Clean up
	gdi32::DeleteDC(shot_dc);
	gdi32::DeleteDC(screen_dc);
	gdi32::SelectObject(shot_dc, old_obj);

	return ret;
}

fn main() {
	unsafe {
		let hInstance = kernel32::GetModuleHandleW(0 as LPCWSTR);
		let m_class_name = to_wstring(g_class_name);
		let wnd = WNDCLASSW {
			hInstance: hInstance,
			lpszClassName: m_class_name,
			lpszMenuName: 0 as LPCWSTR,
			lpfnWndProc: Some(window_proc),
			cbClsExtra: 0,
			cbWndExtra: 0,
			style: winapi::winuser::CS_HREDRAW | winapi::winuser::CS_VREDRAW,
			hbrBackground: 0,
			hCursor: user32::LoadCursorW(0 as HINSTANCE, winapi::winuser::IDC_CROSS),
			hIcon: user32::LoadIconW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
		};

		user32::RegisterClassW(&wnd);
		let rect = get_screen_rect();
		let exstyle = winapi::winuser::WS_EX_TRANSPARENT;
		let style = winapi::winuser::WS_POPUP;

		let win = user32::CreateWindowExW(exstyle,
			m_class_name,
			m_class_name,
			style,
			// dimensions
			0, 0, rect.x2, rect.y2,
			0, // no parent
			0, // no menu
			hInstance, // module_instance
			0 as LPARAM,
		);

		user32::ShowWindow(win, winapi::winuser::SW_SHOW);
		user32::ShowWindow(win, winapi::winuser::SW_SHOWMAXIMIZED);
		user32::SetForegroundWindow(win);

		capture_screen_clipboard(win, Rectangle{
			x: 0,
			y: 0,
			x2: 200,
			y2: 200,
		});
		user32::DestroyWindow(win);
	}
}

// fn main() {
// 	// Here our unsafe code goes
// 	unsafe {
// 		// First we hide the console window
// 		hide_console_window();

// 		// Then we initialize the WNDCLASS structure
// 		let m_class_name = to_wstring(g_class_name);
// 		let wnd = WNDCLASSW {
// 			hInstance: 0 as HINSTANCE,
// 			lpszClassName = m_class_name,
// 			lpszMenuName: 0 as LPCWSTR,
// 			lpfnWndProc: Some(window_proc),

// 			style: winapi::winuser::CS_HREDRAW | winapi::winuser::CS_VREDRAW,

// 			cbClsExtra: 0,
// 			cbWndExtra: 0,

// 			hIcon: user32::LoadIconW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
// 			hCursor: user32::LoadCursorW(0 as HINSTANCE, winapi::winuser::IDI_APPLICATION),
// 			hbrBackground: 16 as HBRUSH,

// 		};

// 		// Register our class
// 		user32::RegisterClassW(&wnd);

// 		let h_wnd_desktop = user32::GetDesktopWindow();

// 		user32::CreateWindowExA(0, "my_window".as_ptr() as *mut _,
// 			"Simple Window".as_ptr() as *mut _, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
// 			0, 0, 400, 400, h_wnd_desktop, 0 as HMENU, 0 as HINSTANCE,
// 			std::ptr::null_mut());

// 		let mut msg = winapi::winuser::MSG {
// 			hwnd: 0 as HWND,
// 			message: 0 as UINT,
// 			wParam: 0 as WPARAM,
// 			lParam: 0 as LPARAM,
// 			time: 0 as DWORD,
// 			pt : winapi::windef::POINT{ x: 0, y: 0, },
// 		};

// 		// Kick off the application loop
// 		loop {
// 			let pm = user32::PeekMessageW(&mut msg, 0 as HWND, 0, 0, winapi::winuser::PM_REMOVE);

// 			if pm == 0 {
// 				continue;
// 			}

// 			if msg.message == winapi::winuser::WM_QUIT {
// 				break;
// 			}

// 			user32::TranslateMessage(&mut msg);
// 			user32::DispatchMessageW(&mut msg);
// 		}
// 	}
// }<|endoftext|>


<commit_before>extern crate clap;
extern crate walkdir;
extern crate twox_hash;

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

use clap::{App, Arg};
use walkdir::WalkDir;
use twox_hash::XxHash;
use std::hash::Hasher;

#[derive(Default)]
struct Stats {
    file_count: u64,
    total_size: u64,
    duplicate_count: u64,
}

fn collect_files(path: &str, stats: &mut Stats) -> HashMap<u64, Vec<PathBuf>> {

    let mut files = HashMap::new();

    for entry in WalkDir::new(path) {
        let entry = entry.unwrap();

        if !entry.file_type().is_file() {
            continue;
        }

        let metadata = entry.metadata().unwrap();

        if metadata.len() == 0 {
            continue;
        }

        stats.file_count += 1;
        stats.total_size += metadata.len();

        let path = entry.path().to_path_buf();

        files.entry(metadata.len()).or_insert(Vec::new()).push(path);
    }

    files
}

fn main() {
    let matches = App::new("dupr")
        .version("0.1.0")
        .author("Mike Sampson")
        .about("Duplicate file finder")
        .arg(
            Arg::with_name("DIR")
                .help("Directory to process")
                .required(true),
        )
        .arg(
            Arg::with_name("summary")
                .short("s")
                .long("summary")
                .help("Print out summary information after duplicates")
        )
        .get_matches();

    let mut stats: Stats = Default::default();

    let files = collect_files(matches.value_of("DIR").unwrap(), &mut stats);

    for f_paths in files.values() {
        if f_paths.len() == 1 {
            continue;
        }

        let mut hashes = HashMap::new();
        for f_path in f_paths {
            hashes
                .entry(hash_file(&f_path))
                .or_insert(Vec::new())
                .push(f_path);
        }

        for (hash, paths) in hashes {
            if paths.len() < 2 {
                continue;
            }
            stats.duplicate_count += paths.len() as u64;
            for p in paths {
                println!("{:016x} - {}", hash, p.display());
            }
        }
    }

    if matches.is_present("summary")  {
        println!(
            "Processed {} files with a total size of {} bytes. {} duplicates found.",
            stats.file_count,
            stats.total_size,
            stats.duplicate_count
        );
    }
}

fn hash_file<P: AsRef<Path>>(path: P) -> u64 {
    let mut file = File::open(path).unwrap();

    let mut hash = XxHash::with_seed(0);

    let mut buffer = [0; 32 * 1024];

    while let Ok(n) = file.read(&mut buffer) {
        if n == 0 {
            break;
        }
        hash.write(&buffer[0..n]);
    }

    hash.finish()
}
<commit_msg>Use filter.<commit_after>extern crate clap;
extern crate walkdir;
extern crate twox_hash;

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

use clap::{App, Arg};
use walkdir::WalkDir;
use twox_hash::XxHash;
use std::hash::Hasher;

#[derive(Default)]
struct Stats {
    file_count: u64,
    total_size: u64,
    duplicate_count: u64,
}

fn collect_files(path: &str, stats: &mut Stats) -> HashMap<u64, Vec<PathBuf>> {

    let mut files = HashMap::new();

    for entry in WalkDir::new(path) {
        let entry = entry.unwrap();

        if !entry.file_type().is_file() {
            continue;
        }

        let metadata = entry.metadata().unwrap();

        if metadata.len() == 0 {
            continue;
        }

        stats.file_count += 1;
        stats.total_size += metadata.len();

        let path = entry.path().to_path_buf();

        files.entry(metadata.len()).or_insert(Vec::new()).push(path);
    }

    files
}

fn main() {
    let matches = App::new("dupr")
        .version("0.1.0")
        .author("Mike Sampson")
        .about("Duplicate file finder")
        .arg(
            Arg::with_name("DIR")
                .help("Directory to process")
                .required(true),
        )
        .arg(
            Arg::with_name("summary")
                .short("s")
                .long("summary")
                .help("Print out summary information after duplicates")
        )
        .get_matches();

    let mut stats: Stats = Default::default();

    let files = collect_files(matches.value_of("DIR").unwrap(), &mut stats);

    for f_paths in files.values().filter(|x| x.len() > 1) {

        let mut hashes = HashMap::new();
        for f_path in f_paths {
            hashes
                .entry(hash_file(&f_path))
                .or_insert(Vec::new())
                .push(f_path);
        }

        for (hash, paths) in hashes.iter().filter(|&(_, v)| v.len() > 1) {
            stats.duplicate_count += paths.len() as u64;
            for p in paths {
                println!("{:016x} - {}", hash, p.display());
            }
        }
    }

    if matches.is_present("summary")  {
        println!(
            "Processed {} files with a total size of {} bytes. {} duplicates found.",
            stats.file_count,
            stats.total_size,
            stats.duplicate_count
        );
    }
}

fn hash_file<P: AsRef<Path>>(path: P) -> u64 {
    let mut file = File::open(path).unwrap();

    let mut hash = XxHash::with_seed(0);

    let mut buffer = [0; 32 * 1024];

    while let Ok(n) = file.read(&mut buffer) {
        if n == 0 {
            break;
        }
        hash.write(&buffer[0..n]);
    }

    hash.finish()
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate rocket;

#[macro_use]
extern crate rocket_contrib;

mod airport_data;
mod path;
mod server_route;

use anyhow::{Context, Result};
use rocket::config::{Config, Environment};
use rocket_contrib::serve::StaticFiles;

#[rocket::main]
async fn main() -> Result<()> {
    airport_data::ensure_updated().context("failed to update airport data")?;

    println!("loading airport data..");
    let airports = airport_data::Airport::load_all().context("failed to load airport data")?;
    println!("finished loading airport data");

    let config = {
        let env = Environment::active().context("failed to get Rocket config")?;

        Config::build(env)
            .workers(1)
            .finalize()
            .context("failed to build Rocket config")?
    };

    rocket::custom(config)
        .manage(airports)
        .mount("/", StaticFiles::from("frontend/public/"))
        .mount("/api", routes![server_route::search_routes::search_routes])
        .launch()
        .await
        .context("failed to initialize Rocket")
}
<commit_msg>backend: Load airport data after loading Rocket config<commit_after>#[macro_use]
extern crate rocket;

#[macro_use]
extern crate rocket_contrib;

mod airport_data;
mod path;
mod server_route;

use anyhow::{Context, Result};
use rocket::config::{Config, Environment};
use rocket_contrib::serve::StaticFiles;

#[rocket::main]
async fn main() -> Result<()> {
    let config = {
        let env = Environment::active().context("failed to get Rocket config")?;

        Config::build(env)
            .workers(1)
            .finalize()
            .context("failed to build Rocket config")?
    };

    airport_data::ensure_updated().context("failed to update airport data")?;

    println!("loading airport data..");
    let airports = airport_data::Airport::load_all().context("failed to load airport data")?;
    println!("finished loading airport data");

    rocket::custom(config)
        .manage(airports)
        .mount("/", StaticFiles::from("frontend/public/"))
        .mount("/api", routes![server_route::search_routes::search_routes])
        .launch()
        .await
        .context("failed to initialize Rocket")
}
<|endoftext|>


<commit_before>#![feature(plugin, rustc_private)]
#![plugin(string_cache_plugin)]
extern crate iron;
extern crate router;
extern crate urlencoded;
extern crate serialize;
extern crate html5ever;
extern crate regex;
extern crate core;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use iron::prelude::*;
use iron::status;
use iron::headers::{ContentType};
use iron::modifiers::Header;
use iron::mime::Mime;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use core::str::FromStr;
use std::collections::BTreeMap;

#[macro_use]
extern crate string_cache;

use pink_spider::scraper::extract_tracks;
use pink_spider::model::{Track, Entry, create_tables};
use serialize::json::{ToJson, Json};

extern crate pink_spider;

fn playlistify(req: &mut Request) -> IronResult<Response> {
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) => {
            match params.get("url") {
                Some(url) => {
                    let entry = find_or_create_entry(&url[0]);
                    let json_obj: Json = entry.to_json();
                    let json_str: String = json_obj.to_string();
                    return Ok(Response::with((status::Ok, json_str)))
                },
                None => println!("no url")
            }
        }
        Err(ref e) =>
            println!("{:?}", e)
    };

    Ok(Response::with((status::Ok, "{}")))
}

fn find_or_create_entry(url: &str) -> Entry {
    match Entry::find_by_url(url) {
        Some(entry) => {
            println!("Get entry from database cache");
            entry
        },
        None => {
            let tracks = extract_tracks(url);
            match Entry::create_by_url(url.to_string()) {
                Some(mut entry) => {
                    println!("Create new entry to database cache");
                    for t in tracks {
                        match Track::create(t.provider, t.title, t.url, t.identifier) {
                            Some(track) => entry.add_track(track),
                            None        => ()
                        }
                    }
                    entry
                },
                None => {
                    println!("Failed to create entry database cache");
                    Entry {
                            id: 0,
                           url: url.to_string(),
                        tracks: tracks
                    }
                }
            }
        }
    }
}

fn show_track(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    let tid: Option<i32> = track_id.parse().ok();
    let json_type = Header(ContentType(Mime::from_str("application/json").ok().unwrap()));
    match tid {
        Some(n) =>
            match Track::find_by_id(n) {
                Some(track) => {
                    let res = Response::with((status::Ok,
                                              json_type,
                                              track.to_json().to_string()));
                    Ok(res)
                },
                None =>
                    Ok(Response::with((status::Ok, json_type, "{}")))
            },
        None => Ok(Response::with((status::Ok, json_type, "{}")))
    }
}

fn update_track(req: &mut Request) -> IronResult<Response> {
    let json_type = Header(ContentType(Mime::from_str("application/json").ok().unwrap()));
    fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
        match req.get_ref::<UrlEncodedBody>() {
            Ok(ref params) => match params.get(key) {
                Some(val) => Some(val[0].clone()),
                None      => None
            },
            Err(_) => None
        }
    }

    fn query_as_string(req: &mut Request, key: &str) -> String {
        return req.extensions.get::<Router>().unwrap()
                  .find(key).unwrap().to_string();
    }

    let track_id = query_as_string(req, "track_id");
    let tid: Option<i32> = track_id.parse().ok();

    let opt_track = match tid {
        Some(id) => Track::find_by_id(id),
        None     => None
    };

    match opt_track {
        Some(mut track) => {
            match param_as_string(req, "title") {
                Some(title) => track.title = title,
                None        => println!("no title")
            }
            match param_as_string(req, "url") {
                Some(url) => track.url = url,
                None      => println!("no url")
            }
            if track.save() {
                let res = Response::with((status::Ok,
                                          json_type,
                                          track.to_json().to_string()));
                Ok(res)
            } else {
                let mut info = BTreeMap::new();
                info.insert("error".to_string(), "Failed to save".to_string());
                Ok(Response::with((status::BadRequest,
                                   json_type,
                                   info.to_json().to_string())))
            }
        },
        None =>  {
            let mut info = BTreeMap::new();
            info.insert("error".to_string(), "Track is not found".to_string());
            Ok(Response::with((status::NotFound,
                               json_type,
                               info.to_json().to_string())))
        }
    }
}

fn main() {
    create_tables();

    let mut router = Router::new();
//    router.post(  "auth",                    signin);
    router.get(   "/playlistify",            playlistify);
//    router.get(   "/entry/:entry_id",        show_entry);
//    router.post(  "/entry/:entry_id",        update_entry);
//    router.delete("/entry/:entry_id",        destroy_entry);
//    router.put(   "/tracks/:track_id",       create_track);
    router.get(   "/tracks/:track_id",       show_track);
    router.post(  "/tracks/:track_id",       update_track);
//    router.delete("/tracks/:track_id",       destroy_track);
//    router.post(  "/entry/:entry_id/tracks", add_track);*/

    let opt_port = std::env::var("PORT");
    let port_str = match opt_port {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<commit_msg>Add content-type: application/json to GET /playlistify api<commit_after>#![feature(plugin, rustc_private)]
#![plugin(string_cache_plugin)]
extern crate iron;
extern crate router;
extern crate urlencoded;
extern crate serialize;
extern crate html5ever;
extern crate regex;
extern crate core;

use std::net::SocketAddrV4;
use std::net::Ipv4Addr;
use iron::prelude::*;
use iron::status;
use iron::headers::{ContentType};
use iron::modifiers::Header;
use iron::mime::Mime;
use router::{Router};
use urlencoded::UrlEncodedQuery;
use urlencoded::UrlEncodedBody;
use core::str::FromStr;
use std::collections::BTreeMap;

#[macro_use]
extern crate string_cache;

use pink_spider::scraper::extract_tracks;
use pink_spider::model::{Track, Entry, create_tables};
use serialize::json::{ToJson, Json};

extern crate pink_spider;

fn playlistify(req: &mut Request) -> IronResult<Response> {
    let json_type = Header(ContentType(Mime::from_str("application/json").ok().unwrap()));
    match req.get_ref::<UrlEncodedQuery>() {
        Ok(ref params) => {
            match params.get("url") {
                Some(url) => {
                    let entry = find_or_create_entry(&url[0]);
                    let json_obj: Json = entry.to_json();
                    let json_str: String = json_obj.to_string();
                    return Ok(Response::with((status::Ok, json_type, json_str)))
                },
                None => println!("no url")
            }
        }
        Err(ref e) =>
            println!("{:?}", e)
    };

    Ok(Response::with((status::Ok, "{}")))
}

fn find_or_create_entry(url: &str) -> Entry {
    match Entry::find_by_url(url) {
        Some(entry) => {
            println!("Get entry from database cache");
            entry
        },
        None => {
            let tracks = extract_tracks(url);
            match Entry::create_by_url(url.to_string()) {
                Some(mut entry) => {
                    println!("Create new entry to database cache");
                    for t in tracks {
                        match Track::create(t.provider, t.title, t.url, t.identifier) {
                            Some(track) => entry.add_track(track),
                            None        => ()
                        }
                    }
                    entry
                },
                None => {
                    println!("Failed to create entry database cache");
                    Entry {
                            id: 0,
                           url: url.to_string(),
                        tracks: tracks
                    }
                }
            }
        }
    }
}

fn show_track(req: &mut Request) -> IronResult<Response> {
    let ref track_id = req.extensions.get::<Router>().unwrap()
                          .find("track_id").unwrap();
    let tid: Option<i32> = track_id.parse().ok();
    let json_type = Header(ContentType(Mime::from_str("application/json").ok().unwrap()));
    match tid {
        Some(n) =>
            match Track::find_by_id(n) {
                Some(track) => {
                    let res = Response::with((status::Ok,
                                              json_type,
                                              track.to_json().to_string()));
                    Ok(res)
                },
                None =>
                    Ok(Response::with((status::Ok, json_type, "{}")))
            },
        None => Ok(Response::with((status::Ok, json_type, "{}")))
    }
}

fn update_track(req: &mut Request) -> IronResult<Response> {
    let json_type = Header(ContentType(Mime::from_str("application/json").ok().unwrap()));
    fn param_as_string(req: &mut Request, key: &str) -> Option<String> {
        match req.get_ref::<UrlEncodedBody>() {
            Ok(ref params) => match params.get(key) {
                Some(val) => Some(val[0].clone()),
                None      => None
            },
            Err(_) => None
        }
    }

    fn query_as_string(req: &mut Request, key: &str) -> String {
        return req.extensions.get::<Router>().unwrap()
                  .find(key).unwrap().to_string();
    }

    let track_id = query_as_string(req, "track_id");
    let tid: Option<i32> = track_id.parse().ok();

    let opt_track = match tid {
        Some(id) => Track::find_by_id(id),
        None     => None
    };

    match opt_track {
        Some(mut track) => {
            match param_as_string(req, "title") {
                Some(title) => track.title = title,
                None        => println!("no title")
            }
            match param_as_string(req, "url") {
                Some(url) => track.url = url,
                None      => println!("no url")
            }
            if track.save() {
                let res = Response::with((status::Ok,
                                          json_type,
                                          track.to_json().to_string()));
                Ok(res)
            } else {
                let mut info = BTreeMap::new();
                info.insert("error".to_string(), "Failed to save".to_string());
                Ok(Response::with((status::BadRequest,
                                   json_type,
                                   info.to_json().to_string())))
            }
        },
        None =>  {
            let mut info = BTreeMap::new();
            info.insert("error".to_string(), "Track is not found".to_string());
            Ok(Response::with((status::NotFound,
                               json_type,
                               info.to_json().to_string())))
        }
    }
}

fn main() {
    create_tables();

    let mut router = Router::new();
//    router.post(  "auth",                    signin);
    router.get(   "/playlistify",            playlistify);
//    router.get(   "/entry/:entry_id",        show_entry);
//    router.post(  "/entry/:entry_id",        update_entry);
//    router.delete("/entry/:entry_id",        destroy_entry);
//    router.put(   "/tracks/:track_id",       create_track);
    router.get(   "/tracks/:track_id",       show_track);
    router.post(  "/tracks/:track_id",       update_track);
//    router.delete("/tracks/:track_id",       destroy_track);
//    router.post(  "/entry/:entry_id/tracks", add_track);*/

    let opt_port = std::env::var("PORT");
    let port_str = match opt_port {
        Ok(n)    => n,
        Err(_) => "8080".to_string()
    };
    let port: u16 = match port_str.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("Faild to parse port");
            return;
        }
    };
    println!("PORT {}", port_str);
    let ip = Ipv4Addr::new(0, 0, 0, 0);
    Iron::new(router).http(SocketAddrV4::new(ip, port)).unwrap();
}
<|endoftext|>


<commit_before>use macroquad::prelude::*;

// Represent the state of the game as a graph.  One node for each cell.  There is an edge between
// two cells if and only if they are the same colour and have a distance of 1 according to the
// Manhattan metric.
//
// The game has only one real operation (i.e. not counting level generation): Switching the colour
// of the connected component containing the top left cell to whichever colour the clicked cell
// has.  This results in said component growing by every component it neighbours which has its new
// colour.  In essence, the aim of the gaim is to join connected components until only one is
// left.  Fewer clicks is better.
//
// So, we represent the game state as a collection of connected components, each of which has a
// colour, a list of coordinates of the constituent cells, and a list of it s neighbours.  As we
// do all our operations on connected components, we actually work not with the graph of
// neighbouring cells but with a graph of connected components.  The graph of connected components
// is made up of one node representing each connected component and an edge between any two
// connected components that have cells which share an edge, i.e. two cells which would have been
// connected by an edge in the original graph if they had had the same colour (which they did
// not).

#[macroquad::main("BasicShapes")]
async fn main() {
    loop {
        clear_background(RED);

        draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
        draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
        draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
        draw_text("HELLO", 20.0, 20.0, 20.0, DARKGRAY);

        next_frame().await
    }
}
<commit_msg>Define enum for colours to be used<commit_after>use macroquad::prelude::*;

// Represent the state of the game as a graph.  One node for each cell.  There is an edge between
// two cells if and only if they are the same colour and have a distance of 1 according to the
// Manhattan metric.
//
// The game has only one real operation (i.e. not counting level generation): Switching the colour
// of the connected component containing the top left cell to whichever colour the clicked cell
// has.  This results in said component growing by every component it neighbours which has its new
// colour.  In essence, the aim of the gaim is to join connected components until only one is
// left.  Fewer clicks is better.
//
// So, we represent the game state as a collection of connected components, each of which has a
// colour, a list of coordinates of the constituent cells, and a list of it s neighbours.  As we
// do all our operations on connected components, we actually work not with the graph of
// neighbouring cells but with a graph of connected components.  The graph of connected components
// is made up of one node representing each connected component and an edge between any two
// connected components that have cells which share an edge, i.e. two cells which would have been
// connected by an edge in the original graph if they had had the same colour (which they did
// not).

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Colour {
    Red,
    Yellow,
    Green,
    LightBrown,
    Purple,
    Cyan,
    Blue,
    Fuchsia,
}

#[macroquad::main("BasicShapes")]
async fn main() {
    loop {
        clear_background(RED);

        draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
        draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
        draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
        draw_text("HELLO", 20.0, 20.0, 20.0, DARKGRAY);

        next_frame().await
    }
}
<|endoftext|>