added %img:YOUR_TAG% custom reactions placeholder to pull imgur images with that tag.

This commit is contained in:
Master Kwoth 2017-06-17 15:23:13 +02:00
parent 838da3d827
commit abd2937708
2 changed files with 68 additions and 20 deletions

View File

@ -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());
}
}
}

View File

@ -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)