Files
archived-discord-bot/CompatBot/Utils/EmbedPager.cs
13xforever 7fd7d09973 RPCS3 Compatibility Bot reimplemented in C# for .NET Core
RPCS3 Compatibility Bot reimplemented in C# for .NET Core

Current status of this PR:
* tested and targeted for .NET Core 2.1
* all functionality is either on par or improved compared to the python version
* compatibility with current bot.db should be preserved in all upgrade scenarios
* some bot management commands were changed (now under !sudo bot)
* standard help generator for the new discord client is ... different;
  compatibility with old format could be restored through custom formatter if needed
* everything has been split in more loosely tied components for easier extensibility and maintenance
* log parsing has been rewritten and should work ~2x as fast
2018-07-20 09:22:28 +02:00

114 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using CompatApiClient;
using DSharpPlus.Entities;
using Remotion.Linq.Parsing;
namespace CompatBot.Utils
{
internal class EmbedPager
{
private const int MaxFieldLength = 1024;
private const int MaxTitleSize = 256;
private const int MaxFields = 25;
public IEnumerable<DiscordEmbed> BreakInEmbeds(DiscordEmbedBuilder builder, IEnumerable<string> lines, int maxLinesPerField = 10)
{
var fieldCount = 0;
foreach (var field in BreakInFieldContent(lines, maxLinesPerField))
{
if (fieldCount == MaxFields)
{
yield return builder.Build();
builder.ClearFields();
fieldCount = 0;
}
builder.AddField(field.title.Trim(MaxTitleSize), field.content, true);
fieldCount++;
}
if (fieldCount > 0)
yield return builder.Build();
}
private IEnumerable<(string title, string content)> BreakInFieldContent(IEnumerable<string> lines, int maxLinesPerField = 10)
{
if (maxLinesPerField < 1)
throw new ArgumentException("Expected a number greater than 0, but was " + maxLinesPerField, nameof(maxLinesPerField));
var buffer = new StringBuilder();
var lineCount = 0;
string firstLine = null;
string lastLine = null;
foreach (var line in lines)
{
if (string.IsNullOrEmpty(firstLine))
firstLine = line;
if (lineCount == maxLinesPerField)
{
yield return (MakeTitle(firstLine, lastLine), buffer.ToString());
buffer.Clear();
lineCount = 0;
firstLine = line;
}
if (buffer.Length + line.Length + Environment.NewLine.Length > MaxFieldLength)
{
if (buffer.Length + line.Length > MaxFieldLength)
{
if (buffer.Length == 0)
yield return (MakeTitle(line, line), line.Trim(MaxFieldLength));
else
{
yield return (MakeTitle(firstLine, lastLine), buffer.ToString());
buffer.Clear().Append(line);
lineCount = 1;
firstLine = line;
}
}
else
{
yield return (MakeTitle(firstLine, line), buffer.Append(line).ToString());
buffer.Clear();
lineCount = 0;
}
}
else
{
if (buffer.Length > 0)
buffer.AppendLine();
buffer.Append(line);
lineCount++;
lastLine = line;
}
}
if (buffer.Length > 0)
yield return (MakeTitle(firstLine, lastLine), buffer.ToString());
}
private static string MakeTitle(string first, string last)
{
if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(last))
return first + last;
if (first == last)
return first;
if (last.StartsWith(first))
return $"{first} - {last}";
var commonPrefix = "";
var maxPrefixSize = Math.Min(Math.Min(first.Length, last.Length), MaxTitleSize/2);
for (var i = 0; i < maxPrefixSize; i++)
{
if (first[i] == last[i])
commonPrefix += first[i];
else
return $"{commonPrefix}{first[i]}-{commonPrefix}{last[i]}";
}
return commonPrefix;
}
}
}