2017-07-17 19:42:36 +00:00
|
|
|
|
using System;
|
2017-06-16 22:17:07 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
2017-07-17 19:42:36 +00:00
|
|
|
|
using Discord;
|
|
|
|
|
using NadekoBot.Common.Collections;
|
|
|
|
|
using NadekoBot.Extensions;
|
2017-10-13 04:14:54 +00:00
|
|
|
|
using NadekoBot.Core.Services;
|
2017-06-16 22:17:07 +00:00
|
|
|
|
|
2017-07-17 19:42:36 +00:00
|
|
|
|
namespace NadekoBot.Modules.Administration.Services
|
2017-06-16 22:17:07 +00:00
|
|
|
|
{
|
2017-07-15 03:04:16 +00:00
|
|
|
|
public class PruneService : INService
|
2017-06-16 22:17:07 +00:00
|
|
|
|
{
|
|
|
|
|
//channelids where prunes are currently occuring
|
2017-06-19 15:57:12 +00:00
|
|
|
|
private ConcurrentHashSet<ulong> _pruningGuilds = new ConcurrentHashSet<ulong>();
|
2017-06-16 22:17:07 +00:00
|
|
|
|
private readonly TimeSpan twoWeeks = TimeSpan.FromDays(14);
|
|
|
|
|
|
|
|
|
|
public async Task PruneWhere(ITextChannel channel, int amount, Func<IMessage, bool> predicate)
|
|
|
|
|
{
|
|
|
|
|
channel.ThrowIfNull(nameof(channel));
|
|
|
|
|
if (amount <= 0)
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(amount));
|
|
|
|
|
|
2017-06-19 15:57:12 +00:00
|
|
|
|
if (!_pruningGuilds.Add(channel.GuildId))
|
2017-06-16 22:17:07 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IMessage[] msgs;
|
|
|
|
|
IMessage lastMessage = null;
|
2017-06-19 15:57:12 +00:00
|
|
|
|
msgs = (await channel.GetMessagesAsync(50).Flatten()).Where(predicate).Take(amount).ToArray();
|
2017-06-16 22:17:07 +00:00
|
|
|
|
while (amount > 0 && msgs.Any())
|
|
|
|
|
{
|
|
|
|
|
lastMessage = msgs[msgs.Length - 1];
|
|
|
|
|
|
|
|
|
|
var bulkDeletable = new List<IMessage>();
|
|
|
|
|
var singleDeletable = new List<IMessage>();
|
|
|
|
|
foreach (var x in msgs)
|
|
|
|
|
{
|
|
|
|
|
if (DateTime.UtcNow - x.CreatedAt < twoWeeks)
|
|
|
|
|
bulkDeletable.Add(x);
|
|
|
|
|
else
|
|
|
|
|
singleDeletable.Add(x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bulkDeletable.Count > 0)
|
|
|
|
|
await Task.WhenAll(Task.Delay(1000), channel.DeleteMessagesAsync(bulkDeletable)).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
var i = 0;
|
|
|
|
|
foreach (var group in singleDeletable.GroupBy(x => ++i / (singleDeletable.Count / 5)))
|
|
|
|
|
await Task.WhenAll(Task.Delay(1000), Task.WhenAll(group.Select(x => x.DeleteAsync()))).ConfigureAwait(false);
|
|
|
|
|
|
2017-06-17 11:54:21 +00:00
|
|
|
|
//this isn't good, because this still work as if i want to remove only specific user's messages from the last
|
|
|
|
|
//100 messages, Maybe this needs to be reduced by msgs.Length instead of 100
|
2017-06-19 15:57:12 +00:00
|
|
|
|
amount -= 50;
|
2017-06-16 22:17:07 +00:00
|
|
|
|
if(amount > 0)
|
2017-06-19 15:57:12 +00:00
|
|
|
|
msgs = (await channel.GetMessagesAsync(lastMessage, Direction.Before, 50).Flatten()).Where(predicate).Take(amount).ToArray();
|
2017-06-16 22:17:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-17 11:54:21 +00:00
|
|
|
|
catch
|
2017-06-16 22:17:07 +00:00
|
|
|
|
{
|
2017-06-17 11:54:21 +00:00
|
|
|
|
//ignore
|
2017-06-16 22:17:07 +00:00
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
2017-06-19 15:57:12 +00:00
|
|
|
|
_pruningGuilds.TryRemove(channel.GuildId);
|
2017-06-16 22:17:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|