<commit_before>use LalafellBot;
use config::Listener;
use listeners::ReceivesEvents;
use discord::model::{Event, Channel, ReactionEmoji};

use xivdb::error::*;

use serde_json;

use std::sync::Arc;

pub struct ReactionAuthorize {
  bot: Arc<LalafellBot>,
  config: ReactionAuthorizeConfig
}

impl ReactionAuthorize {
  pub fn new(bot: Arc<LalafellBot>, listener: &Listener) -> Result<ReactionAuthorize> {
    let config = match listener.config {
      Some(ref c) => serde_json::from_value(c.clone()).chain_err(|| "could not parse reaction_authorize configuration")?,
      None => return Err("missing configuration for reaction_authorize listener".into())
    };
    Ok(ReactionAuthorize {
      bot: bot,
      config: config
    })
  }
}

impl ReceivesEvents for ReactionAuthorize {
  fn receive(&self, event: &Event) {
    let (added, reaction) = match *event {
      Event::ReactionAdd(ref reaction) => (true, reaction),
      Event::ReactionRemove(ref reaction) => (false, reaction),
      _ => return
    };
    let channel = match self.bot.discord.get_channel(reaction.channel_id) {
      Ok(Channel::Public(c)) => c,
      Ok(_) => {
        warn!("invalid channel: {}", reaction.channel_id.0);
        return;
      },
      Err(e) => {
        warn!("couldn't get channel: {}", e);
        return;
      }
    };
    match reaction.emoji {
      ReactionEmoji::Unicode(ref emoji) if *emoji == self.config.emoji => {},
      _ => return
    }
    let roles = match self.bot.discord.get_roles(channel.server_id) {
      Ok(r) => r,
      Err(e) => {
        warn!("couldn't get roles: {}", e);
        return;
      }
    };
    let role = match roles.iter().filter(|r| r.name == self.config.role).next() {
      Some(r) => r,
      None => {
        warn!("couldn't find role for name \"{}\"", self.config.role);
        return;
      }
    };
    let result = if added {
      self.bot.discord.add_user_to_role(channel.server_id, reaction.user_id, role.id)
    } else {
      self.bot.discord.remove_user_from_role(channel.server_id, reaction.user_id, role.id)
    };
    if let Err(e) = result {
      warn!("could not change role: {}", e);
    }
  }
}

#[derive(Debug, Deserialize)]
pub struct ReactionAuthorizeConfig {
  message: u64,
  emoji: String,
  role: String
}
<commit_msg>refactor: use find instead of filter, next<commit_after>use LalafellBot;
use config::Listener;
use listeners::ReceivesEvents;
use discord::model::{Event, Channel, ReactionEmoji};

use xivdb::error::*;

use serde_json;

use std::sync::Arc;

pub struct ReactionAuthorize {
  bot: Arc<LalafellBot>,
  config: ReactionAuthorizeConfig
}

impl ReactionAuthorize {
  pub fn new(bot: Arc<LalafellBot>, listener: &Listener) -> Result<ReactionAuthorize> {
    let config = match listener.config {
      Some(ref c) => serde_json::from_value(c.clone()).chain_err(|| "could not parse reaction_authorize configuration")?,
      None => return Err("missing configuration for reaction_authorize listener".into())
    };
    Ok(ReactionAuthorize {
      bot: bot,
      config: config
    })
  }
}

impl ReceivesEvents for ReactionAuthorize {
  fn receive(&self, event: &Event) {
    let (added, reaction) = match *event {
      Event::ReactionAdd(ref reaction) => (true, reaction),
      Event::ReactionRemove(ref reaction) => (false, reaction),
      _ => return
    };
    let channel = match self.bot.discord.get_channel(reaction.channel_id) {
      Ok(Channel::Public(c)) => c,
      Ok(_) => {
        warn!("invalid channel: {}", reaction.channel_id.0);
        return;
      },
      Err(e) => {
        warn!("couldn't get channel: {}", e);
        return;
      }
    };
    match reaction.emoji {
      ReactionEmoji::Unicode(ref emoji) if *emoji == self.config.emoji => {},
      _ => return
    }
    let roles = match self.bot.discord.get_roles(channel.server_id) {
      Ok(r) => r,
      Err(e) => {
        warn!("couldn't get roles: {}", e);
        return;
      }
    };
    let role = match roles.iter().find(|r| r.name == self.config.role) {
      Some(r) => r,
      None => {
        warn!("couldn't find role for name \"{}\"", self.config.role);
        return;
      }
    };
    let result = if added {
      self.bot.discord.add_user_to_role(channel.server_id, reaction.user_id, role.id)
    } else {
      self.bot.discord.remove_user_from_role(channel.server_id, reaction.user_id, role.id)
    };
    if let Err(e) = result {
      warn!("could not change role: {}", e);
    }
  }
}

#[derive(Debug, Deserialize)]
pub struct ReactionAuthorizeConfig {
  message: u64,
  emoji: String,
  role: String
}

{'fraction_non_alphanumeric': 0.1490238611713666, 'fraction_numerical': 0.0013015184381778742, 'mean_word_length': 2.975, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5983496', 'n_tokens_mistral': 1522, 'n_tokens_neox': 1525, 'n_words': 330}