<commit_before>#![allow(dead_code)]
#![feature(unsafe_no_drop_flag)]
#![feature(scoped)]

extern crate rand;

mod types;
mod config;
mod player;
mod zobrist;
mod cell;
mod field;
mod uct;
mod bot;

use std::io;
use std::io::{Read, Write};
use std::str::FromStr;
use std::string::ToString;
use types::Coord;
use player::Player;
use bot::Bot;

fn write_author<T: Write>(output: &mut T, id: u32) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" author kurnevsky_evgeny\n".as_bytes()).ok();
}

fn write_author_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" author\n".as_bytes()).ok();
}

fn write_init<T: Write>(output: &mut T, id: u32) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" init\n".as_bytes()).ok();
}

fn write_init_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" init\n".as_bytes()).ok();
}

fn write_gen_move<T: Write>(output: &mut T, id: u32, x: Coord, y: Coord, player: Player) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move ".as_bytes()).ok();
  output.write_all(x.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all(y.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all((player.to_bool() as u8).to_string().as_bytes()).ok();
  output.write_all("\n".as_bytes()).ok();
}

fn write_gen_move_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move\n".as_bytes()).ok();
}

fn write_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" input_error\n".as_bytes()).ok();
}

fn main() {
  let mut input = io::stdin();
  let mut output = io::stdout();
  let mut bot_option = None;
  let mut s = String::new();
  loop {
    input.read_to_string(&mut s).ok();
    let mut split = s.split(' ').fuse();
    if let Some(id) = split.next().and_then(|id_str| u32::from_str(id_str).ok()) {
      match split.next() {
        Some("author") => {
          if split.next().is_some() {
            write_author_error(&mut output, id);
          } else {
            write_author(&mut output, id);
          }
        },
        Some("init") => {
          let x_option = split.next().and_then(|x_str| Coord::from_str(x_str).ok());
          let y_option = split.next().and_then(|y_str| Coord::from_str(y_str).ok());;
          let seed_option = split.next();
          if split.next().is_some() {
            write_init_error(&mut output, id);
          } else if let (Some(x), Some(y), Some(seed)) = (x_option, y_option, seed_option) {
            bot_option = Some(Bot::new(x, y));
            write_init(&mut output, id);
          } else {
            write_init_error(&mut output, id);
          }
        },
        Some("gen_move") => {
          let player_option = split.next().and_then(|player_str| u8::from_str(player_str).ok()).and_then(|player_u8| match player_u8 { //TODO: from_number method
            0 => Some(Player::Red),
            1 => Some(Player::Black),
            _ => None
          });
          if split.next().is_some() {
            write_gen_move_error(&mut output, id);
          } else if let (Some(player), Some(bot)) = (player_option, bot_option.as_mut()) {
            if let Some((x, y)) = bot.best_move(player, 10000) {
              write_gen_move(&mut output, id, x, y, player);
            } else {
              write_gen_move_error(&mut output, id);
            }
          } else {
            write_gen_move_error(&mut output, id);
          }
        },
        _ => {
          write_error(&mut output, id);
        }
      }
    } else {
      write_error(&mut output, 0);
    }
  }
}
<commit_msg>gen_move_with_complexity implemented.<commit_after>#![allow(dead_code)]
#![feature(unsafe_no_drop_flag)]
#![feature(scoped)]

extern crate rand;

mod types;
mod config;
mod player;
mod zobrist;
mod cell;
mod field;
mod uct;
mod bot;

use std::io;
use std::io::{Read, Write};
use std::str::FromStr;
use std::string::ToString;
use types::Coord;
use player::Player;
use bot::Bot;

fn write_author<T: Write>(output: &mut T, id: u32) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" author kurnevsky_evgeny\n".as_bytes()).ok();
}

fn write_author_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" author\n".as_bytes()).ok();
}

fn write_init<T: Write>(output: &mut T, id: u32) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" init\n".as_bytes()).ok();
}

fn write_init_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" init\n".as_bytes()).ok();
}

fn write_gen_move<T: Write>(output: &mut T, id: u32, x: Coord, y: Coord, player: Player) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move ".as_bytes()).ok();
  output.write_all(x.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all(y.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all((player.to_bool() as u8).to_string().as_bytes()).ok();
  output.write_all("\n".as_bytes()).ok();
}

fn write_gen_move_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move\n".as_bytes()).ok();
}

fn write_gen_move_with_complexity<T: Write>(output: &mut T, id: u32, x: Coord, y: Coord, player: Player) {
  output.write_all("= ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move_with_complexity ".as_bytes()).ok();
  output.write_all(x.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all(y.to_string().as_bytes()).ok();
  output.write_all(" ".as_bytes()).ok();
  output.write_all((player.to_bool() as u8).to_string().as_bytes()).ok();
  output.write_all("\n".as_bytes()).ok();
}

fn write_gen_move_with_complexity_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" gen_move_with_complexity\n".as_bytes()).ok();
}

fn write_error<T: Write>(output: &mut T, id: u32) {
  output.write_all("? ".as_bytes()).ok();
  output.write_all(id.to_string().as_bytes()).ok();
  output.write_all(" input_error\n".as_bytes()).ok();
}

fn main() {
  let mut input = io::stdin();
  let mut output = io::stdout();
  let mut bot_option = None;
  let mut s = String::new();
  loop {
    input.read_to_string(&mut s).ok();
    let mut split = s.split(' ').fuse();
    if let Some(id) = split.next().and_then(|id_str| u32::from_str(id_str).ok()) {
      match split.next() {
        Some("author") => {
          if split.next().is_some() {
            write_author_error(&mut output, id);
          } else {
            write_author(&mut output, id);
          }
        },
        Some("init") => {
          let x_option = split.next().and_then(|x_str| Coord::from_str(x_str).ok());
          let y_option = split.next().and_then(|y_str| Coord::from_str(y_str).ok());;
          let seed_option = split.next();
          if split.next().is_some() {
            write_init_error(&mut output, id);
          } else if let (Some(x), Some(y), Some(_)) = (x_option, y_option, seed_option) {
            bot_option = Some(Bot::new(x, y));
            write_init(&mut output, id);
          } else {
            write_init_error(&mut output, id);
          }
        },
        Some("gen_move") => {
          let player_option = split.next().and_then(|player_str| u8::from_str(player_str).ok()).and_then(|player_u8| match player_u8 { //TODO: from_number method
            0 => Some(Player::Red),
            1 => Some(Player::Black),
            _ => None
          });
          if split.next().is_some() {
            write_gen_move_error(&mut output, id);
          } else if let (Some(player), Some(bot)) = (player_option, bot_option.as_mut()) {
            if let Some((x, y)) = bot.best_move(player, 10000) {
              write_gen_move(&mut output, id, x, y, player);
            } else {
              write_gen_move_error(&mut output, id);
            }
          } else {
            write_gen_move_error(&mut output, id);
          }
        },
        Some("gen_move_with_complexity") => {
          let player_option = split.next().and_then(|player_str| u8::from_str(player_str).ok()).and_then(|player_u8| match player_u8 { //TODO: from_number method
            0 => Some(Player::Red),
            1 => Some(Player::Black),
            _ => None
          });
          let complexity_option = split.next().and_then(|complexity_str| u8::from_str(complexity_str).ok() );
          if split.next().is_some() {
            write_gen_move_with_complexity_error(&mut output, id);
          } else if let (Some(player), Some(_), Some(bot)) = (player_option, complexity_option, bot_option.as_mut()) {
            if let Some((x, y)) = bot.best_move(player, 10000) {
              write_gen_move_with_complexity(&mut output, id, x, y, player);
            } else {
              write_gen_move_with_complexity_error(&mut output, id);
            }
          } else {
            write_gen_move_with_complexity_error(&mut output, id);
          }
        },
        _ => {
          write_error(&mut output, id);
        }
      }
    } else {
      write_error(&mut output, 0);
    }
  }
}
<|endoftext|>


<commit_before>use std::thread;
use std::path::PathBuf;
use crossbeam_channel;
use std::env;
use std::fs;

#[derive(Debug)]
struct TranscodeJob {
    src: PathBuf,
    dest: PathBuf,
}

fn main() {
    const NTHREADS: i32 = 4;

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

    let path = match args.len() {
        2 => PathBuf::from(&args[1]),
        _ => env::current_dir().unwrap(),
    };

    println!("looking for videos at: {}", path.display());

    thread::scope(|s| {
        let (job_sender, job_recv) = crossbeam_channel::bounded::<TranscodeJob>(0);

        for i in 0..NTHREADS {
            let job_recv = job_recv.clone();
            s.spawn(move || transcoder(i, job_recv));
        }

        jobscheduler(path, job_sender);
    });

    println!("done");
}

fn jobscheduler(path: PathBuf, job_sender: crossbeam_channel::Sender<TranscodeJob>) {
        println!("starting job scheduler");

        let entries = fs::read_dir(path).unwrap();

        let job = TranscodeJob{
            src: PathBuf::from("src"),
            dest: PathBuf::from("dest"),
        };
        job_sender.send(job).expect("failed to send job to workers");
        drop(job_sender);
}

fn transcoder(id: i32, job_recv: crossbeam_channel::Receiver<TranscodeJob>) {
    println!("starting transcoder {}", id);

    while let Ok(job) = job_recv.recv() {
        println!("transcoder {} transcoding from {} to {}", id,
            job.src.display(), job.dest.display());
    }

    println!("finishing transcoder {}", id);
}
<commit_msg>feat: advance on listing and filtering files per extension<commit_after>use crossbeam_channel::bounded;
use crossbeam_channel::Receiver;
use crossbeam_channel::Sender;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::thread;
use std::vec::Vec;

#[derive(Debug)]
struct TranscodeJob {
    src: PathBuf,
    dest: PathBuf,
}

fn main() {
    const NTHREADS: i32 = 4;

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

    let pathbuf = match args.len() {
        2 => PathBuf::from(&args[1]),
        _ => env::current_dir().unwrap(),
    };

    println!("looking for videos at: {}", pathbuf.display());

    thread::scope(|s| {
        let (job_sender, job_recv) = bounded::<TranscodeJob>(0);

        for i in 0..NTHREADS {
            let job_recv = job_recv.clone();
            s.spawn(move || transcoder(i, job_recv));
        }

        jobscheduler(pathbuf.as_path(), job_sender);
    });

    println!("done");
}

fn jobscheduler(path: &Path, job_sender: Sender<TranscodeJob>) {
    println!("starting job scheduler");

    let entries = fs::read_dir(path).unwrap();
    let mut srcs = Vec::new();

    for entry in entries {
        match entry {
            Ok(entry) => {
                let path = entry.path();
                if let Some(extension) = path.extension() {
                    let extension = extension
                        .to_str()
                        .expect("file extensions should be valid utf-8");

                    match extension {
                        "avi" => {
                            srcs.push(path);
                        }
                        _ => {
                            println!("ignoring file with extension: {}", extension)
                        }
                    }
                }
            }
            Err(err) => {
                print!("error reading dir {}: {}", path.display(), err);
            }
        }
    }

    let job = TranscodeJob {
        src: PathBuf::from("src"),
        dest: PathBuf::from("dest"),
    };
    job_sender.send(job).expect("failed to send job to workers");
    drop(job_sender);
}

fn transcoder(id: i32, job_recv: Receiver<TranscodeJob>) {
    println!("starting transcoder {}", id);

    while let Ok(job) = job_recv.recv() {
        println!(
            "transcoder {} transcoding from {} to {}",
            id,
            job.src.display(),
            job.dest.display()
        );
    }

    println!("finishing transcoder {}", id);
}
<|endoftext|>


<commit_before>#![warn(clippy::all)]

#[macro_use]
extern crate serenity;

use std::io;
use stalch::{run_with_state, InOuter, State, Result as StalchResult};

use std::env;
use std::io::Read;
use std::result::Result as StdResult;
use typemap::Key;

use rand::Rng;
use rand::thread_rng;

use serenity::prelude::*;
use serenity::model::*;
use serenity::Result;
use serenity::utils;

use serenity::framework::StandardFramework;

const PREFIX: &str = "]";
#[allow(clippy::unreadable_literal)]
const WESTMANN: UserId = UserId(229154015626264577);
#[allow(clippy::unreadable_literal)]
const FALCH: UserId = UserId(165877785544491008);
#[allow(clippy::unreadable_literal)]
const MEMES: ChannelId = ChannelId(306454829738491904);
#[allow(clippy::unreadable_literal)]
const FALCHATS: GuildId = GuildId(189120762659995648);

command!(info(_ctx, msg, _args) {
    msg.channel_id.send_message(|cm| {
        cm.embed(|e| {
            e.title("falchbot")
             .colour(utils::Colour::blue())
             .description("(c) LFalch.com 2018")
             .footer(|f| f.text(serenity::constants::USER_AGENT))
        })
    }).unwrap();
});

command!(setgame(ctx, msg, args) {
    if msg.author.id == FALCH {
        ctx.set_game(Game::playing(&args.join(" ")));
    } else {
        msg.reply("Unauthorised")?;
    }
});

command!(seticon(_ctx, msg, args) {
    let s = args.join("/");

    if msg.author.id == FALCH {
        let img = {
            let client = hyper::Client::new();
            let mut resp = client.get(&format!("http://dev.lfalch.com/{}.png", s)).send()?;
            if !resp.status.is_success() {
                msg.reply("No success")?;
                return Ok(());
            }

            let mut v = Vec::new();

            resp.read_to_end(&mut v)?;

            let b64 = base64::encode(&v);
            let ext = "png";

            format!("data:image/{};base64,{}", ext, b64)
        };

        FALCHATS.edit(|e| e.icon(Some(&img)))?;
    } else {
        msg.reply("Unauthorised")?;
    }
});

command!(rpn(_ctx, msg, args) {
    match calculate(&*args) {
        Ok(r) => msg.reply(&format!("Result: {}", r)),
        Err(e) => msg.reply(&format!("Error: {:?}", e))
    }?;
});

command!(stalch(_ctx, msg, args) {
    match stalch_run(&(args.join(" ") + "\n")) {
        Ok((r, s)) => {
            if r.is_empty() {
                msg.reply(&format!("Stack:\n```\n{}\n```", s))
            } else {
                msg.reply(&format!("Output:\n```\n{}\n```", r))
            }
        }
        Err(e) => msg.reply(&format!("Error: {:?}", e))
    }?;
});

command!(seximal(_ctx, msg, args) {
    let s = args.join("");
    match seximal::to_seximal_words(&s) {
        Ok(ref s) => msg.reply(s),
        Err(_) => msg.reply("Malformed number")
    }?;
});

const CSGO_MSGS: [&str; 6] = [
    "Vi varmer op med en comp!",
    "Jeg er på!",
    "Jeg er mere til Call of Duty ..",
    "Сука блядь!",
    "-skyder en bot for at få dens Bizon-",
    "Mongoskrald!"
];

const BEARTOOTH: [&str; 3] = [
    "I’m not useless! I’m just the king of excuses!",
    "One life and one decision! Make sure it ends with you still living!",
    "Lorteskat på T-shirts."
];

const RESPONSES: [&str; 4] = [
    "Undskyld, kan ikke snakke lige nu :(",
    "Hey, kan jeg ringe igen senere?",
    "Hva' så, din noob!? :P",
    "Ad, hvem er du?"
];

const REDALERT: [&str; 4] = [
    "Your base is under a salt!",
    "Det gamle lortespil?",
    "Jeg er mere til CSGO.",
    "\"Mine depleted\" ..."
];

struct BotUser;

impl Key for BotUser {
    type Value = String;
}

struct Handler;

fn main() {
    println!("{} in {}", WESTMANN, MEMES);

    let token = env::var("DISCORD_TOKEN")
        .expect("Expected a token in the environment");
    let mut client = Client::new(&token, Handler);

    client.with_framework(StandardFramework::new()
        .configure(|c| c.prefix(PREFIX))
        .command("ping", |c| c.exec_str("Pong!"))
        .on("info", info)
        .on("setgame", setgame)
        .on("rpn", rpn)
        .on("stalch", stalch)
        .on("seximal", seximal)
        .on("seticon", seticon)
    );

    {
        let mut data = client.data.lock();
        data.insert::<BotUser>(String::default());
    }

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}

macro_rules! joke {
    ($s:expr; $($trigger:expr),+; $bl:block) => (
        if $($s.contains($trigger))||* $bl
    );
    ($s:expr, $channel_id:expr; $($trigger:expr),+;; $joke:expr) => (
        joke!($s; $($trigger),*; {
            $channel_id.say($joke).unwrap();
        })
    );
    ($s:expr, $channel_id:expr; $($trigger:expr),+; $jokes:expr) => (
        joke!($s; $($trigger),*; {
            send_random($channel_id, &$jokes).unwrap();
        })
    );
}

impl EventHandler for Handler {
    fn on_ready(&self, ctx: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
        println!("Guilds:");
        for name in ready.guilds.iter().map(|g| g.id().get().unwrap().name) {
            println!("    {}", name);
        }
        {
            let mut data = ctx.data.lock();
            *data.get_mut::<BotUser>().unwrap() = ready.user.tag();
        }
    }

    fn on_message(&self, ctx: Context, msg: Message) {
        if msg.author.bot {
            return
        }
        eprintln!("{} in {}: image: {}", msg.channel_id.0, msg.author.id.0, msg.attachments.iter().any(|a| a.width.is_some()));
        if msg.channel_id == MEMES && msg.author.id == WESTMANN && msg.attachments.iter().any(|a| a.width.is_some()) {
            msg.channel_id.say("Den er gammel!").unwrap();
        }
        let s: String = msg.content.chars()
        .filter(|c| c.is_alphanumeric())
        .flat_map(|c|c.to_lowercase())
        .collect();

        joke!(s, msg.channel_id; "css", "source";; "Hvor er mine skins!?");
        joke!(s, msg.channel_id; "csgo", "counterstrike", "globaloffensive"; CSGO_MSGS);
        joke!(s, msg.channel_id; "mc", "minecraft";; "MINECRAFT!");
        joke!(s, msg.channel_id; "beartooth"; BEARTOOTH);
        joke!(s, msg.channel_id; "rep";; "Rep mig!");
        joke!(s, msg.channel_id; "ftl";; "Zoltan shield OP");
        joke!(s, msg.channel_id; "bindingofisaac";; "Mom OP");
        joke!(s, msg.channel_id; "meme";; "krydrede migmig'er");
        joke!(s, msg.channel_id; "gunsoficarus";; "Spillere online: 85");
        joke!(s, msg.channel_id; "doom";; "Rip and tear!");
        joke!(s, msg.channel_id; "dyinglight";; "Det dér Left 4 Dead-spil?");
        joke!(s, msg.channel_id; "report";; "ReviewBrah");
        joke!(s; "english"; {
            msg.channel_id.send_message(|cm| {
                cm.embed(|e| {
                    e.image("http://dev.lfalch.com/english.jpg")
                })
            }).unwrap();
        });
        joke!(s, msg.channel_id; "warthunder", "wt", "thunder", "tankspil";; "Jeg hader World of Tanks!");
        joke!(s, msg.channel_id; "ra3", "redalert"; REDALERT);
        joke!(s, msg.channel_id; "rusland", "russia", "росси", "russisk",
        "russian", "русск", "russer";; "Communism is the ultimate goal of socialism.");

        let user = {
            ctx.data.lock().get::<BotUser>().unwrap().clone()
        };
        if msg.mentions.iter().map(|u| u.tag()).any(|u| u == user) {
            send_random(msg.channel_id, &RESPONSES).unwrap();
        }
    }
}

fn send_random(chl: ChannelId, list: &[&str]) -> Result<Message> {
    let i = thread_rng().gen_range(0, list.len());
    chl.say(list[i])
}

#[derive(Debug, Copy, Clone)]
pub enum RpnError<'a> {
    StackTooSmall,
    UnknownOperator(&'a str)
}

use crate::RpnError::*;

pub fn calculate<'a, T: IntoIterator<Item=&'a String>>(operations: T) -> StdResult<f64, RpnError<'a>> {
    let mut stack = Vec::new();

    for operation in operations {
        if let Ok(d) = operation.parse::<f64>() {
            stack.push(d)
        }else{
            calc(operation, &mut stack)?
        }
    }

    stack.pop().ok_or(StackTooSmall)
}

fn calc<'a>(op: &'a str, stack: &mut Vec<f64>) -> StdResult<(), RpnError<'a>>{
    let res = match (stack.pop(), stack.pop()){
        (Some(op1), Some(op2)) => match op{
            "+"|"add" => op2 + op1,
            "-"|"sub" => op2 - op1,
            "/"|"div" => op2 / op1,
            "*"|"mul" => op2 * op1,
            "^"|"pow" => op2.powf(op1),
            "log" => op2.log(op1),
            "hypot" => op2.hypot(op1),
            "%"|"rem" => op2 % op1,
            "|"|"or" => (op2 as i64 | op1 as i64) as f64,
            "&"|"and" => (op2 as i64 & op1 as i64) as f64,
            "xor" => (op2  as i64 ^ op1 as i64) as f64,
            _ => return Err(UnknownOperator(op))
        },
        _ => return Err(StackTooSmall)
    };
    stack.push(res);
    Ok(())
}

fn stalch_run(s: &str) -> StalchResult<(String, String)> {
    let mut state = State::new();
    let mut io = InOuter::new(Vec::new(), io::repeat(b'\n'));

    run_with_state(s.as_bytes(), &mut state, &mut io)?;

    let (output, _) = io.extract();

    let s = String::from_utf8(output).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;

    Ok((s, format!("{:?}", state.stack())))
}
<commit_msg>Add pdgqz command<commit_after>#![warn(clippy::all)]

#[macro_use]
extern crate serenity;

use std::io;
use stalch::{run_with_state, InOuter, State, Result as StalchResult};

use std::env;
use std::io::Read;
use std::result::Result as StdResult;
use typemap::Key;

use rand::Rng;
use rand::thread_rng;

use serenity::prelude::*;
use serenity::model::*;
use serenity::Result;
use serenity::utils;

use serenity::framework::StandardFramework;

const PREFIX: &str = "]";
#[allow(clippy::unreadable_literal)]
const WESTMANN: UserId = UserId(229154015626264577);
#[allow(clippy::unreadable_literal)]
const FALCH: UserId = UserId(165877785544491008);
#[allow(clippy::unreadable_literal)]
const MEMES: ChannelId = ChannelId(306454829738491904);
#[allow(clippy::unreadable_literal)]
const FALCHATS: GuildId = GuildId(189120762659995648);

command!(info(_ctx, msg, _args) {
    msg.channel_id.send_message(|cm| {
        cm.embed(|e| {
            e.title("falchbot")
             .colour(utils::Colour::blue())
             .description("(c) LFalch.com 2018")
             .footer(|f| f.text(serenity::constants::USER_AGENT))
        })
    }).unwrap();
});

command!(setgame(ctx, msg, args) {
    if msg.author.id == FALCH {
        ctx.set_game(Game::playing(&args.join(" ")));
    } else {
        msg.reply("Unauthorised")?;
    }
});

command!(seticon(_ctx, msg, args) {
    let s = args.join("/");

    if msg.author.id == FALCH {
        let img = {
            let client = hyper::Client::new();
            let mut resp = client.get(&format!("http://dev.lfalch.com/{}.png", s)).send()?;
            if !resp.status.is_success() {
                msg.reply("No success")?;
                return Ok(());
            }

            let mut v = Vec::new();

            resp.read_to_end(&mut v)?;

            let b64 = base64::encode(&v);
            let ext = "png";

            format!("data:image/{};base64,{}", ext, b64)
        };

        FALCHATS.edit(|e| e.icon(Some(&img)))?;
    } else {
        msg.reply("Unauthorised")?;
    }
});

command!(rpn(_ctx, msg, args) {
    match calculate(&*args) {
        Ok(r) => msg.reply(&format!("Result: {}", r)),
        Err(e) => msg.reply(&format!("Error: {:?}", e))
    }?;
});

command!(stalch(_ctx, msg, args) {
    match stalch_run(&(args.join(" ") + "\n")) {
        Ok((r, s)) => {
            if r.is_empty() {
                msg.reply(&format!("Stack:\n```\n{}\n```", s))
            } else {
                msg.reply(&format!("Output:\n```\n{}\n```", r))
            }
        }
        Err(e) => msg.reply(&format!("Error: {:?}", e))
    }?;
});

command!(pdgqz(ctx, msg, _args) {
    let mut pdqz = ctx.data.lock();
    let pdqz = pdqz.get_mut::<PdgqzDisalloweds>().unwrap();

    if let Some(i) = pdqz.iter().position(|ch| ch == &msg.channel_id) {
        pdqz.remove(i);
    } else {
        pdqz.push(msg.channel_id);
    }
});

command!(seximal(_ctx, msg, args) {
    let s = args.join("");
    match seximal::to_seximal_words(&s) {
        Ok(ref s) => msg.reply(s),
        Err(_) => msg.reply("Malformed number")
    }?;
});

const CSGO_MSGS: [&str; 6] = [
    "Vi varmer op med en comp!",
    "Jeg er på!",
    "Jeg er mere til Call of Duty ..",
    "Сука блядь!",
    "-skyder en bot for at få dens Bizon-",
    "Mongoskrald!"
];

const BEARTOOTH: [&str; 3] = [
    "I’m not useless! I’m just the king of excuses!",
    "One life and one decision! Make sure it ends with you still living!",
    "Lorteskat på T-shirts."
];

const RESPONSES: [&str; 4] = [
    "Undskyld, kan ikke snakke lige nu :(",
    "Hey, kan jeg ringe igen senere?",
    "Hva' så, din noob!? :P",
    "Ad, hvem er du?"
];

const REDALERT: [&str; 4] = [
    "Your base is under a salt!",
    "Det gamle lortespil?",
    "Jeg er mere til CSGO.",
    "\"Mine depleted\" ..."
];

struct PdgqzDisalloweds;

impl Key for PdgqzDisalloweds {
    type Value = Vec<ChannelId>;
}

struct BotUser;

impl Key for BotUser {
    type Value = String;
}

#[derive(Default)]
struct Handler;

fn main() {
    println!("{} in {}", WESTMANN, MEMES);

    let token = env::var("DISCORD_TOKEN")
        .expect("Expected a token in the environment");
    let mut client = Client::new(&token, Handler::default());

    client.with_framework(StandardFramework::new()
        .configure(|c| c.prefix(PREFIX))
        .command("ping", |c| c.exec_str("Pong!"))
        .on("info", info)
        .on("setgame", setgame)
        .on("rpn", rpn)
        .on("stalch", stalch)
        .on("pdgqz", pdgqz)
        .on("seximal", seximal)
        .on("seticon", seticon)
    );

    {
        let mut data = client.data.lock();
        data.insert::<BotUser>(String::default());
        data.insert::<PdgqzDisalloweds>(Vec::new());
    }

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}

macro_rules! joke {
    ($s:expr; $($trigger:expr),+; $bl:block) => (
        if $($s.contains($trigger))||* $bl
    );
    ($s:expr, $channel_id:expr; $($trigger:expr),+;; $joke:expr) => (
        joke!($s; $($trigger),*; {
            $channel_id.say($joke).unwrap();
        })
    );
    ($s:expr, $channel_id:expr; $($trigger:expr),+; $jokes:expr) => (
        joke!($s; $($trigger),*; {
            send_random($channel_id, &$jokes).unwrap();
        })
    );
}

impl EventHandler for Handler {
    fn on_ready(&self, ctx: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
        println!("Guilds:");
        for name in ready.guilds.iter().map(|g| g.id().get().unwrap().name) {
            println!("    {}", name);
        }
        {
            let mut data = ctx.data.lock();
            *data.get_mut::<BotUser>().unwrap() = ready.user.tag();
        }
    }

    fn on_message(&self, ctx: Context, msg: Message) {
        if msg.author.bot {
            return
        }
        {
            if ctx.data.lock().get::<PdgqzDisalloweds>().unwrap().contains(&msg.channel_id) {
                let filter = |c: char| {
                    let c = c.to_lowercase().next().unwrap();
                     c == 'p' || c == 'd' || c == 'g' || c == 'q' || c == 'z'
                };
                if msg.content.chars().any(filter) {
                    let s = msg.content.chars().filter(|c| !filter(*c)).collect::<String>();
                    if !s.is_empty() {
                        msg.channel_id.say(s).unwrap();
                    }
                }
            }
        }
        if msg.channel_id == MEMES && msg.author.id == WESTMANN && msg.attachments.iter().any(|a| a.width.is_some()) {
            msg.channel_id.say("Den er gammel!").unwrap();
        }
        let s: String = msg.content.chars()
        .filter(|c| c.is_alphanumeric())
        .flat_map(|c|c.to_lowercase())
        .collect();

        joke!(s, msg.channel_id; "css", "source";; "Hvor er mine skins!?");
        joke!(s, msg.channel_id; "csgo", "counterstrike", "globaloffensive"; CSGO_MSGS);
        joke!(s, msg.channel_id; "mc", "minecraft";; "MINECRAFT!");
        joke!(s, msg.channel_id; "beartooth"; BEARTOOTH);
        joke!(s, msg.channel_id; "rep";; "Rep mig!");
        joke!(s, msg.channel_id; "ftl";; "Zoltan shield OP");
        joke!(s, msg.channel_id; "bindingofisaac";; "Mom OP");
        joke!(s, msg.channel_id; "meme";; "krydrede migmig'er");
        joke!(s, msg.channel_id; "gunsoficarus";; "Spillere online: 85");
        joke!(s, msg.channel_id; "doom";; "Rip and tear!");
        joke!(s, msg.channel_id; "dyinglight";; "Det dér Left 4 Dead-spil?");
        joke!(s, msg.channel_id; "report";; "ReviewBrah");
        joke!(s; "english"; {
            msg.channel_id.send_message(|cm| {
                cm.embed(|e| {
                    e.image("http://dev.lfalch.com/english.jpg")
                })
            }).unwrap();
        });
        joke!(s, msg.channel_id; "warthunder", "wt", "thunder", "tankspil";; "Jeg hader World of Tanks!");
        joke!(s, msg.channel_id; "ra3", "redalert"; REDALERT);
        joke!(s, msg.channel_id; "rusland", "russia", "росси", "russisk",
        "russian", "русск", "russer";; "Communism is the ultimate goal of socialism.");

        let user = {
            ctx.data.lock().get::<BotUser>().unwrap().clone()
        };
        if msg.mentions.iter().map(|u| u.tag()).any(|u| u == user) {
            send_random(msg.channel_id, &RESPONSES).unwrap();
        }
    }
}

fn send_random(chl: ChannelId, list: &[&str]) -> Result<Message> {
    let i = thread_rng().gen_range(0, list.len());
    chl.say(list[i])
}

#[derive(Debug, Copy, Clone)]
pub enum RpnError<'a> {
    StackTooSmall,
    UnknownOperator(&'a str)
}

use crate::RpnError::*;

pub fn calculate<'a, T: IntoIterator<Item=&'a String>>(operations: T) -> StdResult<f64, RpnError<'a>> {
    let mut stack = Vec::new();

    for operation in operations {
        if let Ok(d) = operation.parse::<f64>() {
            stack.push(d)
        }else{
            calc(operation, &mut stack)?
        }
    }

    stack.pop().ok_or(StackTooSmall)
}

fn calc<'a>(op: &'a str, stack: &mut Vec<f64>) -> StdResult<(), RpnError<'a>>{
    let res = match (stack.pop(), stack.pop()){
        (Some(op1), Some(op2)) => match op{
            "+"|"add" => op2 + op1,
            "-"|"sub" => op2 - op1,
            "/"|"div" => op2 / op1,
            "*"|"mul" => op2 * op1,
            "^"|"pow" => op2.powf(op1),
            "log" => op2.log(op1),
            "hypot" => op2.hypot(op1),
            "%"|"rem" => op2 % op1,
            "|"|"or" => (op2 as i64 | op1 as i64) as f64,
            "&"|"and" => (op2 as i64 & op1 as i64) as f64,
            "xor" => (op2  as i64 ^ op1 as i64) as f64,
            _ => return Err(UnknownOperator(op))
        },
        _ => return Err(StackTooSmall)
    };
    stack.push(res);
    Ok(())
}

fn stalch_run(s: &str) -> StalchResult<(String, String)> {
    let mut state = State::new();
    let mut io = InOuter::new(Vec::new(), io::repeat(b'\n'));

    run_with_state(s.as_bytes(), &mut state, &mut io)?;

    let (output, _) = io.extract();

    let s = String::from_utf8(output).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;

    Ok((s, format!("{:?}", state.stack())))
}
<|endoftext|>


<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.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 whitespace on command args<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, &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>#![feature(slice_patterns)]
extern crate fsync;

use std::process;
use std::env;
use std::iter::Iterator;

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

    if args.len() != 3 {
        println!("Usage: {} <source> <target>", args[0]);
        process::exit(1);
    }

    let (source, target) = (&args[1], &args[2]);

    fsync::sync(source, target).unwrap();
}
<commit_msg>Remove unused feature `slice_patterns`<commit_after>extern crate fsync;

use std::process;
use std::env;
use std::iter::Iterator;

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

    if args.len() != 3 {
        println!("Usage: {} <source> <target>", args[0]);
        process::exit(1);
    }

    let (source, target) = (&args[1], &args[2]);

    fsync::sync(source, target).unwrap();
}
<|endoftext|>


<commit_before>extern crate mmap;
extern crate time;
extern crate timely;
extern crate getopts;

use timely::progress::timestamp::RootTimestamp;
use timely::progress::nested::Summary::Local;
use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::*;
use timely::communication::pact::Exchange;
use timely::drain::DrainExt;

mod typedrw;
mod graphmap;
mod sorting;
use graphmap::GraphMMap;
use sorting::{SegmentList, radix_sort_32};

fn main () {

    let source = std::env::args().skip(1).next().unwrap();
    let strategy = std::env::args().skip(2).next().unwrap() == "process";

    // currently need timely's full option set to parse args
    let mut opts = getopts::Options::new();
    opts.optopt("w", "workers", "", "");
    opts.optopt("p", "process", "", "");
    opts.optopt("n", "processes", "", "");
    opts.optopt("h", "hostfile", "", "");

    if let Ok(matches) = opts.parse(std::env::args().skip(3)) {

        let workers: usize = matches.opt_str("w").map(|x| x.parse().unwrap_or(1)).unwrap_or(1);

        timely::initialize(std::env::args().skip(2), move |communicator| {
            pagerank_thread(communicator, &source, workers, strategy);
        });
    }
    else {
        println!("error parsing arguments");
        println!("usage:\tpagerank <source> (worker|process) [timely options]");
    }
}

// returns [src/peers] degrees, (dst, deg) pairs, and a list of [src/peers] endpoints
fn transpose(mut edges: Vec<Vec<(u32, u32)>>, peers: usize, nodes: usize) -> (Vec<u32>, Vec<(u32, u32)>, Vec<u32>)  {

    let mut deg = vec![0; (nodes as usize / peers) + 1];
    for list in &edges {
        for &(s, _) in list {
            deg[s as usize / peers] += 1;
        }
    }

    radix_sort_32(&mut edges, &mut Vec::new(), &|&(_,d)| d);

    let mut rev = Vec::<(u32,u32)>::with_capacity(deg.len());
    let mut trn = Vec::with_capacity(edges.len() * 1024);
    for list in edges {
        for (s,d) in list {
            let len = rev.len();
            if (len == 0) || (rev[len-1].0 < d) {
                rev.push((d, 0u32));
            }

            let len = rev.len();
            rev[len-1].1 += 1;
            trn.push(s / peers as u32);
        }
    }

    return (deg, rev, trn);
}

// pagerank dataflow graph has a set of edges as input, and a binary vertex that for each epoch of
// received edges initiates an iterative subcomputation to compute the pagerank.

fn pagerank_thread<C>(communicator: C, filename: &String, _workers: usize, _process_aggregate: bool)
where C: Communicator {
    let index = communicator.index() as usize;
    let peers = communicator.peers() as usize;

    let mut root = GraphRoot::new(communicator);

    let start = time::precise_time_s();

    let nodes = GraphMMap::new(&filename).nodes();

    let mut segments = SegmentList::new(1024); // list of edge segments

    let mut src = vec![];   // holds ranks
    let mut deg = vec![];   // holds source degrees
    let mut rev = vec![];   // holds (dst, deg) pairs
    let mut trn = vec![];   // holds transposed sources

    let mut going = start;

    let mut input = root.subcomputation(|builder| {

        let (input, edges) = builder.new_input::<(u32, u32)>();
        let (cycle, ranks) = builder.loop_variable::<(u32, f32)>(RootTimestamp::new(20), Local(1));

        let mut ranks = edges.binary_notify(&ranks,
                            Exchange::new(|x: &(u32,u32)| x.0 as u64),
                            Exchange::new(|x: &(u32,f32)| x.0 as u64),
                            format!("pagerank"),
                            vec![RootTimestamp::new(0)],
                            move |input1, input2, output, notificator| {

            // receive incoming edges (should only be iter 0)
            while let Some((_index, data)) = input1.pull() {
                segments.push(data.drain_temp());
            }

            // all inputs received for iter, commence multiplication
            while let Some((iter, _)) = notificator.next() {

                let now = time::now();

                if index == 0 { println!("{}:{}:{}.{} starting iteration {}", now.tm_hour, now.tm_min, now.tm_sec, now.tm_nsec, iter.inner); }

                // if the very first iteration, prepare some stuff.
                // specifically, transpose edges and sort by destination.
                if iter.inner == 0 {
                    let (a, b, c) = transpose(segments.finalize(), peers, nodes);
                    deg = a; rev = b; trn = c;
                    src = vec![0.0f32; deg.len()];
                }

                // record some timings in order to estimate per-iteration times
                if iter.inner == 0  && index == 0 { println!("src: {}, dst: {}, edges: {}", src.len(), rev.len(), trn.len()); }
                if iter.inner == 10 && index == 0 { going = time::precise_time_s(); }
                if iter.inner == 20 && index == 0 { println!("average: {}", (time::precise_time_s() - going) / 10.0 ); }

                // prepare src for transmitting to destinations
                for s in 0..src.len() { src[s] = 0.15 + 0.85 * src[s] / deg[s] as f32; }

                // wander through destinations
                let mut trn_slice = &trn[..];
                let mut rev_slice = &rev[..];
                while rev_slice.len() > 0 {
                    // TODO: session should flush automatically...
                    let mut session = output.session(&iter);
                    let next = std::cmp::min(200_000, rev_slice.len());
                    for &(dst, deg) in &rev_slice[..next] {
                        let mut accum = 0.0;
                        for &s in &trn_slice[..deg as usize] {
                            accum += src[s as usize];
                        }
                        trn_slice = &trn_slice[deg as usize..];
                        session.give((dst, accum));
                    }
                    rev_slice = &rev_slice[next..];
                }

                // clean out src to accumulate into
                for s in &mut src { *s = 0.0; }
            }

            // receive data from workers, accumulate in src
            while let Some((iter, data)) = input2.pull() {
                notificator.notify_at(&iter);
                for x in data.drain_temp() {
                    src[x.0 as usize / peers] += x.1;
                }
            }
        });

        // optionally, do process-local accumulation
        if _process_aggregate {
            let local_base = _workers * (index / _workers);
            let local_index = index % _workers;
            let mut acc = vec![0.0; (nodes / _workers) + 1];   // holds ranks
            ranks = ranks.unary_notify(
                Exchange::new(move |x: &(u32,f32)| (local_base as u64 + (x.0 as u64 % _workers as u64))),
                format!("Aggregation"),
                vec![],
                move |input, output, iterator| {
                    while let Some((iter, data)) = input.pull() {
                        iterator.notify_at(&iter);
                        for x in data.drain_temp() {
                            acc[x.0 as usize / _workers] += x.1;
                        }
                    }

                    while let Some((item, _)) = iterator.next() {
                        output.give_at(&item, acc.drain_temp().enumerate().filter(|x| x.1 != 0.0)
                                                 .map(|(u,f)| ((u * _workers + local_index) as u32, f)));

                        for _ in 0..(1 + (nodes/_workers)) { acc.push(0.0); }
                    }
                }
            );
        }

        ranks.connect_loop(cycle);

        input
    });

    // introduce edges into the computation;
    // allow mmaped file to drop
    {
        let graph = GraphMMap::new(&filename);

        let mut edges = Vec::new();
        for node in 0..graph.nodes() {
            if node % peers == index {
                for dst in graph.edges(node) {
                    edges.push((node as u32, *dst as u32));
                }
                if edges.len() > 100_000 {
                    input.send_at(0, edges.drain_temp());
                    root.step();
                }
            }
        }

        input.send_at(0, edges.drain_temp());
    }
    input.close();
    while root.step() { }

    if index == 0 { println!("elapsed: {}", time::precise_time_s() - start); }
}
<commit_msg>switched to less copying input session<commit_after>extern crate mmap;
extern crate time;
extern crate timely;
extern crate getopts;

use timely::progress::timestamp::RootTimestamp;
use timely::progress::nested::Summary::Local;
use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::*;
use timely::communication::pact::Exchange;
use timely::drain::DrainExt;

mod typedrw;
mod graphmap;
mod sorting;
use graphmap::GraphMMap;
use sorting::{SegmentList, radix_sort_32};

fn main () {

    let source = std::env::args().skip(1).next().unwrap();
    let strategy = std::env::args().skip(2).next().unwrap() == "process";

    // currently need timely's full option set to parse args
    let mut opts = getopts::Options::new();
    opts.optopt("w", "workers", "", "");
    opts.optopt("p", "process", "", "");
    opts.optopt("n", "processes", "", "");
    opts.optopt("h", "hostfile", "", "");

    if let Ok(matches) = opts.parse(std::env::args().skip(3)) {

        let workers: usize = matches.opt_str("w").map(|x| x.parse().unwrap_or(1)).unwrap_or(1);

        timely::initialize(std::env::args().skip(2), move |communicator| {
            pagerank_thread(communicator, &source, workers, strategy);
        });
    }
    else {
        println!("error parsing arguments");
        println!("usage:\tpagerank <source> (worker|process) [timely options]");
    }
}

// returns [src/peers] degrees, (dst, deg) pairs, and a list of [src/peers] endpoints
fn transpose(mut edges: Vec<Vec<(u32, u32)>>, peers: usize, nodes: usize) -> (Vec<u32>, Vec<(u32, u32)>, Vec<u32>)  {

    let mut deg = vec![0; (nodes as usize / peers) + 1];
    for list in &edges {
        for &(s, _) in list {
            deg[s as usize / peers] += 1;
        }
    }

    radix_sort_32(&mut edges, &mut Vec::new(), &|&(_,d)| d);

    let mut rev = Vec::<(u32,u32)>::with_capacity(deg.len());
    let mut trn = Vec::with_capacity(edges.len() * 1024);
    for list in edges {
        for (s,d) in list {
            let len = rev.len();
            if (len == 0) || (rev[len-1].0 < d) {
                rev.push((d, 0u32));
            }

            let len = rev.len();
            rev[len-1].1 += 1;
            trn.push(s / peers as u32);
        }
    }

    return (deg, rev, trn);
}

// pagerank dataflow graph has a set of edges as input, and a binary vertex that for each epoch of
// received edges initiates an iterative subcomputation to compute the pagerank.

fn pagerank_thread<C>(communicator: C, filename: &String, _workers: usize, _process_aggregate: bool)
where C: Communicator {
    let index = communicator.index() as usize;
    let peers = communicator.peers() as usize;

    let mut root = GraphRoot::new(communicator);

    let start = time::precise_time_s();

    let nodes = GraphMMap::new(&filename).nodes();

    let mut segments = SegmentList::new(1024); // list of edge segments

    let mut src = vec![];   // holds ranks
    let mut deg = vec![];   // holds source degrees
    let mut rev = vec![];   // holds (dst, deg) pairs
    let mut trn = vec![];   // holds transposed sources

    let mut going = start;

    let mut input = root.subcomputation(|builder| {

        let (input, edges) = builder.new_input::<(u32, u32)>();
        let (cycle, ranks) = builder.loop_variable::<(u32, f32)>(RootTimestamp::new(20), Local(1));

        let mut ranks = edges.binary_notify(&ranks,
                            Exchange::new(|x: &(u32,u32)| x.0 as u64),
                            Exchange::new(|x: &(u32,f32)| x.0 as u64),
                            format!("pagerank"),
                            vec![RootTimestamp::new(0)],
                            move |input1, input2, output, notificator| {

            // receive incoming edges (should only be iter 0)
            while let Some((_index, data)) = input1.pull() {
                segments.push(data.drain_temp());
            }

            // all inputs received for iter, commence multiplication
            while let Some((iter, _)) = notificator.next() {

                let now = time::now();

                if index == 0 { println!("{}:{}:{}.{} starting iteration {}", now.tm_hour, now.tm_min, now.tm_sec, now.tm_nsec, iter.inner); }

                // if the very first iteration, prepare some stuff.
                // specifically, transpose edges and sort by destination.
                if iter.inner == 0 {
                    let (a, b, c) = transpose(segments.finalize(), peers, nodes);
                    deg = a; rev = b; trn = c;
                    src = vec![0.0f32; deg.len()];
                }

                // record some timings in order to estimate per-iteration times
                if iter.inner == 0  && index == 0 { println!("src: {}, dst: {}, edges: {}", src.len(), rev.len(), trn.len()); }
                if iter.inner == 10 && index == 0 { going = time::precise_time_s(); }
                if iter.inner == 20 && index == 0 { println!("average: {}", (time::precise_time_s() - going) / 10.0 ); }

                // prepare src for transmitting to destinations
                for s in 0..src.len() { src[s] = 0.15 + 0.85 * src[s] / deg[s] as f32; }

                // wander through destinations
                let mut trn_slice = &trn[..];
                let mut session = output.session(&iter);
                for &(dst, deg) in &rev {
                    let mut accum = 0.0;
                    for &s in &trn_slice[..deg as usize] {
                        accum += src[s as usize];
                    }
                    trn_slice = &trn_slice[deg as usize..];
                    session.give((dst, accum));
                }

                // let mut rev_slice = &rev[..];
                // while rev_slice.len() > 0 {
                //     // TODO: session should flush automatically...
                //     let mut session = output.session(&iter);
                //     let next = std::cmp::min(200_000, rev_slice.len());
                //     for &(dst, deg) in &rev_slice[..next] {
                //         let mut accum = 0.0;
                //         for &s in &trn_slice[..deg as usize] {
                //             accum += src[s as usize];
                //         }
                //         trn_slice = &trn_slice[deg as usize..];
                //         session.give((dst, accum));
                //     }
                //     rev_slice = &rev_slice[next..];
                // }

                // clean out src to accumulate into
                for s in &mut src { *s = 0.0; }
            }

            // receive data from workers, accumulate in src
            while let Some((iter, data)) = input2.pull() {
                notificator.notify_at(&iter);
                for x in data.drain_temp() {
                    src[x.0 as usize / peers] += x.1;
                }
            }
        });

        // optionally, do process-local accumulation
        if _process_aggregate {
            let local_base = _workers * (index / _workers);
            let local_index = index % _workers;
            let mut acc = vec![0.0; (nodes / _workers) + 1];   // holds ranks
            ranks = ranks.unary_notify(
                Exchange::new(move |x: &(u32,f32)| (local_base as u64 + (x.0 as u64 % _workers as u64))),
                format!("Aggregation"),
                vec![],
                move |input, output, iterator| {
                    while let Some((iter, data)) = input.pull() {
                        iterator.notify_at(&iter);
                        for x in data.drain_temp() {
                            acc[x.0 as usize / _workers] += x.1;
                        }
                    }

                    while let Some((item, _)) = iterator.next() {
                        output.give_at(&item, acc.drain_temp().enumerate().filter(|x| x.1 != 0.0)
                                                 .map(|(u,f)| ((u * _workers + local_index) as u32, f)));

                        for _ in 0..(1 + (nodes/_workers)) { acc.push(0.0); }
                    }
                }
            );
        }

        ranks.connect_loop(cycle);

        input
    });

    // introduce edges into the computation;
    // allow mmaped file to drop
    {
        let graph = GraphMMap::new(&filename);

        let mut edges = Vec::new();
        for node in 0..graph.nodes() {
            if node % peers == index {
                for dst in graph.edges(node) {
                    edges.push((node as u32, *dst as u32));
                }
                if edges.len() > 100_000 {
                    input.send_at(0, edges.drain_temp());
                    root.step();
                }
            }
        }

        input.send_at(0, edges.drain_temp());
    }
    input.close();
    while root.step() { }

    if index == 0 { println!("elapsed: {}", time::precise_time_s() - start); }
}
<|endoftext|>


<commit_before>/*
 * A simple program that aims to extract various string constants from a JAR file (Java)
 */

extern crate classreader;
extern crate zip;
extern crate docopt;
extern crate serde;
extern crate java_properties;
extern crate shannon_entropy;

use docopt::Docopt;
use serde::Deserialize;
use classreader::*;
use std::fs::File;
use java_properties::PropertiesIter;
use std::io::BufReader;
use shannon_entropy::shannon_entropy;

const USAGE: &'static str = "
Java Strings extractor.

Usage:
  jstrings [-e] <source>...
  javaminer (-h | --help)

Options:
  -e            Print average entropy of each string (average of entropy of each word in the string)
  -h --help     Show this screen.

Source can be one or more class or jar files.
";

#[derive(Debug, Deserialize)]
struct Args {
    flag_e: bool,
    arg_source: Vec<String>
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());
    let printer = printer_factory(&args);
    for f in args.arg_source {
        if f.ends_with(".class") {
            process_class_file(&f, printer);
        } else if f.ends_with(".jar") {
            process_jar_file(&f, printer);
        } else if f.ends_with(".properties") {
            process_properties_file(&f, printer);
        }
    }
}

fn process_jar_file(file_name: &str, printer: fn(&str)) {
    let file = File::open(file_name).expect("couldn't find a file!");
    let mut zip = zip::ZipArchive::new(file).expect("could not read JAR");
    for i in 0..zip.len() {
        let mut class_file = zip.by_index(i).unwrap();
        if class_file.name().ends_with(".class") {
            let class = ClassReader::new_from_reader(&mut class_file).unwrap();
            process_class(&class, printer);
        } else if class_file.name().ends_with(".properties") {
            process_properties(class_file, printer);
        }
    }
}

fn process_class_file(file_name: &str, printer: fn(&str)) {
    let class = ClassReader::new_from_path(file_name).unwrap();
    process_class(&class, printer);
}

fn process_class(class: &Class, printer: fn(&str)) {
    assert_eq!(0xCAFEBABE, class.magic);
    for jstr in &class.constant_pool {
		if let ConstantPoolInfo::String(index) = *jstr {
			printer(get_string(class, index as usize));
		}
    }
}

/// Get constant from a pool, correcting for java's 1-based indexes.
fn get_const(class: &Class, i: usize) -> &ConstantPoolInfo {
    &class.constant_pool[i - 1]
}

/// Get string from constant pool
fn get_string(class: &Class, index: usize) -> &str {
    match *get_const(class, index) {
        ConstantPoolInfo::Utf8(ref s) => s,
        _ => "?"
    }
}

fn process_properties_file(file_name: &str, printer: fn(&str)) {
    let f = File::open(file_name).expect("couldn't find a file!");
    process_properties(BufReader::new(f), printer);
}

fn process_properties<R: std::io::Read>(f: R, printer: fn(&str)) {
    PropertiesIter::new(f).read_into(|_, v| {
      printer(&v);
    }).expect("failed to read a properties file");
}

// Output variants
fn printer_factory(args: &Args) -> fn(&str) {
    if args.flag_e {
        return print_entropy;
    }
    print_only
}

fn print_only(s: &str) {
    println!("{}", s);
}

fn print_entropy(s: &str) {
    println!("{:>6.2} {}", average_entropy(s), s);
}

fn average_entropy(s: &str) -> f32 {
    let tuple = s.split_whitespace().map(shannon_entropy).fold( (0.0, 0),
      |acc, w| (acc.0 + w, acc.1 + 1));
    tuple.0 / tuple.1 as f32
}
<commit_msg>Added threshold<commit_after>/*
 * A simple program that aims to extract various string constants from a JAR file (Java)
 */

extern crate classreader;
extern crate zip;
extern crate docopt;
extern crate serde;
extern crate java_properties;
extern crate shannon_entropy;

use docopt::Docopt;
use serde::Deserialize;
use classreader::*;
use std::fs::File;
use java_properties::PropertiesIter;
use std::io::BufReader;
use shannon_entropy::shannon_entropy;

const USAGE: &'static str = "
Java Strings extractor.

Usage:
  jstrings [-e] <source>...
  jstrings [-t <threshold>] <source>...
  jstrings (-h | --help)

Options:
  -e              Print average entropy of each string (average of entropy of each word in the string)
  -t <threshold>  Do not print string with entropy below threshold. Implies entropy computation.
  -h --help       Show this screen.

Source can be one or more class or jar files.
";

#[derive(Debug, Deserialize)]
struct Args {
    flag_e: bool,
    flag_t: Option<f32>,
    arg_source: Vec<String>
}

type Printer = Box<Fn(&str)>;

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());
    let printer = printer_factory(&args);
    for f in args.arg_source {
        if f.ends_with(".class") {
            process_class_file(&f, &printer);
        } else if f.ends_with(".jar") {
            process_jar_file(&f, &printer);
        } else if f.ends_with(".properties") {
            process_properties_file(&f, &printer);
        }
    }
}

fn process_jar_file(file_name: &str, printer: &Printer) {
    let file = File::open(file_name).expect("couldn't find a file!");
    let mut zip = zip::ZipArchive::new(file).expect("could not read JAR");
    for i in 0..zip.len() {
        let mut class_file = zip.by_index(i).unwrap();
        if class_file.name().ends_with(".class") {
            let class = ClassReader::new_from_reader(&mut class_file).unwrap();
            process_class(&class, printer);
        } else if class_file.name().ends_with(".properties") {
            process_properties(class_file, printer);
        }
    }
}

fn process_class_file(file_name: &str, printer: &Printer) {
    let class = ClassReader::new_from_path(file_name).unwrap();
    process_class(&class, printer);
}

fn process_class(class: &Class, printer: &Printer) {
    assert_eq!(0xCAFEBABE, class.magic);
    for jstr in &class.constant_pool {
		if let ConstantPoolInfo::String(index) = *jstr {
			printer(get_string(class, index as usize));
		}
    }
}

/// Get constant from a pool, correcting for java's 1-based indexes.
fn get_const(class: &Class, i: usize) -> &ConstantPoolInfo {
    &class.constant_pool[i - 1]
}

/// Get string from constant pool
fn get_string(class: &Class, index: usize) -> &str {
    match *get_const(class, index) {
        ConstantPoolInfo::Utf8(ref s) => s,
        _ => "?"
    }
}

fn process_properties_file(file_name: &str, printer: &Printer) {
    let f = File::open(file_name).expect("couldn't find a file!");
    process_properties(BufReader::new(f), printer);
}

fn process_properties<R: std::io::Read>(f: R, printer: &Printer) {
    PropertiesIter::new(f).read_into(|_, v| {
      printer(&v);
    }).expect("failed to read a properties file");
}

// Output variants
fn printer_factory(args: &Args) -> Printer {
	if let Some(t) = args.flag_t {
		return Box::new(move |s: &str| {
				let e = average_entropy(s);
				if e >= t {
					println!("{:>6.2} {}", e, s)
				}
			})
	}
    if args.flag_e {
        return Box::new(print_entropy)
    }
    Box::new(print_only)
}

fn print_only(s: &str) {
    println!("{}", s)
}

fn print_entropy(s: &str) {
    println!("{:>6.2} {}", average_entropy(s), s)
}

fn average_entropy(s: &str) -> f32 {
    let tuple = s.split_whitespace().map(shannon_entropy).fold( (0.0, 0),
      |acc, w| (acc.0 + w, acc.1 + 1));
    tuple.0 / tuple.1 as f32
}
<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::collections;
use std::io;
use std::path;
use std::process;

use std::os::unix::fs::FileTypeExt;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] [<path>] <pattern>
    srch --help
    srch --version

Options:
    -h, --help              Show this help screen
    -v, --version           Show this program's version
    -i, --invisible         Also search inside directories starting with a . character
    -f, --filesonly         Only search filenames and NOT directory names
";

#[derive(RustcDecodable)]
struct Args {
    arg_pattern: String,
    arg_path: String,

    flag_i: bool,
    flag_invisible: bool,

    flag_f: bool,
    flag_filesonly: bool,
}

struct Settings {
    pattern: String,
    path: String,

    invisible: bool,
    files_only: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .unwrap()
        .help(true)
        .version(Some(String::from("srch ") +
                      option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
        .decode()
        .unwrap_or_else(|e| e.exit());

    let settings = Settings {
        pattern: args.arg_pattern,
        path: args.arg_path,
        invisible: args.flag_i || args.flag_invisible,
        files_only: args.flag_f || args.flag_filesonly,
    };

    let dir = path::PathBuf::from(&settings.path);
    if settings.path.is_empty() {
        let curdir = path::PathBuf::from(".");
        handle(&curdir, &settings);
    } else if !dir.exists() {
        println!("Invalid search path: {}",
                 Colour::Red.bold().paint(settings.path.as_str()));
        process::exit(1);
    } else {
        handle(&dir, &settings);
    }
}

fn ignore(path: &path::PathBuf, settings: &Settings) -> io::Result<bool> {
    if !path.is_dir() {
        return Ok(true);
    }

    let m = try!(path.symlink_metadata()).file_type();
    if m.is_symlink() || m.is_block_device() || m.is_char_device() || m.is_fifo() || m.is_socket() {
        return Ok(true);
    }

    if settings.invisible {
        return Ok(false);
    }

    let fname = path.file_name();
    if fname == None {
        return Ok(false);
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return Ok(true);
    }

    Ok(false)
}

trait Misc {
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if self.is_dir() {
            Ok(Colour::Purple.paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false;
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true;
        }
        false
    }
}

struct SearchResults {
    directories: i32,
    files: i32,

    scanned: i32,
    pushed: i32,
}

impl SearchResults {
    fn add(&mut self, other: SearchResults) {
        self.directories += other.directories;
        self.files += other.files;

        self.scanned += other.scanned;
        self.pushed += other.pushed;
    }
}

fn handle(path: &path::PathBuf, settings: &Settings) -> () {
    let mut q: collections::VecDeque<path::PathBuf> = collections::VecDeque::new();
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 1,
    };

    let pattern = &settings.pattern;

    println!("Searching {} for {}",
             Colour::Yellow.bold().paint(path.to_str().unwrap()),
             Colour::Green.bold().paint(pattern.as_str()));
    q.push_back(path.clone());
    while q.len() > 0 {
        let p = q.pop_front().unwrap();
        let i = ignore(&p, settings);
        match i {
            Ok(tf) => {
                if tf {
                    continue;
                }
            }
            Err(_) => continue,
        };

        let r = search(&mut q, &p, pattern, settings.files_only);
        match r {
            Ok(n) => {
                results.add(n);
            }
            Err(_) => (),
        };
    }

    print!("Explored {} directories and searched {} objects, ",
           Colour::Yellow.bold().paint(results.pushed.to_string()),
           Colour::Yellow.bold().paint(results.scanned.to_string()));
    println!("found {} directories and {} files",
             Colour::Green.bold().paint(results.directories.to_string()),
             Colour::Green.bold().paint(results.files.to_string()));
}

fn search(q: &mut collections::VecDeque<path::PathBuf>,
          path: &path::PathBuf,
          pattern: &String,
          ignore_dirs: bool)
          -> std::io::Result<SearchResults> {
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 0,
    };

    for item in try!(path.read_dir()) {
        let f = try!(item); // f is a DirEntry
        let dir: bool;
        if f.path().is_dir() {
            results.pushed += 1;
            q.push_back(f.path());
            if ignore_dirs {
                continue;
            }
            dir = true;
            results.scanned += 1;
        } else {
            dir = false;
            results.scanned += 1;
        }

        if f.path().matches(&pattern) {
            println!("{}", try!(f.path().display_colour()));
            if dir {
                results.directories += 1;
            } else {
                results.files += 1;
            }
        }
    }

    Ok(results)
}
<commit_msg>Use single results object<commit_after>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::collections;
use std::io;
use std::path;
use std::process;

use std::os::unix::fs::FileTypeExt;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] [<path>] <pattern>
    srch --help
    srch --version

Options:
    -h, --help              Show this help screen
    -v, --version           Show this program's version
    -i, --invisible         Also search inside directories starting with a . character
    -f, --filesonly         Only search filenames and NOT directory names
";

#[derive(RustcDecodable)]
struct Args {
    arg_pattern: String,
    arg_path: String,

    flag_i: bool,
    flag_invisible: bool,

    flag_f: bool,
    flag_filesonly: bool,
}

struct Settings {
    pattern: String,
    path: String,

    invisible: bool,
    files_only: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .unwrap()
        .help(true)
        .version(Some(String::from("srch ") +
                      option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
        .decode()
        .unwrap_or_else(|e| e.exit());

    let settings = Settings {
        pattern: args.arg_pattern,
        path: args.arg_path,
        invisible: args.flag_i || args.flag_invisible,
        files_only: args.flag_f || args.flag_filesonly,
    };

    let dir = path::PathBuf::from(&settings.path);
    if settings.path.is_empty() {
        let curdir = path::PathBuf::from(".");
        handle(&curdir, &settings);
    } else if !dir.exists() {
        println!("Invalid search path: {}",
                 Colour::Red.bold().paint(settings.path.as_str()));
        process::exit(1);
    } else {
        handle(&dir, &settings);
    }
}

fn ignore(path: &path::PathBuf, settings: &Settings) -> io::Result<bool> {
    if !path.is_dir() {
        return Ok(true);
    }

    let m = try!(path.symlink_metadata()).file_type();
    if m.is_symlink() || m.is_block_device() || m.is_char_device() || m.is_fifo() || m.is_socket() {
        return Ok(true);
    }

    if settings.invisible {
        return Ok(false);
    }

    let fname = path.file_name();
    if fname == None {
        return Ok(false);
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return Ok(true);
    }

    Ok(false)
}

trait Misc {
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if self.is_dir() {
            Ok(Colour::Purple.paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false;
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true;
        }
        false
    }
}

struct SearchResults {
    directories: i32,
    files: i32,

    scanned: i32,
    pushed: i32,
}

fn handle(path: &path::PathBuf, settings: &Settings) -> () {
    let mut q: collections::VecDeque<path::PathBuf> = collections::VecDeque::new();
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 1,
    };

    let pattern = &settings.pattern;

    println!("Searching {} for {}",
             Colour::Yellow.bold().paint(path.to_str().unwrap()),
             Colour::Green.bold().paint(pattern.as_str()));
    q.push_back(path.clone());
    while q.len() > 0 {
        let p = q.pop_front().unwrap();
        match ignore(&p, settings) {
            Ok(i) => i && continue,
            Err(_) => continue,
        };

        match search(&mut q, &p, pattern, settings.files_only, &mut results) {
            Ok(_) => (),
            Err(_) => (),
        };
    }

    println!("Explored {} directories and searched {} objects, found {} directories and {} files",
             Colour::Yellow.bold().paint(results.pushed.to_string()),
             Colour::Yellow.bold().paint(results.scanned.to_string()),
             Colour::Green.bold().paint(results.directories.to_string()),
             Colour::Green.bold().paint(results.files.to_string()));
}

fn search(q: &mut collections::VecDeque<path::PathBuf>,
          path: &path::PathBuf,
          pattern: &String,
          ignore_dirs: bool,
          results: &mut SearchResults)
          -> std::io::Result<()> {

    for item in try!(path.read_dir()) {
        let f = try!(item); // f is a DirEntry
        let p = f.path();
        let dir = p.is_dir();
        if dir {
            results.pushed += 1;
            q.push_back(f.path());
            if ignore_dirs {
                continue;
            }
            results.scanned += 1;
        } else {
            results.scanned += 1;
        }

        if p.matches(&pattern) {
            println!("{}", try!(p.display_colour()));
            if dir {
                results.directories += 1;
            } else {
                results.files += 1;
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate toml;
extern crate glob;

use std::io::fs::PathExtensions;
use std::io::fs;
use std::io;
use std::os;

use app_result::{AppResult, app_err};

use dependencies::{
   TagsRoot,
   read_dependencies
};

use tags::{
   update_tags,
   update_tags_and_check_for_reexports,
   create_tags,
   merge_tags
};

use dirs::rusty_tags_dir;

mod app_result;
mod dependencies;
mod dirs;
mod tags;

fn main()
{
   update_all_tags().unwrap_or_else(|err| {
      let stderr = &mut io::stderr();
      let _ = writeln!(stderr, "rusty-tags: {}", err);
      os::set_exit_status(1);
   });
}

fn update_all_tags() -> AppResult<()>
{
   let cwd = try!(os::getcwd());
   let cargo_dir = try!(find_cargo_toml_dir(&cwd));
   let tags_roots = try!(read_dependencies(&cargo_dir));

   for tags_root in tags_roots.iter() {
      let mut tag_files: Vec<Path> = Vec::new();
      let mut tag_dir: Option<Path> = None;

      match *tags_root {
         TagsRoot::Src { ref src_dir, ref dependencies } => {
            let mut src_tags = src_dir.clone();
            src_tags.push("rusty.tags");
            try!(create_tags(src_dir, &src_tags));
            tag_files.push(src_tags);

            for dep in dependencies.iter() {
               tag_files.push(try!(update_tags(dep)).tags_file);
            }

            tag_dir = Some(src_dir.clone());
         },

         TagsRoot::Lib { ref src_kind, ref dependencies } => {
            let lib_tags = try!(update_tags_and_check_for_reexports(src_kind, dependencies));
            if lib_tags.cached {
               let mut src_tags = lib_tags.src_dir.clone();
               src_tags.push("rusty.tags");
               if src_tags.is_file() {
                  continue;
               }
            }

            tag_files.push(lib_tags.tags_file);

            for dep in dependencies.iter() {
               tag_files.push(try!(update_tags(dep)).tags_file);
            }

            tag_dir = Some(lib_tags.src_dir.clone());
         }
      }

      if tag_files.is_empty() || tag_dir.is_none() {
         continue;
      }

      let mut rust_tags = try!(rusty_tags_dir());
      rust_tags.push("rust");
      if rust_tags.is_file() {
         tag_files.push(rust_tags);
      }

      let mut tags_file = tag_dir.unwrap();
      tags_file.push("rusty.tags");

      try!(merge_tags(&tag_files, &tags_file));
   }

   Ok(())
}

/// Searches for a directory containing a `Cargo.toml` file starting at
/// `start_dir` and continuing the search upwards the directory tree
/// until a directory is found.
fn find_cargo_toml_dir(start_dir: &Path) -> AppResult<Path>
{
   let mut dir = start_dir.clone();
   loop {
      if let Ok(files) = fs::readdir(&dir) {
         for file in files.iter() {
            if file.is_file() {
               if let Some("Cargo.toml") = file.filename_str() {
                  return Ok(dir);
               }
            }
         }
      }

      if ! dir.pop() {
         return Err(app_err(format!("Couldn't find 'Cargo.toml' starting at directory '{}'!", start_dir.display())));
      }
   }
}
<commit_msg>Define tags file name at one place<commit_after>extern crate toml;
extern crate glob;

use std::io::fs::PathExtensions;
use std::io::fs;
use std::io;
use std::os;

use app_result::{AppResult, app_err};

use dependencies::{
   TagsRoot,
   read_dependencies
};

use tags::{
   update_tags,
   update_tags_and_check_for_reexports,
   create_tags,
   merge_tags
};

use dirs::rusty_tags_dir;

mod app_result;
mod dependencies;
mod dirs;
mod tags;

fn main()
{
   update_all_tags().unwrap_or_else(|err| {
      let stderr = &mut io::stderr();
      let _ = writeln!(stderr, "rusty-tags: {}", err);
      os::set_exit_status(1);
   });
}

fn update_all_tags() -> AppResult<()>
{
   let cwd = try!(os::getcwd());
   let cargo_dir = try!(find_cargo_toml_dir(&cwd));
   let tags_roots = try!(read_dependencies(&cargo_dir));

   for tags_root in tags_roots.iter() {
      let mut tag_files: Vec<Path> = Vec::new();
      let mut tag_dir: Option<Path> = None;

      match *tags_root {
         TagsRoot::Src { ref src_dir, ref dependencies } => {
            let mut src_tags = src_dir.clone();
            src_tags.push(rusty_tags_file_name());
            try!(create_tags(src_dir, &src_tags));
            tag_files.push(src_tags);

            for dep in dependencies.iter() {
               tag_files.push(try!(update_tags(dep)).tags_file);
            }

            tag_dir = Some(src_dir.clone());
         },

         TagsRoot::Lib { ref src_kind, ref dependencies } => {
            let lib_tags = try!(update_tags_and_check_for_reexports(src_kind, dependencies));
            if lib_tags.cached {
               let mut src_tags = lib_tags.src_dir.clone();
               src_tags.push(rusty_tags_file_name());
               if src_tags.is_file() {
                  continue;
               }
            }

            tag_files.push(lib_tags.tags_file);

            for dep in dependencies.iter() {
               tag_files.push(try!(update_tags(dep)).tags_file);
            }

            tag_dir = Some(lib_tags.src_dir.clone());
         }
      }

      if tag_files.is_empty() || tag_dir.is_none() {
         continue;
      }

      let mut rust_tags = try!(rusty_tags_dir());
      rust_tags.push("rust");
      if rust_tags.is_file() {
         tag_files.push(rust_tags);
      }

      let mut tags_file = tag_dir.unwrap();
      tags_file.push(rusty_tags_file_name());

      try!(merge_tags(&tag_files, &tags_file));
   }

   Ok(())
}

/// Searches for a directory containing a `Cargo.toml` file starting at
/// `start_dir` and continuing the search upwards the directory tree
/// until a directory is found.
fn find_cargo_toml_dir(start_dir: &Path) -> AppResult<Path>
{
   let mut dir = start_dir.clone();
   loop {
      if let Ok(files) = fs::readdir(&dir) {
         for file in files.iter() {
            if file.is_file() {
               if let Some("Cargo.toml") = file.filename_str() {
                  return Ok(dir);
               }
            }
         }
      }

      if ! dir.pop() {
         return Err(app_err(format!("Couldn't find 'Cargo.toml' starting at directory '{}'!", start_dir.display())));
      }
   }
}

/// the name under which the tags files are saved
fn rusty_tags_file_name() -> &'static str
{
   "rusty.tags"
}
<|endoftext|>


<commit_before>// TODO
// when sending too much data, size gets printed. it is not beeing sent a u8, it is being sent as a string i think
// add nickname
// check how to print prompt. is it possible without using a CLI interface?
// modularize
// print list of peers (exclude myself or print myself and state it is me)
// add /help
//     Help:          -h --help
//    Host IP:       -H --host {host IP}
//    Broadcast IP:  -B --broadcast {broadcast IP}
//    RPC Port:      -P --port {port}
// add encryption
// add rooms
// add CLI with https://github.com/gchp/rustbox or https://github.com/jeaye/ncurses-rs?

use std::net::UdpSocket;
use std::io;
use std::io::Write;
use std::thread;
use std::time::Duration;
use std::process;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::time::SystemTime;

fn main () {
    let peers = Arc::new(Mutex::new(HashMap::new()));

    let peers_sender = peers.clone();
    let sender = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");

        print!("> ");
        io::stdout().flush().unwrap();

        loop {
            let mut input = String::new();
            match io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input.pop();

                    process(&socket, input);
                    io::stdout().flush().unwrap();
                    print!("> ");
                   // println!("peers {:?}", *peers_sender.lock().unwrap()); //TODO move this to the process of the sender when writting /peers
                }
                Err(error) =>
                    println!("error: {}", error),
            }
        }
    });

    let prober = thread::spawn(|| {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");
        loop {
            let message = format!("P");
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
            thread::sleep(Duration::from_millis(5000)); //TODO put in seconds
        }
    });

    let peers_rec = peers.clone();
    let receiver = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:4041").expect("couldn't bind to address");

        loop {
            let mut buffer = [0; 512];
            let (received_bytes, source) = socket.recv_from(&mut buffer)
                .expect("Didn't receive data");

            match std::str::from_utf8(&buffer[0..1]).unwrap() {
                "M" => {
                    println!("{}", std::str::from_utf8(&buffer[2..received_bytes]).unwrap());
                    io::stdout().flush().unwrap();
                }

                "P" => {
                    //println!("probe with source {}", source);
                    peers_rec.lock().unwrap().insert(source, SystemTime::now()); //TODO insert only seconds and IP
                    // clean hosts that have not received content for more than x seconds
                }

                _ =>  {
                }
            }

        }
    });

    receiver.join().unwrap();
    sender.join().unwrap();
    prober.join().unwrap();
}

fn process(socket: &UdpSocket, input: String) {
    match input.as_ref() {
        "" => {

        },

        "/quit" => {
            process::exit(0x0f00);
        },

        "/peers" => {
            //TODO print list of
        },

        "/rooms" => {
        },

        "/help" => {
        },

        _ => {
            let size = input.len();
            let message = format!("M{}{}", size, input);
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
        }
    }
    ()
}
<commit_msg>Print > when i receive it<commit_after>// TODO
// when sending too much data, size gets printed. it is not beeing sent a u8, it is being sent as a string i think
// add nickname
// modularize
// print list of peers (exclude myself or print myself and state it is me)
// add /help
//     Help:          -h --help
//    Host IP:       -H --host {host IP}
//    Broadcast IP:  -B --broadcast {broadcast IP}
//    RPC Port:      -P --port {port}
// add encryption
// add rooms, by default join lobby

use std::net::UdpSocket;
use std::io;
use std::io::Write;
use std::thread;
use std::time::Duration;
use std::process;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::time::SystemTime;

fn main () {
    let peers = Arc::new(Mutex::new(HashMap::new()));

    let peers_sender = peers.clone();
    let sender = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");

        print!("> ");
        io::stdout().flush().unwrap();

        loop {
            let mut input = String::new();
            match io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input.pop();

                    process(&socket, input);
                    io::stdout().flush().unwrap();
                   // println!("peers {:?}", *peers_sender.lock().unwrap()); //TODO move this to the process of the sender when writting /peers
                }
                Err(error) =>
                    println!("error: {}", error),
            }
        }
    });

    let prober = thread::spawn(|| {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");
        loop {
            let message = format!("P");
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
            thread::sleep(Duration::from_millis(5000)); //TODO put in seconds
        }
    });

    let peers_rec = peers.clone();
    let receiver = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:4041").expect("couldn't bind to address");

        loop {
            let mut buffer = [0; 512];
            let (received_bytes, source) = socket.recv_from(&mut buffer)
                .expect("Didn't receive data");

            match std::str::from_utf8(&buffer[0..1]).unwrap() {
                "M" => {
                    println!("{}", std::str::from_utf8(&buffer[2..received_bytes]).unwrap());
                    io::stdout().flush().unwrap();
                    print!("> ");
                    io::stdout().flush().unwrap();
                }

                "P" => {
                    //println!("probe with source {}", source);
                    peers_rec.lock().unwrap().insert(source, SystemTime::now()); //TODO insert only seconds and IP
                    // clean hosts that have not received content for more than x seconds
                }

                _ =>  {
                }
            }

        }
    });

    receiver.join().unwrap();
    sender.join().unwrap();
    prober.join().unwrap();
}

fn process(socket: &UdpSocket, input: String) {
    match input.as_ref() {
        "" => {

        },

        "/quit" => {
            process::exit(0x0f00);
        },

        "/peers" => {
            //TODO print list of
        },

        "/rooms" => {
        },

        "/help" => {
        },

        _ => {
            let size = input.len();
            let message = format!("M{}{}", size, input);
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
        }
    }
    ()
}
<|endoftext|>