This commit is contained in:
lemonsh 2022-07-20 10:58:33 +02:00
parent c12509268a
commit cbbdcb145c
7 changed files with 67 additions and 22 deletions

View file

@ -2,7 +2,9 @@ use crate::bot::{Command, Context};
use async_trait::async_trait;
const HELP: &str = concat!(
"=- \x1d\x02Überbot\x0f ", env!("CARGO_PKG_VERSION"), " -=\r\n",
"=- \x1d\x02Überbot\x0f ",
env!("CARGO_PKG_VERSION"),
" -=\r\n",
" * waifu <category> * grab [count] <user>\r\n",
" * owo/mock/leet [user] * quot <user>\r\n",
" * ev <math expression> * qsearch <query>\r\n",

View file

@ -7,7 +7,7 @@ pub struct Grab;
pub struct Quot;
pub struct Search {
limit: usize
limit: usize,
}
impl Search {
@ -17,7 +17,7 @@ impl Search {
}
pub struct SearchNext {
limit: usize
limit: usize,
}
impl SearchNext {
@ -83,7 +83,10 @@ impl Command for Search {
} else {
return Ok("Invalid usage.".into());
};
let results = msg.db.search_quotes(msg.author.into(), query.into(), self.limit).await?;
let results = msg
.db
.search_quotes(msg.author.into(), query.into(), self.limit)
.await?;
if results.is_empty() {
return Ok("No results.".into());
}
@ -104,7 +107,7 @@ impl Command for SearchNext {
let results = if let Some(o) = msg.db.advance_search(msg.author.into(), self.limit).await? {
o
} else {
return Ok("You need to initiate a search first using 'qsearch'.".into())
return Ok("You need to initiate a search first using 'qsearch'.".into());
};
if results.is_empty() {
return Ok("No results.".into());

View file

@ -47,7 +47,15 @@ async fn resolve_spotify(
resource_type: &str,
resource_id: &str,
) -> anyhow::Result<String> {
if spotify.token.lock().await.unwrap().as_ref().unwrap().is_expired() {
if spotify
.token
.lock()
.await
.unwrap()
.as_ref()
.unwrap()
.is_expired()
{
spotify.request_token().await?;
}
tracing::debug!(

View file

@ -5,7 +5,7 @@ pub struct UberConfig {
pub log_level: Option<String>,
pub irc: IrcConfig,
pub spotify: Option<SpotifyConfig>,
pub bot: BotConfig
pub bot: BotConfig,
}
#[derive(Deserialize)]
@ -30,5 +30,5 @@ pub struct IrcConfig {
pub struct BotConfig {
pub db_path: Option<String>,
pub history_depth: usize,
pub search_limit: Option<usize>
}
pub search_limit: Option<usize>,
}

View file

@ -1,6 +1,6 @@
use std::collections::HashMap;
use rusqlite::{params, OptionalExtension, Params};
use serde::Serialize;
use std::collections::HashMap;
use tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
oneshot,
@ -14,8 +14,17 @@ enum Task {
oneshot::Sender<rusqlite::Result<Option<Quote>>>,
Option<String>,
),
StartSearch(oneshot::Sender<rusqlite::Result<Vec<Quote>>>, String, String, usize),
NextSearch(oneshot::Sender<rusqlite::Result<Option<Vec<Quote>>>>, String, usize)
StartSearch(
oneshot::Sender<rusqlite::Result<Vec<Quote>>>,
String,
String,
usize,
),
NextSearch(
oneshot::Sender<rusqlite::Result<Option<Vec<Quote>>>>,
String,
usize,
),
}
pub struct DbExecutor {
@ -66,27 +75,43 @@ impl DbExecutor {
tx.send(result).unwrap();
}
Task::StartSearch(tx, user, query, limit) => {
tx.send(self.start_search(&mut searches, user, query, limit)).unwrap();
tx.send(self.start_search(&mut searches, user, query, limit))
.unwrap();
}
Task::NextSearch(tx, user, limit) => {
tx.send(self.next_search(&mut searches, &user, limit)).unwrap();
tx.send(self.next_search(&mut searches, &user, limit))
.unwrap();
}
}
tracing::debug!("task took {}ms", Instant::now().duration_since(before).as_secs_f64()/1000.0)
tracing::debug!(
"task took {}ms",
Instant::now().duration_since(before).as_secs_f64() / 1000.0
)
}
}
fn start_search(&self, searches: &mut HashMap<String, (String, i64)>, user: String, query: String, limit: usize) -> rusqlite::Result<Vec<Quote>> {
fn start_search(
&self,
searches: &mut HashMap<String, (String, i64)>,
user: String,
query: String,
limit: usize,
) -> rusqlite::Result<Vec<Quote>> {
let (quotes, oid) = self.yield_quotes_oid("select oid,quote,username from quotes where quote like '%'||?1||'%' order by oid asc limit ?", params![query, limit])?;
searches.insert(user, (query, oid));
Ok(quotes)
}
fn next_search(&self, searches: &mut HashMap<String, (String, i64)>, user: &str, limit: usize) -> rusqlite::Result<Option<Vec<Quote>>> {
fn next_search(
&self,
searches: &mut HashMap<String, (String, i64)>,
user: &str,
limit: usize,
) -> rusqlite::Result<Option<Vec<Quote>>> {
let (query, old_oid) = if let Some(o) = searches.get_mut(user) {
o
} else {
return Ok(None)
return Ok(None);
};
let (quotes, new_oid) = self.yield_quotes_oid("select oid,quote,username from quotes where oid > ? and quote like '%'||?||'%' order by oid asc limit ?", params![*old_oid, &*query, limit])?;
if new_oid != -1 {
@ -95,7 +120,11 @@ impl DbExecutor {
Ok(Some(quotes))
}
fn yield_quotes_oid<P: Params>(&self, sql: &str, params: P) -> rusqlite::Result<(Vec<Quote>, i64)> {
fn yield_quotes_oid<P: Params>(
&self,
sql: &str,
params: P,
) -> rusqlite::Result<(Vec<Quote>, i64)> {
let mut lastoid = -1i64;
let quotes = self.db.prepare(sql).and_then(|mut v| {
v.query(params).and_then(|mut v| {

View file

@ -16,7 +16,9 @@ impl MessageHistory {
pub async fn last_msg(&self, user: &str) -> Option<String> {
let map = self.map.read().await;
map.get(user).and_then(|d| d.get(0)).map(ToString::to_string)
map.get(user)
.and_then(|d| d.get(0))
.map(ToString::to_string)
}
pub async fn last_msgs(&self, user: &str, count: usize) -> Option<Vec<String>> {

View file

@ -1,10 +1,10 @@
#![allow(clippy::module_name_repetitions)]
use fancy_regex::Regex;
use std::{env, fs};
use std::str::FromStr;
use std::sync::Arc;
use std::thread;
use std::{env, fs};
use crate::bot::Bot;
use crate::commands::eval::Eval;
@ -72,7 +72,8 @@ async fn main() -> anyhow::Result<()> {
})
.init();
let (db_exec, db_conn) = DbExecutor::create(cfg.bot.db_path.as_deref().unwrap_or("uberbot.db3"))?;
let (db_exec, db_conn) =
DbExecutor::create(cfg.bot.db_path.as_deref().unwrap_or("uberbot.db3"))?;
let exec_thread = thread::spawn(move || db_exec.run());
let uber_ver = concat!("Überbot ", env!("CARGO_PKG_VERSION"));