made reminders a bit cooler
This commit is contained in:
parent
7a9c6cec16
commit
d69b90bbd1
|
@ -11,15 +11,15 @@ namespace DeukBot4.Database
|
||||||
public static ConnectionMultiplexer Redis = ConnectionMultiplexer.Connect("127.0.0.1");
|
public static ConnectionMultiplexer Redis = ConnectionMultiplexer.Connect("127.0.0.1");
|
||||||
|
|
||||||
|
|
||||||
public void AddReminder(TimeSpan time, string message, ulong channel, ulong author, ulong recipient)
|
public async Task AddReminder(TimeSpan time, string message, ulong channel, ulong author, ulong recipient)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var db = Redis.GetDatabase();
|
var db = Redis.GetDatabase();
|
||||||
var id = Guid.NewGuid().ToString();
|
var id = Guid.NewGuid().ToString();
|
||||||
var expectedTime = DateTime.UtcNow.Add(time);
|
var expectedTime = DateTime.UtcNow.Add(time);
|
||||||
db.SortedSetAdd("deukbot_reminders", (RedisValue)id, expectedTime.ToBinary());
|
db.SortedSetAddAsync("deukbot_reminders", (RedisValue)id, expectedTime.ToBinary());
|
||||||
db.HashSet((RedisKey) id, new[]
|
db.HashSetAsync((RedisKey) id, new[]
|
||||||
{
|
{
|
||||||
new HashEntry("channel", channel),
|
new HashEntry("channel", channel),
|
||||||
new HashEntry("message", message),
|
new HashEntry("message", message),
|
||||||
|
@ -62,7 +62,7 @@ namespace DeukBot4.Database
|
||||||
db.KeyDelete(val);
|
db.KeyDelete(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.SortedSetRemoveRangeByScore("deukbot_reminders", Double.MinValue, desiredTopScore);
|
db.SortedSetRemoveRangeByScoreAsync("deukbot_reminders", Double.MinValue, desiredTopScore);
|
||||||
|
|
||||||
await Task.Delay(checkTime);
|
await Task.Delay(checkTime);
|
||||||
await CheckReminders();
|
await CheckReminders();
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
|
||||||
using DeukBot4.APIHandlers;
|
|
||||||
using DeukBot4.Database;
|
|
||||||
using DeukBot4.Utilities;
|
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
@ -24,7 +18,7 @@ namespace DeukBot4.MessageHandlers
|
||||||
#pragma warning disable 4014
|
#pragma warning disable 4014
|
||||||
CommandHandler.CommandHandler.HandleMessage(message);
|
CommandHandler.CommandHandler.HandleMessage(message);
|
||||||
HandlePrivateMessage(message);
|
HandlePrivateMessage(message);
|
||||||
HandleReminder(message);
|
ReminderHandler.HandleReminder(message);
|
||||||
ImageBackupHandler.Backup(message);
|
ImageBackupHandler.Backup(message);
|
||||||
JokeHandlers.DeltaHandler(message);
|
JokeHandlers.DeltaHandler(message);
|
||||||
JokeHandlers.DadJokeHandler(message);
|
JokeHandlers.DadJokeHandler(message);
|
||||||
|
@ -66,70 +60,5 @@ namespace DeukBot4.MessageHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Regex ReminderMatcher =
|
|
||||||
new Regex(
|
|
||||||
@".*(remind\s*((?<recipient>me)|<@!*(?<recipient>\d*)>)\s*to)(?<action>.*)(in\s*)(?<timeNum>\d)\s*(?<timeId>\w*)",
|
|
||||||
RegexOptions.IgnoreCase);
|
|
||||||
private static async Task HandleReminder(SocketMessage message)
|
|
||||||
{
|
|
||||||
var match = ReminderMatcher.Match(message.Content);
|
|
||||||
if (!match.Success)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var recipient = match.Groups["recipient"].Captures[0].Value;
|
|
||||||
var action = match.Groups["action"].Value.Trim();
|
|
||||||
if (string.IsNullOrWhiteSpace(action))
|
|
||||||
return;
|
|
||||||
var timeNumber = double.Parse(match.Groups["timeNum"].Value);
|
|
||||||
var timeIdentifier = match.Groups["timeId"].Value.Trim();
|
|
||||||
TimeSpan timespan;
|
|
||||||
if (timeIdentifier.ToLowerInvariant().StartsWith("minu"))
|
|
||||||
{
|
|
||||||
timespan = TimeSpan.FromMinutes(timeNumber);
|
|
||||||
}
|
|
||||||
else if (timeIdentifier.ToLowerInvariant().StartsWith("hour"))
|
|
||||||
{
|
|
||||||
timespan = TimeSpan.FromHours(timeNumber);
|
|
||||||
}
|
|
||||||
else if (timeIdentifier.ToLowerInvariant().StartsWith("day"))
|
|
||||||
{
|
|
||||||
timespan = TimeSpan.FromDays(timeNumber);
|
|
||||||
}
|
|
||||||
else if (timeIdentifier.ToLowerInvariant().StartsWith("month"))
|
|
||||||
{
|
|
||||||
var dest = DateTime.UtcNow.AddMonths((int) (timeNumber));
|
|
||||||
dest = dest.AddDays(timeNumber % 1 * 30);
|
|
||||||
timespan = dest - DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
else if (timeIdentifier.ToLowerInvariant().StartsWith("year"))
|
|
||||||
{
|
|
||||||
var dest = DateTime.UtcNow.AddYears((int) (timeNumber));
|
|
||||||
dest = dest.AddDays(timeNumber % 1 * 365);
|
|
||||||
timespan = dest - DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Main.LogError("Unknown timespan identifier: " + timeIdentifier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timespan.TotalMinutes < 5)
|
|
||||||
{
|
|
||||||
message.Channel.SendMessageAsync("A reminder should be at least 5 minutes in the future");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ulong.TryParse(recipient, out var recip))
|
|
||||||
{
|
|
||||||
recip = message.Author.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReminderHandler.Main.AddReminder(timespan, action, message.Channel.Id, message.Author.Id, recip);
|
|
||||||
message.Channel.SendMessageAsync(
|
|
||||||
message.Author.Id == recip
|
|
||||||
? $"Reminder set! I will remind you in {timespan.ToPrettyFormat()} to {action}"
|
|
||||||
: $"Reminder set! I will remind <@!{recip}> in {timespan.ToPrettyFormat()} to {action}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DeukBot4.Utilities;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace DeukBot4.MessageHandlers
|
||||||
|
{
|
||||||
|
public static class ReminderHandler
|
||||||
|
{
|
||||||
|
private static Regex ReminderMatcher =
|
||||||
|
new Regex(
|
||||||
|
@".*(remind\s*((?<recipient>me)|<@!*(?<recipient2>\d*)>)\s*to)(?<action>.*)(in\s+)(?<time>.*)",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
public static async Task HandleReminder(SocketMessage message)
|
||||||
|
{
|
||||||
|
var match = ReminderMatcher.Match(message.Content);
|
||||||
|
if (!match.Success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var recipient = match.Groups["recipient"].Captures[0].Value;
|
||||||
|
var action = match.Groups["action"].Value.Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(action))
|
||||||
|
return;
|
||||||
|
var time = match.Groups["time"].Value;
|
||||||
|
var timespan = ParseTime(time);
|
||||||
|
if (!timespan.HasValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (timespan.Value.TotalMinutes < 5)
|
||||||
|
{
|
||||||
|
message.Channel.SendMessageAsync("A reminder should be at least 5 minutes in the future");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ulong.TryParse(recipient, out var recip))
|
||||||
|
{
|
||||||
|
recip = message.Author.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Database.ReminderHandler.Main.AddReminder(timespan.Value, action, message.Channel.Id, message.Author.Id, recip);
|
||||||
|
message.Channel.SendMessageAsync(
|
||||||
|
message.Author.Id == recip
|
||||||
|
? $"Reminder set! I will remind you in {timespan.Value.ToPrettyFormat()} to {action}"
|
||||||
|
: $"Reminder set! I will remind <@!{recip}> in {timespan.Value.ToPrettyFormat()} to {action}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Regex TimespanMatcher =
|
||||||
|
new Regex(@"(?<timeNumber>\d+.?\d*)\s*(?<timeId>minutes*|hours*|days*|weeks*|months*|years*)\W*(and )*",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
private static TimeSpan? ParseTime(string message)
|
||||||
|
{
|
||||||
|
var matches = TimespanMatcher.Matches(message);
|
||||||
|
if (matches.Count == 0)
|
||||||
|
return null;
|
||||||
|
var timespan = new TimeSpan();
|
||||||
|
foreach (Match match in matches)
|
||||||
|
{
|
||||||
|
if (!match.Success)
|
||||||
|
continue;
|
||||||
|
var timeId = match.Groups["timeId"].Value.ToLowerInvariant();
|
||||||
|
var timeAmount = double.Parse(match.Groups["timeNumber"].Value);
|
||||||
|
if (timeId.StartsWith("minute"))
|
||||||
|
timespan += TimeSpan.FromMinutes(timeAmount);
|
||||||
|
else if (timeId.StartsWith("hour"))
|
||||||
|
timespan += TimeSpan.FromHours(timeAmount);
|
||||||
|
else if (timeId.StartsWith("day"))
|
||||||
|
timespan += TimeSpan.FromDays(timeAmount);
|
||||||
|
else if (timeId.StartsWith("week"))
|
||||||
|
timespan += TimeSpan.FromDays(timeAmount * 7);
|
||||||
|
else if (timeId.StartsWith("month"))
|
||||||
|
{
|
||||||
|
var target = DateTime.UtcNow.AddMonths((int) timeAmount);
|
||||||
|
target = target.AddDays(timeAmount % 1 * 30);
|
||||||
|
timespan += (target - DateTime.UtcNow);
|
||||||
|
}
|
||||||
|
else if (timeId.StartsWith("month"))
|
||||||
|
{
|
||||||
|
var target = DateTime.UtcNow.AddMonths((int) timeAmount);
|
||||||
|
target = target.AddDays(timeAmount % 1 * 30);
|
||||||
|
timespan += (target - DateTime.UtcNow);
|
||||||
|
}
|
||||||
|
else if (timeId.StartsWith("year"))
|
||||||
|
{
|
||||||
|
var target = DateTime.UtcNow.AddYears((int) timeAmount);
|
||||||
|
target = target.AddDays(timeAmount % 1 * 365);
|
||||||
|
timespan += (target - DateTime.UtcNow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return timespan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ using Discord;
|
||||||
using Discord.Commands.Builders;
|
using Discord.Commands.Builders;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
using ReminderHandler = DeukBot4.Database.ReminderHandler;
|
||||||
|
|
||||||
namespace DeukBot4
|
namespace DeukBot4
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue