added %img:YOUR_TAG% custom reactions placeholder to pull imgur images with that tag.
This commit is contained in:
		@@ -1,10 +1,13 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using AngleSharp;
 | 
			
		||||
using AngleSharp.Dom.Html;
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.DataStructures;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@@ -14,13 +17,7 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
    {
 | 
			
		||||
        public static Dictionary<string, Func<IUserMessage, string, string>> responsePlaceholders = new Dictionary<string, Func<IUserMessage, string, string>>()
 | 
			
		||||
        {
 | 
			
		||||
            {"%target%", (ctx, trigger) => { return ctx.Content.Substring(trigger.Length).Trim().SanitizeMentions(); } }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        public static Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>> placeholders = new Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>>()
 | 
			
		||||
        {
 | 
			
		||||
            {"%mention%", (ctx, client) => { return $"<@{client.CurrentUser.Id}>"; } },
 | 
			
		||||
            {"%user%", (ctx, client) => { return ctx.Author.Mention; } },
 | 
			
		||||
            {"%target%", (ctx, trigger) => { return ctx.Content.Substring(trigger.Length).Trim().SanitizeMentions(); } },
 | 
			
		||||
            {"%rnduser%", (ctx, client) => {
 | 
			
		||||
                //var ch = ctx.Channel as ITextChannel;
 | 
			
		||||
                //if(ch == null)
 | 
			
		||||
@@ -40,15 +37,22 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
                //var users = g.Users.ToArray();
 | 
			
		||||
 | 
			
		||||
                //return users[new NadekoRandom().Next(0, users.Length-1)].Mention;
 | 
			
		||||
            } }
 | 
			
		||||
            } },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        public static Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>> placeholders = new Dictionary<string, Func<IUserMessage, DiscordShardedClient, string>>()
 | 
			
		||||
        {
 | 
			
		||||
            {"%mention%", (ctx, client) => { return $"<@{client.CurrentUser.Id}>"; } },
 | 
			
		||||
            {"%user%", (ctx, client) => { return ctx.Author.Mention; } },
 | 
			
		||||
            //{"%rng%", (ctx) => { return new NadekoRandom().Next(0,10).ToString(); } }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly Regex rngRegex = new Regex("%rng(?:(?<from>(?:-)?\\d+)-(?<to>(?:-)?\\d+))?%", RegexOptions.Compiled);
 | 
			
		||||
        private static readonly Regex imgRegex = new Regex("%(img|image):(?<tag>.*?)%", RegexOptions.Compiled);
 | 
			
		||||
 | 
			
		||||
        private static readonly NadekoRandom rng = new NadekoRandom();
 | 
			
		||||
 | 
			
		||||
        public static Dictionary<Regex, MatchEvaluator> regexPlaceholders = new Dictionary<Regex, MatchEvaluator>()
 | 
			
		||||
        public static Dictionary<Regex, Func<Match, Task<string>>> regexPlaceholders = new Dictionary<Regex, Func<Match, Task<string>>>()
 | 
			
		||||
        {
 | 
			
		||||
            { rngRegex, (match) => {
 | 
			
		||||
                int from = 0;
 | 
			
		||||
@@ -59,13 +63,34 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
 | 
			
		||||
                if(from == 0 && to == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    return rng.Next(0, 11).ToString();
 | 
			
		||||
                    return Task.FromResult(rng.Next(0, 11).ToString());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if(from >= to)
 | 
			
		||||
                    return Task.FromResult(string.Empty);
 | 
			
		||||
 | 
			
		||||
                return Task.FromResult(rng.Next(from,to+1).ToString());
 | 
			
		||||
            } },
 | 
			
		||||
            { imgRegex, async (match) => {
 | 
			
		||||
                var tag = match.Groups["tag"].ToString();
 | 
			
		||||
                if(string.IsNullOrWhiteSpace(tag))
 | 
			
		||||
                    return "";
 | 
			
		||||
 | 
			
		||||
                return rng.Next(from,to+1).ToString();
 | 
			
		||||
                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)
 | 
			
		||||
                    return "";
 | 
			
		||||
 | 
			
		||||
                return " "+img.Source.Replace("b.", ".") + " ";
 | 
			
		||||
            } }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -73,26 +98,31 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var ph in placeholders)
 | 
			
		||||
            {
 | 
			
		||||
                str = str.ToLowerInvariant().Replace(ph.Key, ph.Value(ctx, client));
 | 
			
		||||
                if (str.Contains(ph.Key))
 | 
			
		||||
                    str = str.ToLowerInvariant().Replace(ph.Key, ph.Value(ctx, client));
 | 
			
		||||
            }
 | 
			
		||||
            return str;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string ResolveResponseString(this string str, IUserMessage ctx, DiscordShardedClient client, string resolvedTrigger)
 | 
			
		||||
        private static async Task<string> ResolveResponseStringAsync(this string str, IUserMessage ctx, DiscordShardedClient client, string resolvedTrigger)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var ph in placeholders)
 | 
			
		||||
            {
 | 
			
		||||
                str = str.Replace(ph.Key.ToLowerInvariant(), ph.Value(ctx, client));
 | 
			
		||||
                var lowerKey = ph.Key.ToLowerInvariant();
 | 
			
		||||
                if (str.Contains(lowerKey))
 | 
			
		||||
                    str = str.Replace(lowerKey, ph.Value(ctx, client));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var ph in responsePlaceholders)
 | 
			
		||||
            {
 | 
			
		||||
                str = str.Replace(ph.Key.ToLowerInvariant(), ph.Value(ctx, resolvedTrigger));
 | 
			
		||||
                var lowerKey = ph.Key.ToLowerInvariant();
 | 
			
		||||
                if (str.Contains(lowerKey))
 | 
			
		||||
                    str = str.Replace(lowerKey, ph.Value(ctx, resolvedTrigger));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var ph in regexPlaceholders)
 | 
			
		||||
            {
 | 
			
		||||
                str = ph.Key.Replace(str, ph.Value);
 | 
			
		||||
                str = await ph.Key.ReplaceAsync(str, ph.Value);
 | 
			
		||||
            }
 | 
			
		||||
            return str;
 | 
			
		||||
        }
 | 
			
		||||
@@ -100,8 +130,8 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
        public static string TriggerWithContext(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client)
 | 
			
		||||
            => cr.Trigger.ResolveTriggerString(ctx, client);
 | 
			
		||||
 | 
			
		||||
        public static string ResponseWithContext(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client)
 | 
			
		||||
            => cr.Response.ResolveResponseString(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client));
 | 
			
		||||
        public static Task<string > ResponseWithContextAsync(this CustomReaction cr, IUserMessage ctx, DiscordShardedClient client)
 | 
			
		||||
            => cr.Response.ResolveResponseStringAsync(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client));
 | 
			
		||||
 | 
			
		||||
        public static async Task<IUserMessage> Send(this CustomReaction cr, IUserMessage context, DiscordShardedClient client, CustomReactionsService crs)
 | 
			
		||||
        {
 | 
			
		||||
@@ -113,7 +143,7 @@ namespace NadekoBot.Services.CustomReactions
 | 
			
		||||
            {
 | 
			
		||||
                return await channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText ?? "");
 | 
			
		||||
            }
 | 
			
		||||
            return await channel.SendMessageAsync(cr.ResponseWithContext(context, client).SanitizeMentions());
 | 
			
		||||
            return await channel.SendMessageAsync((await cr.ResponseWithContextAsync(context, client)).SanitizeMentions());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@@ -18,6 +19,23 @@ namespace NadekoBot.Extensions
 | 
			
		||||
{
 | 
			
		||||
    public static class Extensions
 | 
			
		||||
    {
 | 
			
		||||
        public static async Task<string> ReplaceAsync(this Regex regex, string input, Func<Match, Task<string>> replacementFn)
 | 
			
		||||
        {
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var lastIndex = 0;
 | 
			
		||||
 | 
			
		||||
            foreach (Match match in regex.Matches(input))
 | 
			
		||||
            {
 | 
			
		||||
                sb.Append(input, lastIndex, match.Index - lastIndex)
 | 
			
		||||
                  .Append(await replacementFn(match).ConfigureAwait(false));
 | 
			
		||||
 | 
			
		||||
                lastIndex = match.Index + match.Length;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            sb.Append(input, lastIndex, input.Length - lastIndex);
 | 
			
		||||
            return sb.ToString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void ThrowIfNull<T>(this T obj, string name) where T : class
 | 
			
		||||
        {
 | 
			
		||||
            if (obj == null)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user