From a1b5db843036d6d7f153ecdc6d9c72172bce2db7 Mon Sep 17 00:00:00 2001 From: Basique Evangelist Date: Sun, 21 Jul 2019 01:54:37 +0300 Subject: [PATCH] Make everything asynchronous --- JetKarmaBot/CommandRouter.cs | 18 ++++++++--- JetKarmaBot/Commands/AwardCommand.cs | 34 +++++++++++---------- JetKarmaBot/Commands/ChangeLocaleCommand.cs | 21 +++++++------ JetKarmaBot/Commands/CurrenciesCommand.cs | 10 +++--- JetKarmaBot/Commands/HelpCommand.cs | 9 +++--- JetKarmaBot/Commands/IChatCommand.cs | 3 +- JetKarmaBot/Commands/LeaderboardCommand.cs | 20 ++++++------ JetKarmaBot/Commands/StatusCommand.cs | 20 +++++++----- JetKarmaBot/JetKarmaBot.cs | 33 ++++++++++---------- 9 files changed, 95 insertions(+), 73 deletions(-) diff --git a/JetKarmaBot/CommandRouter.cs b/JetKarmaBot/CommandRouter.cs index 21ed3cc..1f02714 100644 --- a/JetKarmaBot/CommandRouter.cs +++ b/JetKarmaBot/CommandRouter.cs @@ -1,10 +1,12 @@ using JetKarmaBot.Commands; using JetKarmaBot.Services; +using Microsoft.EntityFrameworkCore; using NLog; using Perfusion; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Telegram.Bot; using Telegram.Bot.Args; @@ -22,7 +24,7 @@ namespace JetKarmaBot BotUser = botUser; } - public bool Execute(object sender, MessageEventArgs args) + public async Task Execute(object sender, MessageEventArgs args) { log.Debug("Message received"); var text = args.Message.Text; @@ -40,27 +42,33 @@ namespace JetKarmaBot if (commands.ContainsKey(cmd.Command)) { log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}"); - return commands[cmd.Command].Execute(cmd, args); + return await commands[cmd.Command].Execute(cmd, args); } } catch (Exception e) { log.Error($"Error while handling command {cmd.Command}!"); log.Error(e); - ReportToAdministratorChats($"Error while handling command {cmd.Command}!\n{e.ToString()}"); + await ReportToAdministratorChats($"Error while handling command {cmd.Command}!\n{e.ToString()}"); } } return false; } - public void ReportToAdministratorChats(string text) + public async Task ReportToAdministratorChats(string text) { using (var db = Db.GetContext()) { + await Task.WhenAll( + (await db.Chats + .Where(x => x.IsAdministrator) + .Select(x => x.ChatId) + .ToArrayAsync()) + .Select(x => Client.SendTextMessageAsync(x, text))); foreach (long chatid in db.Chats.Where(x => x.IsAdministrator).Select(x => x.ChatId)) { - Client.SendTextMessageAsync(chatid, text); + await Client.SendTextMessageAsync(chatid, text); } } } diff --git a/JetKarmaBot/Commands/AwardCommand.cs b/JetKarmaBot/Commands/AwardCommand.cs index 587403a..d36648a 100644 --- a/JetKarmaBot/Commands/AwardCommand.cs +++ b/JetKarmaBot/Commands/AwardCommand.cs @@ -7,6 +7,8 @@ using Telegram.Bot.Types; using Perfusion; using JetKarmaBot.Services; using NLog; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; namespace JetKarmaBot.Commands { @@ -16,14 +18,14 @@ namespace JetKarmaBot.Commands [Inject] private Logger log; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; if (args.Message.ReplyToMessage == null) { - Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardnoreply"]); + await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardnoreply"]); return true; } @@ -34,7 +36,7 @@ namespace JetKarmaBot.Commands if (awarder.Id == recipient.Id) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardself"], replyToMessageId: args.Message.MessageId); @@ -43,7 +45,7 @@ namespace JetKarmaBot.Commands if (Me.Id == recipient.Id) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, awarding ? currentLocale["jetkarmabot.award.errawardbot"] @@ -55,18 +57,18 @@ namespace JetKarmaBot.Commands var text = args.Message.Text; var awardTypeText = cmd.Parameters.FirstOrDefault(); global::JetKarmaBot.Models.AwardType awardType = awardTypeText != null - ? db.AwardTypes.First(at => at.CommandName == awardTypeText) - : db.AwardTypes.Find((sbyte)1); + ? await db.AwardTypes.FirstAsync(at => at.CommandName == awardTypeText) + : await db.AwardTypes.FindAsync((sbyte)1); DateTime cutoff = DateTime.Now - TimeSpan.FromMinutes(5); - if (db.Awards.Where(x => x.Date > cutoff && x.FromId == awarder.Id).Count() >= 10) + if (await db.Awards.Where(x => x.Date > cutoff && x.FromId == awarder.Id).CountAsync() >= 10) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.award.ratelimit"], replyToMessageId: args.Message.MessageId); return true; } - db.Awards.Add(new Models.Award() + await db.Awards.AddAsync(new Models.Award() { AwardTypeId = awardType.AwardTypeId, Amount = (sbyte)(awarding ? 1 : -1), @@ -75,21 +77,21 @@ namespace JetKarmaBot.Commands ChatId = args.Message.Chat.Id }); log.Debug($"Awarded {(awarding ? 1 : -1)}{awardType.Symbol} to {recipient.Username}"); - db.SaveChanges(); - - var recUserName = db.Users.Find(recipient.Id).Username; + await db.SaveChangesAsync(); + + var recUserName = (await db.Users.FindAsync(recipient.Id)).Username; string message = awarding ? string.Format(currentLocale["jetkarmabot.award.awardmessage"], getLocalizedName(awardType, currentLocale), recUserName) : string.Format(currentLocale["jetkarmabot.award.revokemessage"], getLocalizedName(awardType, currentLocale), recUserName); - var currentCount = db.Awards + var currentCount = await db.Awards .Where(aw => aw.ToId == recipient.Id && aw.AwardTypeId == awardType.AwardTypeId && aw.ChatId == args.Message.Chat.Id) - .Sum(aw => aw.Amount); + .SumAsync(aw => aw.Amount); var response = message + "\n" + String.Format(currentLocale["jetkarmabot.award.statustext"], recUserName, currentCount, awardType.Symbol); - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, response, replyToMessageId: args.Message.MessageId); diff --git a/JetKarmaBot/Commands/ChangeLocaleCommand.cs b/JetKarmaBot/Commands/ChangeLocaleCommand.cs index f567e7f..99464e6 100644 --- a/JetKarmaBot/Commands/ChangeLocaleCommand.cs +++ b/JetKarmaBot/Commands/ChangeLocaleCommand.cs @@ -5,6 +5,7 @@ using Perfusion; using JetKarmaBot.Services; using NLog; using System.Linq; +using System.Threading.Tasks; namespace JetKarmaBot.Commands { @@ -14,14 +15,14 @@ namespace JetKarmaBot.Commands [Inject] private Logger log; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; if (cmd.Parameters.Length < 1) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.changelocale.getlocale"], replyToMessageId: args.Message.MessageId); @@ -29,7 +30,7 @@ namespace JetKarmaBot.Commands } else if (cmd.Parameters[0] == "list") { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.changelocale.listalltext"] + "\n" + string.Join("\n", Locale.Select(a => a.Key)), @@ -38,7 +39,7 @@ namespace JetKarmaBot.Commands } else if (cmd.Parameters[0] == "all") { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.changelocale.errorall"], replyToMessageId: args.Message.MessageId); @@ -54,19 +55,19 @@ namespace JetKarmaBot.Commands } catch (LocalizationException e) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, currentLocale["jetkarmabot.changelocale.toomany"] + "\n" + string.Join("\n", (e.Data["LocaleNames"] as Locale[]).Select(x => x.Name)), replyToMessageId: args.Message.MessageId); return true; } - db.Chats.Find(args.Message.Chat.Id).Locale = localeId; + (await db.Chats.FindAsync(args.Message.Chat.Id)).Locale = localeId; log.Debug($"Changed language of chat {args.Message.Chat.Id} to {localeId}"); - db.SaveChanges(); + await db.SaveChangesAsync(); - currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, (currentLocale.HasNote ? currentLocale["jetkarmabot.changelocale.beforenote"] + currentLocale.Note + "\n" : "") + currentLocale["jetkarmabot.changelocale.justchanged"], diff --git a/JetKarmaBot/Commands/CurrenciesCommand.cs b/JetKarmaBot/Commands/CurrenciesCommand.cs index c007365..27c3572 100644 --- a/JetKarmaBot/Commands/CurrenciesCommand.cs +++ b/JetKarmaBot/Commands/CurrenciesCommand.cs @@ -5,6 +5,8 @@ using JetKarmaBot.Services; using Telegram.Bot; using Telegram.Bot.Types.Enums; using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; namespace JetKarmaBot.Commands { @@ -21,14 +23,14 @@ namespace JetKarmaBot.Commands public IReadOnlyCollection Arguments => new ChatCommandArgument[] { }; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; string resp = currentLocale["jetkarmabot.currencies.listtext"] + "\n" + string.Join("\n", - db.AwardTypes.ToList().Select(x => $"{x.Symbol} ({x.CommandName}) {currentLocale["jetkarmabot.awardtypes.nominative." + x.CommandName]}")); - Client.SendTextMessageAsync( + (await db.AwardTypes.ToListAsync()).Select(x => $"{x.Symbol} ({x.CommandName}) {currentLocale["jetkarmabot.awardtypes.nominative." + x.CommandName]}")); + await Client.SendTextMessageAsync( args.Message.Chat.Id, resp, replyToMessageId: args.Message.MessageId, diff --git a/JetKarmaBot/Commands/HelpCommand.cs b/JetKarmaBot/Commands/HelpCommand.cs index 1e455f7..000cfb1 100644 --- a/JetKarmaBot/Commands/HelpCommand.cs +++ b/JetKarmaBot/Commands/HelpCommand.cs @@ -4,6 +4,7 @@ using Perfusion; using JetKarmaBot.Services; using Telegram.Bot; using Telegram.Bot.Types.Enums; +using System.Threading.Tasks; namespace JetKarmaBot.Commands { @@ -28,14 +29,14 @@ namespace JetKarmaBot.Commands } }; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; if (cmd.Parameters.Length < 1) { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, Router.GetHelpText(currentLocale), replyToMessageId: args.Message.MessageId, @@ -44,7 +45,7 @@ namespace JetKarmaBot.Commands } else { - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, Router.GetHelpTextFor(cmd.Parameters[0], currentLocale), replyToMessageId: args.Message.MessageId, diff --git a/JetKarmaBot/Commands/IChatCommand.cs b/JetKarmaBot/Commands/IChatCommand.cs index 436f789..9ebe00c 100644 --- a/JetKarmaBot/Commands/IChatCommand.cs +++ b/JetKarmaBot/Commands/IChatCommand.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using Telegram.Bot.Args; namespace JetKarmaBot.Commands @@ -10,7 +11,7 @@ namespace JetKarmaBot.Commands string DescriptionID { get; } IReadOnlyCollection Arguments { get; } - bool Execute(CommandString cmd, MessageEventArgs messageEventArgs); + Task Execute(CommandString cmd, MessageEventArgs messageEventArgs); } public struct ChatCommandArgument diff --git a/JetKarmaBot/Commands/LeaderboardCommand.cs b/JetKarmaBot/Commands/LeaderboardCommand.cs index a37ac85..ac81e45 100644 --- a/JetKarmaBot/Commands/LeaderboardCommand.cs +++ b/JetKarmaBot/Commands/LeaderboardCommand.cs @@ -17,11 +17,11 @@ namespace JetKarmaBot.Commands { public IReadOnlyCollection Names => new[] { "leaderboard" }; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; var asker = args.Message.From; var awardTypeName = cmd.Parameters.FirstOrDefault(); @@ -33,19 +33,21 @@ namespace JetKarmaBot.Commands var awardTypeIdQuery = from awt in db.AwardTypes where awt.CommandName == awardTypeName select awt.AwardTypeId; - var awardTypeId = awardTypeIdQuery.First(); - var awardType = db.AwardTypes.Find(awardTypeId); + var awardTypeId = await awardTypeIdQuery.FirstAsync(); + var awardType = await db.AwardTypes.FindAsync(awardTypeId); - response = string.Format(currentLocale["jetkarmabot.leaderboard.specifictext"], awardType.Symbol) + "\n" + string.Join('\n', db.Awards + response = string.Format(currentLocale["jetkarmabot.leaderboard.specifictext"], awardType.Symbol) + "\n" + string.Join('\n', + await Task.WhenAll((await db.Awards .Where(x => x.ChatId == args.Message.Chat.Id && x.AwardTypeId == awardTypeId) .GroupBy(x => x.ToId) - .Select(x => new {UserId = x.Key, Amount = x.Sum(y => y.Amount)}) + .Select(x => new { UserId = x.Key, Amount = x.Sum(y => y.Amount) }) .OrderByDescending(x => x.Amount) .Take(5) - .ToList() - .Select((x,index) => $"{index+1}. {db.Users.Find(x.UserId).Username} - {x.Amount}")); + .ToListAsync()) + .Select(async (x, index) => $"{index + 1}. {(await db.Users.FindAsync(x.UserId)).Username} - {x.Amount}")) + ); - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, response, replyToMessageId: args.Message.MessageId); diff --git a/JetKarmaBot/Commands/StatusCommand.cs b/JetKarmaBot/Commands/StatusCommand.cs index 995448d..f753d57 100644 --- a/JetKarmaBot/Commands/StatusCommand.cs +++ b/JetKarmaBot/Commands/StatusCommand.cs @@ -8,6 +8,8 @@ using Telegram.Bot.Args; using Telegram.Bot.Types; using JetKarmaBot.Models; using JetKarmaBot.Services; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; namespace JetKarmaBot.Commands { @@ -15,11 +17,11 @@ namespace JetKarmaBot.Commands { public IReadOnlyCollection Names => new[] { "status" }; - public bool Execute(CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { - var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; var asker = args.Message.From; var awardTypeName = cmd.Parameters.FirstOrDefault(); @@ -38,9 +40,11 @@ namespace JetKarmaBot.Commands where award.ToId == asker.Id && award.ChatId == args.Message.Chat.Id group award by award.AwardTypeId into g select new { AwardTypeId = g.Key, Amount = g.Sum(x => x.Amount) }; - var awardsByType = awardsQuery.ToList(); + var awardsByType = await awardsQuery.ToListAsync(); response = currentLocale["jetkarmabot.status.listalltext"] + "\n" - + string.Join("\n", awardsByType.Select(a => $" - {db.AwardTypes.Find(a.AwardTypeId).Symbol} {a.Amount}")); + + string.Join("\n", await Task.WhenAll( + awardsByType.Select(async a => $" - {(await db.AwardTypes.FindAsync(a.AwardTypeId)).Symbol} {a.Amount}") + )); } } @@ -49,13 +53,13 @@ namespace JetKarmaBot.Commands var awardTypeIdQuery = from awt in db.AwardTypes where awt.CommandName == awardTypeName select awt.AwardTypeId; - var awardTypeId = awardTypeIdQuery.First(); - var awardType = db.AwardTypes.Find(awardTypeId); + var awardTypeId = await awardTypeIdQuery.FirstAsync(); + var awardType = await db.AwardTypes.FindAsync(awardTypeId); - response = string.Format(currentLocale["jetkarmabot.status.listspecifictext"], db.Awards.Where(x => x.AwardTypeId == awardTypeId && x.ToId == asker.Id && x.ChatId == args.Message.Chat.Id).Sum(x => x.Amount), awardType.Symbol); + response = string.Format(currentLocale["jetkarmabot.status.listspecifictext"], await db.Awards.Where(x => x.AwardTypeId == awardTypeId && x.ToId == asker.Id && x.ChatId == args.Message.Chat.Id).SumAsync(x => x.Amount), awardType.Symbol); } - Client.SendTextMessageAsync( + await Client.SendTextMessageAsync( args.Message.Chat.Id, response, replyToMessageId: args.Message.MessageId); diff --git a/JetKarmaBot/JetKarmaBot.cs b/JetKarmaBot/JetKarmaBot.cs index 47f91c6..1e1a841 100644 --- a/JetKarmaBot/JetKarmaBot.cs +++ b/JetKarmaBot/JetKarmaBot.cs @@ -55,22 +55,23 @@ namespace JetKarmaBot var message = messageEventArgs.Message; if (message == null || message.Type != MessageType.Text) return; - using (KarmaContext db = Db.GetContext()) + + Task.Run(async () => { - AddUserToDatabase(db, messageEventArgs.Message.From); - if (messageEventArgs.Message.ReplyToMessage != null) - AddUserToDatabase(db, messageEventArgs.Message.ReplyToMessage.From); - if (!db.Chats.Any(x => x.ChatId == messageEventArgs.Message.Chat.Id)) - db.Chats.Add(new Models.Chat { ChatId = messageEventArgs.Message.Chat.Id }); - db.SaveChanges(); - } - string s = message.Text; - long id = message.Chat.Id; - long from = message.From.Id; - Task.Run(() => Commands.Execute(sender, messageEventArgs)); + using (KarmaContext db = Db.GetContext()) + { + await AddUserToDatabase(db, messageEventArgs.Message.From); + if (messageEventArgs.Message.ReplyToMessage != null) + await AddUserToDatabase(db, messageEventArgs.Message.ReplyToMessage.From); + if (!db.Chats.Any(x => x.ChatId == messageEventArgs.Message.Chat.Id)) + db.Chats.Add(new Models.Chat { ChatId = messageEventArgs.Message.Chat.Id }); + await db.SaveChangesAsync(); + } + await Commands.Execute(sender, messageEventArgs); + }); } - private void AddUserToDatabase(KarmaContext db, Telegram.Bot.Types.User u) + private async Task AddUserToDatabase(KarmaContext db, Telegram.Bot.Types.User u) { string un; if (u.Username == null) @@ -78,9 +79,9 @@ namespace JetKarmaBot else un = "@" + u.Username; if (!db.Users.Any(x => x.UserId == u.Id)) - db.Users.Add(new Models.User { UserId = u.Id, Username = un}); - else - db.Users.Find(u.Id).Username = un; + await db.Users.AddAsync(new Models.User { UserId = u.Id, Username = un }); + else + (await db.Users.FindAsync(u.Id)).Username = un; } void InitCommands(IContainer c)