From 5471b412d93384811f3ce8860c0d1d0e49594a95 Mon Sep 17 00:00:00 2001 From: Andriy <30056636+West14@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:53:01 +0300 Subject: [PATCH 1/2] [code-watcher] Add CodeWatcherMode option. There are three option values: - Disabled: module does nothing (wow). - Remove: module removes matching messages and sends temporary message to instruct user what to do. - Upload: module uploads detected code to configured Haste Server. --- modules/CodeWatcher/CodeWatcher.cs | 14 +++++++ modules/CodeWatcher/CodeWatcher.csproj | 6 +++ modules/CodeWatcher/Dto/HasteResponse.cs | 11 +++++ modules/CodeWatcher/Handler.cs | 42 +++++++++++++++++-- .../CodeWatcher/Options/CodeWatcherMode.cs | 21 ++++++++++ modules/CodeWatcher/Service/HasteService.cs | 32 ++++++++++++++ modules/CodeWatcher/Service/IHasteService.cs | 9 ++++ modules/CodeWatcher/StringExtension.cs | 9 ++-- 8 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 modules/CodeWatcher/Dto/HasteResponse.cs create mode 100644 modules/CodeWatcher/Options/CodeWatcherMode.cs create mode 100644 modules/CodeWatcher/Service/HasteService.cs create mode 100644 modules/CodeWatcher/Service/IHasteService.cs diff --git a/modules/CodeWatcher/CodeWatcher.cs b/modules/CodeWatcher/CodeWatcher.cs index 0dfe046..0b51462 100644 --- a/modules/CodeWatcher/CodeWatcher.cs +++ b/modules/CodeWatcher/CodeWatcher.cs @@ -1,9 +1,23 @@ using Kruzya.TelegramBot.Core; +using Kruzya.TelegramBot.Core.Extensions; +using Microsoft.Extensions.DependencyInjection; +using West.TelegramBot.CodeWatcher.Options; +using West.TelegramBot.CodeWatcher.Service; namespace West.TelegramBot.CodeWatcher { public class CodeWatcher : Module { public CodeWatcher(Core core) : base(core) {} + + public override void ConfigureServices(IServiceCollection services) + { + services.AddOption(); + + services.AddHttpClient(c => + { + c.BaseAddress = new Uri(Core.Configuration["HastebinUrl"]!); + }); + } } } \ No newline at end of file diff --git a/modules/CodeWatcher/CodeWatcher.csproj b/modules/CodeWatcher/CodeWatcher.csproj index 62dbc28..d4176ad 100644 --- a/modules/CodeWatcher/CodeWatcher.csproj +++ b/modules/CodeWatcher/CodeWatcher.csproj @@ -12,4 +12,10 @@ + + + + + + diff --git a/modules/CodeWatcher/Dto/HasteResponse.cs b/modules/CodeWatcher/Dto/HasteResponse.cs new file mode 100644 index 0000000..1a1f31f --- /dev/null +++ b/modules/CodeWatcher/Dto/HasteResponse.cs @@ -0,0 +1,11 @@ +namespace West.TelegramBot.CodeWatcher.Dto; + +public class HasteResponse +{ + public HasteResponse(string key) + { + Key = key; + } + + public string Key { get; set; } +} \ No newline at end of file diff --git a/modules/CodeWatcher/Handler.cs b/modules/CodeWatcher/Handler.cs index b4ea6f2..939d520 100644 --- a/modules/CodeWatcher/Handler.cs +++ b/modules/CodeWatcher/Handler.cs @@ -7,16 +7,22 @@ using Kruzya.TelegramBot.Core.Extensions; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; +using West.TelegramBot.CodeWatcher.Options; +using West.TelegramBot.CodeWatcher.Service; namespace West.TelegramBot.CodeWatcher; public class Handler : BotEventHandler { private readonly ConcurrentBag _requests; + private readonly CodeWatcherMode _mode; + private readonly IHasteService _haste; - public Handler(ConcurrentBag requests) + public Handler(ConcurrentBag requests, CodeWatcherMode mode, IHasteService haste) { _requests = requests; + _mode = mode; + _haste = haste; } [Update(InChat.Public, UpdateFlag.Message | UpdateFlag.EditedMessage)] @@ -35,7 +41,6 @@ public class Handler : BotEventHandler return; } - if (!await Bot.CanDeleteMessagesAsync(Chat)) { return; @@ -69,14 +74,43 @@ public class Handler : BotEventHandler if (entityLines.Count >= 20 || entityLines.Any(line => line.Length > 160)) { - await DeleteAndNotifyAsync(message); + await ProcessDetectedCode(message); return; } } } } - public async Task DeleteAndNotifyAsync(Message message) + public async Task ProcessDetectedCode(Message message) + { + switch (await _mode.GetValueAsync(Chat.Id)) + { + case "disabled": + return; + + case "remove": + await RemoveDetectedCode(message); + break; + + case "upload": + await UploadDetectedCode(message); + break; + + } + } + + public async Task UploadDetectedCode(Message message) + { + var resp = await _haste.PostDocumentAsync(message.Text!); + await Bot.DeleteMessageAsync(Chat.Id, message.MessageId); + + await Bot.SendTextMessageAsync(Chat.Id, + $"{message.From?.ToHtml()}, you posted something long and pre-escaped, so I decided to upload it to our paste service for you.\n" + + $"Here is the link: {_haste.GetHasteUri() + resp.Key}", + parseMode: ParseMode.Html); + } + + public async Task RemoveDetectedCode(Message message) { await Bot.DeleteMessageAsync(Chat.Id, message.MessageId); var notifyMsg = await Bot.SendTextMessageAsync(Chat.Id, diff --git a/modules/CodeWatcher/Options/CodeWatcherMode.cs b/modules/CodeWatcher/Options/CodeWatcherMode.cs new file mode 100644 index 0000000..c68610a --- /dev/null +++ b/modules/CodeWatcher/Options/CodeWatcherMode.cs @@ -0,0 +1,21 @@ +using Kruzya.TelegramBot.Core.Options; + +namespace West.TelegramBot.CodeWatcher.Options; + +public class CodeWatcherMode : AbstractOption +{ + public override string OptionId => "codeWatcherMode"; + public override string OptionName => "CodeWatcher™ mode"; + public override OptionType OptionType => OptionType.Select; + public override string DefaultValue => "remove"; + + public CodeWatcherMode(IOptionProvider optionProvider) : base(optionProvider) + { + ChoiceList.AddRange(new [] + { + new SelectChoice("disabled", "Disabled", "D"), + new SelectChoice("remove", "Remove", "R"), + new SelectChoice("upload", "Upload", "U") + }); + } +} \ No newline at end of file diff --git a/modules/CodeWatcher/Service/HasteService.cs b/modules/CodeWatcher/Service/HasteService.cs new file mode 100644 index 0000000..4ad574b --- /dev/null +++ b/modules/CodeWatcher/Service/HasteService.cs @@ -0,0 +1,32 @@ +using System.Net.Http.Json; +using West.TelegramBot.CodeWatcher.Dto; + +namespace West.TelegramBot.CodeWatcher.Service; + +public class HasteService : IHasteService +{ + private readonly HttpClient _client; + + public HasteService(HttpClient client) + { + _client = client; + } + + public async Task PostDocumentAsync(string data) + { + var response = await (await _client.PostAsync("documents", new StringContent(data))) + .Content.ReadFromJsonAsync(); + + if (response == null) + { + throw new Exception("Haste returned some shit"); + } + + return response; + } + + public Uri GetHasteUri() + { + return _client.BaseAddress!; + } +} \ No newline at end of file diff --git a/modules/CodeWatcher/Service/IHasteService.cs b/modules/CodeWatcher/Service/IHasteService.cs new file mode 100644 index 0000000..5f93e70 --- /dev/null +++ b/modules/CodeWatcher/Service/IHasteService.cs @@ -0,0 +1,9 @@ +using West.TelegramBot.CodeWatcher.Dto; + +namespace West.TelegramBot.CodeWatcher.Service; + +public interface IHasteService +{ + public Task PostDocumentAsync(string data); + public Uri GetHasteUri(); +} \ No newline at end of file diff --git a/modules/CodeWatcher/StringExtension.cs b/modules/CodeWatcher/StringExtension.cs index b3e98a8..cc56088 100644 --- a/modules/CodeWatcher/StringExtension.cs +++ b/modules/CodeWatcher/StringExtension.cs @@ -5,13 +5,10 @@ public static class StringExtension // https://stackoverflow.com/a/23408020 public static IEnumerable SplitToLines(this string input) { - using (var reader = new StringReader(input)) + using var reader = new StringReader(input); + while (reader.ReadLine() is { } line) { - string line; - while ((line = reader.ReadLine()) != null) - { - yield return line; - } + yield return line; } } } \ No newline at end of file From 80718630377e7cd3a849d3bc2e45902fa8ad0e67 Mon Sep 17 00:00:00 2001 From: Andriy <30056636+West14@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:22:28 +0300 Subject: [PATCH 2/2] [core] Reduce chunk to fit option title into button --- Core/Handler/SettingsHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Handler/SettingsHandler.cs b/Core/Handler/SettingsHandler.cs index f192994..9ab34a8 100644 --- a/Core/Handler/SettingsHandler.cs +++ b/Core/Handler/SettingsHandler.cs @@ -184,7 +184,7 @@ public class SettingsHandler : CommonHandler var keyboardLayout = _options.ToAsyncEnumerable() .SelectAwait(async x => await GetKeyboardButton(x)) .ToEnumerable() - .Chunk(3); + .Chunk(2); return new InlineKeyboardMarkup(keyboardLayout); }