summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2017-12-16 18:13:02 +0100
committerJokler <jokler.contact@gmail.com>2017-12-24 01:24:58 +0100
commit4b5693d3c6781a5ca4ef32f43f3994a65020c933 (patch)
treefcea35b595542661d1f6713d860d647832aabd47
parent5928afc3bf83661cd3b11130a31a2d97ef135a9e (diff)
downloadfrippy-4b5693d3c6781a5ca4ef32f43f3994a65020c933.tar.gz
frippy-4b5693d3c6781a5ca4ef32f43f3994a65020c933.zip
Add more info to factoids and save old versions
-rw-r--r--Cargo.lock78
-rw-r--r--Cargo.toml19
-rw-r--r--bin/main.rs30
-rw-r--r--migrations/.gitkeep0
-rw-r--r--migrations/2017-11-03-164322_create_factoids/up.sql8
-rw-r--r--src/lib.rs9
-rw-r--r--src/plugins/factoids/database.rs120
-rw-r--r--src/plugins/factoids/mod.rs146
8 files changed, 322 insertions, 88 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 91693d5..936d8a4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -220,32 +220,40 @@ dependencies = [
[[package]]
name = "diesel"
-version = "0.16.0"
+version = "1.0.0-rc1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel_derives 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
"mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "diesel_codegen"
-version = "0.16.0"
+name = "diesel_derives"
+version = "1.0.0-rc1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "diesel_infer_schema"
-version = "0.16.0"
+version = "1.0.0-rc1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "infer_schema_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "diesel_migrations"
+version = "1.0.0-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "migrations_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -350,9 +358,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "frippy"
version = "0.3.1"
dependencies = [
+ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)",
- "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel_infer_schema 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel_migrations 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
"dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frippy_derive 0.1.0",
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -503,6 +513,25 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "infer_schema_internals"
+version = "1.0.0-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "infer_schema_macros"
+version = "1.0.0-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "infer_schema_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "iovec"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -629,6 +658,24 @@ dependencies = [
]
[[package]]
+name = "migrations_internals"
+version = "1.0.0-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "migrations_macros"
+version = "1.0.0-rc1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "mime"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1389,9 +1436,10 @@ dependencies = [
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a"
-"checksum diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "304226fa7a3982b0405f6bb95dd9c10c3e2000709f194038a60ec2c277150951"
-"checksum diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a42ca5c9b660add51d58bc5a50a87123380e1e458069c5504528a851ed7384"
-"checksum diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1957ff5cd3b04772e43c162c2f69c2aa918080ff9b020276792d236be8be52"
+"checksum diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b9e512c7fbcc7240848252ff620ed5f0e996e25d5c694b2b535d27db7465c6"
+"checksum diesel_derives 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "a631faea061a7b5ab85e842866da57dbc31cc5fe715397a5e5a5b0effd7146b9"
+"checksum diesel_infer_schema 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cee2c5104f0258a4461c4c8694e870161cb974f4de8609fae3d496e26336590"
+"checksum diesel_migrations 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "e1fd168d237ae0bd9e8bfdcb82ba87a4b72e4c1d9edd864242a67149c7f3c960"
"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
@@ -1419,6 +1467,8 @@ dependencies = [
"checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
+"checksum infer_schema_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2af8e23352c51aff14633500bfff361e9ea310375044b40dd8939e2defccd5c"
+"checksum infer_schema_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa05e92983b3f9af1e7508f7d4981452542d505640d1b328fe74f4466c82b953"
"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7"
"checksum irc 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c5053c25509042e963baa67d0d648add9f72b7487784505a5d5a3054d136a615"
"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
@@ -1435,6 +1485,8 @@ dependencies = [
"checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
+"checksum migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "c39531d07a48b5920d19310f9ba644667aac56edd933a6e7649893551756ad50"
+"checksum migrations_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "12d6c72b7dae5fb40009c6313ef5a2075aa25f479a8a51f6a487abef887a7a2c"
"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd"
"checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495"
"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb"
diff --git a/Cargo.toml b/Cargo.toml
index 5ff779f..5f535e4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,7 @@ path = "bin/main.rs"
doc = false
[features]
-mysql = ["diesel", "diesel_codegen", "dotenv"]
+mysql = ["diesel", "diesel_infer_schema", "diesel_migrations", "dotenv"]
[dependencies]
irc = "0.12.5"
@@ -27,13 +27,14 @@ tokio-core = "0.1.10"
futures = "0.1.16"
log = "0.3.8"
time = "0.1"
-rlua = "0.9.2"
+rlua = "0.9.3"
reqwest = "0.8.0"
select = "0.4.2"
regex = "0.2.2"
lazy_static = "0.2.9"
serde = "1.0.15"
serde_json = "1.0.3"
+chrono = "0.4.0"
glob = "0.2"
frippy_derive = { path = "frippy_derive" }
@@ -42,13 +43,19 @@ frippy_derive = { path = "frippy_derive" }
git = 'https://github.com/Jokler/unicode_names'
branch = 'update-to-latest-unicode'
+
[dependencies.diesel]
-version = "0.16.0"
+version = "1.0.0-beta1"
+optional = true
+features = ["mysql", "chrono"]
+
+[dependencies.diesel_infer_schema]
+version = "1.0.0-beta1"
optional = true
features = ["mysql"]
-[dependencies.diesel_codegen]
-version = "0.16.0"
+[dependencies.diesel_migrations]
+version = "1.0.0-beta1"
optional = true
features = ["mysql"]
@@ -58,4 +65,4 @@ optional = true
[dependencies.clippy]
version = "*"
-optional = true \ No newline at end of file
+optional = true
diff --git a/bin/main.rs b/bin/main.rs
index 1597a70..7869548 100644
--- a/bin/main.rs
+++ b/bin/main.rs
@@ -4,9 +4,16 @@ extern crate tokio_core;
extern crate glob;
extern crate futures;
+#[cfg(feature = "mysql")]
+#[macro_use]
+extern crate diesel_migrations;
+#[cfg(feature = "mysql")]
+extern crate diesel;
+
#[macro_use]
extern crate log;
+#[cfg(not(feature = "mysql"))]
use std::collections::HashMap;
use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata};
@@ -18,6 +25,9 @@ use glob::glob;
use frippy::plugins;
use frippy::Config;
+#[cfg(feature = "mysql")]
+embed_migrations!();
+
struct Logger;
impl log::Log for Logger {
@@ -44,7 +54,6 @@ impl log::Log for Logger {
}
fn main() {
-
let log_level = if cfg!(debug_assertions) {
LogLevelFilter::Debug
} else {
@@ -87,7 +96,10 @@ fn main() {
let mut disabled_plugins = None;
if let &Some(ref options) = &config.options {
if let Some(disabled) = options.get("disabled_plugins") {
- disabled_plugins = Some(disabled.split(",").map(|p| p.trim()).collect::<Vec<_>>());
+ disabled_plugins = Some(disabled
+ .split(",")
+ .map(|p| p.trim())
+ .collect::<Vec<_>>());
}
}
@@ -97,8 +109,22 @@ fn main() {
bot.add_plugin(plugins::Emoji::new());
bot.add_plugin(plugins::Currency::new());
bot.add_plugin(plugins::KeepNick::new());
+ #[cfg(feature = "mysql")]
+ {
+ use diesel;
+ use diesel::Connection;
+ match diesel::mysql::MysqlConnection::establish("mysql://user:password@address/db") {
+ Ok(conn) => {
+ embedded_migrations::run(&conn).unwrap();
+ bot.add_plugin(plugins::Factoids::new(conn));
+ }
+ Err(e) => error!("Failed to connect to database: {}", e),
+ }
+ }
+ #[cfg(not(feature = "mysql"))]
bot.add_plugin(plugins::Factoids::new(HashMap::new()));
+
if let Some(disabled_plugins) = disabled_plugins {
for name in disabled_plugins {
if let None = bot.remove_plugin(name) {
diff --git a/migrations/.gitkeep b/migrations/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/migrations/.gitkeep
+++ /dev/null
diff --git a/migrations/2017-11-03-164322_create_factoids/up.sql b/migrations/2017-11-03-164322_create_factoids/up.sql
index 84e9f9d..784a3f4 100644
--- a/migrations/2017-11-03-164322_create_factoids/up.sql
+++ b/migrations/2017-11-03-164322_create_factoids/up.sql
@@ -1,4 +1,8 @@
CREATE TABLE factoids (
- name VARCHAR(32) PRIMARY KEY,
- content VARCHAR(5000) NOT NULL
+ name VARCHAR(32) NOT NULL,
+ idx INTEGER NOT NULL,
+ content TEXT NOT NULL,
+ author VARCHAR(32) NOT NULL,
+ created TIMESTAMP NOT NULL,
+ PRIMARY KEY (name, idx)
)
diff --git a/src/lib.rs b/src/lib.rs
index 1f5514e..4407e6a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -35,8 +35,10 @@
#[macro_use]
extern crate diesel;
#[cfg(feature = "mysql")]
+extern crate diesel_infer_schema;
+#[cfg(feature = "mysql")]
#[macro_use]
-extern crate diesel_codegen;
+extern crate diesel_migrations;
#[macro_use]
extern crate log;
@@ -48,12 +50,15 @@ extern crate frippy_derive;
extern crate irc;
extern crate futures;
extern crate tokio_core;
+extern crate regex;
+extern crate chrono;
+extern crate time;
pub mod plugin;
pub mod plugins;
-use std::fmt;
use std::collections::HashMap;
+use std::fmt;
use std::thread::spawn;
use std::sync::Arc;
diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs
index dbf136c..522c9d0 100644
--- a/src/plugins/factoids/database.rs
+++ b/src/plugins/factoids/database.rs
@@ -9,66 +9,112 @@ use diesel::prelude::*;
#[cfg(feature = "mysql")]
use diesel::mysql::MysqlConnection;
+use chrono::NaiveDateTime;
+
+pub enum DbResponse {
+ Success,
+ Failed(&'static str),
+}
+
+#[cfg_attr(feature = "mysql", derive(Queryable))]
+#[derive(Clone, Debug)]
+pub struct Factoid {
+ pub name: String,
+ pub idx: i32,
+ pub content: String,
+ pub author: String,
+ pub created: NaiveDateTime,
+}
+
+#[cfg_attr(feature = "mysql", derive(Insertable))]
+#[cfg_attr(feature = "mysql", table_name="factoids")]
+pub struct NewFactoid<'a> {
+ pub name: &'a str,
+ pub idx: i32,
+ pub content: &'a str,
+ pub author: &'a str,
+ pub created: NaiveDateTime,
+}
+
+
pub trait Database: Send {
- fn insert(&mut self, name: &str, content: &str) -> Option<()>;
- fn get(&self, name: &str) -> Option<String>;
+ fn insert(&mut self, factoid: &NewFactoid) -> DbResponse;
+ fn get(&self, name: &str, idx: i32) -> Option<Factoid>;
+ fn count(&self, name: &str) -> Result<i32, &'static str>;
}
-impl Database for HashMap<String, String> {
- fn insert(&mut self, name: &str, content: &str) -> Option<()> {
- self.insert(String::from(name), String::from(content)).map(|_| ())
+// HashMap
+impl Database for HashMap<(String, i32), Factoid> {
+ fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
+ let factoid = Factoid {
+ name: String::from(factoid.name),
+ idx: factoid.idx,
+ content: factoid.content.to_string(),
+ author: factoid.author.to_string(),
+ created: factoid.created,
+ };
+
+ let name = String::from(factoid.name.clone());
+ match self.insert((name, factoid.idx), factoid) {
+ None => DbResponse::Success,
+ Some(_) => DbResponse::Failed("Factoid was overwritten"),
+ }
}
- fn get(&self, name: &str) -> Option<String> {
- self.get(name).cloned()
+ fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
+ self.get(&(String::from(name), idx)).map(|f| f.clone())
}
-}
-#[cfg(feature = "mysql")]
-#[derive(Queryable)]
-struct Factoid {
- pub name: String,
- pub content: String,
+ fn count(&self, name: &str) -> Result<i32, &'static str> {
+ Ok(self.iter()
+ .filter(|&(&(ref n, _), _)| n == name)
+ .count() as i32)
+ }
}
+// MySql
#[cfg(feature = "mysql")]
table! {
- factoids (name) {
+ factoids (name, idx) {
name -> Varchar,
- content -> Varchar,
+ idx -> Integer,
+ content -> Text,
+ author -> Varchar,
+ created -> Timestamp,
}
}
#[cfg(feature = "mysql")]
-#[derive(Insertable)]
-#[table_name="factoids"]
-struct NewFactoid<'a> {
- pub name: &'a str,
- pub content: &'a str,
-}
-
-
-#[cfg(feature = "mysql")]
impl Database for MysqlConnection {
- fn insert(&mut self, name: &str, content: &str) -> Option<()> {
- let factoid = NewFactoid {
- name: name,
- content: content,
- };
+ fn insert(&mut self, factoid: &NewFactoid) -> DbResponse {
+ use diesel;
- ::diesel::insert(&factoid)
- .into(factoids::table)
- .execute(self)
- .ok()
- .map(|_| ())
+ match diesel::insert_into(factoids::table)
+ .values(factoid)
+ .execute(self) {
+ Ok(_) => DbResponse::Success,
+ Err(_) => DbResponse::Failed("Database error - possible duplicate"),
+ }
}
- fn get(&self, name: &str) -> Option<String> {
+ fn get(&self, name: &str, idx: i32) -> Option<Factoid> {
factoids::table
- .filter(factoids::columns::name.eq(name))
+ .find((name, idx))
.limit(1)
.load::<Factoid>(self)
.ok()
- .and_then(|v| v.first().map(|f| f.content.clone()))
+ .and_then(|v| v.into_iter().next())
+ }
+
+ fn count(&self, name: &str) -> Result<i32, &'static str> {
+ let count: Result<i64, _> = factoids::table
+ .filter(factoids::columns::name.eq(name))
+ .count()
+ .first(self);
+
+ match count {
+ Ok(c) => Ok(c as i32),
+ Err(_) => Err("Database Error"),
+ }
}
}
diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs
index 5f9f99a..bb83700 100644
--- a/src/plugins/factoids/mod.rs
+++ b/src/plugins/factoids/mod.rs
@@ -1,15 +1,18 @@
extern crate rlua;
use std::fmt;
+use std::str::FromStr;
+use std::sync::Mutex;
use self::rlua::prelude::*;
use irc::client::prelude::*;
use irc::error::Error as IrcError;
-use std::sync::Mutex;
+use time;
+use chrono::NaiveDateTime;
use plugin::*;
mod database;
-use self::database::Database;
+use self::database::{Database, DbResponse};
static LUA_SANDBOX: &'static str = include_str!("sandbox.lua");
@@ -33,50 +36,140 @@ impl<T: Database> Factoids<T> {
}
fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> {
-
if command.tokens.len() < 2 {
return self.invalid_command(server, command);
}
let name = command.tokens.remove(0);
-
- try_lock!(self.factoids)
- .insert(&name, &command.tokens.join(" "));
-
- server.send_notice(&command.source, "Successfully added")
+ let content = command.tokens.join(" ");
+ let count = match try_lock!(self.factoids).count(&name) {
+ Ok(c) => c,
+ Err(e) => return server.send_notice(&command.source, e),
+ };
+
+ let tm = time::now().to_timespec();
+
+ let factoid = database::NewFactoid {
+ name: &name,
+ idx: count,
+ content: &content,
+ author: &command.source,
+ created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32),
+ };
+
+ match try_lock!(self.factoids).insert(&factoid) {
+ DbResponse::Success => server.send_notice(&command.source, "Successfully added"),
+ DbResponse::Failed(e) => server.send_notice(&command.source, &e),
+ }
}
fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> {
- if command.tokens.len() < 1 {
- self.invalid_command(server, command)
+ let (name, idx) = match command.tokens.len() {
+ 0 => return self.invalid_command(server, command),
+ 1 => {
+ let name = &command.tokens[0];
+ let count = match try_lock!(self.factoids).count(name) {
+ Ok(c) => c,
+ Err(e) => return server.send_notice(&command.source, e),
+ };
+
+ if count < 1 {
+ return server.send_notice(&command.source, &format!("{} does not exist", name));
+ }
- } else {
- let name = &command.tokens[0];
- let factoids = try_lock!(self.factoids);
- let factoid = match factoids.get(name) {
- Some(v) => v,
- None => return self.invalid_command(server, command),
- };
+ (name, count - 1)
+ }
+ _ => {
+ let name = &command.tokens[0];
+ let idx = match i32::from_str(&command.tokens[1]) {
+ Ok(i) => i,
+ Err(_) => return server.send_notice(&command.source, "Invalid index"),
+ };
+
+ (name, idx)
+ }
+ };
+
+ let factoid = match try_lock!(self.factoids).get(name, idx) {
+ Some(v) => v,
+ None => return server.send_notice(&command.source, &format!("{}~{} does not exist", name, idx)),
+ };
+
+ server.send_privmsg(&command.target,
+ &format!("{}: {}", factoid.name, factoid.content))
+ }
+
+ fn info(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> {
+
+ match command.tokens.len() {
+ 0 => self.invalid_command(server, command),
+ 1 => {
+ let name = &command.tokens[0];
+ let count = match try_lock!(self.factoids).count(name) {
+ Ok(c) => c,
+ Err(e) => return server.send_notice(&command.source, e),
+ };
+
+ match count {
+ 0 => server.send_notice(&command.source, &format!("{} does not exist", name)),
+ 1 => {
+ server.send_privmsg(&command.target,
+ &format!("There is 1 version of {}", name))
+ }
+ _ => {
+ server.send_privmsg(&command.target,
+ &format!("There are {} versions of {}", count, name))
+ }
+ }
+ }
+ _ => {
+ let name = &command.tokens[0];
+ let idx = match i32::from_str(&command.tokens[1]) {
+ Ok(i) => i,
+ Err(_) => return server.send_notice(&command.source, "Invalid index"),
+ };
+
+ let factoid = match try_lock!(self.factoids).get(name, idx) {
+ Some(v) => v,
+ None => {
+ return server.send_notice(&command.source,
+ &format!("{}~{} does not exist", name, idx))
+ }
+ };
+
+ server.send_privmsg(&command.target,
+ &format!("{}: Added by {} at {} UTC",
+ name,
+ factoid.author,
+ factoid.created))
+ }
- server.send_privmsg(&command.target, &format!("{}: {}", name, factoid))
}
}
- fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> {
+ fn exec(&self,
+ server: &IrcServer,
+ mut command: PluginCommand,
+ error: bool)
+ -> Result<(), IrcError> {
if command.tokens.len() < 1 {
self.invalid_command(server, &command)
} else {
let name = command.tokens.remove(0);
+ let count = match try_lock!(self.factoids).count(&name) {
+ Ok(c) => c,
+ Err(e) => return server.send_notice(&command.source, e),
+ };
- let factoids = try_lock!(self.factoids);
- let factoid = match factoids.get(&name) {
- Some(v) => v,
- None => return self.invalid_command(server, &command),
+ let factoid = match try_lock!(self.factoids).get(&name, count - 1) {
+ Some(v) => v.content,
+ None if error => return self.invalid_command(server, &command),
+ None => return Ok(()),
};
- let value = if factoid.starts_with(">") {
+ let value = &if factoid.starts_with(">") {
let factoid = String::from(&factoid[1..]);
if factoid.starts_with(">") {
@@ -149,7 +242,7 @@ impl<T: Database> Plugin for Factoids<T> {
tokens: t,
};
- self.exec(server, c)
+ self.exec(server, c, false)
} else {
Ok(())
@@ -165,7 +258,8 @@ impl<T: Database> Plugin for Factoids<T> {
match sub_command.as_ref() {
"add" => self.add(server, &mut command),
"get" => self.get(server, &command),
- "exec" => self.exec(server, command),
+ "info" => self.info(server, &command),
+ "exec" => self.exec(server, command, true),
_ => self.invalid_command(server, &command),
}
}