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 ) ;
2016-08-28 00:46:36 +00:00
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 ( ) ;
2016-08-28 00:46:36 +00:00
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 (
2016-08-28 00:46:36 +00:00
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 ( ) ;
}
}
}
2016-09-23 08:23:54 +00:00
[LocalizedCommand, LocalizedRemarks, LocalizedSummary, LocalizedAlias]
2016-08-25 22:05:29 +00:00
[RequireContext(ContextType.Guild)]
2016-08-28 02:33:09 +00:00
public async Task Remind ( IUserMessage umsg , string meorchannel , string timeStr , [ Remainder ] string message )
2016-08-25 22:05:29 +00:00
{
2016-08-28 02:33:09 +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 ;
2016-08-28 02:33:09 +00:00
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 )
{
2016-08-28 02:33:09 +00:00
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 ,
2016-08-28 02:33:09 +00:00
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
}
2016-08-28 02:33:09 +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
}
2016-09-30 02:20:09 +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
2016-09-30 02:20:09 +00:00
if ( string . IsNullOrWhiteSpace ( arg ) )
return ;
2016-08-25 22:05:29 +00:00
2016-09-30 02:20:09 +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
}
}
}