227 lines
No EOL
7.4 KiB
C#
227 lines
No EOL
7.4 KiB
C#
#nullable disable
|
|
using CommandLine;
|
|
using EllieBot.Modules.Administration.Services;
|
|
|
|
namespace EllieBot.Modules.Administration;
|
|
|
|
public partial class Administration
|
|
{
|
|
[Group]
|
|
public partial class PruneCommands : EllieModule<PruneService>
|
|
{
|
|
private static readonly TimeSpan _twoWeeks = TimeSpan.FromDays(14);
|
|
|
|
public sealed class PruneOptions : IEllieCommandOptions
|
|
{
|
|
[Option(shortName: 's',
|
|
longName: "safe",
|
|
Default = false,
|
|
HelpText = "Whether pinned messages should be deleted.",
|
|
Required = false)]
|
|
public bool Safe { get; set; }
|
|
|
|
[Option(shortName: 'a',
|
|
longName: "after",
|
|
Default = null,
|
|
HelpText = "Prune only messages after the specified message ID.",
|
|
Required = false)]
|
|
public ulong? After { get; set; }
|
|
|
|
public void NormalizeOptions()
|
|
{
|
|
}
|
|
}
|
|
|
|
//deletes her own messages, no perm required
|
|
[Cmd]
|
|
[RequireContext(ContextType.Guild)]
|
|
[EllieOptions<PruneOptions>]
|
|
public async Task Prune(params string[] args)
|
|
{
|
|
var (opts, _) = OptionsParser.ParseFrom(new PruneOptions(), args);
|
|
|
|
var user = await ctx.Guild.GetCurrentUserAsync();
|
|
|
|
var progressMsg = await Response().Pending(strs.prune_progress(0, 100)).SendAsync();
|
|
var progress = GetProgressTracker(progressMsg);
|
|
|
|
PruneResult result;
|
|
if (opts.Safe)
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
100,
|
|
x => x.Author.Id == user.Id && !x.IsPinned,
|
|
progress,
|
|
opts.After);
|
|
else
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
100,
|
|
x => x.Author.Id == user.Id,
|
|
progress,
|
|
opts.After);
|
|
|
|
ctx.Message.DeleteAfter(3);
|
|
|
|
await SendResult(result);
|
|
await progressMsg.DeleteAsync();
|
|
}
|
|
|
|
// prune x
|
|
[Cmd]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(ChannelPerm.ManageMessages)]
|
|
[BotPerm(ChannelPerm.ManageMessages)]
|
|
[EllieOptions<PruneOptions>]
|
|
[Priority(1)]
|
|
public async Task Prune(int count, params string[] args)
|
|
{
|
|
count++;
|
|
if (count < 1)
|
|
return;
|
|
|
|
if (count > 1000)
|
|
count = 1000;
|
|
|
|
var (opts, _) = OptionsParser.ParseFrom<PruneOptions>(new PruneOptions(), args);
|
|
|
|
var progressMsg = await Response().Pending(strs.prune_progress(0, count)).SendAsync();
|
|
var progress = GetProgressTracker(progressMsg);
|
|
|
|
PruneResult result;
|
|
if (opts.Safe)
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
count,
|
|
x => !x.IsPinned && x.Id != progressMsg.Id,
|
|
progress,
|
|
opts.After);
|
|
else
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
count,
|
|
x => x.Id != progressMsg.Id,
|
|
progress,
|
|
opts.After);
|
|
|
|
await SendResult(result);
|
|
await progressMsg.DeleteAsync();
|
|
}
|
|
|
|
private IProgress<(int, int)> GetProgressTracker(IUserMessage progressMsg)
|
|
{
|
|
var progress = new Progress<(int, int)>(async (x) =>
|
|
{
|
|
var (deleted, total) = x;
|
|
try
|
|
{
|
|
await progressMsg.ModifyAsync(props =>
|
|
{
|
|
props.Embed = CreateEmbed()
|
|
.WithPendingColor()
|
|
.WithDescription(GetText(strs.prune_progress(deleted, total)))
|
|
.Build();
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
});
|
|
|
|
return progress;
|
|
}
|
|
|
|
//prune @user [x]
|
|
[Cmd]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(ChannelPerm.ManageMessages)]
|
|
[BotPerm(ChannelPerm.ManageMessages)]
|
|
[EllieOptions<PruneOptions>]
|
|
[Priority(0)]
|
|
public Task Prune(IGuildUser user, int count = 100, params string[] args)
|
|
=> Prune(user.Id, count, args);
|
|
|
|
//prune userid [x]
|
|
[Cmd]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(ChannelPerm.ManageMessages)]
|
|
[BotPerm(ChannelPerm.ManageMessages)]
|
|
[EllieOptions<PruneOptions>]
|
|
[Priority(0)]
|
|
public async Task Prune(ulong userId, int count = 100, params string[] args)
|
|
{
|
|
if (userId == ctx.User.Id)
|
|
count++;
|
|
|
|
if (count < 1)
|
|
return;
|
|
|
|
if (count > 1000)
|
|
count = 1000;
|
|
|
|
var (opts, _) = OptionsParser.ParseFrom<PruneOptions>(new PruneOptions(), args);
|
|
|
|
var progressMsg = await Response().Pending(strs.prune_progress(0, count)).SendAsync();
|
|
var progress = GetProgressTracker(progressMsg);
|
|
|
|
PruneResult result;
|
|
if (opts.Safe)
|
|
{
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
count,
|
|
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks && !m.IsPinned,
|
|
progress,
|
|
opts.After
|
|
);
|
|
}
|
|
else
|
|
{
|
|
result = await _service.PruneWhere((ITextChannel)ctx.Channel,
|
|
count,
|
|
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks,
|
|
progress,
|
|
opts.After
|
|
);
|
|
}
|
|
|
|
await SendResult(result);
|
|
await progressMsg.DeleteAsync();
|
|
}
|
|
|
|
[Cmd]
|
|
[RequireContext(ContextType.Guild)]
|
|
[UserPerm(ChannelPerm.ManageMessages)]
|
|
[BotPerm(ChannelPerm.ManageMessages)]
|
|
public async Task PruneCancel()
|
|
{
|
|
var ok = await _service.CancelAsync(ctx.Guild.Id);
|
|
|
|
if (!ok)
|
|
{
|
|
await Response().Error(strs.prune_not_found).SendAsync();
|
|
return;
|
|
}
|
|
|
|
|
|
await Response().Confirm(strs.prune_cancelled).SendAsync();
|
|
}
|
|
|
|
|
|
private async Task SendResult(PruneResult result)
|
|
{
|
|
switch (result)
|
|
{
|
|
case PruneResult.Success:
|
|
break;
|
|
case PruneResult.AlreadyRunning:
|
|
var msg = await Response().Pending(strs.prune_already_running).SendAsync();
|
|
msg.DeleteAfter(5);
|
|
break;
|
|
case PruneResult.FeatureLimit:
|
|
var msg2 = await Response().Pending(strs.feature_limit_reached_owner).SendAsync();
|
|
msg2.DeleteAfter(10);
|
|
break;
|
|
default:
|
|
Log.Error("Unhandled result received in prune: {Result}", result);
|
|
await Response().Error(strs.error_occured).SendAsync();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} |