Skip to content

Commit b7439f1

Browse files
authored
Merge pull request #999 from 13xforever/feature/ocr
Re-introduce OCR for images
2 parents cdac510 + e99e507 commit b7439f1

18 files changed

+421
-118
lines changed

Clients/CompatApiClient/CompatApiClient.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
1111
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.6" />
1212
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
13-
<PackageReference Include="NLog" Version="5.5.0" />
13+
<PackageReference Include="NLog" Version="6.0.1" />
1414
</ItemGroup>
1515

1616
</Project>

CompatBot/Commands/AutoCompleteProviders/EventNameAutoCompleteProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ public async ValueTask<IEnumerable<DiscordAutoCompleteChoice>> AutoCompleteAsync
8383
.AsEnumerable()
8484
.Concat(fuzzy)
8585
.Distinct();
86-
query = eventNames.Concat(names);
86+
query = new[] { context.UserInput }
87+
.Concat(eventNames)
88+
.Concat(names);
8789
}
8890
return query
8991
.Distinct()

CompatBot/Commands/AutoCompleteProviders/ProductCodeAutoCompleteProvider.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ public async ValueTask<IEnumerable<DiscordAutoCompleteChoice>> AutoCompleteAsync
6666
.AsNoTracking()
6767
.AsEnumerable()
6868
.Select(t => (code: t.ProductCode, title: t.Name!));
69-
result = prefixMatches
69+
result = new[] { (code: context.UserInput, title: context.UserInput.Trim(100)) }
70+
.Concat(prefixMatches)
7071
.Concat(substringMatches)
7172
.Distinct()
7273
.Take(25);
7374
}
74-
return result.Select(i => new DiscordAutoCompleteChoice($"{i.code}: {i.title}".Trim(100), i.code)).ToList();
75+
return result
76+
.Select(i => new DiscordAutoCompleteChoice($"{i.code}: {i.title}".Trim(100), i.code))
77+
.ToList();
7578
}
7679
}

CompatBot/Commands/BotStatus.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using CompatBot.Database.Providers;
66
using CompatBot.EventHandlers;
77
using CompatBot.EventHandlers.LogParsing.SourceHandlers;
8+
using CompatBot.Ocr;
89
using Microsoft.EntityFrameworkCore;
910

1011
namespace CompatBot.Commands;
@@ -20,11 +21,8 @@ public static async ValueTask Show(SlashCommandContext ctx)
2021
var latency = ctx.Client.GetConnectionLatency(Config.BotGuildId);
2122
var embed = new DiscordEmbedBuilder { Color = DiscordColor.Purple }
2223
.AddField("Current Uptime", Config.Uptime.Elapsed.AsShortTimespan(), true)
23-
.AddField("Discord Latency", $"{latency.TotalMilliseconds:0.0} ms", true);
24-
if (Config.AzureComputerVisionKey is {Length: >0})
25-
embed.AddField("Max OCR Queue", MediaScreenshotMonitor.MaxQueueLength.ToString(), true);
26-
else
27-
embed.AddField("Max OCR Queue", "-", true);
24+
.AddField("Discord Latency", $"{latency.TotalMilliseconds:0.0} ms", true)
25+
.AddField("Max OCR Queue", $"{OcrProvider.BackendName} / {MediaScreenshotMonitor.MaxQueueLength}", true);
2826
var osInfo = RuntimeInformation.OSDescription;
2927
if (Environment.OSVersion.Platform is PlatformID.Unix or PlatformID.MacOSX)
3028
osInfo = RuntimeInformation.RuntimeIdentifier;

CompatBot/Commands/Vision.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.IO;
22
using System.Net;
33
using System.Net.Http;
4+
using System.Net.Mime;
45
using CompatBot.EventHandlers;
56
using CompatBot.Utils.Extensions;
67
using DSharpPlus.Commands.Processors.TextCommands;
@@ -354,20 +355,20 @@ internal static IEnumerable<string> GetImagesFromEmbeds(DiscordMessage msg)
354355
{
355356
foreach (var embed in msg.Embeds)
356357
{
357-
if (embed.Image?.Url?.ToString() is string url)
358+
if (embed.Image?.Url?.ToString() is {Length: >0} url)
358359
yield return url;
359-
else if (embed.Thumbnail?.Url?.ToString() is string thumbUrl)
360+
else if (embed.Thumbnail?.Url?.ToString() is {Length: >0} thumbUrl)
360361
yield return thumbUrl;
361362
}
362363
}
363364

364-
internal static IEnumerable<DiscordAttachment> GetImageAttachments(DiscordMessage message)
365+
internal static IEnumerable<string> GetImageAttachments(DiscordMessage message)
365366
=> message.Attachments.Where(a =>
366-
a.FileName.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase)
367-
|| a.FileName.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)
368-
|| a.FileName.EndsWith(".jpeg", StringComparison.InvariantCultureIgnoreCase)
369-
//|| a.FileName.EndsWith(".webp", StringComparison.InvariantCultureIgnoreCase)
370-
);
367+
a.MediaType is MediaTypeNames.Image.Jpeg
368+
or MediaTypeNames.Image.Png
369+
or MediaTypeNames.Image.Webp
370+
&& a.Url is {Length: >0}
371+
).Select(att => att.Url!);
371372

372373
private static string GetDescription(ImageDescriptionDetails description, AdultInfo adultInfo)
373374
{
@@ -416,8 +417,8 @@ private static async Task ReactToTagsAsync(DiscordMessage reactMsg, IEnumerable<
416417
return null;
417418

418419
var reactMsg = tctx.Message;
419-
if (GetImageAttachments(reactMsg).FirstOrDefault() is DiscordAttachment attachment)
420-
imageUrl = attachment.Url;
420+
if (GetImageAttachments(reactMsg).FirstOrDefault() is {} attUrl)
421+
imageUrl = attUrl;
421422
imageUrl = imageUrl?.Trim() ?? "";
422423
if (!string.IsNullOrEmpty(imageUrl)
423424
&& imageUrl.StartsWith('<')
@@ -431,17 +432,16 @@ private static async Task ReactToTagsAsync(DiscordMessage reactMsg, IEnumerable<
431432
|| str.StartsWith("last")
432433
|| str.StartsWith("previous")
433434
|| str.StartsWith("^"))
434-
&& ctx.Channel.PermissionsFor(
435-
await ctx.Client.GetMemberAsync(ctx.Guild, ctx.Client.CurrentUser).ConfigureAwait(false)
436-
).HasPermission(DiscordPermission.ReadMessageHistory))
435+
&& await ctx.Client.GetMemberAsync(ctx.Guild, ctx.Client.CurrentUser).ConfigureAwait(false) is {} member
436+
&& ctx.Channel.PermissionsFor(member).HasPermission(DiscordPermission.ReadMessageHistory))
437437
try
438438
{
439439
var previousMessages = (await ctx.Channel.GetMessagesBeforeCachedAsync(tctx.Message.Id, 10).ConfigureAwait(false))!;
440440
imageUrl = (
441441
from m in previousMessages
442442
where m.Attachments?.Count > 0
443-
from a in GetImageAttachments(m)
444-
select a.Url
443+
from url in GetImageAttachments(m)
444+
select url
445445
).FirstOrDefault();
446446
if (string.IsNullOrEmpty(imageUrl))
447447
{

CompatBot/CompatBot.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<PackageReference Include="DSharpPlus.Commands" Version="5.0.0-nightly-02520" />
4747
<PackageReference Include="DSharpPlus.Interactivity" Version="5.0.0-nightly-02520" />
4848
<PackageReference Include="DSharpPlus.Natives.Zstd" Version="1.5.7.21" />
49+
<PackageReference Include="Florence2" Version="24.11.53800" />
4950
<PackageReference Include="Google.Apis.Drive.v3" Version="1.69.0.3783" />
5051
<PackageReference Include="MathParser.org-mXparser" Version="6.1.0" />
5152
<PackageReference Include="MegaApiClient" Version="1.10.4" />
@@ -66,12 +67,13 @@
6667
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.22.1" />
6768
<PackageReference Include="Nerdbank.Streams" Version="2.12.87" />
6869
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
69-
<PackageReference Include="NLog" Version="5.5.0" />
70-
<PackageReference Include="NLog.Extensions.Logging" Version="5.5.0" />
70+
<PackageReference Include="NLog" Version="6.0.1" />
71+
<PackageReference Include="NLog.Extensions.Logging" Version="6.0.1" />
7172
<PackageReference Include="NReco.Text.AhoCorasickDoubleArrayTrie" Version="1.1.1" />
7273
<PackageReference Include="SharpCompress" Version="0.40.0" />
7374
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.6" />
7475
<PackageReference Include="System.Linq.Async" Version="6.0.3" />
76+
<PackageReference Include="TesseractCSharp" Version="1.0.5" />
7577
</ItemGroup>
7678
<ItemGroup>
7779
<ProjectReference Include="..\Clients\CirrusCiClient\CirrusCiClient.csproj" />

CompatBot/Config.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,16 @@ internal static class Config
8787
public static string PreferredFontFamily => config.GetValue(nameof(PreferredFontFamily), "");
8888
public static string LogPath => config.GetValue(nameof(LogPath), "./logs/"); // paths are relative to the working directory
8989
public static string IrdCachePath => config.GetValue(nameof(IrdCachePath), "./ird/");
90-
public static string RedumpDatfileCachePath => config.GetValue(nameof(RedumpDatfileCachePath), "./datfile/");
90+
public static string BotAppDataFolder => config.GetValue(
91+
nameof(BotAppDataFolder),
92+
Path.Combine(
93+
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
94+
"compat-bot"
95+
)
96+
);
97+
public static string RedumpDatfileCachePath => Path.Combine(BotAppDataFolder, "compat-bot", "datfile");
9198
public static string RenameNameSuffix => config.GetValue(nameof(RenameNameSuffix), " (Rule 7)");
99+
public static string OcrBackend => config.GetValue(nameof(OcrBackend), "auto"); // possible values: auto, tesseract, florence2, azure
92100

93101
public static double GameTitleMatchThreshold => config.GetValue(nameof(GameTitleMatchThreshold), 0.57);
94102
public static byte[] CryptoSalt => Convert.FromBase64String(config.GetValue(nameof(CryptoSalt), ""));
@@ -246,10 +254,12 @@ private static ILogger GetLog()
246254
var loggingConfig = new NLog.Config.LoggingConfiguration();
247255
var fileTarget = new FileTarget("logfile") {
248256
FileName = CurrentLogPath,
257+
ArchiveFileName = CurrentLogPath,
258+
ArchiveSuffixFormat = ".{1:yyyyMMdd}.{0:00}",
259+
//ArchiveNumbering = ArchiveNumberingMode.DateAndSequence,
260+
//ConcurrentWrites = false,
249261
ArchiveEvery = FileArchivePeriod.Day,
250-
//ArchiveSuffixFormat = ".{1:yyyyMMdd}.{0:00}",
251-
ArchiveNumbering = ArchiveNumberingMode.DateAndSequence,
252-
ConcurrentWrites = false,
262+
MaxArchiveDays = 30,
253263
KeepFileOpen = true,
254264
AutoFlush = false,
255265
OpenFileFlushTimeout = 1,
@@ -333,4 +343,4 @@ public static async Task GetCurrentGitRevisionAsync(CancellationToken cancellati
333343
var branch = await GitRunner.Exec("rev-parse --abbrev-ref HEAD", cancellationToken);
334344
GitRevision = $"{commit} on {branch}";
335345
}
336-
}
346+
}

CompatBot/EventHandlers/ContentFilterMonitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public static async Task OnReaction(DiscordClient c, MessageReactionAddedEventAr
2424
if (message?.Author is null)
2525
message = await e.Channel.GetMessageAsync(e.Message.Id).ConfigureAwait(false);
2626
}
27+
if (message.Attachments.Any())
28+
MediaScreenshotMonitor.EnqueueOcrTask(message);
2729
await ContentFilter.IsClean(c, message).ConfigureAwait(false);
2830
}
2931
}

0 commit comments

Comments
 (0)