basic gifs implementation
This commit is contained in:
parent
4be8cd231f
commit
8949409947
7 changed files with 90 additions and 38 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1005,6 +1005,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"form_urlencoded",
|
||||
"json",
|
||||
"rand",
|
||||
"regex",
|
||||
|
|
|
@ -19,6 +19,7 @@ chrono = "0.4.31"
|
|||
sqlx = {version="0.7.3", features=["runtime-tokio", "sqlite"]}
|
||||
json = "0.12.4"
|
||||
reqwest = "0.11.24"
|
||||
form_urlencoded = "1.2.1"
|
||||
|
||||
[features]
|
||||
DEBUG = []
|
||||
|
|
|
@ -14,8 +14,6 @@ use message_handler::handle;
|
|||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
// use chrono::Utc;
|
||||
|
||||
mod commands;
|
||||
mod util;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use chrono::{Datelike, Local};
|
|||
|
||||
use serenity::{all::{GuildId, UserId}, builder::{CreateEmbed, CreateMessage}, client::Context, http::Http, model::Colour};
|
||||
|
||||
use anyhow::Ok;
|
||||
// use anyhow::Ok;
|
||||
|
||||
use sqlx::{Connection, FromRow, SqliteConnection};
|
||||
|
||||
|
@ -12,6 +12,8 @@ use crate::util::utilities;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{tenor, tenor_builder::Tenor, tenor_types::{ContentFilter, MediaFilter}};
|
||||
|
||||
// pub async fn notice_wrapper(http: Arc<Http>) {
|
||||
pub async fn notice_wrapper(ctx: Context) {
|
||||
match notice(ctx.http.clone()).await {
|
||||
|
@ -24,6 +26,7 @@ pub async fn notice_wrapper(ctx: Context) {
|
|||
}
|
||||
|
||||
async fn announce_event(guild_id: GuildId, name: &str, special_message: &str, http: Arc<Http>) -> anyhow::Result<()> {
|
||||
|
||||
let mut event_embed = CreateEmbed::new()
|
||||
.color(Colour::new(rand::random::<u32>() % 0xFFFFFF))
|
||||
.title("Today's event is:");
|
||||
|
@ -45,13 +48,35 @@ async fn announce_event(guild_id: GuildId, name: &str, special_message: &str, ht
|
|||
}
|
||||
|
||||
async fn celebrate_birthday(guild_id: GuildId, user_id: UserId, nick: &str, http: Arc<Http>) -> anyhow::Result<()> {
|
||||
|
||||
const LIMIT: u8 = 20;
|
||||
|
||||
let tenor_response = Tenor::new()
|
||||
.random(true)
|
||||
.contentfilter(ContentFilter::low)
|
||||
.add_media_filter(MediaFilter::gif)
|
||||
.search("vsetko najlepsie").await?;
|
||||
|
||||
let index = rand::random::<usize>() % LIMIT as usize;
|
||||
let gif_url = match tenor::get_gif_url(MediaFilter::gif, tenor_response) {
|
||||
Ok(urls) => Some(urls),
|
||||
Err(e) => {
|
||||
send_error(http.clone(), e.to_string()).await;
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let system_channel = utilities::get_system_channel(guild_id, http.clone()).await?;
|
||||
|
||||
let embed = CreateEmbed::new()
|
||||
let mut embed = CreateEmbed::new()
|
||||
.color(Colour::new(rand::random::<u32>() % 0xFFFFFF))
|
||||
.title(format!("HAPPY BIRTHDAY {}!", nick))
|
||||
.description(format!("<@{}>'s birthday is today!!! Yay!", user_id.get()));
|
||||
|
||||
if gif_url.is_some() {
|
||||
embed = embed.image(gif_url.unwrap()[index].as_str());
|
||||
}
|
||||
|
||||
system_channel.send_message(http.clone(), CreateMessage::new().add_embed(embed.clone())).await?;
|
||||
|
||||
Ok(())
|
||||
|
@ -90,19 +115,19 @@ async fn notice(http: Arc<Http>) -> anyhow::Result<()> {
|
|||
"SELECT id, nick FROM birthdays
|
||||
WHERE day=? AND month=?;"
|
||||
)
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
|
||||
let global_events = sqlx::query_as::<_, EventRow>(
|
||||
"SELECT id, guild, name, year, special_message from events
|
||||
WHERE day=? AND month=? AND guild=0;"
|
||||
)
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
|
||||
let guilds = http.get_guilds(None, None).await?;
|
||||
|
||||
|
@ -127,18 +152,18 @@ async fn notice(http: Arc<Http>) -> anyhow::Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
let global_events = sqlx::query_as::<_, EventRow>(
|
||||
let guild_events = sqlx::query_as::<_, EventRow>(
|
||||
"SELECT id, guild, name, year, special_message from events
|
||||
WHERE day=? AND month=? AND guild!=0;"
|
||||
)
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
.bind(day)
|
||||
.bind(month)
|
||||
.fetch_all(&mut db)
|
||||
.await?;
|
||||
|
||||
// TODO if has year delete it from announce and delete
|
||||
|
||||
for e in &global_events {
|
||||
for e in &guild_events {
|
||||
announce_event(GuildId::new(e.guild), e.name.as_str(), e.special_message.as_str(), http.clone()).await?;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
use super::tenor_types::MediaFilter;
|
||||
|
||||
use json::JsonValue;
|
||||
|
||||
pub fn get_gif_url(filter: MediaFilter, tenor_response: JsonValue) -> anyhow::Result<Vec<String>> {
|
||||
use anyhow::Context;
|
||||
|
||||
let mut urls: Vec<String> = Vec::new();
|
||||
let results = tenor_response["results"].members();
|
||||
|
||||
for result in results {
|
||||
let url = result["media_formats"][filter.to_string()]["url"].as_str().context("Value not found in Json")?;
|
||||
urls.push(url.to_string());
|
||||
}
|
||||
|
||||
Ok(urls)
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
use std::{collections::hash_map::RandomState, fmt};
|
||||
|
||||
use json::JsonValue;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
@ -40,7 +38,7 @@ pub struct Tenor {
|
|||
}
|
||||
|
||||
impl Tenor {
|
||||
fn new(q: String) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Tenor {
|
||||
country: None,
|
||||
locale: None,
|
||||
|
@ -54,31 +52,31 @@ impl Tenor {
|
|||
}
|
||||
|
||||
/// Replaces current country with the passed one
|
||||
fn country(mut self, country: String) -> Self {
|
||||
pub fn country(mut self, country: String) -> Self {
|
||||
self.country = Some(country);
|
||||
self
|
||||
}
|
||||
|
||||
/// Replaces current locale with the passed one
|
||||
fn locale(mut self, locale: String) -> Self {
|
||||
pub fn locale(mut self, locale: String) -> Self {
|
||||
self.locale = Some(locale);
|
||||
self
|
||||
}
|
||||
|
||||
/// Replaces current media_filter with the passed one
|
||||
fn media_filter(mut self, filter: HashSet<MediaFilter>) -> Self {
|
||||
pub fn media_filter(mut self, filter: HashSet<MediaFilter>) -> Self {
|
||||
self.media_filter = Some(filter);
|
||||
self
|
||||
}
|
||||
|
||||
/// Replaces current contentfilter with the passed one
|
||||
fn contentfilter(mut self, filter: ContentFilter) -> Self {
|
||||
pub fn contentfilter(mut self, filter: ContentFilter) -> Self {
|
||||
self.contentfilter = Some(filter);
|
||||
self
|
||||
}
|
||||
|
||||
/// Replaces current media_filter with the passed one
|
||||
fn add_media_filter(mut self, filter: MediaFilter) -> Self {
|
||||
pub fn add_media_filter(mut self, filter: MediaFilter) -> Self {
|
||||
if self.media_filter.is_none() {
|
||||
let mut set = HashSet::new();
|
||||
set.insert(filter);
|
||||
|
@ -90,17 +88,17 @@ impl Tenor {
|
|||
self
|
||||
}
|
||||
|
||||
fn ar_range(mut self, range: ArRange) -> Self {
|
||||
pub fn ar_range(mut self, range: ArRange) -> Self {
|
||||
self.ar_range = Some(range);
|
||||
self
|
||||
}
|
||||
|
||||
fn random(mut self, random: bool) -> Self {
|
||||
pub fn random(mut self, random: bool) -> Self {
|
||||
self.random = Some(random);
|
||||
self
|
||||
}
|
||||
|
||||
fn limit(mut self, mut limit: u8) -> Self {
|
||||
pub fn limit(mut self, mut limit: u8) -> Self {
|
||||
if limit < 20 {
|
||||
limit = 20;
|
||||
}
|
||||
|
@ -112,19 +110,21 @@ impl Tenor {
|
|||
self
|
||||
}
|
||||
|
||||
fn pos(mut self, pos: String) -> Self {
|
||||
pub fn pos(mut self, pos: String) -> Self {
|
||||
self.pos = Some(pos);
|
||||
self
|
||||
}
|
||||
|
||||
async fn search(self, query: String) -> Result<JsonValue, Error> {
|
||||
pub async fn search(self, query: &str) -> Result<JsonValue, Error> {
|
||||
use anyhow::Context;
|
||||
|
||||
let q: String = form_urlencoded::byte_serialize(query.as_bytes()).collect();
|
||||
|
||||
// TODO encode query for urls (replace special characters and stuff)
|
||||
let base_url = "https://tenor.googleapis.com/v2/search?";
|
||||
let api_key = dotenv_var("TENORV2").context("TENORV2 key not found in the .env")?;
|
||||
|
||||
let mut request = format!("{base_url}q={query}&key={api_key}");
|
||||
let mut request = format!("{base_url}q={q}&key={api_key}");
|
||||
|
||||
if self.country.is_some() {
|
||||
request.push_str(&format!("&country={}", self.country.unwrap()));
|
||||
|
@ -134,10 +134,21 @@ impl Tenor {
|
|||
request.push_str(&format!("&locale={}", self.locale.unwrap()));
|
||||
}
|
||||
|
||||
if self.media_filter.is_some() {
|
||||
// TODO implement
|
||||
// self.media_filter_to_string()
|
||||
// request.push_str();
|
||||
if self.contentfilter.is_some() {
|
||||
request.push_str(&format!("&contentfilter={}", self.contentfilter.unwrap()))
|
||||
}
|
||||
|
||||
if self.media_filter.is_some() && self.media_filter.as_ref().unwrap().len() > 0 {
|
||||
request.push_str(
|
||||
format!("&media_filter={}",
|
||||
self.media_filter.unwrap()
|
||||
.iter()
|
||||
.map(|e| e.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
.as_str()
|
||||
).as_str()
|
||||
);
|
||||
}
|
||||
|
||||
if self.ar_range.is_some() {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ContentFilter {
|
||||
off,
|
||||
|
|
Loading…
Reference in a new issue