From ccca613d4bd1454fa57d818c2b2a7c3629cf7ec2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Sun, 7 Jun 2020 17:33:12 +0200 Subject: Repository::new() --- src/discord.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/discord.rs (limited to 'src/discord.rs') diff --git a/src/discord.rs b/src/discord.rs new file mode 100644 index 0000000..c7aea78 --- /dev/null +++ b/src/discord.rs @@ -0,0 +1,98 @@ +use std::sync::Arc; + +use anyhow::Result; +use chrono::prelude::*; +use evtclib::Log; +use serenity::client::bridge::gateway::ShardManager; +use serenity::model::id::*; +use serenity::prelude::*; + +use log::info; + +use super::categories::Categorizable; + +const MAX_HOURS: i64 = 5; + +struct ShardManagerContainer; + +impl TypeMapKey for ShardManagerContainer { + type Value = Arc>; +} + +#[derive(Debug, Clone)] +struct Handler { + channel_id: u64, + log: Log, + link: String, +} + +impl EventHandler for Handler { + fn ready(&self, ctx: Context, _ready: serenity::model::gateway::Ready) { + info!("Discord client is ready"); + let mut messages = ChannelId(self.channel_id) + .messages(&ctx, |r| r.limit(25)) + .unwrap(); + messages.sort_by_key(|m| m.timestamp); + messages.retain(|m| { + m.is_own(&ctx) + && Utc::now().signed_duration_since(m.timestamp) + < chrono::Duration::hours(MAX_HOURS) + }); + + if let Some(mut m) = messages.pop() { + let new_text = insert_link(&m.content, &self.log, &self.link); + m.edit(&ctx, |m| m.content(new_text)).unwrap(); + } else { + let new_text = insert_link("", &self.log, &self.link); + ChannelId(self.channel_id).say(&ctx, new_text).unwrap(); + } + + let data = ctx.data.read(); + if let Some(manager) = data.get::() { + manager.lock().shutdown_all(); + } + } +} + +pub fn post_link(discord_token: &str, channel_id: u64, log: Log, link: String) -> Result<()> { + let mut client = Client::new( + discord_token, + Handler { + channel_id, + log, + link, + }, + )?; + { + let mut data = client.data.write(); + data.insert::(Arc::clone(&client.shard_manager)); + } + client.start()?; + Ok(()) +} + +fn find_insertion(text: &str, category: &str) -> Option { + let cat_pos = text.find(&format!("**{}**", category))?; + let empty_line = text[cat_pos..].find("\n\n")?; + Some(cat_pos + empty_line + 1) +} + +fn insert_link(text: &str, log: &Log, link: &str) -> String { + let mut text = format!("\n\n{}\n\n", text); + let point = find_insertion(&text, log.category()); + let link_line = format!("{} {}\n", state_emoji(log), link); + if let Some(i) = point { + text.insert_str(i, &link_line); + } else { + text.push_str(&format!("**{}**\n{}", log.category(), link_line)); + } + text.trim().into() +} + +fn state_emoji(log: &Log) -> &'static str { + if log.was_rewarded() { + "✔️" + } else { + "❌" + } +} -- cgit v1.2.3