NadekoBot/src/NadekoBot/Services/CustomReactions/Extensions.cs

103 lines
4.1 KiB
C#
Raw Normal View History

using AngleSharp;
using AngleSharp.Dom.Html;
using Discord;
2017-05-25 02:24:43 +00:00
using Discord.WebSocket;
2017-05-24 04:43:00 +00:00
using NadekoBot.DataStructures;
using NadekoBot.DataStructures.Replacements;
using NadekoBot.Extensions;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
2016-12-13 15:17:40 +00:00
using System.Text.RegularExpressions;
2017-05-24 04:43:00 +00:00
using System.Threading.Tasks;
2017-05-25 02:24:43 +00:00
namespace NadekoBot.Services.CustomReactions
{
public static class Extensions
{
private static readonly Regex imgRegex = new Regex("%(img|image):(?<tag>.*?)%", RegexOptions.Compiled);
2016-12-13 15:17:40 +00:00
private static readonly NadekoRandom rng = new NadekoRandom();
public static Dictionary<Regex, Func<Match, Task<string>>> regexPlaceholders = new Dictionary<Regex, Func<Match, Task<string>>>()
2016-12-13 15:17:40 +00:00
{
{ imgRegex, async (match) => {
var tag = match.Groups["tag"].ToString();
if(string.IsNullOrWhiteSpace(tag))
return "";
var fullQueryLink = $"http://imgur.com/search?q={ tag }";
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
var elems = document.QuerySelectorAll("a.image-list-link").ToArray();
if (!elems.Any())
return "";
var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Length))?.Children?.FirstOrDefault() as IHtmlImageElement);
if (img?.Source == null)
2016-12-13 15:17:40 +00:00
return "";
return " "+img.Source.Replace("b.", ".") + " ";
2016-12-13 15:17:40 +00:00
} }
};
private static string ResolveTriggerString(this string str, IUserMessage ctx, DiscordSocketClient client)
{
var rep = new ReplacementBuilder()
.WithUser(ctx.Author)
.WithClient(client)
.Build();
str = rep.Replace(str.ToLowerInvariant());
2016-10-16 03:22:54 +00:00
return str;
}
private static async Task<string> ResolveResponseStringAsync(this string str, IUserMessage ctx, DiscordSocketClient client, string resolvedTrigger)
2016-10-16 03:22:54 +00:00
{
var rep = new ReplacementBuilder()
.WithDefault(ctx.Author, ctx.Channel, (ctx.Channel as ITextChannel)?.Guild, client)
.WithOverride("%target%", () => ctx.Content.Substring(resolvedTrigger.Length).Trim())
.Build();
2016-10-16 03:22:54 +00:00
str = rep.Replace(str);
2016-12-13 15:17:40 +00:00
foreach (var ph in regexPlaceholders)
{
str = await ph.Key.ReplaceAsync(str, ph.Value);
2016-12-13 15:17:40 +00:00
}
return str;
}
public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx, DiscordSocketClient client)
2017-05-25 02:24:43 +00:00
=> cr.Trigger.ResolveTriggerString(ctx, client);
public static Task<string > ResponseWithContextAsync(this CustomReaction cr, IUserMessage ctx, DiscordSocketClient client)
=> cr.Response.ResolveResponseStringAsync(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client));
2017-05-24 04:43:00 +00:00
public static async Task<IUserMessage> Send(this CustomReaction cr, IUserMessage ctx, DiscordSocketClient client, CustomReactionsService crs)
2017-05-24 04:43:00 +00:00
{
var channel = cr.DmResponse ? await ctx.Author.CreateDMChannelAsync() : ctx.Channel;
2017-05-24 04:43:00 +00:00
2017-05-25 02:24:43 +00:00
crs.ReactionStats.AddOrUpdate(cr.Trigger, 1, (k, old) => ++old);
2017-05-24 04:43:00 +00:00
2017-05-25 02:24:43 +00:00
if (CREmbed.TryParse(cr.Response, out CREmbed crembed))
2017-05-24 04:43:00 +00:00
{
var rep = new ReplacementBuilder()
.WithDefault(ctx.Author, ctx.Channel, (ctx.Channel as ITextChannel)?.Guild, client)
.WithOverride("%target%", () => ctx.Content.Substring(cr.Trigger.ResolveTriggerString(ctx, client).Length).Trim())
.Build();
rep.Replace(crembed);
return await channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText?.SanitizeMentions() ?? "");
2017-05-24 04:43:00 +00:00
}
return await channel.SendMessageAsync((await cr.ResponseWithContextAsync(ctx, client)).SanitizeMentions());
2017-05-24 04:43:00 +00:00
}
}
}