diff options
| author | Jokler <jokler.contact@gmail.com> | 2019-06-22 15:51:21 +0200 |
|---|---|---|
| committer | Jokler <jokler.contact@gmail.com> | 2019-06-22 15:51:21 +0200 |
| commit | 3592c7b6fb2522ff57c7f312b8927eb680d6dc5c (patch) | |
| tree | d484a367c205afe43ba7327a888b06844fd24c0c /src/plugins/factoids/mod.rs | |
| parent | 237f6ebe59c90d4ceddd9af6a8a19e562d304aaa (diff) | |
| parent | a92e622a0d42911e8e46239c3bde17169ed60c92 (diff) | |
| download | frippy-3592c7b6fb2522ff57c7f312b8927eb680d6dc5c.tar.gz frippy-3592c7b6fb2522ff57c7f312b8927eb680d6dc5c.zip | |
Diffstat (limited to 'src/plugins/factoids/mod.rs')
| -rw-r--r-- | src/plugins/factoids/mod.rs | 342 |
1 files changed, 0 insertions, 342 deletions
diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs deleted file mode 100644 index 2f3690f..0000000 --- a/src/plugins/factoids/mod.rs +++ /dev/null @@ -1,342 +0,0 @@ -extern crate rlua; - -use std::fmt; -use std::str::FromStr; -use std::sync::Mutex; -use self::rlua::prelude::*; -use irc::client::prelude::*; - -use time; -use chrono::NaiveDateTime; - -use plugin::*; -pub mod database; -use self::database::Database; - -mod utils; -use self::utils::*; - -use failure::ResultExt; -use error::ErrorKind as FrippyErrorKind; -use error::FrippyError; -use self::error::*; - -static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); - -#[derive(PluginName)] -pub struct Factoids<T: Database> { - factoids: Mutex<T>, -} - -macro_rules! try_lock { - ( $m:expr ) => { - match $m.lock() { - Ok(guard) => guard, - Err(poisoned) => poisoned.into_inner(), - } - } -} - -impl<T: Database> Factoids<T> { - pub fn new(db: T) -> Factoids<T> { - Factoids { - factoids: Mutex::new(db), - } - } - - fn create_factoid( - &self, - name: &str, - content: &str, - author: &str, - ) -> Result<&str, FactoidsError> { - let count = try_lock!(self.factoids).count_factoids(name)?; - let tm = time::now().to_timespec(); - - let factoid = database::NewFactoid { - name: name, - idx: count, - content: content, - author: author, - created: NaiveDateTime::from_timestamp(tm.sec, 0u32), - }; - - Ok(try_lock!(self.factoids) - .insert_factoid(&factoid) - .map(|()| "Successfully added!")?) - } - - fn add(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { - if command.tokens.len() < 2 { - Err(ErrorKind::InvalidCommand)?; - } - - let name = command.tokens.remove(0); - let content = command.tokens.join(" "); - - Ok(self.create_factoid(&name, &content, &command.source)?) - } - - fn add_from_url(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { - if command.tokens.len() < 2 { - Err(ErrorKind::InvalidCommand)?; - } - - let name = command.tokens.remove(0); - let url = &command.tokens[0]; - let content = ::utils::download(url, Some(1024)).context(ErrorKind::Download)?; - - Ok(self.create_factoid(&name, &content, &command.source)?) - } - - fn remove(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { - if command.tokens.len() < 1 { - Err(ErrorKind::InvalidCommand)?; - } - - let name = command.tokens.remove(0); - let count = try_lock!(self.factoids).count_factoids(&name)?; - - match try_lock!(self.factoids).delete_factoid(&name, count - 1) { - Ok(()) => Ok("Successfully removed"), - Err(e) => Err(e)?, - } - } - - fn get(&self, command: &PluginCommand) -> Result<String, FactoidsError> { - let (name, idx) = match command.tokens.len() { - 0 => Err(ErrorKind::InvalidCommand)?, - 1 => { - let name = &command.tokens[0]; - let count = try_lock!(self.factoids).count_factoids(name)?; - - if count < 1 { - Err(ErrorKind::NotFound)?; - } - - (name, count - 1) - } - _ => { - let name = &command.tokens[0]; - let idx = match i32::from_str(&command.tokens[1]) { - Ok(i) => i, - Err(_) => Err(ErrorKind::InvalidCommand)?, - }; - - (name, idx) - } - }; - - let factoid = try_lock!(self.factoids) - .get_factoid(name, idx) - .context(ErrorKind::NotFound)?; - - let message = factoid.content.replace("\n", "|").replace("\r", ""); - - Ok(format!("{}: {}", factoid.name, message)) - } - - fn info(&self, command: &PluginCommand) -> Result<String, FactoidsError> { - match command.tokens.len() { - 0 => Err(ErrorKind::InvalidCommand)?, - 1 => { - let name = &command.tokens[0]; - let count = try_lock!(self.factoids).count_factoids(name)?; - - Ok(match count { - 0 => Err(ErrorKind::NotFound)?, - 1 => format!("There is 1 version of {}", name), - _ => format!("There are {} versions of {}", count, name), - }) - } - _ => { - let name = &command.tokens[0]; - let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?; - let factoid = try_lock!(self.factoids).get_factoid(name, idx)?; - - Ok(format!( - "{}: Added by {} at {} UTC", - name, factoid.author, factoid.created - )) - } - } - } - - fn exec(&self, mut command: PluginCommand) -> Result<String, FactoidsError> { - if command.tokens.len() < 1 { - Err(ErrorKind::InvalidIndex)? - } else { - let name = command.tokens.remove(0); - let count = try_lock!(self.factoids).count_factoids(&name)?; - let factoid = try_lock!(self.factoids).get_factoid(&name, count - 1)?; - - let content = factoid.content; - let value = if content.starts_with('>') { - let content = String::from(&content[1..]); - - if content.starts_with('>') { - content - } else { - match self.run_lua(&name, &content, &command) { - Ok(v) => v, - Err(e) => format!("\"{}\"", e), - } - } - } else { - content - }; - - Ok(value.replace("\n", "|").replace("\r", "")) - } - } - - fn run_lua( - &self, - name: &str, - code: &str, - command: &PluginCommand, - ) -> Result<String, rlua::Error> { - let args = command - .tokens - .iter() - .filter(|x| !x.is_empty()) - .map(ToOwned::to_owned) - .collect::<Vec<String>>(); - - let lua = unsafe { Lua::new_with_debug() }; - let globals = lua.globals(); - - globals.set("factoid", code)?; - globals.set("download", lua.create_function(download)?)?; - globals.set("sleep", lua.create_function(sleep)?)?; - globals.set("args", args)?; - globals.set("input", command.tokens.join(" "))?; - globals.set("user", command.source.clone())?; - globals.set("channel", command.target.clone())?; - globals.set("output", lua.create_table()?)?; - - lua.exec::<()>(LUA_SANDBOX, Some(name))?; - let output: Vec<String> = globals.get::<_, Vec<String>>("output")?; - - Ok(output.join("|")) - } -} - -impl<T: Database> Plugin for Factoids<T> { - fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus { - match message.command { - Command::PRIVMSG(_, ref content) => if content.starts_with('!') { - ExecutionStatus::RequiresThread - } else { - ExecutionStatus::Done - }, - _ => ExecutionStatus::Done, - } - } - - fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> { - if let Command::PRIVMSG(_, mut content) = message.command.clone() { - content.remove(0); - - let t: Vec<String> = content.split(' ').map(ToOwned::to_owned).collect(); - - let c = PluginCommand { - source: message.source_nickname().unwrap().to_owned(), - target: message.response_target().unwrap().to_owned(), - tokens: t, - }; - - Ok(match self.exec(c) { - Ok(f) => client - .send_privmsg(&message.response_target().unwrap(), &f) - .context(FrippyErrorKind::Connection)?, - Err(_) => (), - }) - } else { - Ok(()) - } - } - - fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), FrippyError> { - if command.tokens.is_empty() { - return Ok(client - .send_notice(&command.target, "Invalid command") - .context(FrippyErrorKind::Connection)?); - } - - let target = command.target.clone(); - let source = command.source.clone(); - - let sub_command = command.tokens.remove(0); - let result = match sub_command.as_ref() { - "add" => self.add(&mut command).map(|s| s.to_owned()), - "fromurl" => self.add_from_url(&mut command).map(|s| s.to_owned()), - "remove" => self.remove(&mut command).map(|s| s.to_owned()), - "get" => self.get(&command), - "info" => self.info(&command), - "exec" => self.exec(command), - _ => Err(ErrorKind::InvalidCommand.into()), - }; - - Ok(match result { - Ok(v) => client - .send_privmsg(&target, &v) - .context(FrippyErrorKind::Connection)?, - Err(e) => { - let message = e.to_string(); - client - .send_notice(&source, &message) - .context(FrippyErrorKind::Connection)?; - Err(e).context(FrippyErrorKind::Factoids)? - } - }) - } - - fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result<String, String> { - Err(String::from( - "Evaluation of commands is not implemented for Factoids at this time", - )) - } -} - -impl<T: Database> fmt::Debug for Factoids<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Factoids {{ ... }}") - } -} - -pub mod error { - #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] - #[error = "FactoidsError"] - pub enum ErrorKind { - /// Invalid command error - #[fail(display = "Invalid Command")] - InvalidCommand, - - /// Invalid index error - #[fail(display = "Invalid index")] - InvalidIndex, - - /// Download error - #[fail(display = "Download failed")] - Download, - - /// Duplicate error - #[fail(display = "Entry already exists")] - Duplicate, - - /// Not found error - #[fail(display = "Factoid was not found")] - NotFound, - - /// MySQL error - #[cfg(feature = "mysql")] - #[fail(display = "Failed to execute MySQL Query")] - MysqlError, - - /// No connection error - #[cfg(feature = "mysql")] - #[fail(display = "No connection to the database")] - NoConnection, - } -} |
