Rustfmt
This commit is contained in:
parent
25a7635408
commit
329f6d6dae
|
@ -1,14 +1,13 @@
|
|||
use async_trait::async_trait;
|
||||
use crate::bot::{Command, Context};
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub struct LastMsg;
|
||||
|
||||
#[async_trait]
|
||||
impl Command for LastMsg {
|
||||
//noinspection RsNeedlessLifetimes
|
||||
async fn execute<'a>(&mut self, msg: Context<'a>) -> anyhow::Result<String> {
|
||||
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
||||
let nick = msg.content.unwrap_or(msg.author);
|
||||
let lastmsg = msg.last_msg.read().await;
|
||||
let lastmsg = msg.history.read().await;
|
||||
Ok(format!("{}: {:?}", nick, lastmsg.get(nick)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use rspotify::{ClientCredsSpotify, Credentials};
|
||||
use crate::bot::{Context, Trigger};
|
||||
use async_trait::async_trait;
|
||||
use fancy_regex::Captures;
|
||||
use rspotify::clients::BaseClient;
|
||||
use rspotify::model::{Id, PlayableItem};
|
||||
use crate::bot::{Context, Trigger};
|
||||
use rspotify::{ClientCredsSpotify, Credentials};
|
||||
|
||||
pub struct Spotify {
|
||||
spotify: ClientCredsSpotify,
|
||||
|
@ -13,22 +13,25 @@ impl Spotify {
|
|||
pub async fn new(creds: Credentials) -> anyhow::Result<Self> {
|
||||
let mut spotify = ClientCredsSpotify::new(creds);
|
||||
spotify.request_token().await?;
|
||||
Ok(Self {
|
||||
spotify
|
||||
})
|
||||
Ok(Self { spotify })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Trigger for Spotify {
|
||||
async fn execute<'a>(&mut self, msg: Context<'a>, captures: Captures<'a>) -> anyhow::Result<String> {
|
||||
async fn execute<'a>(
|
||||
&mut self,
|
||||
msg: Context<'a>,
|
||||
captures: Captures<'a>,
|
||||
) -> anyhow::Result<String> {
|
||||
let tp_group = captures.get(1).unwrap();
|
||||
let id_group = captures.get(2).unwrap();
|
||||
resolve_spotify(
|
||||
&mut self.spotify,
|
||||
&msg.content.unwrap()[tp_group.start()..tp_group.end()],
|
||||
&msg.content.unwrap()[id_group.start()..id_group.end()],
|
||||
).await
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
use crate::bot::{Context, Trigger};
|
||||
use async_trait::async_trait;
|
||||
use fancy_regex::{Captures, Regex};
|
||||
use reqwest::Client;
|
||||
use htmlescape::decode_html;
|
||||
use crate::bot::{Context, Trigger};
|
||||
use reqwest::Client;
|
||||
|
||||
pub struct Title {
|
||||
http: Client,
|
||||
title_regex: Regex
|
||||
title_regex: Regex,
|
||||
}
|
||||
|
||||
impl Title {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
Ok(Title {
|
||||
http: Client::new(),
|
||||
title_regex: Regex::new(r"(?<=<title>)(.*)(?=</title>)")?
|
||||
title_regex: Regex::new(r"(?<=<title>)(.*)(?=</title>)")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Trigger for Title {
|
||||
async fn execute<'a>(&mut self, _msg: Context<'a>, captures: Captures<'a>) -> anyhow::Result<String> {
|
||||
async fn execute<'a>(
|
||||
&mut self,
|
||||
_msg: Context<'a>,
|
||||
captures: Captures<'a>,
|
||||
) -> anyhow::Result<String> {
|
||||
let url = captures.get(0).unwrap().as_str();
|
||||
tracing::debug!("url: {}", url);
|
||||
|
||||
|
@ -33,18 +37,19 @@ impl Trigger for Title {
|
|||
let body = response.text().await?;
|
||||
if let Some(tm) = self.title_regex.find(&body)? {
|
||||
let title_match = &body[tm.start()..tm.end()];
|
||||
let result = decode_html(title_match).unwrap_or_else(|_| title_match.to_string());
|
||||
let result =
|
||||
decode_html(title_match).unwrap_or_else(|_| title_match.to_string());
|
||||
Ok(format!("\x039[Title]\x0311 {}", result))
|
||||
} else {
|
||||
Ok("\x039[Title]\x0311 No title".into())
|
||||
}
|
||||
} else {
|
||||
let content_length = response.content_length().map(|l| (l/1024).to_string());
|
||||
let content_length = response.content_length().map(|l| (l / 1024).to_string());
|
||||
let size = content_length.as_deref().unwrap_or("unknown");
|
||||
Ok(format!("\x039[Title]\x0311 File: {}; {}kb", mime, size))
|
||||
}
|
||||
} else {
|
||||
Ok("\x039[Title]\x0311 No Content-Type header".into())
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
use crate::bot::{Context, Command};
|
||||
use crate::bot::{Command, Context};
|
||||
use async_trait::async_trait;
|
||||
use reqwest::Client;
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Waifu {
|
||||
http: Client
|
||||
http: Client,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Command for Waifu {
|
||||
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
||||
let category = msg.content.unwrap_or("waifu");
|
||||
let request = self.http.get(format!("https://api.waifu.pics/sfw/{}", category)).build()?;
|
||||
let response = self.http.execute(request)
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
let request = self
|
||||
.http
|
||||
.get(format!("https://api.waifu.pics/sfw/{}", category))
|
||||
.build()?;
|
||||
let response = self.http.execute(request).await?.text().await?;
|
||||
let response = response.trim();
|
||||
let value: Value = serde_json::from_str(response)?;
|
||||
let url = value["url"]
|
||||
|
|
|
@ -7,10 +7,12 @@ use tokio::sync::{
|
|||
|
||||
#[derive(Debug)]
|
||||
enum Task {
|
||||
AddQuote(oneshot::Sender<bool>, Quote),
|
||||
GetQuote(oneshot::Sender<Option<Quote>>, Option<String>),
|
||||
SearchQuotes(oneshot::Sender<Option<Vec<Quote>>>, String),
|
||||
RandomNQuotes(oneshot::Sender<Option<Vec<Quote>>>, u8),
|
||||
AddQuote(oneshot::Sender<rusqlite::Result<()>>, Quote),
|
||||
GetQuote(
|
||||
oneshot::Sender<rusqlite::Result<Option<Quote>>>,
|
||||
Option<String>,
|
||||
),
|
||||
SearchQuotes(oneshot::Sender<rusqlite::Result<Vec<Quote>>>, String),
|
||||
}
|
||||
|
||||
pub struct DbExecutor {
|
||||
|
@ -40,45 +42,34 @@ impl DbExecutor {
|
|||
while let Some(task) = self.rx.blocking_recv() {
|
||||
match task {
|
||||
Task::AddQuote(tx, quote) => {
|
||||
if let Err(e) = self.db.execute(
|
||||
"insert into quotes(quote,username) values(?,?)",
|
||||
params![quote.quote, quote.author],
|
||||
) {
|
||||
tracing::error!("A database error has occurred: {}", e);
|
||||
tx.send(false).unwrap();
|
||||
} else {
|
||||
tx.send(true).unwrap();
|
||||
}
|
||||
let result = self
|
||||
.db
|
||||
.execute(
|
||||
"insert into quotes(quote,username) values(?,?)",
|
||||
params![quote.quote, quote.author],
|
||||
)
|
||||
.map(|_| ());
|
||||
tx.send(result).unwrap();
|
||||
}
|
||||
Task::GetQuote(tx, author) => {
|
||||
let quote = if let Some(ref author) = author {
|
||||
let result = if let Some(ref author) = author {
|
||||
self.db.query_row("select quote,username from quotes where username=? order by random() limit 1", params![author], |v| Ok(Quote {quote:v.get(0)?, author:v.get(1)?}))
|
||||
} else {
|
||||
self.db.query_row("select quote,username from quotes order by random() limit 1", params![], |v| Ok(Quote {quote:v.get(0)?, author:v.get(1)?}))
|
||||
}.optional().unwrap_or_else(|e| {
|
||||
tracing::error!("A database error has occurred: {}", e);
|
||||
None
|
||||
});
|
||||
tx.send(quote).unwrap();
|
||||
}.optional();
|
||||
tx.send(result).unwrap();
|
||||
}
|
||||
Task::SearchQuotes(tx, query) => {
|
||||
tx.send(self.yield_quotes("select quote,username from quotes where quote like '%'||?1||'%' order by quote asc limit 5", params![query])).unwrap();
|
||||
}
|
||||
Task::RandomNQuotes(tx, count) => {
|
||||
tx.send(self.yield_quotes(
|
||||
"select quote,username from quotes order by random() limit ?",
|
||||
params![count],
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn yield_quotes<P: Params>(&self, sql: &str, params: P) -> Option<Vec<Quote>> {
|
||||
match self.db.prepare(sql).and_then(|mut v| {
|
||||
fn yield_quotes<P: Params>(&self, sql: &str, params: P) -> rusqlite::Result<Vec<Quote>> {
|
||||
self.db.prepare(sql).and_then(|mut v| {
|
||||
v.query(params).and_then(|mut v| {
|
||||
let mut quotes: Vec<Quote> = Vec::with_capacity(50);
|
||||
let mut quotes: Vec<Quote> = Vec::new();
|
||||
while let Some(row) = v.next()? {
|
||||
quotes.push(Quote {
|
||||
quote: row.get(0)?,
|
||||
|
@ -87,13 +78,7 @@ impl DbExecutor {
|
|||
}
|
||||
Ok(quotes)
|
||||
})
|
||||
}) {
|
||||
Ok(o) => Some(o),
|
||||
Err(e) => {
|
||||
tracing::error!("A database error has occurred: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,23 +113,22 @@ macro_rules! executor_wrapper {
|
|||
|
||||
impl ExecutorConnection {
|
||||
// WARNING: these methods are NOT cancel-safe
|
||||
executor_wrapper!(add_quote, Task::AddQuote, bool, quote: Quote);
|
||||
executor_wrapper!(
|
||||
add_quote,
|
||||
Task::AddQuote,
|
||||
rusqlite::Result<()>,
|
||||
quote: Quote
|
||||
);
|
||||
executor_wrapper!(
|
||||
get_quote,
|
||||
Task::GetQuote,
|
||||
Option<Quote>,
|
||||
rusqlite::Result<Option<Quote>>,
|
||||
author: Option<String>
|
||||
);
|
||||
executor_wrapper!(
|
||||
search_quotes,
|
||||
Task::SearchQuotes,
|
||||
Option<Vec<Quote>>,
|
||||
rusqlite::Result<Vec<Quote>>,
|
||||
query: String
|
||||
);
|
||||
executor_wrapper!(
|
||||
random_n_quotes,
|
||||
Task::RandomNQuotes,
|
||||
Option<Vec<Quote>>,
|
||||
count: u8
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue