<commit_before>use nom;
use nom::{Err, IResult};

use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};
use utility::{ErrorKind, ByteStream, ReadStream, StreamProducer};

use std::io;
use std::usize;
use std::fs::File;

enum ParserState {
  Marker,
  Metadata,
  Frame,
}

pub struct Stream {
  info: StreamInfo,
  pub metadata: Vec<Metadata>,
  frames: Vec<Frame>,
  state: ParserState,
  output: Vec<i32>,
  frame_index: usize,
}

named!(pub stream_parser <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    frames: many1!(apply!(frame_parser, &blocks.0)),
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
        frames: frames,
        state: ParserState::Marker,
        output: Vec::new(),
        frame_index: 0,
      }
    }
  )
);

impl Stream {
  pub fn new() -> Stream {
    Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    }
  }

  pub fn info(&self) -> StreamInfo {
    self.info
  }

  pub fn from_file(filename: &str) -> io::Result<Stream> {
    File::open(filename).and_then(|file| {
      let mut producer = ReadStream::new(file);
      let error_str    = format!("parser: couldn't parse the given file {}",
                                 filename);

      Stream::from_stream_producer(&mut producer, &error_str)
    })
  }

  pub fn from_buffer(buffer: &[u8]) -> io::Result<Stream> {
    let mut producer = ByteStream::new(buffer);
    let error_str    = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(&mut producer, error_str)
  }

  fn from_stream_producer<P>(producer: &mut P, error_str: &str)
                             -> io::Result<Stream>
   where P: StreamProducer {
    let mut is_error = false;
    let mut stream   = Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    };

    loop {
      match stream.handle(producer) {
        Ok(_)                         => break,
        Err(ErrorKind::EndOfInput)    => break,
        Err(ErrorKind::Consumed(_))   => continue,
        Err(ErrorKind::Incomplete(_)) => continue,
        Err(_)                        => {
          is_error = true;

          break;
        }
      }
    }

    if !is_error {
      let channels    = stream.info.channels as usize;
      let block_size  = stream.info.max_block_size as usize;
      let output_size = block_size * channels;

      stream.output.reserve_exact(output_size);

      unsafe { stream.output.set_len(output_size) }

      Ok(stream)
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  pub fn iter(&mut self) -> Iter {
    Iter::new(self)
  }

  fn next_frame<'a>(&'a mut self) -> Option<&'a [i32]> {
    if self.frames.is_empty() || self.frame_index >= self.frames.len() {
      None
    } else {
      let frame       = &self.frames[self.frame_index];
      let channels    = frame.header.channels as usize;
      let block_size  = frame.header.block_size as usize;
      let mut channel = 0;

      for subframe in &frame.subframes[0..channels] {
        let start  = channel * block_size;
        let end    = (channel + 1) * block_size;
        let output = &mut self.output[start..end];

        subframe::decode(&subframe, output);

        channel += 1;
      }

      frame::decode(frame.header.channel_assignment, &mut self.output);

      self.frame_index += 1;

      Some(&self.output[0..(block_size * channels)])
    }
  }

  fn handle_marker<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(0);

    match tag!(input, "fLaC") {
      IResult::Done(i, _)    => {
        self.state = ParserState::Metadata;

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_metadata<'a>(&mut self, input: &'a [u8])
                         -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(1);

    match metadata::block(input) {
      IResult::Done(i, block) => {
        let is_last = block.is_last;

        if let metadata::Data::StreamInfo(info) = block.data {
          self.info = info;
        } else {
          self.metadata.push(block);
        }

        if is_last {
          self.state = ParserState::Frame;
        }

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_frame<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(2);

    match frame_parser(input, &self.info) {
      IResult::Done(i, frame) => {
        self.frames.push(frame);

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle<S: StreamProducer>(&mut self, stream: &mut S)
                               -> Result<(), ErrorKind> {
    stream.parse(|input| {
      match self.state {
        ParserState::Marker   => self.handle_marker(input),
        ParserState::Metadata => self.handle_metadata(input),
        ParserState::Frame    => self.handle_frame(input),
      }
    })
  }
}

pub struct Iter<'a> {
  stream: &'a mut Stream,
  channel: usize,
  frame_index: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a> Iter<'a> {
  pub fn new(stream: &'a mut Stream) -> Iter<'a> {
    let samples_left = stream.info.total_samples;

    Iter {
      stream: stream,
      channel: 0,
      frame_index: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }
}

impl<'a> Iterator for Iter<'a> {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.block_size == 0 || self.sample_index == self.block_size {
      if self.stream.next_frame().is_none() {
        return None;
      } else {
        let frame = &self.stream.frames[self.frame_index];

        self.sample_index = 0;
        self.block_size   = frame.header.block_size as usize;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel      += 1;
    self.samples_left -= 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a change that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}
<commit_msg>Fix a typo in size_hint comment<commit_after>use nom;
use nom::{Err, IResult};

use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo, metadata_parser};
use frame::{frame_parser, Frame};
use utility::{ErrorKind, ByteStream, ReadStream, StreamProducer};

use std::io;
use std::usize;
use std::fs::File;

enum ParserState {
  Marker,
  Metadata,
  Frame,
}

pub struct Stream {
  info: StreamInfo,
  pub metadata: Vec<Metadata>,
  frames: Vec<Frame>,
  state: ParserState,
  output: Vec<i32>,
  frame_index: usize,
}

named!(pub stream_parser <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    frames: many1!(apply!(frame_parser, &blocks.0)),
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
        frames: frames,
        state: ParserState::Marker,
        output: Vec::new(),
        frame_index: 0,
      }
    }
  )
);

impl Stream {
  pub fn new() -> Stream {
    Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    }
  }

  pub fn info(&self) -> StreamInfo {
    self.info
  }

  pub fn from_file(filename: &str) -> io::Result<Stream> {
    File::open(filename).and_then(|file| {
      let mut producer = ReadStream::new(file);
      let error_str    = format!("parser: couldn't parse the given file {}",
                                 filename);

      Stream::from_stream_producer(&mut producer, &error_str)
    })
  }

  pub fn from_buffer(buffer: &[u8]) -> io::Result<Stream> {
    let mut producer = ByteStream::new(buffer);
    let error_str    = "parser: couldn't parse the buffer";

    Stream::from_stream_producer(&mut producer, error_str)
  }

  fn from_stream_producer<P>(producer: &mut P, error_str: &str)
                             -> io::Result<Stream>
   where P: StreamProducer {
    let mut is_error = false;
    let mut stream   = Stream {
      info: StreamInfo::new(),
      metadata: Vec::new(),
      frames: Vec::new(),
      state: ParserState::Marker,
      output: Vec::new(),
      frame_index: 0,
    };

    loop {
      match stream.handle(producer) {
        Ok(_)                         => break,
        Err(ErrorKind::EndOfInput)    => break,
        Err(ErrorKind::Consumed(_))   => continue,
        Err(ErrorKind::Incomplete(_)) => continue,
        Err(_)                        => {
          is_error = true;

          break;
        }
      }
    }

    if !is_error {
      let channels    = stream.info.channels as usize;
      let block_size  = stream.info.max_block_size as usize;
      let output_size = block_size * channels;

      stream.output.reserve_exact(output_size);

      unsafe { stream.output.set_len(output_size) }

      Ok(stream)
    } else {
      Err(io::Error::new(io::ErrorKind::InvalidData, error_str))
    }
  }

  pub fn iter(&mut self) -> Iter {
    Iter::new(self)
  }

  fn next_frame<'a>(&'a mut self) -> Option<&'a [i32]> {
    if self.frames.is_empty() || self.frame_index >= self.frames.len() {
      None
    } else {
      let frame       = &self.frames[self.frame_index];
      let channels    = frame.header.channels as usize;
      let block_size  = frame.header.block_size as usize;
      let mut channel = 0;

      for subframe in &frame.subframes[0..channels] {
        let start  = channel * block_size;
        let end    = (channel + 1) * block_size;
        let output = &mut self.output[start..end];

        subframe::decode(&subframe, output);

        channel += 1;
      }

      frame::decode(frame.header.channel_assignment, &mut self.output);

      self.frame_index += 1;

      Some(&self.output[0..(block_size * channels)])
    }
  }

  fn handle_marker<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(0);

    match tag!(input, "fLaC") {
      IResult::Done(i, _)    => {
        self.state = ParserState::Metadata;

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_metadata<'a>(&mut self, input: &'a [u8])
                         -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(1);

    match metadata::block(input) {
      IResult::Done(i, block) => {
        let is_last = block.is_last;

        if let metadata::Data::StreamInfo(info) = block.data {
          self.info = info;
        } else {
          self.metadata.push(block);
        }

        if is_last {
          self.state = ParserState::Frame;
        }

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle_frame<'a>(&mut self, input: &'a [u8]) -> IResult<&'a [u8], ()> {
    let kind = nom::ErrorKind::Custom(2);

    match frame_parser(input, &self.info) {
      IResult::Done(i, frame) => {
        self.frames.push(frame);

        IResult::Error(Err::Position(kind, i))
      }
      IResult::Error(_)      => IResult::Error(Err::Code(kind)),
      IResult::Incomplete(n) => IResult::Incomplete(n),
    }
  }

  fn handle<S: StreamProducer>(&mut self, stream: &mut S)
                               -> Result<(), ErrorKind> {
    stream.parse(|input| {
      match self.state {
        ParserState::Marker   => self.handle_marker(input),
        ParserState::Metadata => self.handle_metadata(input),
        ParserState::Frame    => self.handle_frame(input),
      }
    })
  }
}

pub struct Iter<'a> {
  stream: &'a mut Stream,
  channel: usize,
  frame_index: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
}

impl<'a> Iter<'a> {
  pub fn new(stream: &'a mut Stream) -> Iter<'a> {
    let samples_left = stream.info.total_samples;

    Iter {
      stream: stream,
      channel: 0,
      frame_index: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
    }
  }
}

impl<'a> Iterator for Iter<'a> {
  type Item = i32;

  fn next(&mut self) -> Option<Self::Item> {
    if self.block_size == 0 || self.sample_index == self.block_size {
      if self.stream.next_frame().is_none() {
        return None;
      } else {
        let frame = &self.stream.frames[self.frame_index];

        self.sample_index = 0;
        self.block_size   = frame.header.block_size as usize;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.stream.output[index];

    self.channel      += 1;
    self.samples_left -= 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
    }

    Some(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}
<|endoftext|>


<commit_before>use rutorch::*;
use std::ops::{Index, IndexMut, Deref, DerefMut};
//use std::convert::From;
use std::cmp::max;

use storage::*;
use rand;
use {Ixs, RcMut};

pub struct Tensor<T> {
    value: RcMut<TensorImpl<T, Output = T>>,
}
impl<T> Tensor<T> {
    pub fn new() -> Self {
        panic!("implement")
    }
    pub fn len(&self) -> usize {
        panic!("implement")
    }
    pub fn cuda(&self) -> Self {
        panic!("implement");
        self.clone()
    }
    pub fn cpu(&self) -> Self {
        panic!("implement");
        self.clone()
    }
    pub fn reduce_max(&self, axis: usize) -> (Self, Tensor<i64>) {
        panic!("implement");
    }
    pub fn tensor_eq(&self, rhs: Self) -> Tensor<i64> {
        panic!("implement")

    }
    pub fn sum(&self) -> u32 {
        panic!("implement");
        0
    }
    pub fn s(&self, dim: usize) -> Self {
        panic!("implement");

    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        panic!("")
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor { value: self.value.clone() }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        panic!("implement")
    }
}
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}
<commit_msg>make rhs reference to avoid move<commit_after>use rutorch::*;
use std::ops::{Index, IndexMut, Deref, DerefMut};
//use std::convert::From;
use std::cmp::max;

use storage::*;
use rand;
use {Ixs, RcMut};

pub struct Tensor<T> {
    value: RcMut<TensorImpl<T, Output = T>>,
}
impl<T> Tensor<T> {
    pub fn new() -> Self {
        panic!("implement")
    }
    pub fn len(&self) -> usize {
        panic!("implement")
    }
    pub fn cuda(&self) -> Self {
        panic!("implement");
        self.clone()
    }
    pub fn cpu(&self) -> Self {
        panic!("implement");
        self.clone()
    }
    pub fn reduce_max(&self, axis: usize) -> (Self, Tensor<i64>) {
        panic!("implement");
    }
    pub fn tensor_eq(&self, rhs: &Self) -> Tensor<i64> {
        panic!("implement")

    }
    pub fn sum(&self) -> u32 {
        panic!("implement");
        0
    }
    pub fn s(&self, dim: usize) -> Self {
        panic!("implement");

    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        panic!("")
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor { value: self.value.clone() }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        panic!("implement")
    }
}
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use diesel::result::Error;
use diesel;
use diesel::*;
use self::models::{ImageLocation, SubmitImageLocation};
use database::schema::image_locations::dsl::*;
use database::schema::image_locations;
use super::database;

pub mod models;

static IMAGE_PATH: &'static str = "/static/media";

pub fn load_image(file_name: String) -> Option<File> {
    let conn = database::get_db_connection();

    let image_location: ImageLocation = match image_locations.filter(name.eq(file_name)).
        first::<ImageLocation>(&*conn) {
        Ok(image_location) => image_location,
        Err(_) => return None,
    };

    match File::open(image_location.url) {
        Ok(file) => Some(file),
        Err(_) => None,
    }
}

/// Uploads the image to the server with the given filename.
/// Returns the identifier of the image.
pub fn store_image(image_name: String, image: Vec<u8>) -> io::Result<String> {
    let file_path: String = format!(".{path}/{filename}", path = IMAGE_PATH, filename = image_name);
    let mut file = File::create(Path::new(file_path.as_str())).unwrap();
    file.write(image.as_slice()).unwrap();

    Ok(file_path)
}

pub fn insert_image_location(image_name: String, image_path: String) -> Result<i32, Error> {
    let conn = &*database::get_db_connection();

    println!("inserting image path {}", image_path.clone());

    let image_location = SubmitImageLocation { name: image_name, url: image_path };

    match diesel::insert(&image_location)
        .into(image_locations)
        .execute(conn) {
        Ok(_) => (),
        Err(e) => return Err(e),
    };
    println!("Getting image id!");

    match image_locations::table
        .order(image_locations::id.desc())
        .first::<ImageLocation>(conn) {
        Ok(img_loc) => Ok(img_loc.id),
        Err(e) => Err(e),
    }
}<commit_msg>Galleries: - Fixed (again): Now properly uploads and stores the correct local URL<commit_after>use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use diesel::result::Error;
use diesel;
use diesel::*;
use self::models::{ImageLocation, SubmitImageLocation};
use database::schema::image_locations::dsl::*;
use database::schema::image_locations;
use super::database;

pub mod models;

static IMAGE_PATH: &'static str = "/static/media";

pub fn load_image(file_name: String) -> Option<File> {
    let conn = database::get_db_connection();

    let image_location: ImageLocation = match image_locations.filter(name.eq(file_name)).
        first::<ImageLocation>(&*conn) {
        Ok(image_location) => image_location,
        Err(_) => return None,
    };

    match File::open(image_location.url) {
        Ok(file) => Some(file),
        Err(_) => None,
    }
}

/// Uploads the image to the server with the given filename.
/// Returns the identifier of the image.
pub fn store_image(image_name: String, image: Vec<u8>) -> io::Result<String> {
    let file_path: String = format!("{path}/{filename}", path = IMAGE_PATH, filename = image_name);
    let mut file = File::create(Path::new( format!(".{path}", path=file_path).as_str() )).unwrap();
    file.write(image.as_slice()).unwrap();

    Ok(file_path)
}

pub fn insert_image_location(image_name: String, image_path: String) -> Result<i32, Error> {
    let conn = &*database::get_db_connection();

    println!("inserting image path {}", image_path.clone());/

    let image_location = SubmitImageLocation { name: image_name, url: image_path };

    match diesel::insert(&image_location)
        .into(image_locations)
        .execute(conn) {
        Ok(_) => (),
        Err(e) => return Err(e),
    };
    println!("Getting image id!");

    match image_locations::table
        .order(image_locations::id.desc())
        .first::<ImageLocation>(conn) {
        Ok(img_loc) => Ok(img_loc.id),
        Err(e) => Err(e),
    }
}<|endoftext|>


<commit_before>use std::io;

#[deriving(Eq)]
enum Value {
	List(~[Value]),
	Atom(~str),
	Str(~str),
	Num(float)
}

fn read_number(input: &str, start: uint) -> Option<(~Value, uint)> {
	let end = input.iter().skip(start).position(|c| c == ' ' || c == ')');
	let pos = match end {
		Some(end) => start+end,
		None => input.len()
	};
	let acc = input.slice(start, pos);
	match std::float::from_str(acc) {
		Some(f) => Some((~Num(f), pos)),
		None => None
	}
}

fn read_list(input: &str, start: uint) -> Option<(~Value, uint)> {
	let mut list = ~[];
	let mut i = start;
	loop {
		match read_value(input, i) {
			Some((v,new_i)) => {
				list.push(*v);
				i = new_i;
			}
			None if input[i] as char == ')' => return Some((~List(list), i)),
			None => return None
		}
	}
}

fn read_atom(input: &str, start: uint) -> Option<(~Value, uint)> {
	let atom = std::str::from_chars(input.iter().skip(start).take_while(|&c| c != ' ' && c != ')').to_owned_vec());
	let len = atom.len();
	Some((~Atom(atom), start + len))
}

fn read_value(input: &str, start: uint) -> Option<(~Value, uint)> {
	if(start >= input.len() || input.is_whitespace() || input.slice(start, input.len()).is_whitespace()) {
		return None
	}

	match input[start] as char {
		' ' => read_value(input, start+1),
		'(' => read_list(input, start+1),
		')' => None,
		c if c.is_digit() || c == '.' => read_number(input, start),
		c => read_atom(input, start)
	}
}

fn parse(input: &str) -> Option<Value> {
	/*do io::with_str_reader(input) |r| {
		//let c =
		println("blah: " + input + " -> " + read_token(r));
		List(~[])
	}*/
	match read_value(input, 0) {
		Some((v,_)) => Some(*v),
		None => None
	}
}

#[test]
fn test_sexp() {
	assert_eq!(parse(""), None);
	assert_eq!(parse("123"), Some(Num(123.0)));
	assert_eq!(parse("()"), Some(List(~[])));
	assert_eq!(parse("3.14159265358"), Some(Num(3.14159265358)));
	assert_eq!(parse("(hi)"), Some(List(~[Atom(~"hi")])));
	assert_eq!(parse("(1)"), Some(List(~[Num(1.0)])));
	assert_eq!(parse("(hi there)"), Some(List(~[Atom(~"hi"), Atom(~"there")])));
	assert_eq!(parse("(hi (there))"), Some(List(~[Atom(~"hi"), List(~[Atom(~"there")])])));
	assert_eq!(parse("(hi 123456)"), Some(List(~[Atom(~"hi"), Num(123456.0)])));
	assert_eq!(parse("(())"), Some(List(~[List(~[])])));
	assert_eq!(parse("(hi (there (fellow (human-bot!))))"), Some(
		List(~[Atom(~"hi"),
			List(~[Atom(~"there"),
				List(~[Atom(~"fellow"),
					List(~[Atom(~"human-bot!")])])])])
	));
}<commit_msg>fix whitespace parsing issues and add tests<commit_after>use std::io;

#[deriving(Eq)]
enum Value {
	List(~[Value]),
	Atom(~str),
	Str(~str),
	Num(float)
}

fn read_nows(input: &str, start: uint) -> Option<char> {
	input.iter().skip(start).skip_while(|&c| c == ' ' || c == '\t').next()
}

fn read_number(input: &str, start: uint) -> Option<(~Value, uint)> {
	let end = input.iter().skip(start).position(|c| c == ' ' || c == ')');
	let pos = match end {
		Some(end) => start+end,
		None => input.len()
	};
	let acc = input.slice(start, pos);
	match std::float::from_str(acc) {
		Some(f) => Some((~Num(f), pos)),
		None => None
	}
}

fn read_list(input: &str, start: uint) -> Option<(~Value, uint)> {
	let mut list = ~[];
	let mut i = start;
	loop {
		match read_value(input, i) {
			Some((v,new_i)) => {
				list.push(*v);
				i = new_i;
			}
			None if read_nows(input, i) == Some(')') => return Some((~List(list), i)),
			None => return None
		}
	}
}

fn read_atom(input: &str, start: uint) -> Option<(~Value, uint)> {
	let atom = std::str::from_chars(input.iter().skip(start).take_while(|&c| c != ' ' && c != ')').to_owned_vec());
	let len = atom.len();
	Some((~Atom(atom), start + len))
}

fn read_value(input: &str, start: uint) -> Option<(~Value, uint)> {
	if(start >= input.len() || input.is_whitespace() || input.slice(start, input.len()).is_whitespace()) {
		return None
	}

	match input[start] as char {
		' ' => read_value(input, start+1),
		'(' => read_list(input, start+1),
		')' => None,
		c if c.is_digit() || c == '.' => read_number(input, start),
		c => read_atom(input, start)
	}
}

fn parse(input: &str) -> Option<Value> {
	/*do io::with_str_reader(input) |r| {
		//let c =
		println("blah: " + input + " -> " + read_token(r));
		List(~[])
	}*/
	match read_value(input, 0) {
		Some((v,_)) => Some(*v),
		None => None
	}
}

#[test]
fn test_sexp() {
	assert_eq!(parse(""), None);
	assert_eq!(parse("123"), Some(Num(123.0)));
	assert_eq!(parse("()"), Some(List(~[])));
	assert_eq!(parse("3.14159265358"), Some(Num(3.14159265358)));
	assert_eq!(parse("(hi)"), Some(List(~[Atom(~"hi")])));
	assert_eq!(parse("(1)"), Some(List(~[Num(1.0)])));
	assert_eq!(parse("  (  1  )  "), Some(List(~[Num(1.0)])));
	assert_eq!(parse("(hi there)"), Some(List(~[Atom(~"hi"), Atom(~"there")])));
	assert_eq!(parse("(hi (there))"), Some(List(~[Atom(~"hi"), List(~[Atom(~"there")])])));
	assert_eq!(parse("(hi 123456)"), Some(List(~[Atom(~"hi"), Num(123456.0)])));
	assert_eq!(parse("(())"), Some(List(~[List(~[])])));
	assert_eq!(parse("  (  (  )  )  )"), Some(List(~[List(~[])])));
	assert_eq!(parse("(hi (there (fellow (human-bot!))))"), Some(
		List(~[Atom(~"hi"),
			List(~[Atom(~"there"),
				List(~[Atom(~"fellow"),
					List(~[Atom(~"human-bot!")])])])])
	));
}<|endoftext|>


<commit_before>
use std::cmp;

fn is_blk(size: (usize, usize)) -> bool {
	return size.0 % 4 == 0 && size.1 % 4 == 0;
}

fn bc1_encode(pix: [u8; 4]) -> u16 {
	((pix[0] as u16 >> 3) << 11) |
	((pix[1] as u16 >> 2) << 5) |
	(pix[2] as u16 >> 3)
}

fn bc1_interp(min: [u8; 4], max: [u8; 4], index: usize) -> [u8; 4] {
	let coefs = match index {
		0x0 => (3, 0),
		0x1 => (0, 3),
		0x2 => (2 ,1),
		_ => (1, 2)
	};
	let mut pix = [0u8; 4];
	for i in 0..4 {
		pix[i] = ((coefs.1 * (min[i] as u16) +
				   coefs.0 * (max[i] as u16)) / 3) as u8
	}
	pix
}

fn dist(a: &[u8; 4], b: &[u8; 4]) -> u32 {
	let mut sum = 0u32;
	for i in 0..4 {
		let x = if a[i] < b[i] { b[i] - a[i] } else { a[i] - b[i] } as u32;
		sum += x;
	}
	sum
}

pub fn bc1(image: &Vec<u8>, size: (usize, usize)) -> Result<Vec<u8>, ()> {
	if !is_blk(size) {
		return Err(());
	}

    let mut out = Vec::new();

    let block_size = 4;

    let blk_count = (size.0 / block_size, size.1 / block_size);

   	for x in 0..blk_count.0 {
   		for y in 0..blk_count.1 {

   			let mut pixels = [[0u8; 4]; 16]; // No compile time constants
   			for px in 0..block_size {
   				for py in 0..block_size {
   					let x = x * block_size + px;
   					let y = y * block_size + py;

   					let pi = (x * size.0 + y) * 4; // in bytes
   					let pix = [image[pi], image[pi + 1], image[pi + 2], image[pi + 3]];

   					pixels[px * block_size + py] = pix;
   				}
   			}

   			let mut min = [255u8; 4];
   			let mut max = [0u8; 4];
   			for p in pixels.into_iter() {
   				for i in 0..4 {
   					min[i] = cmp::min(min[i], p[i]);
   					max[i] = cmp::max(max[i], p[i]);
   				}
   			}

   			let mut interps = [[0u8; 4]; 4];
   			for i in 0..4 {
   				interps[i] = bc1_interp(min, max, i);
   			}

   			// if we want alpha swap min/max (or encode min first)
			let min = bc1_encode(min);
			let max = bc1_encode(max);

			out.push((max & 0xFF) as u8);
			out.push((max >> 8) as u8);

			out.push((min & 0xFF) as u8);
			out.push((min >> 8) as u8);

			let mut mask = 0u32;

			for pix in pixels.into_iter().rev() {
				let best = (0..4).into_iter().min_by_key(|x| dist(&interps[*x], pix)).unwrap() as u32;
				mask = (mask << 2) | (best & 0x03);
			}

			for _ in 0..4 {
				out.push((mask & 0xFF) as u8);
				mask >>= 8;
			}
		}
	}

	Ok(out)
}
<commit_msg>made bc1 a little faster<commit_after>
use std::cmp;

fn is_blk(size: (usize, usize)) -> bool {
	return size.0 % 4 == 0 && size.1 % 4 == 0;
}

fn bc1_encode(pix: [u16; 4]) -> u16 {
	((pix[0] >> 3) << 11) |
	((pix[1] >> 2) << 5) |
	(pix[2] >> 3)
}

fn bc1_interp(min: [u16; 4], max: [u16; 4], index: usize) -> [u8; 4] {
	let coefs = match index {
		0x0 => (3, 0),
		0x1 => (0, 3),
		0x2 => (2 ,1),
		_ => (1, 2)
	};
	[(coefs.1 * min[0] + coefs.0 * max[0]) as u8,
	 (coefs.1 * min[1] + coefs.0 * max[1]) as u8,
	 (coefs.1 * min[2] + coefs.0 * max[2]) as u8,
	 (coefs.1 * min[3] + coefs.0 * max[3]) as u8]
}

fn dist_one(a: i16, b: i16) -> u32 {
	(a - b).abs() as u32
}

fn dist(a: &[u8; 4], b: &[u8; 4]) -> u32 {
	dist_one(a[0] as i16, b[0] as i16) +
	dist_one(a[1] as i16, b[1] as i16) +
	dist_one(a[2] as i16, b[2] as i16) +
	dist_one(a[3] as i16, b[3] as i16)
}

pub fn bc1(image: &Vec<u8>, size: (usize, usize)) -> Result<Vec<u8>, ()> {
	if !is_blk(size) {
		return Err(());
	}

    let mut out = Vec::new();

    let block_size = 4;

    let blk_count = (size.0 / block_size, size.1 / block_size);

   	for x in 0..blk_count.0 {
   		for y in 0..blk_count.1 {

   			let mut pixels = [[0u8; 4]; 16]; // No compile time constants
   			for px in 0..block_size {
   				for py in 0..block_size {
   					let x = x * block_size + px;
   					let y = y * block_size + py;

   					let pi = (x * size.0 + y) * 4; // in bytes
   					let pix = [image[pi], image[pi + 1], image[pi + 2], image[pi + 3]];

   					pixels[px * block_size + py] = pix;
   				}
   			}

   			let mut min = [255u16; 4];
   			let mut max = [0u16; 4];
   			for p in pixels.into_iter() {
   				for i in 0..4 {
   					min[i] = cmp::min(min[i], p[i] as u16);
   					max[i] = cmp::max(max[i], p[i] as u16);
   				}
   			}

   			let mut interps = [[0u8; 4]; 4];
   			for i in 0..4 {
   				interps[i] = bc1_interp(min, max, i);
   			}

   			// if we want alpha swap min/max (or encode min first)
			let min = bc1_encode(min);
			let max = bc1_encode(max);

			out.push((max & 0xFF) as u8);
			out.push((max >> 8) as u8);

			out.push((min & 0xFF) as u8);
			out.push((min >> 8) as u8);

			let mut mask = 0u32;

			for pix in pixels.into_iter().rev() {
				let best = (0..4).into_iter().min_by_key(|x| dist(&interps[*x], pix)).unwrap() as u32;
				mask = (mask << 2) | (best & 0x03);
			}

			for _ in 0..4 {
				out.push((mask & 0xFF) as u8);
				mask >>= 8;
			}
		}
	}

	Ok(out)
}
<|endoftext|>


<commit_before>use serde::{Deserialize, Serialize};

/// Trait represents global state of the
/// entire simulation which can updated
/// independently from any particular cell.
/// Consider to store there as much as you can
/// because this data will be created only once
/// and will not be copied.
pub trait EvolutionState {
    /// Method is called once between cells' updates.
    fn update(&mut self);
}

/// Main trait should be implemented in user's code.
/// Such structs contain main logic of cellular
/// automaton. Grids can handle only one cell,
/// so it should be all-in-one.
pub trait Cell: Serialize + Deserialize {
    /// Coords supported by Cell.
    type Coord: Coord;
    /// Global state of evolution.
    type State: EvolutionState;

    /// This method is called for every instance of Cell
    /// in grid. Cell can mutate itself. Grid should pass
    /// neighbors, previous version of this Cell and the
    /// global state.
    fn update<'a, I>(&'a mut self, old: &'a Self, neighbors: I, &Self::State)
        where I: Iterator<Item = Option<&'a Self>>;

    /// Constructs Cell with given coord.
    fn with_coord<C: Coord>(C) -> Self;
    /// Getter for cell's coordinate.
    fn coord(&self) -> &Self::Coord;
    /// Setter for cell's coordinate.
    fn set_coord<C: Coord>(&mut self, &C);
}

/// Represents neighborhood for automata.
pub trait Nhood {
    /// Coords this nhood supports.
    type Coord: Coord;

    /// Method returns for any given coord
    /// coordinates of surrounding neighbors.
    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;
    /// Hint for grid.
    fn neighbors_count(&self) -> usize;
}

/// Basic coordinate with three components.
/// This crate is used for creating automata
/// on 2D grids for now, so `z` has default impl.
pub trait Coord: Clone + Serialize + Deserialize {
    /// Build coord from any other representation of coord.
    fn from_2d(x: i32, y: i32) -> Self;

    /// Returns `x` component.
    fn x(&self) -> i32;
    /// Returns `y` component.
    fn y(&self) -> i32;
    /// Returns `z` component.
    fn z(&self) -> i32 { 0 }
}

/// Grid stores cells and updates them. Also
/// grid contains global evolution state.
pub trait Grid {
    /// Grid wants to work with them.
    type Cell: Cell;
    /// Grid knows how to work with them.
    type Coord: Coord;

    /// One step in evolution.
    fn update(&mut self);

    /// Getter for evolution state.
    fn state(&self) -> &<<Self as Grid>::Cell as Cell>::State;
    /// Getter for all cells. It is `Vec` because
    /// Rust does not have abstract return types for now.
    /// So custom grids are doomed to use `Vec`s internally.
    fn cells(&self) -> &Vec<Self::Cell>;
    /// Returns `Coord` with rows and cols counts of grid (2D).
    /// 3D grids would have more dimensions.
    fn dimensions(&self) -> Self::Coord;

    /// This method gives an ability to change grid externally.
    /// It could be done from consumer, for example
    /// (consider an app where you reacting to user input),
    /// or from engine (consider distributed engine received
    /// updates from nodes).
    fn set_cells(&mut self, Vec<Self::Cell>);
}

/// Interface to the outer world.
pub trait Consumer {
    /// Cells supported by this consumer. Helps
    /// to use cells from grid directly if grid
    /// has the same cell in it.
    type Cell: Cell;

    /// Called once when all cells has been updated.
    fn consume<G>(&mut self, &mut G)
        where G: Grid<Cell = Self::Cell>;
}

/// Interlayer between grid and consumer(s).
pub trait Engine {
    /// Runs evolution fixed number of times.
    fn run_times(&mut self, i64);
}
<commit_msg>Note about traits in general + typo fix.<commit_after>//! Interfaces on which this library is built.

use serde::{Deserialize, Serialize};

/// Trait represents global state of the
/// entire simulation which can be updated
/// independently from any particular cell.
/// Consider to store there as much as you can
/// because this data will be created only once
/// and will not be copied.
pub trait EvolutionState {
    /// Method is called once between cells' updates.
    fn update(&mut self);
}

/// Main trait should be implemented in user's code.
/// Such structs contain main logic of cellular
/// automaton. Grids can handle only one cell,
/// so it should be all-in-one.
pub trait Cell: Serialize + Deserialize {
    /// Coords supported by Cell.
    type Coord: Coord;
    /// Global state of evolution.
    type State: EvolutionState;

    /// This method is called for every instance of Cell
    /// in grid. Cell can mutate itself. Grid should pass
    /// neighbors, previous version of this Cell and the
    /// global state.
    fn update<'a, I>(&'a mut self, old: &'a Self, neighbors: I, &Self::State)
        where I: Iterator<Item = Option<&'a Self>>;

    /// Constructs Cell with given coord.
    fn with_coord<C: Coord>(C) -> Self;
    /// Getter for cell's coordinate.
    fn coord(&self) -> &Self::Coord;
    /// Setter for cell's coordinate.
    fn set_coord<C: Coord>(&mut self, &C);
}

/// Represents neighborhood for automata.
pub trait Nhood {
    /// Coords this nhood supports.
    type Coord: Coord;

    /// Method returns for any given coord
    /// coordinates of surrounding neighbors.
    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;
    /// Hint for grid.
    fn neighbors_count(&self) -> usize;
}

/// Basic coordinate with three components.
/// This crate is used for creating automata
/// on 2D grids for now, so `z` has default impl.
pub trait Coord: Clone + Serialize + Deserialize {
    /// Build coord from any other representation of coord.
    fn from_2d(x: i32, y: i32) -> Self;

    /// Returns `x` component.
    fn x(&self) -> i32;
    /// Returns `y` component.
    fn y(&self) -> i32;
    /// Returns `z` component.
    fn z(&self) -> i32 { 0 }
}

/// Grid stores cells and updates them. Also
/// grid contains global evolution state.
pub trait Grid {
    /// Grid wants to work with them.
    type Cell: Cell;
    /// Grid knows how to work with them.
    type Coord: Coord;

    /// One step in evolution.
    fn update(&mut self);

    /// Getter for evolution state.
    fn state(&self) -> &<<Self as Grid>::Cell as Cell>::State;
    /// Getter for all cells. It is `Vec` because
    /// Rust does not have abstract return types for now.
    /// So custom grids are doomed to use `Vec`s internally.
    fn cells(&self) -> &Vec<Self::Cell>;
    /// Returns `Coord` with rows and cols counts of grid (2D).
    /// 3D grids would have more dimensions.
    fn dimensions(&self) -> Self::Coord;

    /// This method gives an ability to change grid externally.
    /// It could be done from consumer, for example
    /// (consider an app where you reacting to user input),
    /// or from engine (consider distributed engine received
    /// updates from nodes).
    fn set_cells(&mut self, Vec<Self::Cell>);
}

/// Interface to the outer world.
pub trait Consumer {
    /// Cells supported by this consumer. Helps
    /// to use cells from grid directly if grid
    /// has the same cell in it.
    type Cell: Cell;

    /// Called once when all cells has been updated.
    fn consume<G>(&mut self, &mut G)
        where G: Grid<Cell = Self::Cell>;
}

/// Interlayer between grid and consumer(s).
pub trait Engine {
    /// Runs evolution fixed number of times.
    fn run_times(&mut self, i64);
}
<|endoftext|>


<commit_before>use actix::prelude::*;
use diesel;
use diesel::prelude::*;
use failure::Error;
use schema::mailbox;
use std::time::{Duration, SystemTime};
use utils::{ConnectionPool, LoggedResult};

const VACUUM_CUTOFF_SECS: u64 = 24 * 60 * 60 * 7; // one week
const VACUUM_INTERVAL_SECS: u64 = 5;

pub struct VacuumCleaner {
    connection_pool: ConnectionPool,
}

impl VacuumCleaner {
    pub fn new(connection_pool: ConnectionPool) -> VacuumCleaner {
        VacuumCleaner { connection_pool }
    }
}

struct Vacuum;

impl Message for Vacuum {
    type Result = Result<(), Error>;
}

impl Actor for VacuumCleaner {
    type Context = Context<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        ctx.run_interval(Duration::new(VACUUM_INTERVAL_SECS, 0), |_actor, ctx| {
            ctx.notify(Vacuum)
        });
    }
}

impl Handler<Vacuum> for VacuumCleaner {
    type Result = Result<(), Error>;

    fn handle(&mut self, _msg: Vacuum, _ctx: &mut Context<Self>) -> Self::Result {
        vacuum_old_mailboxes(&self.connection_pool).log_errors()
    }
}

pub fn vacuum_old_mailboxes(pool: &ConnectionPool) -> Result<(), Error> {
    let cutoff = SystemTime::now() - Duration::from_secs(VACUUM_CUTOFF_SECS);
    debug!(
        "Vacuuming - deleting inactive mailboxes older than {:?}...",
        cutoff
    );
    diesel::delete(mailbox::table.filter(mailbox::columns::last_activity.lt(cutoff)))
        .execute(&pool.get()?)
        .log_errors()?;
    debug!("Vacuum complete");
    Ok(())
}
<commit_msg>Fix vacuum interval<commit_after>use actix::prelude::*;
use diesel;
use diesel::prelude::*;
use failure::Error;
use schema::mailbox;
use std::time::{Duration, SystemTime};
use utils::{ConnectionPool, LoggedResult};

const VACUUM_CUTOFF_SECS: u64 = 24 * 60 * 60 * 7; // one week
const VACUUM_INTERVAL_SECS: u64 = 60 * 60;

pub struct VacuumCleaner {
    connection_pool: ConnectionPool,
}

impl VacuumCleaner {
    pub fn new(connection_pool: ConnectionPool) -> VacuumCleaner {
        VacuumCleaner { connection_pool }
    }
}

struct Vacuum;

impl Message for Vacuum {
    type Result = Result<(), Error>;
}

impl Actor for VacuumCleaner {
    type Context = Context<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        ctx.run_interval(Duration::new(VACUUM_INTERVAL_SECS, 0), |_actor, ctx| {
            ctx.notify(Vacuum)
        });
    }
}

impl Handler<Vacuum> for VacuumCleaner {
    type Result = Result<(), Error>;

    fn handle(&mut self, _msg: Vacuum, _ctx: &mut Context<Self>) -> Self::Result {
        vacuum_old_mailboxes(&self.connection_pool).log_errors()
    }
}

pub fn vacuum_old_mailboxes(pool: &ConnectionPool) -> Result<(), Error> {
    let cutoff = SystemTime::now() - Duration::from_secs(VACUUM_CUTOFF_SECS);
    debug!(
        "Vacuuming - deleting inactive mailboxes older than {:?}...",
        cutoff
    );
    diesel::delete(mailbox::table.filter(mailbox::columns::last_activity.lt(cutoff)))
        .execute(&pool.get()?)
        .log_errors()?;
    debug!("Vacuum complete");
    Ok(())
}
<|endoftext|>


<commit_before>use std::fmt;
pub use self::DecodeError::*;

const BASE: u64 = 62;
const ALPHABET: [u8; BASE as usize] = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
                                       b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J',
                                       b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T',
                                       b'U', b'V', b'W', b'X', b'Y', b'Z', b'a', b'b', b'c', b'd',
                                       b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n',
                                       b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x',
                                       b'y', b'z'];

pub fn encode(mut num: u64) -> String {
    if num == 0 {
        return "0".to_owned();
    }
    let mut bytes = Vec::new();

    while num > 0 {
        bytes.push(ALPHABET[(num % BASE) as usize]);
        num /= BASE
    }
    bytes.reverse();

    String::from_utf8(bytes).unwrap()
}

pub enum DecodeError {
    InvalidBase62Byte(char, usize),
    ArithmeticOverflow,
}

impl fmt::Debug for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            InvalidBase62Byte(ch, idx) =>
                write!(f, "Invalid character '{}' at position {}", ch, idx),
            ArithmeticOverflow => write!(f, "Decode result is too large"),
        }
    }
}

impl fmt::Display for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self, f)
    }
}

pub fn decode(string: &str) -> Result<u64, DecodeError> {
    let mut result = 0;

    for (i, c) in string.as_bytes().iter().rev().enumerate() {
        let num = BASE.pow(i as u32);
        match ALPHABET.binary_search(&c) {
            Ok(v) => {
                match (v as u64).checked_mul(num) {
                    Some(z) => result += z,
                    None => return Err(ArithmeticOverflow),
                }
            }
            Err(_e) => {
                return Err(InvalidBase62Byte(c.to_owned() as char, string.len() - i));
            }
        }
    }

    Ok(result)
}

#[cfg(test)]
mod tests {
    use base62;

    #[test]
    fn test_encode() {
        assert_eq!(base62::encode(852751187393), "F0ob4rZ");
    }

    #[test]
    fn test_decode() {
        assert_eq!(base62::decode("F0ob4rZ").unwrap(), 852751187393);
    }

    #[test]
    fn test_decode_invalid_char() {
        assert!(base62::decode("ds{Z455f").is_err());
    }

    #[test]
    fn test_decode_long_string() {
        assert!(base62::decode("dsZ455fzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\
                                zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")
                    .is_err());
    }
}
<commit_msg>Another rustfmt<commit_after>use std::fmt;
pub use self::DecodeError::*;

const BASE: u64 = 62;
const ALPHABET: [u8; BASE as usize] = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
                                       b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J',
                                       b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T',
                                       b'U', b'V', b'W', b'X', b'Y', b'Z', b'a', b'b', b'c', b'd',
                                       b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n',
                                       b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x',
                                       b'y', b'z'];

pub fn encode(mut num: u64) -> String {
    if num == 0 {
        return "0".to_owned();
    }
    let mut bytes = Vec::new();

    while num > 0 {
        bytes.push(ALPHABET[(num % BASE) as usize]);
        num /= BASE
    }
    bytes.reverse();

    String::from_utf8(bytes).unwrap()
}

pub enum DecodeError {
    InvalidBase62Byte(char, usize),
    ArithmeticOverflow,
}

impl fmt::Debug for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            InvalidBase62Byte(ch, idx) => {
                write!(f, "Invalid character '{}' at position {}", ch, idx)
            }
            ArithmeticOverflow => write!(f, "Decode result is too large"),
        }
    }
}

impl fmt::Display for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self, f)
    }
}

pub fn decode(string: &str) -> Result<u64, DecodeError> {
    let mut result = 0;

    for (i, c) in string.as_bytes().iter().rev().enumerate() {
        let num = BASE.pow(i as u32);
        match ALPHABET.binary_search(&c) {
            Ok(v) => {
                match (v as u64).checked_mul(num) {
                    Some(z) => result += z,
                    None => return Err(ArithmeticOverflow),
                }
            }
            Err(_e) => {
                return Err(InvalidBase62Byte(c.to_owned() as char, string.len() - i));
            }
        }
    }

    Ok(result)
}

#[cfg(test)]
mod tests {
    use base62;

    #[test]
    fn test_encode() {
        assert_eq!(base62::encode(852751187393), "F0ob4rZ");
    }

    #[test]
    fn test_decode() {
        assert_eq!(base62::decode("F0ob4rZ").unwrap(), 852751187393);
    }

    #[test]
    fn test_decode_invalid_char() {
        assert!(base62::decode("ds{Z455f").is_err());
    }

    #[test]
    fn test_decode_long_string() {
        assert!(base62::decode("dsZ455fzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\
                                zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")
                    .is_err());
    }
}
<|endoftext|>


<commit_before>extern crate discord;
extern crate dotenv;
#[macro_use]
extern crate serde_derive;
extern crate envy;

use discord::{Discord, State};
use discord::model::{Event};
use discord::voice::AudioSource;

use std::collections::HashMap;
use std::sync::mpsc::{channel, Sender, Receiver};

#[derive(Default)]
struct Dj {
  controls: HashMap<u64, Sender<AudioSourceControl>>
}

pub enum MusicItem {
  YouTube(String)
}

fn main() {
  println!("Loading .env");

  dotenv::dotenv().ok();

  println!("Reading environment variables");

  let environment: Environment = envy::from_env().expect("Invalid or missing environment variables");

  println!("Creating bot");

  let discord = Discord::from_bot_token(&environment.discord_bot_token).expect("could not start discord from bot token");
  let (mut connection, ready) = discord.connect().expect("could not connect");
  let mut state = State::new(ready);

  let mut dj = Dj::default();

  loop {
    let event = match connection.recv_event() {
      Ok(e) => e,
      Err(e) => {
        println!("could not receive event: {}", e);
        continue;
      }
    };

    state.update(&event);

    let valid_commands = &["!play", "!stop", "!clear", "!pause", "!resume"];

    match event {
      Event::MessageCreate(message) => {
        let params: Vec<&str> = message.content.split_whitespace().collect();
        if params.is_empty() || params[0].len() < 2 {
          continue;
        }

        let command: String = params[0].to_lowercase().chars().skip(1).collect();
        if !params[0].starts_with('!') && !valid_commands.contains(&command.as_ref()) {
          continue;
        }

        let (server_id, voice_channel) = match state.find_voice_user(message.author.id) {
          Some((Some(server_id), voice_channel)) => (server_id, voice_channel),
          _ => {
            if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Must be in a public voice channel to DJ.")) {
              println!("could not send message: {}", e);
            }
            continue;
          }
        };

        let voice = connection.voice(Some(server_id));

        match command.as_ref() {
          "play" => {
            if params.len() < 2 {
              if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Please provide a YouTube URL to play.")) {
                println!("could not send message: {}", e);
              }
              continue;
            }
            let url = params[1];
            if let Some((_, controls)) = dj.controls.iter().find(|&(id, _)| *id == voice_channel.0) {
              if let Err(e) = controls.send(AudioSourceControl::AddQueue(url.to_string())) {
                println!("could not send control: {}", e);
              }
              continue;
            }
            let source = match discord::voice::open_ytdl_stream(url) {
              Ok(s) => s,
              Err(e) => {
                println!("could not open source: {}", e);
                if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Could not open video for streaming.")) {
                  println!("could not send message: {}", e);
                }
                continue;
              }
            };

            voice.connect(voice_channel);

            let (tx, rx) = channel();
            dj.controls.insert(voice_channel.0, tx);
            let buf_source = BufferedQueuedAudioSource::new(source, rx);
            voice.play(Box::new(buf_source));
          },
          "stop" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Stop) {
              println!("couldn't send control: {}", e);
            }
          },
          "pause" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Pause) {
              println!("couldn't send control: {}", e);
            }
          },
          "resume" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Resume) {
              println!("couldn't send control: {}", e);
            }
          },
          "clear" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::ClearQueue) {
              println!("couldn't send control: {}", e);
            }
          },
          _ => continue
        }
      },
      Event::VoiceStateUpdate(server_id, _) => {
        let chan = match connection.voice(server_id).current_channel() {
          Some(c) => c,
          None => continue
        };
        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(chan)).count() <= 1 {
              connection.voice(Some(server_id)).disconnect();
            }
          },
          None => if let Some(call) = state.calls().get(&chan) {
            if call.voice_states.len() <= 1 {
              connection.voice(server_id).disconnect();
            }
          }
        }
      },
      _ => {}
    }
  }
}

#[derive(Debug, Deserialize)]
pub struct Environment {
  #[serde(rename = "lb_discord_bot_token")]
  pub discord_bot_token: String,
}

pub enum AudioSourceControl {
  Pause,
  Resume,
  Stop,
  AddQueue(String),
  ClearQueue
}

struct BufferedQueuedAudioSource {
  controls: Receiver<AudioSourceControl>,
  source: Box<AudioSource>,
  buffer: Box<[i16]>,
  queue: Vec<String>,
  position: usize,
  capacity: usize,
  paused: bool,
  finished: bool
}

impl BufferedQueuedAudioSource {
  fn new(source: Box<AudioSource>, controls: Receiver<AudioSourceControl>) -> Self {
    BufferedQueuedAudioSource {
      controls: controls,
      source: source,
      buffer: vec![0; 61440].into_boxed_slice(),
      queue: Vec::default(),
      position: 0,
      capacity: 0,
      paused: false,
      finished: false
    }
  }
}

impl AudioSource for BufferedQueuedAudioSource {
  fn is_stereo(&mut self) -> bool {
    self.source.is_stereo()
  }

  fn read_frame(&mut self, buffer: &mut [i16]) -> Option<usize> {
    self.read_controls();
    self.handle_queue();
    if self.paused {
      for byte in buffer.iter_mut() {
        *byte = 0;
      }
      return Some(buffer.len());
    }
    self.read(buffer)
  }
}

impl BufferedQueuedAudioSource {
  fn read_controls(&mut self) {
    while let Ok(control) = self.controls.try_recv() {
      match control {
        AudioSourceControl::Resume => self.paused = false,
        AudioSourceControl::Pause => self.paused = true,
        AudioSourceControl::AddQueue(s) => self.queue.push(s),
        AudioSourceControl::ClearQueue => self.queue.clear(),
        AudioSourceControl::Stop => {
          self.queue.clear();
          self.finished = true;
        }
      }
    }
  }

  fn handle_queue(&mut self) {
    if !self.finished || self.queue.is_empty() {
      return;
    }
    while !self.queue.is_empty() {
      let first = self.queue.remove(0);
      match discord::voice::open_ytdl_stream(&first) {
        Ok(s) => {
          self.source = s;
          self.finished = false;
          break;
        },
        Err(e) => {
          println!("could not open ytdl stream in queue: {}", e);
          continue;
        }
      }
    }
  }

  fn read(&mut self, buffer: &mut [i16]) -> Option<usize> {
    if self.position == self.capacity && buffer.len() >= self.buffer.len() {
      return self.source.read_frame(buffer);
    }
    let nread = {
      let rem = match self.fill_buff() {
        Some(s) => s,
        None => return None
      };
      let read = std::cmp::min(buffer.len(), rem.len());
      for i in 0..read {
        buffer[i] = rem[i];
      }
      read
    };
    self.consume(nread);
    Some(nread)
  }

  fn fill_buff(&mut self) -> Option<&[i16]> {
    if self.position >= self.capacity {
      self.capacity = match self.source.read_frame(&mut self.buffer) {
        Some(s) => s,
        None => return None
      };
      // FIXME: This should happen when read_frame turns None, but discord-rs has a bug
      // https://github.com/SpaceManiac/discord-rs/issues/107
      if self.capacity == 0 && !self.finished {
        self.finished = true;
      }
      self.position = 0;
    }
    Some(&self.buffer[self.position..self.capacity])
  }

  fn consume(&mut self, amt: usize) {
    self.position = std::cmp::min(self.position + amt, self.capacity);
  }
}
<commit_msg>fix: use or, not and<commit_after>extern crate discord;
extern crate dotenv;
#[macro_use]
extern crate serde_derive;
extern crate envy;

use discord::{Discord, State};
use discord::model::{Event};
use discord::voice::AudioSource;

use std::collections::HashMap;
use std::sync::mpsc::{channel, Sender, Receiver};

#[derive(Default)]
struct Dj {
  controls: HashMap<u64, Sender<AudioSourceControl>>
}

pub enum MusicItem {
  YouTube(String)
}

fn main() {
  println!("Loading .env");

  dotenv::dotenv().ok();

  println!("Reading environment variables");

  let environment: Environment = envy::from_env().expect("Invalid or missing environment variables");

  println!("Creating bot");

  let discord = Discord::from_bot_token(&environment.discord_bot_token).expect("could not start discord from bot token");
  let (mut connection, ready) = discord.connect().expect("could not connect");
  let mut state = State::new(ready);

  let mut dj = Dj::default();

  loop {
    let event = match connection.recv_event() {
      Ok(e) => e,
      Err(e) => {
        println!("could not receive event: {}", e);
        continue;
      }
    };

    state.update(&event);

    let valid_commands = &["!play", "!stop", "!clear", "!pause", "!resume"];

    match event {
      Event::MessageCreate(message) => {
        let params: Vec<&str> = message.content.split_whitespace().collect();
        if params.is_empty() || params[0].len() < 2 {
          continue;
        }

        let command: String = params[0].to_lowercase().chars().skip(1).collect();
        if !params[0].starts_with('!') || !valid_commands.contains(&command.as_ref()) {
          continue;
        }

        let (server_id, voice_channel) = match state.find_voice_user(message.author.id) {
          Some((Some(server_id), voice_channel)) => (server_id, voice_channel),
          _ => {
            if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Must be in a public voice channel to DJ.")) {
              println!("could not send message: {}", e);
            }
            continue;
          }
        };

        let voice = connection.voice(Some(server_id));

        match command.as_ref() {
          "play" => {
            if params.len() < 2 {
              if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Please provide a YouTube URL to play.")) {
                println!("could not send message: {}", e);
              }
              continue;
            }
            let url = params[1];
            if let Some((_, controls)) = dj.controls.iter().find(|&(id, _)| *id == voice_channel.0) {
              if let Err(e) = controls.send(AudioSourceControl::AddQueue(url.to_string())) {
                println!("could not send control: {}", e);
              }
              continue;
            }
            let source = match discord::voice::open_ytdl_stream(url) {
              Ok(s) => s,
              Err(e) => {
                println!("could not open source: {}", e);
                if let Err(e) = discord.send_embed(message.channel_id, "", |e| e.description("Could not open video for streaming.")) {
                  println!("could not send message: {}", e);
                }
                continue;
              }
            };

            voice.connect(voice_channel);

            let (tx, rx) = channel();
            dj.controls.insert(voice_channel.0, tx);
            let buf_source = BufferedQueuedAudioSource::new(source, rx);
            voice.play(Box::new(buf_source));
          },
          "stop" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Stop) {
              println!("couldn't send control: {}", e);
            }
          },
          "pause" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Pause) {
              println!("couldn't send control: {}", e);
            }
          },
          "resume" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::Resume) {
              println!("couldn't send control: {}", e);
            }
          },
          "clear" => {
            let control = match dj.controls.get(&voice_channel.0) {
              Some(c) => c,
              None => continue
            };
            if let Err(e) = control.send(AudioSourceControl::ClearQueue) {
              println!("couldn't send control: {}", e);
            }
          },
          _ => continue
        }
      },
      Event::VoiceStateUpdate(server_id, _) => {
        let chan = match connection.voice(server_id).current_channel() {
          Some(c) => c,
          None => continue
        };
        if let Some(server_id) = 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(chan)).count() <= 1 {
              connection.voice(Some(server_id)).disconnect();
            }
          }
        }
      },
      _ => {}
    }
  }
}

#[derive(Debug, Deserialize)]
pub struct Environment {
  #[serde(rename = "lb_discord_bot_token")]
  pub discord_bot_token: String,
}

pub enum AudioSourceControl {
  Pause,
  Resume,
  Stop,
  AddQueue(String),
  ClearQueue
}

struct BufferedQueuedAudioSource {
  controls: Receiver<AudioSourceControl>,
  source: Box<AudioSource>,
  buffer: Box<[i16]>,
  queue: Vec<String>,
  position: usize,
  capacity: usize,
  paused: bool,
  finished: bool
}

impl BufferedQueuedAudioSource {
  fn new(source: Box<AudioSource>, controls: Receiver<AudioSourceControl>) -> Self {
    BufferedQueuedAudioSource {
      controls: controls,
      source: source,
      buffer: vec![0; 61440].into_boxed_slice(),
      queue: Vec::default(),
      position: 0,
      capacity: 0,
      paused: false,
      finished: false
    }
  }
}

impl AudioSource for BufferedQueuedAudioSource {
  fn is_stereo(&mut self) -> bool {
    self.source.is_stereo()
  }

  fn read_frame(&mut self, buffer: &mut [i16]) -> Option<usize> {
    self.read_controls();
    self.handle_queue();
    if self.paused {
      for byte in buffer.iter_mut() {
        *byte = 0;
      }
      return Some(buffer.len());
    }
    self.read(buffer)
  }
}

impl BufferedQueuedAudioSource {
  fn read_controls(&mut self) {
    while let Ok(control) = self.controls.try_recv() {
      match control {
        AudioSourceControl::Resume => self.paused = false,
        AudioSourceControl::Pause => self.paused = true,
        AudioSourceControl::AddQueue(s) => self.queue.push(s),
        AudioSourceControl::ClearQueue => self.queue.clear(),
        AudioSourceControl::Stop => {
          self.queue.clear();
          self.finished = true;
        }
      }
    }
  }

  fn handle_queue(&mut self) {
    if !self.finished || self.queue.is_empty() {
      return;
    }
    while !self.queue.is_empty() {
      let first = self.queue.remove(0);
      match discord::voice::open_ytdl_stream(&first) {
        Ok(s) => {
          self.source = s;
          self.finished = false;
          break;
        },
        Err(e) => {
          println!("could not open ytdl stream in queue: {}", e);
          continue;
        }
      }
    }
  }

  fn read(&mut self, buffer: &mut [i16]) -> Option<usize> {
    if self.position == self.capacity && buffer.len() >= self.buffer.len() {
      return self.source.read_frame(buffer);
    }
    let nread = {
      let rem = match self.fill_buff() {
        Some(s) => s,
        None => return None
      };
      let read = std::cmp::min(buffer.len(), rem.len());
      for i in 0..read {
        buffer[i] = rem[i];
      }
      read
    };
    self.consume(nread);
    Some(nread)
  }

  fn fill_buff(&mut self) -> Option<&[i16]> {
    if self.position >= self.capacity {
      self.capacity = match self.source.read_frame(&mut self.buffer) {
        Some(s) => s,
        None => return None
      };
      // FIXME: This should happen when read_frame turns None, but discord-rs has a bug
      // https://github.com/SpaceManiac/discord-rs/issues/107
      if self.capacity == 0 && !self.finished {
        self.finished = true;
      }
      self.position = 0;
    }
    Some(&self.buffer[self.position..self.capacity])
  }

  fn consume(&mut self, amt: usize) {
    self.position = std::cmp::min(self.position + amt, self.capacity);
  }
}
<|endoftext|>


<commit_before>// Copyright 2016-2018 James Bostock. See the LICENSE file at the top-level
// directory of this distribution.

// An implementation of the od(1) command in Rust.
// See http://man.cat-v.org/unix-6th/1/od
use std::env;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Stdout;
use std::io::Write;
use std::num::ParseIntError;

mod util;

/// Writes a chunk of output data as octal byte values.
fn write_oct_bytes(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for byte in data {
        write!(out, " {:03o}", byte)?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as octal (16 bit) word values. Words are
/// assumed to be little endian.
fn write_oct_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06o}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as decimal (16 bit) word values. Words are
/// assumed to be little endian.
fn write_dec_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as hexadecimal (16 bit) word values. Words
/// are assumed to be little endian.
fn write_hex_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06x}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of data as ASCII, reverting to octal byte values for
/// non-printable characters. Standard escape sequences are supported.
fn write_ascii_chars(out: &mut BufWriter<Stdout>, data: &[u8])
                     -> io::Result<usize> {
    for byte in data {
        match *byte {
            7u8 => write!(out, " \\g")?,
            8u8 => write!(out, " \\b")?,
            9u8 => write!(out, " \\t")?,
            10u8 => write!(out, " \\n")?,
            11u8 => write!(out, " \\v")?,
            12u8 => write!(out, " \\f")?,
            13u8 => write!(out, " \\r")?,
            _ => if *byte < 32u8 || *byte > 126u8 {
                write!(out, " {:03o}", *byte)?
            } else {
                write!(out, "   {}", *byte as char)?
            }
        }
    }
    writeln!(out)?;
    Ok(data.len())
}

const CHUNK_SIZE: usize = 16;

// The offset string is of the form [+]offset[.][b]
// +100 => 0o100
// +100. => 100
// +100b => 0o100 * 512
// +100.b => 100 * 512
fn parse_offset(offstr: &str) -> Result<u64, ParseIntError> {
    let mut char_indices = offstr.char_indices().rev();
    let mut mult = 1;
    let (s, r) = match char_indices.next() {
        Some((x, 'b')) => {
            mult = 512;
            match char_indices.next() {
                Some((y, '.')) => (&offstr[0..y], 10),
                Some((_, _)) => (&offstr[0..x], 8),
                None => (&offstr[0..0], 8)
            }
        },
        Some((x, '.')) => (&offstr[0..x], 10),
        Some((_, _)) => (&offstr[..], 8),
        None => (&offstr[0..0], 8)
    };

    match u64::from_str_radix(s, r) {
        Ok(n) => Ok(n * mult),
        Err(e) => Err(e)
    }
}

#[test]
fn test_parse_offset() {
    match parse_offset("100") {
        Ok(off) => assert!(off == 0o100),
        Err(e) => assert!(false)
    }

    match parse_offset("100.") {
        Ok(off) => assert!(off == 100),
        Err(e) => assert!(false)
    }

    match parse_offset("100b") {
        Ok(off) => assert!(off == 0o100 * 512),
        Err(e) => assert!(false)
    }

    match parse_offset("100.b") {
        Ok(off) => assert!(off == 100 * 512),
        Err(e) => assert!(false)
    }
}

/// Dumps the data read from the named input source to the standard output.
fn od(filename: &str, offset: u64,
      fmts: &[fn(&mut BufWriter<Stdout>,&[u8]) -> io::Result<usize>])
      -> io::Result<u64> {
    let mut reader = BufReader::new(util::Input::open(filename)?);
    let mut writer = BufWriter::new(io::stdout());
    let mut offset = offset;

    if offset > 0 {
        reader.seek(SeekFrom::Start(offset))?;
    }

    let mut chunk = [0; CHUNK_SIZE];
    loop {
        let n = reader.read(&mut chunk)?;
        if n > 0 {
            let mut first = true;
            for fmt in fmts.iter() {
                if first {
                    write!(writer, "{:07o}", offset)?;
                    first = false;
                } else {
                    write!(writer, "       ")?;
                }
                fmt(&mut writer, &chunk)?;
                offset += chunk.len() as u64;
            }
        }

        if n < CHUNK_SIZE {
            break
        }
    }
    writeln!(writer, "{:07o}", offset)?;
    Ok(offset)
}

fn main() {
    let args: Vec<_> = env::args().skip(1).collect();
    let mut idx = 0;
    let mut offset : u64 = 0;
    let mut offstr = "0";
    let mut fmts: Vec<fn(&mut BufWriter<Stdout>, &[u8]) -> io::Result<usize>> = Vec::new();

    if args.len() > idx && args[idx].starts_with('-') {
        for opt in args[idx].chars().skip(1) {
            match opt {
                'b' => fmts.push(write_oct_bytes),
                'c' => fmts.push(write_ascii_chars),
                'd' => fmts.push(write_dec_words),
                'h' => fmts.push(write_hex_words),
                'o' => fmts.push(write_oct_words),
                _ => println!("-{}: unrecognised option", opt),
            }
        }
        idx += 1;
    }

    // If no output formats have been specified, default to octal words.
    if fmts.is_empty() {
        fmts.push(write_oct_words);
    }

    let mut filename = String::from("-");
    if args.len() > idx {
        if args[idx].starts_with('+') {
            offstr = &args[idx][..];
        } else {
            filename = String::from(&args[idx][..]);
            idx += 1;
        }
    }

    if args.len() > idx {
        offstr = &args[idx][..];
    }

    match parse_offset(&offstr) {
        Ok(off) => offset = off,
        Err(e) => println!("{}: {}", offstr, e)
    }

    match od(&filename, offset, &fmts) {
        Ok(_) => std::process::exit(0),
        Err(e) => {
            eprintln!("Error: {}", e);
            std::process::exit(1)
        }
    }
}
<commit_msg>Use underscore pattern instead of variable.<commit_after>// Copyright 2016-2018 James Bostock. See the LICENSE file at the top-level
// directory of this distribution.

// An implementation of the od(1) command in Rust.
// See http://man.cat-v.org/unix-6th/1/od
use std::env;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Stdout;
use std::io::Write;
use std::num::ParseIntError;

mod util;

/// Writes a chunk of output data as octal byte values.
fn write_oct_bytes(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for byte in data {
        write!(out, " {:03o}", byte)?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as octal (16 bit) word values. Words are
/// assumed to be little endian.
fn write_oct_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06o}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as decimal (16 bit) word values. Words are
/// assumed to be little endian.
fn write_dec_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of output data as hexadecimal (16 bit) word values. Words
/// are assumed to be little endian.
fn write_hex_words(out: &mut BufWriter<Stdout>, data: &[u8])
                   -> io::Result<usize> {
    for word in data.chunks(2) {
        write!(out, "  {:06x}", u16::from(word[1]) << 8 | u16::from(word[0]))?;
    }
    writeln!(out)?;
    Ok(data.len())
}

/// Writes a chunk of data as ASCII, reverting to octal byte values for
/// non-printable characters. Standard escape sequences are supported.
fn write_ascii_chars(out: &mut BufWriter<Stdout>, data: &[u8])
                     -> io::Result<usize> {
    for byte in data {
        match *byte {
            7u8 => write!(out, " \\g")?,
            8u8 => write!(out, " \\b")?,
            9u8 => write!(out, " \\t")?,
            10u8 => write!(out, " \\n")?,
            11u8 => write!(out, " \\v")?,
            12u8 => write!(out, " \\f")?,
            13u8 => write!(out, " \\r")?,
            _ => if *byte < 32u8 || *byte > 126u8 {
                write!(out, " {:03o}", *byte)?
            } else {
                write!(out, "   {}", *byte as char)?
            }
        }
    }
    writeln!(out)?;
    Ok(data.len())
}

const CHUNK_SIZE: usize = 16;

// The offset string is of the form [+]offset[.][b]
// +100 => 0o100
// +100. => 100
// +100b => 0o100 * 512
// +100.b => 100 * 512
fn parse_offset(offstr: &str) -> Result<u64, ParseIntError> {
    let mut char_indices = offstr.char_indices().rev();
    let mut mult = 1;
    let (s, r) = match char_indices.next() {
        Some((x, 'b')) => {
            mult = 512;
            match char_indices.next() {
                Some((y, '.')) => (&offstr[0..y], 10),
                Some((_, _)) => (&offstr[0..x], 8),
                None => (&offstr[0..0], 8)
            }
        },
        Some((x, '.')) => (&offstr[0..x], 10),
        Some((_, _)) => (&offstr[..], 8),
        None => (&offstr[0..0], 8)
    };

    match u64::from_str_radix(s, r) {
        Ok(n) => Ok(n * mult),
        Err(e) => Err(e)
    }
}

#[test]
fn test_parse_offset() {
    match parse_offset("100") {
        Ok(off) => assert!(off == 0o100),
        Err(_) => assert!(false)
    }

    match parse_offset("100.") {
        Ok(off) => assert!(off == 100),
        Err(_) => assert!(false)
    }

    match parse_offset("100b") {
        Ok(off) => assert!(off == 0o100 * 512),
        Err(_) => assert!(false)
    }

    match parse_offset("100.b") {
        Ok(off) => assert!(off == 100 * 512),
        Err(_) => assert!(false)
    }
}

/// Dumps the data read from the named input source to the standard output.
fn od(filename: &str, offset: u64,
      fmts: &[fn(&mut BufWriter<Stdout>,&[u8]) -> io::Result<usize>])
      -> io::Result<u64> {
    let mut reader = BufReader::new(util::Input::open(filename)?);
    let mut writer = BufWriter::new(io::stdout());
    let mut offset = offset;

    if offset > 0 {
        reader.seek(SeekFrom::Start(offset))?;
    }

    let mut chunk = [0; CHUNK_SIZE];
    loop {
        let n = reader.read(&mut chunk)?;
        if n > 0 {
            let mut first = true;
            for fmt in fmts.iter() {
                if first {
                    write!(writer, "{:07o}", offset)?;
                    first = false;
                } else {
                    write!(writer, "       ")?;
                }
                fmt(&mut writer, &chunk)?;
                offset += chunk.len() as u64;
            }
        }

        if n < CHUNK_SIZE {
            break
        }
    }
    writeln!(writer, "{:07o}", offset)?;
    Ok(offset)
}

fn main() {
    let args: Vec<_> = env::args().skip(1).collect();
    let mut idx = 0;
    let mut offset : u64 = 0;
    let mut offstr = "0";
    let mut fmts: Vec<fn(&mut BufWriter<Stdout>, &[u8]) -> io::Result<usize>> = Vec::new();

    if args.len() > idx && args[idx].starts_with('-') {
        for opt in args[idx].chars().skip(1) {
            match opt {
                'b' => fmts.push(write_oct_bytes),
                'c' => fmts.push(write_ascii_chars),
                'd' => fmts.push(write_dec_words),
                'h' => fmts.push(write_hex_words),
                'o' => fmts.push(write_oct_words),
                _ => println!("-{}: unrecognised option", opt),
            }
        }
        idx += 1;
    }

    // If no output formats have been specified, default to octal words.
    if fmts.is_empty() {
        fmts.push(write_oct_words);
    }

    let mut filename = String::from("-");
    if args.len() > idx {
        if args[idx].starts_with('+') {
            offstr = &args[idx][..];
        } else {
            filename = String::from(&args[idx][..]);
            idx += 1;
        }
    }

    if args.len() > idx {
        offstr = &args[idx][..];
    }

    match parse_offset(&offstr) {
        Ok(off) => offset = off,
        Err(e) => println!("{}: {}", offstr, e)
    }

    match od(&filename, offset, &fmts) {
        Ok(_) => std::process::exit(0),
        Err(e) => {
            eprintln!("Error: {}", e);
            std::process::exit(1)
        }
    }
}
<|endoftext|>


<commit_before>use hyper::Client;
use hyper::client::Body;
use hyper::client::response::Response;
use disco;
use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::{ Decodable, Encodable };
use errors::HueError;
use errors::AppError;
use regex::Regex;

#[derive(Show,Copy,Clone,RustcDecodable)]
pub struct LightState {
    pub on: bool,
    pub bri: u8,
    pub hue: u16,
    pub sat: u8
}

#[derive(Show,Clone,RustcDecodable)]
pub struct Light {
    pub name: String,
    pub modelid: String,
    pub swversion: String,
    pub uniqueid: String,
    pub state: LightState,
}

#[derive(Show,Clone)]
pub struct IdentifiedLight {
    pub id: usize,
    pub light: Light,
}

#[derive(Show,Clone,Copy,RustcEncodable,RustcDecodable)]
pub struct CommandLight {
    pub on:Option<bool>,
    pub bri:Option<u8>,
    pub hue:Option<u16>,
    pub sat:Option<u8>,
    pub transitiontime:Option<u16>,
}

impl CommandLight {
    pub fn empty() -> CommandLight {
        CommandLight { on:None, bri:None, hue:None, sat:None, transitiontime:None }
    }
    pub fn on() -> CommandLight {
        CommandLight { on:Some(true), ..CommandLight::empty() }
    }
    pub fn off() -> CommandLight {
        CommandLight { on:Some(false), ..CommandLight::empty() }
    }
}

#[derive(Show)]
pub struct Bridge {
    ip: String,
    username: Option<String>,
}

impl Bridge {
    #[allow(dead_code)]
    pub fn discover() -> Option<Bridge> {
        disco::discover_hue_bridge().ok().map( |i| Bridge{ ip:i, username:None } )
    }

    pub fn discover_required() -> Bridge {
        Bridge::discover().unwrap_or_else( || panic!("No bridge found!") )
    }

    pub fn with_user(self, username:String) -> Bridge {
        Bridge{ username: Some(username), ..self }
    }

    pub fn register_user(&self, devicetype:&str, username:&str) -> Result<Json,HueError> {
        if username.len() < 10 || username.len() > 40 {
            return HueError::wrap("username must be between 10 and 40 characters")
        }
        #[derive(RustcDecodable, RustcEncodable)]
        struct PostApi {
            devicetype: String,
            username:String
        }
        let obtain = PostApi {
            devicetype:devicetype.to_string(),
            username:username.to_string()
        };
        let body = try!(json::encode(&obtain));
        let mut client = Client::new();
        let url = format!("http://{}/api", self.ip);
        let mut resp = try!(client.post(url.as_slice())
            .body(Body::BufBody(body.as_bytes(), body.as_bytes().len())).send());
        self.parse_write_resp(&mut resp)
    }

    pub fn get_all_lights(&self) -> Result<Vec<IdentifiedLight>,HueError> {
        let url = format!("http://{}/api/{}/lights",
            self.ip, self.username.clone().unwrap());
        let mut client = Client::new();
        let mut resp = try!(client.get(url.as_slice()).send());
        let json = try!(::tools::from_reader(&mut resp));
        let lights:Vec<Result<IdentifiedLight,json::DecoderError>> = json.as_object().unwrap().iter().map( |(k,v)| {
            let mut decoder = json::Decoder::new(v.clone());
            <Light as Decodable>::decode(&mut decoder).map( |l|
                IdentifiedLight{ id: k.parse().unwrap(), light: l }
            )
        }).collect();
        for ref l in lights.iter().cloned() {
            match l {
                &Err(ref e) => {
                    return Err(HueError::JsonDecoderError(e.clone()));
                }
                &Ok(ref _l) => ()
            }
        }
        let mut v:Vec<IdentifiedLight> = lights.iter().cloned().map( |l| l.unwrap() ).collect();
        v.sort_by( |a,b| a.id.cmp(&b.id) );
        Ok(v)
    }

    pub fn set_light_state(&self, light:usize, command:CommandLight) -> Result<Json, HueError> {
        let url = format!("http://{}/api/{}/lights/{}/state",
            self.ip, self.username.clone().unwrap(), light);
        let body = try!(json::encode(&command));
        let re1 = Regex::new("\"[a-z]*\":null").unwrap();
        let cleaned1 = re1.replace_all(body.as_slice(),"");
        let re2 = Regex::new(",+").unwrap();
        let cleaned2 = re2.replace_all(cleaned1.as_slice(),",");
        let re3 = Regex::new(",\\}").unwrap();
        let cleaned3 = re3.replace_all(cleaned2.as_slice(),"}");
        let re3 = Regex::new("\\{,").unwrap();
        let cleaned4 = re3.replace_all(cleaned3.as_slice(),"{");
        let mut client = Client::new();
        let mut resp = try!(client.put(url.as_slice())
            .body(Body::BufBody(cleaned4.as_bytes(), cleaned4.as_bytes().len())).send());
        self.parse_write_resp(&mut resp)
    }

    fn parse_write_resp(&self, resp:&mut Response) -> Result<Json,HueError> {
        let json = try!(::tools::from_reader(resp));
        let objects = try!(json.as_array()
            .ok_or(HueError::Error("expected array".to_string())));
        if objects.len() == 0 {
            return HueError::wrap("expected non-empty array");
        }
        let object = try!(objects[0].as_object()
            .ok_or(HueError::Error("expected first item to be an object".to_string())));
        let obj = object.get(&"error".to_string()).and_then( |o| o.as_object() );
        match obj {
            Some(e) => {
                let error = e.clone();
                let mut decoder = json::Decoder::new(json::Json::Object(error));
                let actual_error = AppError::dec(&mut decoder).ok().unwrap();
                //println!("actual: {:?}",actual_error);
                Err(HueError::BridgeError(actual_error))
            },
            None => Ok(json.clone())
        }
    }
}

<commit_msg>breaking something to test travis notifs<commit_after>use hyper::Client;
use hyper::client::Body;
use hyper::client::response::Response;
use disco;
use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::{ Decodable, Encodable };
use errors::HueError;
use errors::AppError;
use regex::Regex;

just breaking something

#[derive(Show,Copy,Clone,RustcDecodable)]
pub struct LightState {
    pub on: bool,
    pub bri: u8,
    pub hue: u16,
    pub sat: u8
}

#[derive(Show,Clone,RustcDecodable)]
pub struct Light {
    pub name: String,
    pub modelid: String,
    pub swversion: String,
    pub uniqueid: String,
    pub state: LightState,
}

#[derive(Show,Clone)]
pub struct IdentifiedLight {
    pub id: usize,
    pub light: Light,
}

#[derive(Show,Clone,Copy,RustcEncodable,RustcDecodable)]
pub struct CommandLight {
    pub on:Option<bool>,
    pub bri:Option<u8>,
    pub hue:Option<u16>,
    pub sat:Option<u8>,
    pub transitiontime:Option<u16>,
}

impl CommandLight {
    pub fn empty() -> CommandLight {
        CommandLight { on:None, bri:None, hue:None, sat:None, transitiontime:None }
    }
    pub fn on() -> CommandLight {
        CommandLight { on:Some(true), ..CommandLight::empty() }
    }
    pub fn off() -> CommandLight {
        CommandLight { on:Some(false), ..CommandLight::empty() }
    }
}

#[derive(Show)]
pub struct Bridge {
    ip: String,
    username: Option<String>,
}

impl Bridge {
    #[allow(dead_code)]
    pub fn discover() -> Option<Bridge> {
        disco::discover_hue_bridge().ok().map( |i| Bridge{ ip:i, username:None } )
    }

    pub fn discover_required() -> Bridge {
        Bridge::discover().unwrap_or_else( || panic!("No bridge found!") )
    }

    pub fn with_user(self, username:String) -> Bridge {
        Bridge{ username: Some(username), ..self }
    }

    pub fn register_user(&self, devicetype:&str, username:&str) -> Result<Json,HueError> {
        if username.len() < 10 || username.len() > 40 {
            return HueError::wrap("username must be between 10 and 40 characters")
        }
        #[derive(RustcDecodable, RustcEncodable)]
        struct PostApi {
            devicetype: String,
            username:String
        }
        let obtain = PostApi {
            devicetype:devicetype.to_string(),
            username:username.to_string()
        };
        let body = try!(json::encode(&obtain));
        let mut client = Client::new();
        let url = format!("http://{}/api", self.ip);
        let mut resp = try!(client.post(url.as_slice())
            .body(Body::BufBody(body.as_bytes(), body.as_bytes().len())).send());
        self.parse_write_resp(&mut resp)
    }

    pub fn get_all_lights(&self) -> Result<Vec<IdentifiedLight>,HueError> {
        let url = format!("http://{}/api/{}/lights",
            self.ip, self.username.clone().unwrap());
        let mut client = Client::new();
        let mut resp = try!(client.get(url.as_slice()).send());
        let json = try!(::tools::from_reader(&mut resp));
        let lights:Vec<Result<IdentifiedLight,json::DecoderError>> = json.as_object().unwrap().iter().map( |(k,v)| {
            let mut decoder = json::Decoder::new(v.clone());
            <Light as Decodable>::decode(&mut decoder).map( |l|
                IdentifiedLight{ id: k.parse().unwrap(), light: l }
            )
        }).collect();
        for ref l in lights.iter().cloned() {
            match l {
                &Err(ref e) => {
                    return Err(HueError::JsonDecoderError(e.clone()));
                }
                &Ok(ref _l) => ()
            }
        }
        let mut v:Vec<IdentifiedLight> = lights.iter().cloned().map( |l| l.unwrap() ).collect();
        v.sort_by( |a,b| a.id.cmp(&b.id) );
        Ok(v)
    }

    pub fn set_light_state(&self, light:usize, command:CommandLight) -> Result<Json, HueError> {
        let url = format!("http://{}/api/{}/lights/{}/state",
            self.ip, self.username.clone().unwrap(), light);
        let body = try!(json::encode(&command));
        let re1 = Regex::new("\"[a-z]*\":null").unwrap();
        let cleaned1 = re1.replace_all(body.as_slice(),"");
        let re2 = Regex::new(",+").unwrap();
        let cleaned2 = re2.replace_all(cleaned1.as_slice(),",");
        let re3 = Regex::new(",\\}").unwrap();
        let cleaned3 = re3.replace_all(cleaned2.as_slice(),"}");
        let re3 = Regex::new("\\{,").unwrap();
        let cleaned4 = re3.replace_all(cleaned3.as_slice(),"{");
        let mut client = Client::new();
        let mut resp = try!(client.put(url.as_slice())
            .body(Body::BufBody(cleaned4.as_bytes(), cleaned4.as_bytes().len())).send());
        self.parse_write_resp(&mut resp)
    }

    fn parse_write_resp(&self, resp:&mut Response) -> Result<Json,HueError> {
        let json = try!(::tools::from_reader(resp));
        let objects = try!(json.as_array()
            .ok_or(HueError::Error("expected array".to_string())));
        if objects.len() == 0 {
            return HueError::wrap("expected non-empty array");
        }
        let object = try!(objects[0].as_object()
            .ok_or(HueError::Error("expected first item to be an object".to_string())));
        let obj = object.get(&"error".to_string()).and_then( |o| o.as_object() );
        match obj {
            Some(e) => {
                let error = e.clone();
                let mut decoder = json::Decoder::new(json::Json::Object(error));
                let actual_error = AppError::dec(&mut decoder).ok().unwrap();
                //println!("actual: {:?}",actual_error);
                Err(HueError::BridgeError(actual_error))
            },
            None => Ok(json.clone())
        }
    }
}

<|endoftext|>