From e39f0969b06709943d826643b7122373ba338eb9 Mon Sep 17 00:00:00 2001 From: Andreas Bielawski Date: Thu, 5 Nov 2020 19:34:45 +0100 Subject: [PATCH] Reformat --- Bot.cs | 43 ++++++++++++++++------- Commands.cs | 89 +++++++++++++++++++++++++++++------------------- Configuration.cs | 3 +- RegexHandler.cs | 21 +++++++----- RssBotFeed.cs | 36 +++++++++++++------- Utils.cs | 21 ++++++++---- 6 files changed, 137 insertions(+), 76 deletions(-) diff --git a/Bot.cs b/Bot.cs index 0e837c0..5cd7bfb 100644 --- a/Bot.cs +++ b/Bot.cs @@ -19,7 +19,8 @@ namespace RSSBot { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static HashSet Handlers; - private static void Main(string[] args) { + private static void Main(string[] args) + { Configuration.Parse(); BotClient = new TelegramBotClient(Configuration.BotToken); try { @@ -77,12 +78,15 @@ namespace RSSBot { Save(); } - private static void ReadAllFeeds() { + private static void ReadAllFeeds() + { RedisValue[] allFeedUrls = Configuration.Database.SetMembers($"{Configuration.RedisHash}:feeds"); foreach (RedisValue feedUrl in allFeedUrls) { HashSet subs = new HashSet(); RedisValue[] allSubs = Configuration.Database.SetMembers($"{Configuration.RedisHash}:{feedUrl}:subs"); - foreach (RedisValue sub in allSubs) subs.Add(Convert.ToInt64(sub)); + foreach (RedisValue sub in allSubs) { + subs.Add(Convert.ToInt64(sub)); + } string lastEntry = Configuration.Database.HashGet($"{Configuration.RedisHash}:{feedUrl}", "last_entry"); @@ -91,28 +95,43 @@ namespace RSSBot { } } - private static void OnProcessExit(object? sender, EventArgs e) { + private static void OnProcessExit(object? sender, EventArgs e) + { Save(); } - private static void Bot_OnMessage(object? sender, MessageEventArgs messageEventArgs) { + private static void Bot_OnMessage(object? sender, MessageEventArgs messageEventArgs) + { Message message = messageEventArgs.Message; - if (message == null || message.Type != MessageType.Text) return; - if (!Configuration.Admins.Contains(message.From.Id)) return; + if (message == null || message.Type != MessageType.Text) { + return; + } - foreach (RegexHandler handler in Handlers.Where(handler => handler.HandleUpdate(message))) + if (!Configuration.Admins.Contains(message.From.Id)) { + return; + } + + foreach (RegexHandler handler in Handlers.Where(handler => handler.HandleUpdate(message))) { handler.ProcessUpdate(message); + } } - public static async void Save() { - if (RssBotFeeds.Count > 0) Logger.Info("Speichere Daten..."); + public static async void Save() + { + if (RssBotFeeds.Count > 0) { + Logger.Info("Speichere Daten..."); + } foreach (RssBotFeed feed in RssBotFeeds) { string feedKey = $"{Configuration.RedisHash}:{feed.Url}"; - if (string.IsNullOrWhiteSpace(feed.LastEntry)) continue; + if (string.IsNullOrWhiteSpace(feed.LastEntry)) { + continue; + } await Configuration.Database.HashSetAsync(feedKey, "last_entry", feed.LastEntry); - foreach (long chatId in feed.Subs) await Configuration.Database.SetAddAsync($"{feedKey}:subs", chatId); + foreach (long chatId in feed.Subs) { + await Configuration.Database.SetAddAsync($"{feedKey}:subs", chatId); + } await Configuration.Database.SetAddAsync($"{Configuration.RedisHash}:feeds", feed.Url); } diff --git a/Commands.cs b/Commands.cs index 56c8788..3f5edf1 100644 --- a/Commands.cs +++ b/Commands.cs @@ -17,7 +17,8 @@ namespace RSSBot { public static class Commands { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public static async void Welcome(Message message, GroupCollection matches) { + public static async void Welcome(Message message, GroupCollection matches) + { await Bot.BotClient.SendTextMessageAsync( message.Chat, "Willkommen beim RSS-Bot!\nSende /help, um zu starten.", @@ -25,7 +26,8 @@ namespace RSSBot { ); } - public static async void Help(Message message, GroupCollection matches) { + public static async void Help(Message message, GroupCollection matches) + { await Bot.BotClient.SendTextMessageAsync( message.Chat, "/rss [Chat]: Abonnierte Feeds anzeigen\n" + @@ -37,7 +39,8 @@ namespace RSSBot { ); } - public static async void Subscribe(Message message, GroupCollection args) { + public static async void Subscribe(Message message, GroupCollection args) + { string url = args[1].Value; long chatId = message.Chat.Id; RssBotFeed feed = new RssBotFeed(url); @@ -49,20 +52,21 @@ namespace RSSBot { string chatName = args[2].Value; bool isId = long.TryParse(chatName, out chatId); - if (isId) + if (isId) { try { chatInfo = await Bot.BotClient.GetChatAsync(chatId); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } - else + } else { try { chatInfo = await Bot.BotClient.GetChatAsync(chatName); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } + } chatId = chatInfo.Id; @@ -86,10 +90,11 @@ namespace RSSBot { // Check if we already have the feed RssBotFeed existingFeed = Bot.RssBotFeeds .FirstOrDefault(x => x.Url.ToLower().Equals(feed.Url.ToLower())); - if (existingFeed == null) + if (existingFeed == null) { Bot.RssBotFeeds.Add(feed); - else + } else { feed = existingFeed; + } // Check if chat already subscribed if (feed.Subs.Contains(chatId)) { @@ -101,7 +106,8 @@ namespace RSSBot { } } - public static async void Unsubscribe(Message message, GroupCollection args) { + public static async void Unsubscribe(Message message, GroupCollection args) + { string url = args[1].Value; long chatId = message.Chat.Id; RssBotFeed feed = Bot.RssBotFeeds @@ -112,20 +118,21 @@ namespace RSSBot { string chatName = args[2].Value; bool isId = long.TryParse(chatName, out chatId); - if (isId) + if (isId) { try { chatInfo = await Bot.BotClient.GetChatAsync(chatId); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } - else + } else { try { chatInfo = await Bot.BotClient.GetChatAsync(chatName); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } + } chatId = chatInfo.Id; @@ -142,13 +149,16 @@ namespace RSSBot { } feed.Cleanup(chatId); - if (feed.Subs.Count == 0) Bot.RssBotFeeds.Remove(feed); + if (feed.Subs.Count == 0) { + Bot.RssBotFeeds.Remove(feed); + } await Bot.BotClient.SendTextMessageAsync(message.Chat, "✅ Feed deabonniert!"); Bot.Save(); } - public static async void Show(Message message, GroupCollection args) { + public static async void Show(Message message, GroupCollection args) + { long chatId = message.Chat.Id; string chatTitle = message.Chat.Type.Equals(ChatType.Private) ? message.Chat.FirstName : message.Chat.Title; await Bot.BotClient.SendChatActionAsync(message.Chat, ChatAction.Typing); @@ -158,20 +168,21 @@ namespace RSSBot { string chatName = args[1].Value; bool isId = long.TryParse(chatName, out chatId); - if (isId) + if (isId) { try { chatInfo = await Bot.BotClient.GetChatAsync(chatId); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } - else + } else { try { chatInfo = await Bot.BotClient.GetChatAsync(chatName); } catch { await Bot.BotClient.SendTextMessageAsync(message.Chat, "❌ Dieser Kanal existiert nicht."); return; } + } chatId = chatInfo.Id; chatTitle = chatInfo.Title; @@ -190,13 +201,16 @@ namespace RSSBot { text.Append("❌ Keine Feeds abonniert."); } else { text.Append($"{HttpUtility.HtmlEncode(chatTitle)} hat abonniert:\n"); - for (int i = 0; i < feeds.Count; i++) text.Append($"{i + 1}) {feeds[i].Url}\n"); + for (int i = 0; i < feeds.Count; i++) { + text.Append($"{i + 1}) {feeds[i].Url}\n"); + } } await Bot.BotClient.SendTextMessageAsync(message.Chat, text.ToString(), ParseMode.Html, true); } - public static async void Sync() { + public static async void Sync() + { Logger.Info("================================"); bool hadEntries = false; foreach (RssBotFeed feed in Bot.RssBotFeeds.ToList()) { @@ -220,7 +234,9 @@ namespace RSSBot { foreach (FeedItem entry in feed.NewEntries) { string postTitle = "Kein Titel"; - if (!string.IsNullOrWhiteSpace(entry.Title)) postTitle = Utils.StripHtml(entry.Title); + if (!string.IsNullOrWhiteSpace(entry.Title)) { + postTitle = Utils.StripHtml(entry.Title); + } string postLink = feed.MainLink; string linkName = postLink; @@ -234,20 +250,22 @@ namespace RSSBot { // Remove "www." int index = linkName.IndexOf("www.", StringComparison.Ordinal); - if (index > -1) linkName = linkName.Remove(index, 4); + if (index > -1) { + linkName = linkName.Remove(index, 4); + } string content = ""; - if (!string.IsNullOrWhiteSpace(entry.Content)) + if (!string.IsNullOrWhiteSpace(entry.Content)) { content = Utils.ProcessContent(entry.Content); - else if (!string.IsNullOrWhiteSpace(entry.Description)) + } else if (!string.IsNullOrWhiteSpace(entry.Description)) { content = Utils.ProcessContent(entry.Description); + } string text = $"{postTitle}\n{feed.Title}\n{content}"; text += $"\nWeiterlesen auf {linkName}"; // Send - foreach (long chatId in feed.Subs.ToList()) - { + foreach (long chatId in feed.Subs.ToList()) { await SendFinishedMessage(chatId, text, feed); } } @@ -255,38 +273,39 @@ namespace RSSBot { Logger.Info("Nächster Check in 60 Sekunden"); - if (hadEntries) Bot.Save(); + if (hadEntries) { + Bot.Save(); + } Bot.JobQueue.Change(TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1)); } private static async Task SendFinishedMessage(long chatId, string text, RssBotFeed feed, int waitTime = 10) { - try - { + try { await Bot.BotClient.SendTextMessageAsync(chatId, text, ParseMode.Html, true, true); Thread.Sleep(1000); - } catch (ApiRequestException e) - { - if (e.ErrorCode.Equals(403)) - { + } catch (ApiRequestException e) { + if (e.ErrorCode.Equals(403)) { Logger.Warn(e.Message); feed.Cleanup(chatId); if (feed.Subs.Count == 0) // was last subscriber + { Bot.RssBotFeeds.Remove(feed); - } else - { + } + } else { Logger.Error($"{e.ErrorCode}: {e.Message}"); } - } catch (HttpRequestException e) // likely 429 + } catch (HttpRequestException) // likely 429 { - Logger.Warn($"Got rate limited, waiting {waitTime} seconds..."); + Logger.Warn($"Rate-Limit erreicht, warte {waitTime} Sekunden..."); Thread.Sleep(waitTime * 1000); - await SendFinishedMessage(chatId, text, feed, (waitTime * 2)); + await SendFinishedMessage(chatId, text, feed, waitTime * 2); } } - public static async void ShowAvailableFeeds(Message message, GroupCollection args) { + public static async void ShowAvailableFeeds(Message message, GroupCollection args) + { string url = args[1].Value; IEnumerable feeds; try { diff --git a/Configuration.cs b/Configuration.cs index 30642d1..08226b3 100644 --- a/Configuration.cs +++ b/Configuration.cs @@ -18,7 +18,8 @@ namespace RSSBot { public static List Admins; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public static void Parse() { + public static void Parse() + { if (!File.Exists("NLog.config")) { Console.WriteLine("NLog.config nicht gefunden, setze auf INFO..."); LoggingConfiguration config = new LoggingConfiguration(); diff --git a/RegexHandler.cs b/RegexHandler.cs index 765e6e1..6e3293a 100644 --- a/RegexHandler.cs +++ b/RegexHandler.cs @@ -4,38 +4,41 @@ using Telegram.Bot.Types; namespace RSSBot { /// - /// RegexHandler for Telegram Bots. + /// RegexHandler for Telegram Bots. /// public class RegexHandler { - private string Pattern; - private Action CallbackFunction; + private readonly Action CallbackFunction; + private readonly string Pattern; /// - /// Constructor for the RegexHandler. + /// Constructor for the RegexHandler. /// /// Regex pattern /// Callback function to call when the update should be processed - public RegexHandler(string pattern, Action callback) { + public RegexHandler(string pattern, Action callback) + { Pattern = pattern; CallbackFunction = callback; } /// - /// Checks whether the update should be handled by this handler. + /// Checks whether the update should be handled by this handler. /// /// Telegram Message object /// true if the update should be handled - public bool HandleUpdate(Message message) { + public bool HandleUpdate(Message message) + { return Regex.IsMatch(message.Text, Pattern, RegexOptions.IgnoreCase); } /// - /// Calls the assoicated callback function. + /// Calls the assoicated callback function. /// /// Telegram Message object - public void ProcessUpdate(Message message) { + public void ProcessUpdate(Message message) + { GroupCollection matches = Regex.Match(message.Text, Pattern, RegexOptions.IgnoreCase diff --git a/RssBotFeed.cs b/RssBotFeed.cs index e8f9bb4..74f114e 100644 --- a/RssBotFeed.cs +++ b/RssBotFeed.cs @@ -6,14 +6,12 @@ using CodeHollow.FeedReader; namespace RSSBot { public class RssBotFeed { + public readonly HashSet Subs = new HashSet(); public readonly string Url; public string LastEntry; - public readonly HashSet Subs = new HashSet(); - public string MainLink { get; private set; } - public string Title { get; private set; } - public List NewEntries { get; private set; } - - public RssBotFeed(string url, string lastEntry = null, HashSet subs = null) { + + public RssBotFeed(string url, string lastEntry = null, HashSet subs = null) + { Url = url; if (!string.IsNullOrWhiteSpace(lastEntry)) { LastEntry = lastEntry; @@ -24,7 +22,12 @@ namespace RSSBot { } } - public async Task Check() { + public string MainLink { get; private set; } + public string Title { get; private set; } + public List NewEntries { get; private set; } + + public async Task Check() + { Feed feed = await FeedReader.ReadAsync(Url); if (string.IsNullOrWhiteSpace(feed.Link)) { throw new Exception("Kein gültiger RSS-Feed."); @@ -33,7 +36,10 @@ namespace RSSBot { MainLink = feed.Link; Title = feed.Title; - if (feed.Items == null || feed.Items.Count <= 0) return; + if (feed.Items == null || feed.Items.Count <= 0) { + return; + } + NewEntries = string.IsNullOrWhiteSpace(LastEntry) ? feed.Items.ToList() : GetNewEntries(feed.Items); @@ -43,7 +49,8 @@ namespace RSSBot { : feed.Items.First().Id; } - private List GetNewEntries(IEnumerable entries) { + private List GetNewEntries(IEnumerable entries) + { List newEntries = new List(); foreach (FeedItem entry in entries) { if (!string.IsNullOrWhiteSpace(entry.Id)) { @@ -65,17 +72,22 @@ namespace RSSBot { return newEntries; } - public override string ToString() { + public override string ToString() + { return $"RSS-Feed: '{Url}'"; } - public void Cleanup(long chatId) { + public void Cleanup(long chatId) + { Subs.Remove(chatId); string feedKey = $"{Configuration.RedisHash}:{Url}"; Configuration.Database.SetRemove($"{feedKey}:subs", chatId); // No subscribers, delete all references - if (Subs.Count != 0 || !Configuration.Database.KeyExists(feedKey)) return; + if (Subs.Count != 0 || !Configuration.Database.KeyExists(feedKey)) { + return; + } + Configuration.Database.KeyDelete(feedKey); Configuration.Database.KeyDelete($"{feedKey}:subs"); Configuration.Database.SetRemove($"{Configuration.RedisHash}:feeds", Url); diff --git a/Utils.cs b/Utils.cs index 106d97b..01297d5 100644 --- a/Utils.cs +++ b/Utils.cs @@ -9,11 +9,13 @@ namespace RSSBot { public static class Utils { private static readonly Regex RegexHtml = new Regex("<.*?>"); - public static string StripHtml(string input) { + public static string StripHtml(string input) + { return RegexHtml.Replace(input, string.Empty).Trim(); } - private static string CleanRss(string input) { + private static string CleanRss(string input) + { string[] replacements = { "[←]", "[…]", @@ -65,22 +67,27 @@ namespace RSSBot { return input; } - public static string ProcessContent(string input) { - var content = StripHtml(HttpUtility.HtmlDecode(input)); + public static string ProcessContent(string input) + { + string content = StripHtml(HttpUtility.HtmlDecode(input)); content = CleanRss(content); - if (content.Length > 250) content = content.Substring(0, 250) + "..."; + if (content.Length > 250) { + content = content.Substring(0, 250) + "..."; + } return content; } - public static GroupCollection ReturnMatches(string text, string pattern) { + public static GroupCollection ReturnMatches(string text, string pattern) + { return Regex.Match(text, pattern, RegexOptions.IgnoreCase ).Groups; } - public static async Task IsBotAdmin(long chatId) { + public static async Task IsBotAdmin(long chatId) + { ChatMember chatMember = await Bot.BotClient.GetChatMemberAsync(chatId, Bot.BotClient.BotId); return chatMember.Status.Equals(ChatMemberStatus.Administrator); }