implement proper image moderation handler

This commit is contained in:
13xforever
2020-03-08 22:44:05 +05:00
parent 86fce35c35
commit b2a8191050
3 changed files with 81 additions and 19 deletions

View File

@@ -123,7 +123,7 @@ namespace CompatBot.Database.Providers
return false;
}
public static async Task PerformFilterActions(DiscordClient client, DiscordMessage message, Piracystring trigger, FilterAction ignoreFlags = 0, string triggerContext = null)
public static async Task PerformFilterActions(DiscordClient client, DiscordMessage message, Piracystring trigger, FilterAction ignoreFlags = 0, string triggerContext = null, string infraction = null, string warningReason = null)
{
if (trigger == null)
return;
@@ -135,13 +135,21 @@ namespace CompatBot.Database.Providers
try
{
await message.Channel.DeleteMessageAsync(message, $"Removed according to filter '{trigger}'").ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e);
severity = ReportSeverity.High;
}
try
{
var author = client.GetMember(message.Author);
Config.Log.Debug($"Removed message from {author.GetMentionWithNickname()} in #{message.Channel.Name}: {message.Content}");
completedActions.Add(FilterAction.RemoveContent);
}
catch
catch (Exception e)
{
severity = ReportSeverity.High;
Config.Log.Warn(e);
}
}
@@ -149,7 +157,7 @@ namespace CompatBot.Database.Providers
{
try
{
await Warnings.AddAsync(client, message, message.Author.Id, message.Author.Username, client.CurrentUser, "Mention of piracy", message.Content.Sanitize()).ConfigureAwait(false);
await Warnings.AddAsync(client, message, message.Author.Id, message.Author.Username, client.CurrentUser, warningReason ?? "Mention of piracy", message.Content.Sanitize()).ConfigureAwait(false);
completedActions.Add(FilterAction.IssueWarning);
}
catch (Exception e)
@@ -187,7 +195,7 @@ namespace CompatBot.Database.Providers
try
{
if (!trigger.Actions.HasFlag(FilterAction.MuteModQueue) && !ignoreFlags.HasFlag(FilterAction.MuteModQueue))
await client.ReportAsync("🤬 Content filter hit", message, trigger.String, triggerContext ?? message.Content, severity, actionList).ConfigureAwait(false);
await client.ReportAsync(infraction ?? "🤬 Content filter hit", message, trigger.String, triggerContext ?? message.Content, severity, actionList).ConfigureAwait(false);
}
catch (Exception e)
{

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CompatBot.Commands;
using CompatBot.Database;
using CompatBot.Database.Providers;
using CompatBot.Utils;
using CompatBot.Utils.Extensions;
using DSharpPlus.EventArgs;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
@@ -16,13 +17,18 @@ namespace CompatBot.EventHandlers
internal sealed class MediaScreenshotMonitor
{
private static readonly ComputerVisionClient client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(Config.AzureComputerVisionKey)) {Endpoint = Config.AzureComputerVisionEndpoint};
private static readonly SemaphoreSlim workSemaphore = new SemaphoreSlim(0);
private static readonly ConcurrentQueue<(MessageCreateEventArgs evt, string readOperationId)> workQueue = new ConcurrentQueue<(MessageCreateEventArgs args, string readOperationId)>();
public static async Task OnMessageCreated(MessageCreateEventArgs e)
public static async Task OnMessageCreated(MessageCreateEventArgs evt)
{
var message = e.Message;
var message = evt.Message;
if (message == null)
return;
if (Config.Moderation.Channels.Contains(evt.Channel.Id) || evt.Channel.Name.Contains("help"))
return;
#if !DEBUG
if (message.Author.IsBotSafeCheck())
return;
@@ -37,26 +43,73 @@ namespace CompatBot.EventHandlers
tasks.Add(client.BatchReadFileAsync(img.Url, Config.Cts.Token));
foreach (var t in tasks)
{
var headers = await t.ConfigureAwait(false);
Config.Log.Trace($"Read result location url: {headers.OperationLocation}");
ReadOperationResult result;
do
try
{
result = await client.GetReadOperationResultAsync(new Uri(headers.OperationLocation).Segments.Last(), Config.Cts.Token).ConfigureAwait(false);
var headers = await t.ConfigureAwait(false);
workQueue.Enqueue((evt, new Uri(headers.OperationLocation).Segments.Last()));
workSemaphore.Release();
}
catch (Exception ex)
{
Config.Log.Warn(ex, "Failed to create a new text recognition task");
}
}
}
public static async Task ProcessWorkQueue()
{
if (string.IsNullOrEmpty(Config.AzureComputerVisionKey))
return;
string reEnqueId = null;
do
{
await workSemaphore.WaitAsync(Config.Cts.Token).ConfigureAwait(false);
if (Config.Cts.IsCancellationRequested)
return;
if (!workQueue.TryDequeue(out var item))
continue;
if (item.readOperationId == reEnqueId)
{
await Task.Delay(100).ConfigureAwait(false);
reEnqueId = null;
if (Config.Cts.IsCancellationRequested)
return;
}
try
{
var result = await client.GetReadOperationResultAsync(item.readOperationId, Config.Cts.Token).ConfigureAwait(false);
if (result.Status == TextOperationStatusCodes.Succeeded)
{
var cnt = true;
var prefix = $"[{item.evt.Message.Id % 100}]";
Config.Log.Debug($"{prefix} OCR result of message{item.evt.Message.JumpLink}:");
foreach (var r in result.RecognitionResults)
foreach (var l in r.Lines)
{
Config.Log.Debug($"{message.Id} text: {l.Text}");
if (await ContentFilter.FindTriggerAsync(FilterContext.Log, l.Text).ConfigureAwait(false) is Piracystring hit)
Config.Log.Debug($"{prefix} {l.Text}");
if (cnt && await ContentFilter.FindTriggerAsync(FilterContext.Log, l.Text).ConfigureAwait(false) is Piracystring hit)
{
await e.Client.ReportAsync("🖼 Screenshot of a pirated game", message, hit.String, l.Text, ReportSeverity.Medium).ConfigureAwait(false);
await ContentFilter.PerformFilterActions(item.evt.Client, item.evt.Message, hit, triggerContext: l.Text, infraction: "🖼 Screenshot of a pirated game", "Screenshot of a pirated game").ConfigureAwait(false);
cnt = false;
}
}
}
} while (result.Status == TextOperationStatusCodes.Running || result.Status == TextOperationStatusCodes.NotStarted);
}
else if (result.Status == TextOperationStatusCodes.NotStarted || result.Status == TextOperationStatusCodes.Running)
{
workQueue.Enqueue(item);
reEnqueId ??= item.readOperationId;
workSemaphore.Release();
}
}
catch (Exception e)
{
Config.Log.Warn(e);
}
} while (!Config.Cts.IsCancellationRequested);
}
}
}

View File

@@ -107,7 +107,8 @@ namespace CompatBot
new PsnScraper().RunAsync(Config.Cts.Token),
GameTdbScraper.RunAsync(Config.Cts.Token),
new AppveyorClient.Client().GetBuildAsync(Guid.NewGuid().ToString(), Config.Cts.Token),
StatsStorage.BackgroundSaveAsync()
StatsStorage.BackgroundSaveAsync(),
MediaScreenshotMonitor.ProcessWorkQueue()
);
try