mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
247 lines
7.7 KiB
C#
247 lines
7.7 KiB
C#
using System.Threading.Tasks;
|
|
using Discord;
|
|
using Discord.Commands;
|
|
using NadekoBot.Common.Attributes;
|
|
using NadekoBot.Services;
|
|
using NadekoBot.Services.Database.Models;
|
|
using NadekoBot.Db;
|
|
using NadekoBot.Extensions;
|
|
using NadekoBot.Modules.Administration.Services;
|
|
using NadekoBot.Modules.Utility.Services;
|
|
|
|
namespace NadekoBot.Modules.Utility;
|
|
|
|
public partial class Utility
|
|
{
|
|
[Group]
|
|
public class RemindCommands : NadekoSubmodule<RemindService>
|
|
{
|
|
private readonly DbService _db;
|
|
private readonly GuildTimezoneService _tz;
|
|
|
|
public RemindCommands(DbService db, GuildTimezoneService tz)
|
|
{
|
|
_db = db;
|
|
_tz = tz;
|
|
}
|
|
|
|
public enum MeOrHere
|
|
{
|
|
Me,
|
|
Here
|
|
}
|
|
|
|
[NadekoCommand, Aliases]
|
|
[Priority(1)]
|
|
public async Task Remind(MeOrHere meorhere, [Leftover] string remindString)
|
|
{
|
|
if (!_service.TryParseRemindMessage(remindString, out var remindData))
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.remind_invalid);
|
|
return;
|
|
}
|
|
|
|
ulong target;
|
|
target = meorhere == MeOrHere.Me ? ctx.User.Id : ctx.Channel.Id;
|
|
if (!await RemindInternal(target, meorhere == MeOrHere.Me || ctx.Guild is null, remindData.Time, remindData.What)
|
|
.ConfigureAwait(false))
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.remind_too_long).ConfigureAwait(false);
|
|
}
|
|
}
|
|
|
|
[NadekoCommand, Aliases]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(GuildPerm.ManageMessages)]
|
|
[Priority(0)]
|
|
public async Task Remind(ITextChannel channel, [Leftover] string remindString)
|
|
{
|
|
var perms = ((IGuildUser) ctx.User).GetPermissions(channel);
|
|
if (!perms.SendMessages || !perms.ViewChannel)
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.cant_read_or_send).ConfigureAwait(false);
|
|
return;
|
|
}
|
|
|
|
if (!_service.TryParseRemindMessage(remindString, out var remindData))
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.remind_invalid);
|
|
return;
|
|
}
|
|
|
|
|
|
if (!await RemindInternal(channel.Id, false, remindData.Time, remindData.What)
|
|
.ConfigureAwait(false))
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.remind_too_long).ConfigureAwait(false);
|
|
}
|
|
}
|
|
|
|
public enum Server
|
|
{
|
|
Server = int.MinValue,
|
|
Srvr = int.MinValue,
|
|
Serv = int.MinValue,
|
|
S = int.MinValue,
|
|
}
|
|
|
|
[NadekoCommand, Aliases]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(GuildPerm.Administrator)]
|
|
[Priority(0)]
|
|
public Task RemindList(Server _, int page = 1)
|
|
=> RemindList(page, true);
|
|
|
|
[NadekoCommand, Aliases]
|
|
[Priority(1)]
|
|
public Task RemindList(int page = 1)
|
|
=> RemindList(page, false);
|
|
|
|
private async Task RemindList(int page, bool isServer)
|
|
{
|
|
if (--page < 0)
|
|
return;
|
|
|
|
var embed = _eb.Create()
|
|
.WithOkColor()
|
|
.WithTitle(GetText(isServer ? strs.reminder_server_list : strs.reminder_list));
|
|
|
|
List<Reminder> rems;
|
|
await using (var uow = _db.GetDbContext())
|
|
{
|
|
if (isServer)
|
|
{
|
|
rems = uow.Reminders
|
|
.RemindersForServer(ctx.Guild.Id, page)
|
|
.ToList();
|
|
}
|
|
else
|
|
{
|
|
rems = uow.Reminders
|
|
.RemindersFor(ctx.User.Id, page)
|
|
.ToList();
|
|
}
|
|
}
|
|
|
|
if (rems.Any())
|
|
{
|
|
var i = 0;
|
|
foreach (var rem in rems)
|
|
{
|
|
var when = rem.When;
|
|
var diff = when - DateTime.UtcNow;
|
|
embed.AddField(
|
|
$"#{++i + (page * 10)} {rem.When:HH:mm yyyy-MM-dd} UTC (in {(int) diff.TotalHours}h {(int) diff.Minutes}m)",
|
|
$@"`Target:` {(rem.IsPrivate ? "DM" : "Channel")}
|
|
`TargetId:` {rem.ChannelId}
|
|
`Message:` {rem.Message?.TrimTo(50)}", false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
embed.WithDescription(GetText(strs.reminders_none));
|
|
}
|
|
|
|
embed.AddPaginatedFooter(page + 1, null);
|
|
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
|
}
|
|
|
|
[NadekoCommand, Aliases]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(GuildPerm.Administrator)]
|
|
[Priority(0)]
|
|
public Task RemindDelete(Server _, int index)
|
|
=> RemindDelete(index, true);
|
|
|
|
[NadekoCommand, Aliases]
|
|
[Priority(1)]
|
|
public Task RemindDelete(int index)
|
|
=> RemindDelete(index, false);
|
|
|
|
private async Task RemindDelete(int index, bool isServer)
|
|
{
|
|
if (--index < 0)
|
|
return;
|
|
|
|
Reminder rem = null;
|
|
await using (var uow = _db.GetDbContext())
|
|
{
|
|
var rems = isServer
|
|
? uow.Reminders
|
|
.RemindersForServer(ctx.Guild.Id, index / 10)
|
|
.ToList()
|
|
: uow.Reminders
|
|
.RemindersFor(ctx.User.Id, index / 10)
|
|
.ToList();
|
|
|
|
var pageIndex = index % 10;
|
|
if (rems.Count > pageIndex)
|
|
{
|
|
rem = rems[pageIndex];
|
|
uow.Reminders.Remove(rem);
|
|
uow.SaveChanges();
|
|
}
|
|
}
|
|
|
|
if (rem is null)
|
|
{
|
|
await ReplyErrorLocalizedAsync(strs.reminder_not_exist).ConfigureAwait(false);
|
|
}
|
|
else
|
|
{
|
|
await ReplyConfirmLocalizedAsync(strs.reminder_deleted(index + 1));
|
|
}
|
|
}
|
|
|
|
private async Task<bool> RemindInternal(ulong targetId, bool isPrivate, TimeSpan ts, string message)
|
|
{
|
|
var time = DateTime.UtcNow + ts;
|
|
|
|
if (ts > TimeSpan.FromDays(60))
|
|
return false;
|
|
|
|
if (ctx.Guild != null)
|
|
{
|
|
var perms = ((IGuildUser) ctx.User).GetPermissions((IGuildChannel) ctx.Channel);
|
|
if (!perms.MentionEveryone)
|
|
{
|
|
message = message.SanitizeAllMentions();
|
|
}
|
|
}
|
|
|
|
var rem = new Reminder
|
|
{
|
|
ChannelId = targetId,
|
|
IsPrivate = isPrivate,
|
|
When = time,
|
|
Message = message,
|
|
UserId = ctx.User.Id,
|
|
ServerId = ctx.Guild?.Id ?? 0
|
|
};
|
|
|
|
await using (var uow = _db.GetDbContext())
|
|
{
|
|
uow.Reminders.Add(rem);
|
|
await uow.SaveChangesAsync();
|
|
}
|
|
|
|
var gTime = ctx.Guild is null
|
|
? time
|
|
: TimeZoneInfo.ConvertTime(time, _tz.GetTimeZoneOrUtc(ctx.Guild.Id));
|
|
try
|
|
{
|
|
await SendConfirmAsync(
|
|
"⏰ " + GetText(strs.remind(
|
|
Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username),
|
|
Format.Bold(message),
|
|
$"{ts.Days}d {ts.Hours}h {ts.Minutes}min",
|
|
gTime, gTime))).ConfigureAwait(false);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
} |