NadekoBot/src/NadekoBot/Modules/Utility/Commands/Remind.cs

206 lines
7.8 KiB
C#
Raw Normal View History

2016-08-25 22:05:29 +00:00
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility
{
public partial class Utility
{
2016-08-25 22:07:15 +00:00
[Group]
2016-08-25 22:05:29 +00:00
public class RemindCommands
{
Regex regex = new Regex(@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d)w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,2})h)?(?:(?<minutes>\d{1,2})m)?$",
RegexOptions.Compiled | RegexOptions.Multiline);
private string RemindMessageFormat { get; }
2016-08-25 22:05:29 +00:00
IDictionary<string, Func<Reminder, string>> replacements = new Dictionary<string, Func<Reminder, string>>
{
{ "%message%" , (r) => r.Message },
{ "%user%", (r) => $"<@!{r.UserId}>" },
{ "%target%", (r) => r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"}
};
public RemindCommands()
{
List<Reminder> reminders;
using (var uow = DbHandler.UnitOfWork())
{
reminders = uow.Reminders.GetAll().ToList();
RemindMessageFormat = uow.BotConfig.GetOrCreate().RemindMessageFormat;
2016-08-25 22:05:29 +00:00
}
foreach (var r in reminders)
{
var t = StartReminder(r);
}
}
private async Task StartReminder(Reminder r)
{
var now = DateTime.Now;
var twoMins = new TimeSpan(0, 2, 0);
2016-08-26 01:35:10 +00:00
TimeSpan time = r.When - now;
2016-08-25 22:05:29 +00:00
if (time.TotalMilliseconds > int.MaxValue)
return;
await Task.Delay(time);
try
{
IMessageChannel ch;
if (r.IsPrivate)
{
ch = await NadekoBot.Client.GetDMChannelAsync(r.ChannelId).ConfigureAwait(false);
}
else
{
2016-08-29 12:34:46 +00:00
ch = NadekoBot.Client.GetGuild(r.ServerId)?.GetTextChannel(r.ChannelId);
2016-08-25 22:05:29 +00:00
}
if (ch == null)
return;
await ch.SendMessageAsync(
replacements.Aggregate(RemindMessageFormat,
2016-08-25 22:05:29 +00:00
(cur, replace) => cur.Replace(replace.Key, replace.Value(r)))
).ConfigureAwait(false); //it works trust me
}
catch (Exception ex)
{
Console.WriteLine($"Timer error! {ex}");
}
finally
{
using (var uow = DbHandler.UnitOfWork())
{
uow.Reminders.Remove(r);
await uow.CompleteAsync();
}
}
}
[LocalizedCommand, LocalizedRemarks, LocalizedSummary, LocalizedAlias]
2016-08-25 22:05:29 +00:00
[RequireContext(ContextType.Guild)]
public async Task Remind(IUserMessage umsg, string meorchannel, string timeStr, [Remainder] string message)
2016-08-25 22:05:29 +00:00
{
var channel = (ITextChannel)umsg.Channel;
2016-08-25 22:05:29 +00:00
var meorchStr = meorchannel.ToUpperInvariant();
IMessageChannel ch;
bool isPrivate = false;
if (meorchStr == "ME")
{
isPrivate = true;
ch = await ((IGuildUser)umsg.Author).CreateDMChannelAsync().ConfigureAwait(false);
2016-08-25 22:05:29 +00:00
}
else if (meorchStr == "HERE")
{
ch = channel;
}
else
{
ch = channel.Guild.GetTextChannels().FirstOrDefault(c => c.Name == meorchStr || c.Id.ToString() == meorchStr);
}
if (ch == null)
{
await channel.SendMessageAsync($"{umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false);
2016-08-25 22:05:29 +00:00
return;
}
var m = regex.Match(timeStr);
if (m.Length == 0)
{
await channel.SendMessageAsync("Not a valid time format blablabla").ConfigureAwait(false);
return;
}
string output = "";
var namesAndValues = new Dictionary<string, int>();
foreach (var groupName in regex.GetGroupNames())
{
if (groupName == "0") continue;
int value = 0;
int.TryParse(m.Groups[groupName].Value, out value);
if (string.IsNullOrEmpty(m.Groups[groupName].Value))
{
namesAndValues[groupName] = 0;
continue;
}
else if (value < 1 ||
(groupName == "months" && value > 1) ||
(groupName == "weeks" && value > 4) ||
(groupName == "days" && value >= 7) ||
(groupName == "hours" && value > 23) ||
(groupName == "minutes" && value > 59))
{
await channel.SendMessageAsync($"Invalid {groupName} value.").ConfigureAwait(false);
return;
}
else
namesAndValues[groupName] = value;
output += m.Groups[groupName].Value + " " + groupName + " ";
}
var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] +
7 * namesAndValues["weeks"] +
namesAndValues["days"],
namesAndValues["hours"],
namesAndValues["minutes"],
0);
var rem = new Reminder
{
ChannelId = ch.Id,
IsPrivate = isPrivate,
When = time,
Message = message,
UserId = umsg.Author.Id,
2016-08-25 22:05:29 +00:00
ServerId = channel.Guild.Id
};
using (var uow = DbHandler.UnitOfWork())
{
uow.Reminders.Add(rem);
2016-08-26 01:35:10 +00:00
await uow.CompleteAsync();
2016-08-25 22:05:29 +00:00
}
await channel.SendMessageAsync($"⏰ I will remind \"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
2016-08-26 01:35:10 +00:00
await StartReminder(rem);
2016-08-25 22:05:29 +00:00
}
[LocalizedCommand, LocalizedRemarks, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task RemindTemplate(IUserMessage umsg, [Remainder] string arg)
{
var channel = (ITextChannel)umsg.Channel;
2016-08-25 22:05:29 +00:00
if (string.IsNullOrWhiteSpace(arg))
return;
2016-08-25 22:05:29 +00:00
using (var uow = DbHandler.UnitOfWork())
{
uow.BotConfig.GetOrCreate().RemindMessageFormat = arg.Trim();
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.SendMessageAsync("`New remind message set.`");
}
2016-08-25 22:05:29 +00:00
}
}
}