<commit_before>//! The main entry point for the SpaceAPi server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate hyper;
extern crate redis;

mod utils;
mod spaceapi;
mod datastore;
mod redis_store;

use std::io::Write;
use std::net::Ipv4Addr;

use rustc_serialize::json;
use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;
use hyper::net::Fresh;

use datastore::DataStore;

fn build_response_json(people_present: Option<u32>, raspi_temperature: Option<f32>) -> String {
    let people_present_sensor = match people_present {
        Some(count) => vec![
            spaceapi::PeopleNowPresentSensor {
                value: count,
                location: Some("Hackerspace".to_string()),
                name: None,
                description: None,
            }
        ],
        None => Vec::new(),
    };

    let temperature_sensor = match raspi_temperature {
        Some(degrees) => vec![
            spaceapi::TemperatureSensor {
                value: degrees,
                unit: "°C".to_string(),
                location: "Hackerspace".to_string(),
                name: Some("Raspberry CPU".to_string()),
                description: None,
            }
        ],
        None => Vec::new(),
    };

    let status = spaceapi::Status {
        api: "0.13".to_string(),
        space: "coredump".to_string(),
        logo: "https://www.coredump.ch/logo.png".to_string(),
        url: "https://www.coredump.ch/".to_string(),
        location: spaceapi::Location {
            address: "Spinnereistrasse 2, 8640 Rapperswil, Switzerland".to_string(),
            lat: 47.22936,
            lon: 8.82949,
        },
        spacefed: spaceapi::SpaceFED {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        },
        cache: spaceapi::Cache {
            schedule: "m.02".to_string(),
        },
        state: spaceapi::State {
            open: false,
            message: "Open every Monday from 20:00".to_string(),
        },
        contact: spaceapi::Contact {
            irc: "irc://freenode.net/#coredump".to_string(),
            twitter: "@coredump_ch".to_string(),
            foursquare: "525c20e5498e875d8231b1e5".to_string(),
            email: "danilo@coredump.ch".to_string(),
        },
        issue_report_channels: vec![
            "email".to_string(),
            "twitter".to_string(),
        ],
        feeds: spaceapi::Feeds {
            blog: spaceapi::Feed {
                _type: "rss".to_string(),
                url: "https://www.coredump.ch/feed/".to_string(),
            },
        },
        projects: vec![
            "https://www.coredump.ch/projekte/".to_string(),
            "https://discourse.coredump.ch/c/projects".to_string(),
            "https://github.com/coredump-ch/".to_string(),
        ],
        sensors: spaceapi::Sensors {
            people_now_present: people_present_sensor,
            temperature: temperature_sensor,
        },
    };
    json::encode(&status).unwrap()
}

fn status_endpoint(_: Request, res: Response<Fresh>) {
    let mut res = res.start().unwrap();

    let datastore = redis_store::RedisStore::new().unwrap();
    let people_present: Option<u32> = match datastore.retrieve("people_present") {
        Ok(v) => match v.parse::<u32>() {
            Ok(i) => Some(i),
            Err(_) => None,
        },
        Err(_) => None,
    };
    let raspi_temperature: Option<f32> = match datastore.retrieve("raspi_temperature") {
        Ok(v) => match v.parse::<f32>() {
            Ok(i) => Some(i),
            Err(_) => None,
        },
        Err(_) => None,
    };

    let response_body = build_response_json(people_present, raspi_temperature);
    res.write_all(response_body.as_bytes()).unwrap();
    res.end().unwrap();
}

fn main() {
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let port = utils::get_port();

    println!("Starting HTTP server on {}:{}...", ip, port);
    Server::http(status_endpoint).listen((ip, port)).unwrap();
}
<commit_msg>Set ContentLength and ContentType headers<commit_after>//! The main entry point for the SpaceAPi server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate hyper;
extern crate redis;

mod utils;
mod spaceapi;
mod datastore;
mod redis_store;

use std::io::Write;
use std::net::Ipv4Addr;

use rustc_serialize::json;
use hyper::Server;
use hyper::server::Request;
use hyper::server::Response;
use hyper::net::Fresh;
use hyper::header;

use datastore::DataStore;

fn build_response_json(people_present: Option<u32>, raspi_temperature: Option<f32>) -> String {
    let people_present_sensor = match people_present {
        Some(count) => vec![
            spaceapi::PeopleNowPresentSensor {
                value: count,
                location: Some("Hackerspace".to_string()),
                name: None,
                description: None,
            }
        ],
        None => Vec::new(),
    };

    let temperature_sensor = match raspi_temperature {
        Some(degrees) => vec![
            spaceapi::TemperatureSensor {
                value: degrees,
                unit: "°C".to_string(),
                location: "Hackerspace".to_string(),
                name: Some("Raspberry CPU".to_string()),
                description: None,
            }
        ],
        None => Vec::new(),
    };

    let status = spaceapi::Status {
        api: "0.13".to_string(),
        space: "coredump".to_string(),
        logo: "https://www.coredump.ch/logo.png".to_string(),
        url: "https://www.coredump.ch/".to_string(),
        location: spaceapi::Location {
            address: "Spinnereistrasse 2, 8640 Rapperswil, Switzerland".to_string(),
            lat: 47.22936,
            lon: 8.82949,
        },
        spacefed: spaceapi::SpaceFED {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        },
        cache: spaceapi::Cache {
            schedule: "m.02".to_string(),
        },
        state: spaceapi::State {
            open: false,
            message: "Open every Monday from 20:00".to_string(),
        },
        contact: spaceapi::Contact {
            irc: "irc://freenode.net/#coredump".to_string(),
            twitter: "@coredump_ch".to_string(),
            foursquare: "525c20e5498e875d8231b1e5".to_string(),
            email: "danilo@coredump.ch".to_string(),
        },
        issue_report_channels: vec![
            "email".to_string(),
            "twitter".to_string(),
        ],
        feeds: spaceapi::Feeds {
            blog: spaceapi::Feed {
                _type: "rss".to_string(),
                url: "https://www.coredump.ch/feed/".to_string(),
            },
        },
        projects: vec![
            "https://www.coredump.ch/projekte/".to_string(),
            "https://discourse.coredump.ch/c/projects".to_string(),
            "https://github.com/coredump-ch/".to_string(),
        ],
        sensors: spaceapi::Sensors {
            people_now_present: people_present_sensor,
            temperature: temperature_sensor,
        },
    };
    json::encode(&status).unwrap()
}

fn status_endpoint(_: Request, res: Response<Fresh>) {
    // Move response into mutable variable
    let mut res = res;

    // Fetch data from datastore
    let datastore = redis_store::RedisStore::new().unwrap();
    let people_present: Option<u32> = match datastore.retrieve("people_present") {
        Ok(v) => match v.parse::<u32>() {
            Ok(i) => Some(i),
            Err(_) => None,
        },
        Err(_) => None,
    };
    let raspi_temperature: Option<f32> = match datastore.retrieve("raspi_temperature") {
        Ok(v) => match v.parse::<f32>() {
            Ok(i) => Some(i),
            Err(_) => None,
        },
        Err(_) => None,
    };

    // Get response body
    let body = build_response_json(people_present, raspi_temperature);
    let body_bytes = body.as_bytes();

    // Set headers
    {
        let mut headers = res.headers_mut();
        headers.set(header::ContentLength(body_bytes.len() as u64));
        headers.set(header::ContentType("application/json; charset=utf-8".parse().unwrap()));
    }

    // Write response body
    let mut stream = res.start().unwrap();
    stream.write_all(body_bytes).unwrap();

    stream.end().unwrap();
}

fn main() {
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let port = utils::get_port();

    println!("Starting HTTP server on {}:{}...", ip, port);
    Server::http(status_endpoint).listen((ip, port)).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Fixed a couple of mistakes related to rounding analysis<commit_after><|endoftext|>


<commit_before>extern crate image;
extern crate dungenon;
extern crate cast;

use std::io;
use std::path::PathBuf;

use dungenon::level::Level;
use dungenon::tile::{Tile, Faction};
use dungenon::generator::{MazeGen, RoomGen, DungeonGen, FactionGen};
use dungenon::util::Error;

use image::RgbImage;
use image::Rgb;

use std::collections::HashMap;

fn main() {
    Drawer::new().start();
}

struct Drawer {
    pub dungeon_colors: HashMap<Tile, Rgb<u8>>,
    pub faction_colors: HashMap<Faction, Rgb<u8>>,
}

impl Drawer {
    pub fn new() -> Drawer {
        let mut dungeon_colors = HashMap::new();
        dungeon_colors.insert(Tile::Wall(0), Rgb([127u8, 127u8, 127u8]));
        dungeon_colors.insert(Tile::Floor(0), Rgb([200u8, 200u8, 200u8]));
        dungeon_colors.insert(Tile::Void(0), Rgb([0u8, 0u8, 0u8]));

        let mut faction_colors = HashMap::new();
        faction_colors.insert(Faction::Faction(0), Rgb([200u8, 0u8, 0u8]));
        faction_colors.insert(Faction::Faction(1), Rgb([0u8, 0u8, 127u8]));
        faction_colors.insert(Faction::Neutral, Rgb([127u8, 127u8, 127u8]));
        faction_colors.insert(Faction::Void, Rgb([0u8, 0u8, 0u8]));

        Drawer{
            dungeon_colors: dungeon_colors,
            faction_colors: faction_colors,
        }
    }

    pub fn start(&mut self) {
        println!("Choose level type(faction, tile):");
        let t = Self::string_from_cmd();
        match t.trim() {
            "faction" => self.start_faction(),
            "tile" => self.start_tile(),
        }
    }

    pub fn start_faction(&mut self) {
        let mut level = self.init_faction_level();
        let simulator = FactionGen::new();

        println!("This is the faction mode of dungenon-drawer.");
        println!("Type Help for list of possible commands.");
        loop {
            println!("Enter command:");
            let command = Self::string_from_cmd();
            match command.trim() {
                "simulate" => Self::simulate_factions(&mut level, &mut simulator),
                "factions" => Self::edit_level(&mut level),
                "colors" => self.change_faction_colors(),
                "export" => self.faction_png_export(&mut level),
                "help" => println!("Options: help, simulate, factions, colors, export and exit"),
                "exit" => break,
                _ => println!("Invalid command.")
            }
        }
    }

    fn change_faction_colors(&mut self) {
        use cast;
        use std::u8;
        loop {
            println!("Which color would you like to change? (faction, neutral, void), Type exit if you're done with modifying colors.");
            let command = Self::string_from_cmd();
            let key = match command.trim() {
                "faction" => {

                },
                "neutral" => Faction::Neutral,
                "void" => Faction::Void,
                "exit" => break,
                _ => {
                    println!("Invalid command.");
                    continue;
                },
            };
            println!("Input red value for the color:");
            let r = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input green value for the color:");
            let g = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input blue value for the color:");
            let b = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);
            self.faction_colors.insert(key, Rgb([r,g,b]));
        }
    }

    fn init_faction_level(&self) -> Level<Faction> {
        println!("Initializing level...");
        println!("Input level width: ");
        let x = Self::usize_from_cmd();

        println!("Input level height: ");
        let y = Self::usize_from_cmd();

        Level::new_filled_with(Faction::Neutral, x, y)
    }

    fn simulate_factions(level: &mut Level<Faction>, simulator: &mut FactionGen) {
        println!("How many simulation steps are iterated?");
        let iterations = Self::u64_from_cmd();
        for _ in 0 .. iterations {
            level.apply(|m| simulator.generate(m));
        }
    }

    fn faction_png_export(&self, level: &mut Level<Faction>) {
        let mut level_image = RgbImage::new(level.get_width() as u32, level.get_height() as u32);
        for x in 0 .. level.get_width() {
            for y in 0 .. level.get_height() {
                level_image.put_pixel(x as u32, y as u32, self.faction_to_color(&level.get_tile_with_tuple((x,y))));
            }
        }
        let mut p = PathBuf::new();
        println!("Enter png name:");
        p.push(Self::string_from_cmd().trim());
        p.set_extension("png");
        level_image.save(p.as_path()).expect("Something went wrong when saving the png.");
    }

    fn edit_level(level: &mut Level<Faction>) {
        loop {
            println!("Input x coordinate:");
            let x = Self::usize_from_cmd();
            println!("Input y coordinate:");
            let y = Self::usize_from_cmd();

            println!("Select type(faction, neutral, void):");
            let faction_type = Self::string_from_cmd();
            let faction = match faction_type.trim() {
                "faction" => {
                    println!("Input faction number:");
                    let faction_number = Self::usize_from_cmd();
                    Faction::Faction(faction_number)
                },
                "neutral" => Faction::Neutral,
                "void" => Faction::Void,
                _ => {
                    println!("Invalid type.");
                    break;
                }
            };
            match level.get_mut_tile(x,y) {
                Ok(tile) => {
                    *tile = faction;
                },
                Err(_) => println!("Index out of bounds"),
            };
            println!("do you want to change another tile? (yes/no)");
            match Self::string_from_cmd() {
                "yes" => continue,
                "no" => break,
            }
        }
    }

    pub fn start_tile(&mut self) {
        let mut level = self.init_tile_level();

        println!("This is the tile mode of dungenon-drawer. \nType Help for list of commands.");
        loop {
            println!("Enter command:");
            let command = Self::string_from_cmd();
            match command.trim() {
                "dungeon" => Self::carve_dungeon(&mut level),
                "maze" => Self::carve_maze(&mut level),
                "room" => Self::carve_rooms(&mut level),
                "reset" => level = self.init_level(),
                "colors" => self.change_dungeon_colors(),
                "export" => {
                    self.tile_png_export(&mut level);
                },
                "print" => Self::print_level(&level),
                "help" => {
                    println!("Options: dungeon, maze, room, reset, colors, export, print, help, and exit");
                }
                "exit" => break,
                _ => println!("Invalid command."),
            }
        }
    }

    fn faction_to_color(&self, tile: &Result<&Faction, Error>) -> Rgb<u8> {
        match *tile {
            Ok(ref tile) => {
                    match self.faction_colors.get(tile) {
                        Some(color) => color.clone(),
                        None => Rgb([255u8, 0u8, 255u8]),
                    }
            },
            Err(Error::IndexOutOfBounds) => panic!("Tile png import failed. Level indexing went out of bounds."),
        }
    }

    fn change_dungeon_colors(&mut self) {
        use cast;
        use std::u8;
        loop {
            println!("Which color would you like to change? (floor, wall, void), Type exit if you're done with modifying colors.");
            let command = Self::string_from_cmd();
            let key = match command.trim() {
                "floor" => Tile::Floor(0),
                "wall" => Tile::Wall(0),
                "void" => Tile::Void(0),
                "exit" => break,
                _ => {
                    println!("Invalid command.");
                    continue;
                },
            };
            println!("Input red value for the color:");
            let r = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input green value for the color:");
            let g = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input blue value for the color:");
            let b = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);
            self.colors.insert(key, Rgb([r,g,b]));
        }
    }

    fn init_tile_level(&self) -> Level<Tile> {
        println!("Initializing level...");
        println!("Input level width: ");
        let x = Self::usize_from_cmd();

        println!("Input level height: ");
        let y = Self::usize_from_cmd();

        Level::new_filled_with(Tile::Wall(0), x, y)
    }

    fn carve_dungeon(level: &mut Level<Tile>) {
        println!("Creating DungeonGen...");
        let mazegen = Self::create_mazegen();
        let roomgen = Self::create_roomgen();
        let mut dungeongen = DungeonGen::new(mazegen, roomgen);
        level.apply(|m| dungeongen.generate(m));
    }

    fn create_mazegen() -> MazeGen {
        println!("Input MazeGen startpos x coordinate: ");
        let x = Self::usize_from_cmd();

        println!("Input MazeGen startpos y coordinate: ");
        let y = Self::usize_from_cmd();
        MazeGen::new(x,y)
    }

    fn carve_maze(level: &mut Level<Tile>) {
        let mut mazegen = Self::create_mazegen();
        level.apply(|m| mazegen.generate(m));
    }

    fn create_roomgen() -> RoomGen {
        println!("Input min room size:");
        let min_room_size = Self::usize_from_cmd();

        println!("Input max room size:");
        let max_room_size = Self::usize_from_cmd();

        println!("Input min room distance:");
        let room_distance = Self::usize_from_cmd();

        println!("Input room placement amount (Something high preferably):");
        let attempts = Self::u64_from_cmd();

        RoomGen::new(min_room_size, max_room_size, room_distance, attempts)
    }

    fn carve_rooms(level: &mut Level<Tile>) {
        let mut roomgen = Self::create_roomgen();
        level.apply(|m| roomgen.generate(m));
    }

    fn tile_png_export(&self, level: &mut Level<Tile>) {
        let mut level_image = RgbImage::new(level.get_width() as u32, level.get_height() as u32);
        for x in 0 .. level.get_width() {
            for y in 0 .. level.get_height() {
                level_image.put_pixel(x as u32, y as u32, self.tile_to_color(&level.get_tile_with_tuple((x,y))));
            }
        }
        let mut p = PathBuf::new();
        println!("Enter png name:");
        p.push(Self::string_from_cmd().trim());
        p.set_extension("png");
        level_image.save(p.as_path()).expect("Something went wrong when saving the png.");
    }

    fn tile_to_color(&self, tile: &Result<&Tile, Error>) -> Rgb<u8> {
        match *tile {
            Ok(ref tile) => {
                    match self.dungeon_colors.get(tile) {
                        Some(color) => color.clone(),
                        None => Rgb([255u8, 0u8, 255u8]),
                    }
            },
            Err(Error::IndexOutOfBounds) => panic!("Tile png import failed. Level indexing went out of bounds."),
        }
    }

    fn print_level(level: &Level<Tile>) {
        use dungenon::util::Error;
        let mut string = String::new();
        for y in 0 .. level.get_width() {
            for x in 0 .. level.get_height() {
                match level.get_tile_with_tuple((x,y)) {
                    Ok(tile) => {
                        match tile {
                            &Tile::Wall(_) => string.push('#'),
                            &Tile::Floor(_) => string.push(' '),
                            &Tile::Void(_) => string.push('*'),
                        }
                    },
                    Err(Error::IndexOutOfBounds) => panic!("IndexOutOfBounds occurred. Level printing wasn't implemented properly."),
                }
            }
            string.push('\n');
        }
        println!("{}", &string);
    }

    fn usize_from_cmd() -> usize {
        let mut num = String::new();

        io::stdin().read_line(&mut num)
            .expect("failed to read line");

        let num: usize = num.trim().parse()
            .expect("Please type a number!");
        num
    }

    fn u64_from_cmd() -> u64 {
        let mut num = String::new();

        io::stdin().read_line(&mut num)
            .expect("failed to read line");

        let num: u64 = num.trim().parse()
            .expect("Please type a number!");
        num
    }

    fn string_from_cmd() -> String {
        let mut string = String::new();
        io::stdin().read_line(&mut string)
        .expect("Failed to read line");
        string
    }
}
<commit_msg>Faction gen works and prints!<commit_after>extern crate image;
extern crate dungenon;
extern crate cast;

use std::io;
use std::path::PathBuf;

use dungenon::level::Level;
use dungenon::tile::{Tile, Faction};
use dungenon::generator::{MazeGen, RoomGen, DungeonGen, FactionGen};
use dungenon::util::Error;

use image::RgbImage;
use image::Rgb;

use std::collections::HashMap;

fn main() {
    Drawer::new().start();
}

struct Drawer {
    pub dungeon_colors: HashMap<Tile, Rgb<u8>>,
    pub faction_colors: HashMap<Faction, Rgb<u8>>,
}

impl Drawer {
    pub fn new() -> Drawer {
        let mut dungeon_colors = HashMap::new();
        dungeon_colors.insert(Tile::Wall(0), Rgb([127u8, 127u8, 127u8]));
        dungeon_colors.insert(Tile::Floor(0), Rgb([200u8, 200u8, 200u8]));
        dungeon_colors.insert(Tile::Void(0), Rgb([0u8, 0u8, 0u8]));

        let mut faction_colors = HashMap::new();
        faction_colors.insert(Faction::Faction(0), Rgb([200u8, 0u8, 0u8]));
        faction_colors.insert(Faction::Faction(1), Rgb([0u8, 0u8, 127u8]));
        faction_colors.insert(Faction::Neutral, Rgb([127u8, 127u8, 127u8]));
        faction_colors.insert(Faction::Void, Rgb([0u8, 0u8, 0u8]));

        Drawer{
            dungeon_colors: dungeon_colors,
            faction_colors: faction_colors,
        }
    }

    pub fn start(&mut self) {
        loop {
            println!("Choose level type(faction, tile):");
            let t = Self::string_from_cmd();
            match t.trim() {
                "faction" => self.start_faction(),
                "tile" => self.start_tile(),
                _ => continue,
            }
            break;
        }
    }

    pub fn start_faction(&mut self) {
        let mut level = self.init_faction_level();
        let mut simulator = FactionGen::new();

        println!("This is the faction mode of dungenon-drawer.");
        println!("Type Help for list of possible commands.");
        loop {
            println!("Enter command:");
            let command = Self::string_from_cmd();
            match command.trim() {
                "simulate" => Self::simulate_factions(&mut level, &mut simulator),
                "factions" => Self::edit_level(&mut level),
                "colors" => self.change_faction_colors(),
                "export" => self.faction_png_export(&mut level),
                "help" => println!("Options: help, simulate, factions, colors, export and exit"),
                "exit" => break,
                _ => println!("Invalid command.")
            }
        }
    }

    fn change_faction_colors(&mut self) {
        use cast;
        use std::u8;
        loop {
            println!("Which color would you like to change? (faction, neutral, void), Type exit if you're done with modifying colors.");
            let command = Self::string_from_cmd();
            let key = match command.trim() {
                "faction" => {
                    println!("Enter faction number:");
                    Faction::Faction(Self::usize_from_cmd())
                },
                "neutral" => Faction::Neutral,
                "void" => Faction::Void,
                "exit" => break,
                _ => {
                    println!("Invalid command.");
                    continue;
                },
            };
            println!("Input red value for the color:");
            let r = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input green value for the color:");
            let g = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input blue value for the color:");
            let b = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);
            self.faction_colors.insert(key, Rgb([r,g,b]));
        }
    }

    fn init_faction_level(&self) -> Level<Faction> {
        println!("Initializing level...");
        println!("Input level width: ");
        let x = Self::usize_from_cmd();

        println!("Input level height: ");
        let y = Self::usize_from_cmd();

        Level::new_filled_with(Faction::Neutral, x, y)
    }

    fn simulate_factions(level: &mut Level<Faction>, simulator: &mut FactionGen) {
        println!("How many simulation steps are iterated?");
        let iterations = Self::u64_from_cmd();
        for _ in 0 .. iterations {
            level.apply(|m| simulator.generate(m));
        }
    }

    fn faction_png_export(&self, level: &mut Level<Faction>) {
        let mut level_image = RgbImage::new(level.get_width() as u32, level.get_height() as u32);
        for x in 0 .. level.get_width() {
            for y in 0 .. level.get_height() {
                level_image.put_pixel(x as u32, y as u32, self.faction_to_color(&level.get_tile_with_tuple((x,y))));
            }
        }
        let mut p = PathBuf::new();
        println!("Enter png name:");
        p.push(Self::string_from_cmd().trim());
        p.set_extension("png");
        level_image.save(p.as_path()).expect("Something went wrong when saving the png.");
    }

    fn edit_level(level: &mut Level<Faction>) {
        loop {
            println!("Input x coordinate:");
            let x = Self::usize_from_cmd();
            println!("Input y coordinate:");
            let y = Self::usize_from_cmd();

            println!("Select type(faction, neutral, void):");
            let faction_type = Self::string_from_cmd();
            let faction = match faction_type.trim() {
                "faction" => {
                    println!("Input faction number:");
                    let faction_number = Self::usize_from_cmd();
                    Faction::Faction(faction_number)
                },
                "neutral" => Faction::Neutral,
                "void" => Faction::Void,
                _ => {
                    println!("Invalid type.");
                    break;
                }
            };
            match level.get_mut_tile(x,y) {
                Ok(tile) => {
                    *tile = faction;
                },
                Err(_) => println!("Index out of bounds"),
            };
            println!("do you want to change another tile? (yes/no)");
            match Self::string_from_cmd().trim() {
                "yes" => continue,
                "no" => break,
                _ => {println!("Invalid input. Interpretting")}
            }
        }
    }

    pub fn start_tile(&mut self) {
        let mut level = self.init_tile_level();

        println!("This is the tile mode of dungenon-drawer. \nType Help for list of commands.");
        loop {
            println!("Enter command:");
            let command = Self::string_from_cmd();
            match command.trim() {
                "dungeon" => Self::carve_dungeon(&mut level),
                "maze" => Self::carve_maze(&mut level),
                "room" => Self::carve_rooms(&mut level),
                "reset" => level = self.init_tile_level(),
                "colors" => self.change_dungeon_colors(),
                "export" => {
                    self.tile_png_export(&mut level);
                },
                "print" => Self::print_level(&level),
                "help" => {
                    println!("Options: dungeon, maze, room, reset, colors, export, print, help, and exit");
                }
                "exit" => break,
                _ => println!("Invalid command."),
            }
        }
    }

    fn faction_to_color(&self, tile: &Result<&Faction, Error>) -> Rgb<u8> {
        match *tile {
            Ok(ref tile) => {
                    match self.faction_colors.get(tile) {
                        Some(color) => color.clone(),
                        None => Rgb([255u8, 0u8, 255u8]),
                    }
            },
            Err(Error::IndexOutOfBounds) => panic!("Tile png import failed. Level indexing went out of bounds."),
        }
    }

    fn change_dungeon_colors(&mut self) {
        use cast;
        use std::u8;
        loop {
            println!("Which color would you like to change? (floor, wall, void), Type exit if you're done with modifying colors.");
            let command = Self::string_from_cmd();
            let key = match command.trim() {
                "floor" => Tile::Floor(0),
                "wall" => Tile::Wall(0),
                "void" => Tile::Void(0),
                "exit" => break,
                _ => {
                    println!("Invalid command.");
                    continue;
                },
            };
            println!("Input red value for the color:");
            let r = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input green value for the color:");
            let g = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);

            println!("Input blue value for the color:");
            let b = cast::u8(Self::usize_from_cmd()).unwrap_or(u8::MAX);
            self.dungeon_colors.insert(key, Rgb([r,g,b]));
        }
    }

    fn init_tile_level(&self) -> Level<Tile> {
        println!("Initializing level...");
        println!("Input level width: ");
        let x = Self::usize_from_cmd();

        println!("Input level height: ");
        let y = Self::usize_from_cmd();

        Level::new_filled_with(Tile::Wall(0), x, y)
    }

    fn carve_dungeon(level: &mut Level<Tile>) {
        println!("Creating DungeonGen...");
        let mazegen = Self::create_mazegen();
        let roomgen = Self::create_roomgen();
        let mut dungeongen = DungeonGen::new(mazegen, roomgen);
        level.apply(|m| dungeongen.generate(m));
    }

    fn create_mazegen() -> MazeGen {
        println!("Input MazeGen startpos x coordinate: ");
        let x = Self::usize_from_cmd();

        println!("Input MazeGen startpos y coordinate: ");
        let y = Self::usize_from_cmd();
        MazeGen::new(x,y)
    }

    fn carve_maze(level: &mut Level<Tile>) {
        let mut mazegen = Self::create_mazegen();
        level.apply(|m| mazegen.generate(m));
    }

    fn create_roomgen() -> RoomGen {
        println!("Input min room size:");
        let min_room_size = Self::usize_from_cmd();

        println!("Input max room size:");
        let max_room_size = Self::usize_from_cmd();

        println!("Input min room distance:");
        let room_distance = Self::usize_from_cmd();

        println!("Input room placement amount (Something high preferably):");
        let attempts = Self::u64_from_cmd();

        RoomGen::new(min_room_size, max_room_size, room_distance, attempts)
    }

    fn carve_rooms(level: &mut Level<Tile>) {
        let mut roomgen = Self::create_roomgen();
        level.apply(|m| roomgen.generate(m));
    }

    fn tile_png_export(&self, level: &mut Level<Tile>) {
        let mut level_image = RgbImage::new(level.get_width() as u32, level.get_height() as u32);
        for x in 0 .. level.get_width() {
            for y in 0 .. level.get_height() {
                level_image.put_pixel(x as u32, y as u32, self.tile_to_color(&level.get_tile_with_tuple((x,y))));
            }
        }
        let mut p = PathBuf::new();
        println!("Enter png name:");
        p.push(Self::string_from_cmd().trim());
        p.set_extension("png");
        level_image.save(p.as_path()).expect("Something went wrong when saving the png.");
    }

    fn tile_to_color(&self, tile: &Result<&Tile, Error>) -> Rgb<u8> {
        match *tile {
            Ok(ref tile) => {
                    match self.dungeon_colors.get(tile) {
                        Some(color) => color.clone(),
                        None => Rgb([255u8, 0u8, 255u8]),
                    }
            },
            Err(Error::IndexOutOfBounds) => panic!("Tile png import failed. Level indexing went out of bounds."),
        }
    }

    fn print_level(level: &Level<Tile>) {
        use dungenon::util::Error;
        let mut string = String::new();
        for y in 0 .. level.get_width() {
            for x in 0 .. level.get_height() {
                match level.get_tile_with_tuple((x,y)) {
                    Ok(tile) => {
                        match tile {
                            &Tile::Wall(_) => string.push('#'),
                            &Tile::Floor(_) => string.push(' '),
                            &Tile::Void(_) => string.push('*'),
                        }
                    },
                    Err(Error::IndexOutOfBounds) => panic!("IndexOutOfBounds occurred. Level printing wasn't implemented properly."),
                }
            }
            string.push('\n');
        }
        println!("{}", &string);
    }

    fn usize_from_cmd() -> usize {
        let mut num = String::new();

        io::stdin().read_line(&mut num)
            .expect("failed to read line");

        let num: usize = num.trim().parse()
            .expect("Please type a number!");
        num
    }

    fn u64_from_cmd() -> u64 {
        let mut num = String::new();

        io::stdin().read_line(&mut num)
            .expect("failed to read line");

        let num: u64 = num.trim().parse()
            .expect("Please type a number!");
        num
    }

    fn string_from_cmd() -> String {
        let mut string = String::new();
        io::stdin().read_line(&mut string)
        .expect("Failed to read line");
        string
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate gitjournal;

use clap::App;
use gitjournal::GitJournal;

fn main() {
    // Load the CLI parameters from the yaml file
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml).get_matches();
    let path = matches.value_of("path").expect("Could not parse 'path' parameter");

    if matches.is_present("verify") {
        // Verify a commit message and panic! if verification failed.
        match GitJournal::verify(matches.value_of("verify").expect("Could not parse 'verify' value.")) {
            Ok(()) => println!("[ OKAY ] Commit message valid."),
            Err(error) => panic!("Commit message invalid. ({})", error),
        }
    } else if matches.is_present("prepare") {
        // Prepare a commit message before editing by the user
        match GitJournal::prepare(matches.value_of("prepare").expect("Could not parse 'prepare' value.")) {
            Ok(()) => println!("[ OKAY ] Commit message prepared."),
            Err(error) => panic!("Commit message preparation failed. ({})", error),
        }
    } else {
        // Create the journal
        let mut journal = GitJournal::new(path).expect("Could not initialize journal");

        if matches.is_present("setup") {
            journal.setup().expect("Setup error");
        } else {
            // Get all values of the given CLI parameters
            let revision_range = matches.value_of("revision_range")
                .expect("Could not parse 'revision range' parameter");
            let tag_skip_pattern = matches.value_of("tag_skip_pattern")
                .expect("Could not parse 'skip pattern' parameter");
            let tags_count = matches.value_of("tags_count").expect("Could not parse 'tags count' parameter");

            let max_tags = tags_count.parse::<u32>().expect("Could not parse tags count to integer");

            // Parse the log
            journal.parse_log(revision_range,
                           tag_skip_pattern,
                           &max_tags,
                           &matches.is_present("all"),
                           &matches.is_present("skip_unreleased"))
                .expect("Log parsing error");
            journal.print_log(matches.is_present("short")).expect("Could not print log.");
        }
    }
}
<commit_msg>Changed main print handling<commit_after>#[macro_use]
extern crate clap;
extern crate gitjournal;

use std::process::exit;
use clap::App;
use gitjournal::GitJournal;

fn print(string: &str) {
    println!("[Git-Journal] {}", string)
}

fn main() {
    // Load the CLI parameters from the yaml file
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml).get_matches();
    let path = matches.value_of("path").expect("Could not parse 'path' parameter");

    if matches.is_present("verify") {
        // Verify a commit message and panic! if verification failed.
        match GitJournal::verify(matches.value_of("verify").expect("Could not parse 'verify' value.")) {
            Ok(()) => print("Commit message valid."),
            Err(error) => {
                print(&format!("Commit message invalid: {}", error));
                exit(1);
            }
        }
    } else if matches.is_present("prepare") {
        // Prepare a commit message before editing by the user
        match GitJournal::prepare(matches.value_of("prepare").expect("Could not parse 'prepare' value.")) {
            Ok(()) => print("Commit message prepared."),
            Err(error) => {
                print(&format!("Commit message preparation failed: {}", error));
                exit(1);
            }
        }
    } else {
        // Create the journal
        let mut journal = GitJournal::new(path).expect("Could not initialize journal");

        if matches.is_present("setup") {
            journal.setup().expect("Setup error");
        } else {
            // Get all values of the given CLI parameters
            let revision_range = matches.value_of("revision_range")
                .expect("Could not parse 'revision range' parameter");
            let tag_skip_pattern = matches.value_of("tag_skip_pattern")
                .expect("Could not parse 'skip pattern' parameter");
            let tags_count = matches.value_of("tags_count").expect("Could not parse 'tags count' parameter");

            let max_tags = tags_count.parse::<u32>().expect("Could not parse tags count to integer");

            // Parse the log
            journal.parse_log(revision_range,
                           tag_skip_pattern,
                           &max_tags,
                           &matches.is_present("all"),
                           &matches.is_present("skip_unreleased"))
                .expect("Log parsing error");
            journal.print_log(matches.is_present("short")).expect("Could not print log.");
        }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use asm::util::*;
use std::io;
use std::io::Write;
use std::str::FromStr;
extern crate gmp;

mod asm;

fn main() {
	// let mut data = String::new();
	let mut env = asm::environment::Environment::new();
	let mut asm = asm::assembler::Assembler::new();

	asm.add_external_call("printnum", |v,e,_| {
		print!("{}", boolvec_to_bignum(v.get_boolvec(e).as_slice()));
		io::stdout().flush().ok().expect("Could not flush stdout");
	});
	asm.add_external_call("print", |v,e,_| {
		let mut chars:Vec<u8> = vec![];
		let boolvec = v.get_boolvec(e);
		let val = boolvec.as_slice();
		for i in 0..(val.len()/8) {
			let nums = &val[i*8..(i+1)*8];
			chars.push(boolvec_to_u8(nums));
		}
		unsafe {
			let s = String::from_utf8_unchecked(chars);
			print!("{}", s);
			io::stdout().flush().ok().expect("Could not flush stdout");
		}
	});

	asm.add_external_call("valid", |v,e,_a|{
		let pos = v.get_ptr_position(e);
		let num = match e.validity {
			true => gmp::mpz::Mpz::one(),
			false => gmp::mpz::Mpz::zero()
		};
		e.set_bits_bignum(&num, pos, v.get_size());
	});
	asm.add_external_call("input", |v,e,_|{
		let mut input = String::new();
		io::stdin().read_line(&mut input).expect("Invalid Input!");
		let boolvec = str_to_boolvec(input.as_ref());
		let pos = v.get_ptr_position(e);
		e.set_bits_boolvec(boolvec.as_slice(), pos, v.get_size());
	});
	asm.add_external_call("inputnum", |v,e,_|{
		let mut input = String::new();
		io::stdin().read_line(&mut input).expect("Invalid Input!");
		e.validity = true;
		let num = match gmp::mpz::Mpz::from_str(input.as_ref()) {
			Ok(val) => val,
			Err(_) => {
				e.validity = false;
				gmp::mpz::Mpz::zero()
			}
		};
		let pos = v.get_ptr_position(e);
		e.set_bits_bignum(&num, pos, v.get_size());
	});

	let file = File::open("thing.asm").unwrap();
	let buffer = BufReader::new(&file);
	for line in buffer.lines() {
		let l:String = line.unwrap();
		asm.parse_line(&l);
	}

	asm.run(&mut env);
	//env.print_bytes( 32);
	println!("");
}
<commit_msg>removed testing assembly file<commit_after>use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use asm::util::*;
use std::io;
use std::io::Write;
use std::str::FromStr;
extern crate gmp;

mod asm;

fn main() {
	// let mut data = String::new();
	let mut env = asm::environment::Environment::new();
	let mut asm = asm::assembler::Assembler::new();

	asm.add_external_call("printnum", |v,e,_| {
		print!("{}", boolvec_to_bignum(v.get_boolvec(e).as_slice()));
		io::stdout().flush().ok().expect("Could not flush stdout");
	});
	asm.add_external_call("print", |v,e,_| {
		let mut chars:Vec<u8> = vec![];
		let boolvec = v.get_boolvec(e);
		let val = boolvec.as_slice();
		for i in 0..(val.len()/8) {
			let nums = &val[i*8..(i+1)*8];
			chars.push(boolvec_to_u8(nums));
		}
		unsafe {
			let s = String::from_utf8_unchecked(chars);
			print!("{}", s);
			io::stdout().flush().ok().expect("Could not flush stdout");
		}
	});

	asm.add_external_call("valid", |v,e,_a|{
		let pos = v.get_ptr_position(e);
		let num = match e.validity {
			true => gmp::mpz::Mpz::one(),
			false => gmp::mpz::Mpz::zero()
		};
		e.set_bits_bignum(&num, pos, v.get_size());
	});
	asm.add_external_call("input", |v,e,_|{
		let mut input = String::new();
		io::stdin().read_line(&mut input).expect("Invalid Input!");
		let boolvec = str_to_boolvec(input.as_ref());
		let pos = v.get_ptr_position(e);
		e.set_bits_boolvec(boolvec.as_slice(), pos, v.get_size());
	});
	asm.add_external_call("inputnum", |v,e,_|{
		let mut input = String::new();
		io::stdin().read_line(&mut input).expect("Invalid Input!");
		e.validity = true;
		let num = match gmp::mpz::Mpz::from_str(input.as_ref()) {
			Ok(val) => val,
			Err(_) => {
				e.validity = false;
				gmp::mpz::Mpz::zero()
			}
		};
		let pos = v.get_ptr_position(e);
		e.set_bits_bignum(&num, pos, v.get_size());
	});

	let file = File::open("thing.asm").unwrap();
	let buffer = BufReader::new(&file);
	for line in buffer.lines() {
		let l:String = line.unwrap();
		asm.parse_line(&l);
	}

	asm.run(&mut env);
	//env.print_bytes( 32);
	println!("");
}
<|endoftext|>


<commit_before>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
	// Log in to Discord using a bot token from the environment
	let discord = Discord::from_bot_token(
		&env::var("DISCORD_TOKEN").expect("Expected token"),
	).expect("login failed");

	// establish websocket and voice connection
	let (mut connection, ready) = discord.connect().expect("connect failed");
	println!("[Ready] {} is serving {} servers", ready.user.username, ready.servers.len());
	let mut state = State::new(ready);
	connection.sync_calls(&state.all_private_channels());

	// receive events forever
	loop {
		let event = match connection.recv_event() {
			Ok(event) => event,
			Err(err) => {
				println!("[Warning] Receive error: {:?}", err);
				if let discord::Error::WebSocket(..) = err {
					// Handle the websocket connection being dropped
					let (new_connection, ready) = discord.connect().expect("connect failed");
					connection = new_connection;
					state = State::new(ready);
					println!("[Ready] Reconnected successfully.");
				}
				if let discord::Error::Closed(..) = err {
					break
				}
				continue
			},
		};
		state.update(&event);

		match event {
			Event::MessageCreate(message) => {
				use std::ascii::AsciiExt;
				// safeguard: stop if the message is from us
				if message.author.id == state.user().id {
					continue
				}

				// reply to a command if there was one
				let mut split = message.content.split(' ');
				let first_word = split.next().unwrap_or("");
				let argument = split.next().unwrap_or("");

				//Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(message.channel_id, "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)", "", false))
                    }
		    		else if argument.eq_ignore_ascii_case("about") {
			 			warn(discord.send_message(message.channel_id, "Displays info about me. No arguments available.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("uber") {
						warn(discord.send_message(message.channel_id, "Uber an object (I'm picky).", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("distrowiki") {
						warn(discord.send_message(message.channel_id, "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("sourcecode") {
						warn(discord.send_message(message.channel_id, "Displays where I am on GitHub. No arguments available", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("help") {
						warn(discord.send_message(message.channel_id, "Are you trying to break me?", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("[args]") {
						warn(discord.send_message(message.channel_id, "You're helpless.", "", false))
	            	}
                    else {
                    warn(discord.send_message(message.channel_id, "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.", "", false))
                    }
                }

				//Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(message.channel_id, "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.", "", false))
                }
		            if first_word.eq_ignore_ascii_case("!wheresteal") {
			              warn(discord.send_message(message.channel_id, "Go ask him, I know nothing ;_;", "", false))
		            }
                if first_word.eq_ignore_ascii_case("!hello") {
					          warn(discord.send_message(message.channel_id, "https://www.tenor.co/xA8B.gif", "", false))
				        }
                if first_word.eq_ignore_ascii_case("!uber"){
					          if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(message.channel_id, "Alright, 10 minutes.", "", false))
                    }
					          else if argument.eq_ignore_ascii_case("aspire") {
						            warn(discord.send_message(message.channel_id, "Not the meatballs.", "", false))
					          }
					          else if argument.eq_ignore_ascii_case("nic") {
					            	warn(discord.send_message(message.channel_id, "NOT THE BEES!!!", "", false))
					          }
					          else {
                        warn(discord.send_message(message.channel_id, "Fuck off!", "", false))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(message.channel_id, "Okay, here you go. https://github.com/aarroz/rice_bot2", "", false))
                }
				//Section that prints wikis for linux distributions.
				if first_word.eq_ignore_ascii_case("!distrowiki") {
					if argument.eq_ignore_ascii_case("arch") {
						warn(discord.send_message(message.channel_id, "Here's the Arch Wiki! https://wiki.archlinux.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("ubuntu") {
						warn(discord.send_message(message.channel_id, "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/", "", false))
					}
					else if argument.eq_ignore_ascii_case("debian") {
						warn(discord.send_message(message.channel_id, "Here's the Debian Wiki! https://wiki.debian.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("antergos") {
						warn(discord.send_message(message.channel_id, "Here's the Antergos Wiki! https://antergos.com/wiki/", "", false))
					}
					else if argument.eq_ignore_ascii_case("centos") {
						warn(discord.send_message(message.channel_id, "Here's the CentOS Wiki! https://wiki.centos.org/", "", false))
					}
					//Sorry OpenBSD users.
					else if argument.eq_ignore_ascii_case("openbsd") {
						warn(discord.send_message(message.channel_id, "No, just no.", "", false))
					}
					//Not sorry.
					else if argument.eq_ignore_ascii_case("gentoo") {
						warn(discord.send_message(message.channel_id, "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page", "", false))
					}
					else if argument.eq_ignore_ascii_case("opensuse") {
						warn(discord.send_message(message.channel_id, "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki", "", false))
					}
					else if argument.eq_ignore_ascii_case("sabayon") {
						warn(discord.send_message(message.channel_id, "Here's the Sabayon Wiki! https://wiki.sabayon.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("kalilinux") {
						warn(discord.send_message(message.channel_id, "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux", "", false))
					}
					else if argument.eq_ignore_ascii_case("mint") {
						warn(discord.send_message(message.channel_id, "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90", "", false))
					}
					else if argument.eq_ignore_ascii_case("solus") {
						warn(discord.send_message(message.channel_id, "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/", "", false))
					}
					else if argument.eq_ignore_ascii_case("windows") {
						warn(discord.send_message(message.channel_id, "Thats not a distro.", "", false))
					}
					else if argument.eq_ignore_ascii_case("macos") {
						warn(discord.send_message(message.channel_id, "Sure its close to linux, but I'm too tired to have that argument.", "", false))
					}
					else {
						warn(discord.send_message(message.channel_id, "Please use a distro from !help distrowiki.", "", false))
					}
				}

                // Command for using dj.
				if first_word.eq_ignore_ascii_case("!dj") {
					let vchan = state.find_voice_user(message.author.id);
					if argument.eq_ignore_ascii_case("stop") {
						vchan.map(|(sid, _)| connection.voice(sid).stop());
					} else if argument.eq_ignore_ascii_case("quit") {
						vchan.map(|(sid, _)| connection.drop_voice(sid));
					} else {
						let output = if let Some((server_id, channel_id)) = vchan {
							match discord::voice::open_ytdl_stream(argument) {
								Ok(stream) => {
									let voice = connection.voice(server_id);
									voice.set_deaf(true);
									voice.connect(channel_id);
									voice.play(stream);
									String::new()
								},
								Err(error) => format!("Error: {}", error),
							}
						} else {
							"You must be in a voice channel to DJ".to_owned()
						};
						if !output.is_empty() {
							warn(discord.send_message(message.channel_id, &output, "", false));
						}
					}
				}
			}
			Event::VoiceStateUpdate(server_id, _) => {
				// If someone moves/hangs up, and we are in a voice channel,
				if let Some(cur_channel) = connection.voice(server_id).current_channel() {
					// and our current voice channel is empty, disconnect from voice
					match server_id {
						Some(server_id) => if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
							if srv.voice_states.iter().filter(|vs| vs.channel_id == Some(cur_channel)).count() <= 1 {
								connection.voice(Some(server_id)).disconnect();
							}
						},
						None => if let Some(call) = state.calls().get(&cur_channel) {
							if call.voice_states.len() <= 1 {
								connection.voice(server_id).disconnect();
							}
						}
					}
				}
			}
			_ => {}, // discard other events
		}
	}
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
	match result {
		Ok(_) => {},
		Err(err) => println!("[Warning] {:?}", err)
	}
}
<commit_msg>fixed formatting<commit_after>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
	// Log in to Discord using a bot token from the environment
	let discord = Discord::from_bot_token(
		&env::var("DISCORD_TOKEN").expect("Expected token"),
	).expect("login failed");

	// establish websocket and voice connection
	let (mut connection, ready) = discord.connect().expect("connect failed");
	println!("[Ready] {} is serving {} servers", ready.user.username, ready.servers.len());
	let mut state = State::new(ready);
	connection.sync_calls(&state.all_private_channels());

	// receive events forever
	loop {
		let event = match connection.recv_event() {
			Ok(event) => event,
			Err(err) => {
				println!("[Warning] Receive error: {:?}", err);
				if let discord::Error::WebSocket(..) = err {
					// Handle the websocket connection being dropped
					let (new_connection, ready) = discord.connect().expect("connect failed");
					connection = new_connection;
					state = State::new(ready);
					println!("[Ready] Reconnected successfully.");
				}
				if let discord::Error::Closed(..) = err {
					break
				}
				continue
			},
		};
		state.update(&event);

		match event {
			Event::MessageCreate(message) => {
				use std::ascii::AsciiExt;
				// safeguard: stop if the message is from us
				if message.author.id == state.user().id {
					continue
				}

				// reply to a command if there was one
				let mut split = message.content.split(' ');
				let first_word = split.next().unwrap_or("");
				let argument = split.next().unwrap_or("");

				//Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(message.channel_id, "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)", "", false))
                    }
		    		else if argument.eq_ignore_ascii_case("about") {
			 			warn(discord.send_message(message.channel_id, "Displays info about me. No arguments available.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("uber") {
						warn(discord.send_message(message.channel_id, "Uber an object (I'm picky).", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("distrowiki") {
						warn(discord.send_message(message.channel_id, "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.", "", false))
		    		}
		    		else if argument.eq_ignore_ascii_case("sourcecode") {
						warn(discord.send_message(message.channel_id, "Displays where I am on GitHub. No arguments available", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("help") {
						warn(discord.send_message(message.channel_id, "Are you trying to break me?", "", false))
	            	}
		    		else if argument.eq_ignore_ascii_case("[args]") {
						warn(discord.send_message(message.channel_id, "You're helpless.", "", false))
	            	}
                    else {
                    warn(discord.send_message(message.channel_id, "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.", "", false))
                    }
                }

				//Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(message.channel_id, "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.", "", false))
                }
		        if first_word.eq_ignore_ascii_case("!wheresteal") {
			        warn(discord.send_message(message.channel_id, "Go ask him, I know nothing ;_;", "", false))
		        }
                if first_word.eq_ignore_ascii_case("!hello") {
					          warn(discord.send_message(message.channel_id, "https://www.tenor.co/xA8B.gif", "", false))
				        }
                if first_word.eq_ignore_ascii_case("!uber"){
					if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(message.channel_id, "Alright, 10 minutes.", "", false))
                    }
					else if argument.eq_ignore_ascii_case("aspire") {
						warn(discord.send_message(message.channel_id, "Not the meatballs.", "", false))
					}
					else if argument.eq_ignore_ascii_case("nic") {
					    warn(discord.send_message(message.channel_id, "NOT THE BEES!!!", "", false))
					}
					else {
                        warn(discord.send_message(message.channel_id, "Fuck off!", "", false))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(message.channel_id, "Okay, here you go. https://github.com/aarroz/rice_bot2", "", false))
                }
				//Section that prints wikis for linux distributions.
				if first_word.eq_ignore_ascii_case("!distrowiki") {
					if argument.eq_ignore_ascii_case("arch") {
						warn(discord.send_message(message.channel_id, "Here's the Arch Wiki! https://wiki.archlinux.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("ubuntu") {
						warn(discord.send_message(message.channel_id, "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/", "", false))
					}
					else if argument.eq_ignore_ascii_case("debian") {
						warn(discord.send_message(message.channel_id, "Here's the Debian Wiki! https://wiki.debian.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("antergos") {
						warn(discord.send_message(message.channel_id, "Here's the Antergos Wiki! https://antergos.com/wiki/", "", false))
					}
					else if argument.eq_ignore_ascii_case("centos") {
						warn(discord.send_message(message.channel_id, "Here's the CentOS Wiki! https://wiki.centos.org/", "", false))
					}
					//Sorry OpenBSD users.
					else if argument.eq_ignore_ascii_case("openbsd") {
						warn(discord.send_message(message.channel_id, "No, just no.", "", false))
					}
					//Not sorry.
					else if argument.eq_ignore_ascii_case("gentoo") {
						warn(discord.send_message(message.channel_id, "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page", "", false))
					}
					else if argument.eq_ignore_ascii_case("opensuse") {
						warn(discord.send_message(message.channel_id, "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki", "", false))
					}
					else if argument.eq_ignore_ascii_case("sabayon") {
						warn(discord.send_message(message.channel_id, "Here's the Sabayon Wiki! https://wiki.sabayon.org/", "", false))
					}
					else if argument.eq_ignore_ascii_case("kalilinux") {
						warn(discord.send_message(message.channel_id, "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux", "", false))
					}
					else if argument.eq_ignore_ascii_case("mint") {
						warn(discord.send_message(message.channel_id, "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90", "", false))
					}
					else if argument.eq_ignore_ascii_case("solus") {
						warn(discord.send_message(message.channel_id, "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/", "", false))
					}
					else if argument.eq_ignore_ascii_case("windows") {
						warn(discord.send_message(message.channel_id, "Thats not a distro.", "", false))
					}
					else if argument.eq_ignore_ascii_case("macos") {
						warn(discord.send_message(message.channel_id, "Sure its close to linux, but I'm too tired to have that argument.", "", false))
					}
					else {
						warn(discord.send_message(message.channel_id, "Please use a distro from !help distrowiki.", "", false))
					}
				}

                // Command for using dj.
				if first_word.eq_ignore_ascii_case("!dj") {
					let vchan = state.find_voice_user(message.author.id);
					if argument.eq_ignore_ascii_case("stop") {
						vchan.map(|(sid, _)| connection.voice(sid).stop());
					} else if argument.eq_ignore_ascii_case("quit") {
						vchan.map(|(sid, _)| connection.drop_voice(sid));
					} else {
						let output = if let Some((server_id, channel_id)) = vchan {
							match discord::voice::open_ytdl_stream(argument) {
								Ok(stream) => {
									let voice = connection.voice(server_id);
									voice.set_deaf(true);
									voice.connect(channel_id);
									voice.play(stream);
									String::new()
								},
								Err(error) => format!("Error: {}", error),
							}
						} else {
							"You must be in a voice channel to DJ".to_owned()
						};
						if !output.is_empty() {
							warn(discord.send_message(message.channel_id, &output, "", false));
						}
					}
				}
			}
			Event::VoiceStateUpdate(server_id, _) => {
				// If someone moves/hangs up, and we are in a voice channel,
				if let Some(cur_channel) = connection.voice(server_id).current_channel() {
					// and our current voice channel is empty, disconnect from voice
					match server_id {
						Some(server_id) => if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
							if srv.voice_states.iter().filter(|vs| vs.channel_id == Some(cur_channel)).count() <= 1 {
								connection.voice(Some(server_id)).disconnect();
							}
						},
						None => if let Some(call) = state.calls().get(&cur_channel) {
							if call.voice_states.len() <= 1 {
								connection.voice(server_id).disconnect();
							}
						}
					}
				}
			}
			_ => {}, // discard other events
		}
	}
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
	match result {
		Ok(_) => {},
		Err(err) => println!("[Warning] {:?}", err)
	}
}
<|endoftext|>


<commit_before>extern crate log;
extern crate env_logger;
#[macro_use]
extern crate structopt;
extern crate failure;
extern crate mdblog;

use std::env;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
use mdblog::{Mdblog, Result, log_error};

#[derive(StructOpt, Debug)]
#[structopt(name = "mdblog")]
/// static site generator from markdown files
enum Opt {
    #[structopt(name = "init")]
    /// Initialize the blog directory layout
    Init {
        /// the blog directory name
        name: String,
    },
     #[structopt(name = "new")]
    /// Create a blog post
    New {
        #[structopt(short = "t", long = "tag", default_value = "blog")]
        /// Post tags
        tags: Vec<String>,
        /// Post path relative to blog `posts` directory
        path: PathBuf,
    },
    #[structopt(name = "build")]
    /// Build the blog static files
    Build,
    #[structopt(name = "serve")]
    /// Serve the blog, rebuild on change
    Serve {
        #[structopt(short = "p", long = "port", default_value = "5000")]
        /// Serve the blog at http://127.0.0.1:<port>
        port: u16,
    },
    #[structopt(name = "theme")]
    /// Blog theme operations
    Theme(SubCommandTheme),
}

#[derive(StructOpt, Debug)]
enum SubCommandTheme {
    #[structopt(name = "list")]
    /// list blog themes
    List,
    #[structopt(name = "new")]
    /// Create a new theme
    New {
        /// theme name
        name: String,
    },
     #[structopt(name = "delete")]
    /// Delete a theme
    Delete {
        /// theme name
        name: String,
    },
    #[structopt(name = "set")]
    /// Set blog use the theme
    Set {
        /// theme name
        name: String,
    },
}

fn main() {
    env_logger::Builder::new()
        .filter(None, log::LevelFilter::Info)
        .init();

    let opt = Opt::from_args();
    let res = match opt {
        Opt::Init {ref name} => init(name),
        Opt::New {ref tags, ref path} => new(path, tags),
        Opt::Build => build(),
        Opt::Serve { port } => serve(port),
        Opt::Theme(ref subcmd) => theme(subcmd),
    };

    if let Err(ref e) = res {
        log_error(e);
        std::process::exit(1);
    }
}

fn init(name: &str) -> Result<()> {
    let root_dir = env::current_dir()?.join(name);
    let mut mb = Mdblog::new(root_dir)?;
    mb.init()?;
    Ok(())
}

fn new(path: &Path, tags: &Vec<String>) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.create_post(path, tags)?;
    Ok(())
}

fn build() -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.load()?;
    mb.build()?;
    Ok(())
}

fn serve(port: u16) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.load()?;
    mb.build()?;
    mb.serve(port)?;
    Ok(())
}

fn theme(cmd: &SubCommandTheme) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;

    match cmd {
        &SubCommandTheme::List => mb.list_blog_theme()?,
        &SubCommandTheme::New { ref name } => mb.create_blog_theme(name)?,
        &SubCommandTheme::Delete { ref name } => mb.delete_blog_theme(name)?,
        &SubCommandTheme::Set { ref name } => mb.set_blog_theme(name)?,
    }
    Ok(())
}<commit_msg>Updated path parsing in structopt definition<commit_after>extern crate log;
extern crate env_logger;
#[macro_use]
extern crate structopt;
extern crate failure;
extern crate mdblog;

use std::env;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
use mdblog::{Mdblog, Result, log_error};

#[derive(StructOpt, Debug)]
#[structopt(name = "mdblog")]
/// static site generator from markdown files
enum Opt {
    #[structopt(name = "init")]
    /// Initialize the blog directory layout
    Init {
        /// the blog directory name
        name: String,
    },
     #[structopt(name = "new")]
    /// Create a blog post
    New {
        #[structopt(short = "t", long = "tag", default_value = "blog")]
        /// Post tags
        tags: Vec<String>,
        #[structopt(parse(from_os_str))]
        /// Post path relative to blog `posts` directory
        path: PathBuf,
    },
    #[structopt(name = "build")]
    /// Build the blog static files
    Build,
    #[structopt(name = "serve")]
    /// Serve the blog, rebuild on change
    Serve {
        #[structopt(short = "p", long = "port", default_value = "5000")]
        /// Serve the blog at http://127.0.0.1:<port>
        port: u16,
    },
    #[structopt(name = "theme")]
    /// Blog theme operations
    Theme(SubCommandTheme),
}

#[derive(StructOpt, Debug)]
enum SubCommandTheme {
    #[structopt(name = "list")]
    /// list blog themes
    List,
    #[structopt(name = "new")]
    /// Create a new theme
    New {
        /// theme name
        name: String,
    },
     #[structopt(name = "delete")]
    /// Delete a theme
    Delete {
        /// theme name
        name: String,
    },
    #[structopt(name = "set")]
    /// Set blog use the theme
    Set {
        /// theme name
        name: String,
    },
}

fn main() {
    env_logger::Builder::new()
        .filter(None, log::LevelFilter::Info)
        .init();

    let opt = Opt::from_args();
    let res = match opt {
        Opt::Init {ref name} => init(name),
        Opt::New {ref tags, ref path} => new(path, tags),
        Opt::Build => build(),
        Opt::Serve { port } => serve(port),
        Opt::Theme(ref subcmd) => theme(subcmd),
    };

    if let Err(ref e) = res {
        log_error(e);
        std::process::exit(1);
    }
}

fn init(name: &str) -> Result<()> {
    let root_dir = env::current_dir()?.join(name);
    let mut mb = Mdblog::new(root_dir)?;
    mb.init()?;
    Ok(())
}

fn new(path: &Path, tags: &Vec<String>) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.create_post(path, tags)?;
    Ok(())
}

fn build() -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.load()?;
    mb.build()?;
    Ok(())
}

fn serve(port: u16) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;
    mb.load()?;
    mb.build()?;
    mb.serve(port)?;
    Ok(())
}

fn theme(cmd: &SubCommandTheme) -> Result<()> {
    let root_dir = env::current_dir()?;
    let mut mb = Mdblog::new(&root_dir)?;
    mb.load_customize_settings()?;

    match cmd {
        &SubCommandTheme::List => mb.list_blog_theme()?,
        &SubCommandTheme::New { ref name } => mb.create_blog_theme(name)?,
        &SubCommandTheme::Delete { ref name } => mb.delete_blog_theme(name)?,
        &SubCommandTheme::Set { ref name } => mb.set_blog_theme(name)?,
    }
    Ok(())
}
<|endoftext|>