Make everything asynchronous

This commit is contained in:
Basique Evangelist 2019-07-21 01:54:37 +03:00
parent 5e239c934c
commit a1b5db8430
Signed by untrusted user: BasiqueEvangelist
GPG Key ID: B370219149301706
9 changed files with 95 additions and 73 deletions

View File

@ -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<bool> 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);
}
}
}

View File

@ -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<bool> 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);

View File

@ -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<bool> 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"],

View File

@ -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<ChatCommandArgument> Arguments => new ChatCommandArgument[] {
};
public bool Execute(CommandString cmd, MessageEventArgs args)
public async Task<bool> 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}) <i>{currentLocale["jetkarmabot.awardtypes.nominative." + x.CommandName]}</i>"));
Client.SendTextMessageAsync(
(await db.AwardTypes.ToListAsync()).Select(x => $"{x.Symbol} ({x.CommandName}) <i>{currentLocale["jetkarmabot.awardtypes.nominative." + x.CommandName]}</i>"));
await Client.SendTextMessageAsync(
args.Message.Chat.Id,
resp,
replyToMessageId: args.Message.MessageId,

View File

@ -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<bool> 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,

View File

@ -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<ChatCommandArgument> Arguments { get; }
bool Execute(CommandString cmd, MessageEventArgs messageEventArgs);
Task<bool> Execute(CommandString cmd, MessageEventArgs messageEventArgs);
}
public struct ChatCommandArgument

View File

@ -17,11 +17,11 @@ namespace JetKarmaBot.Commands
{
public IReadOnlyCollection<string> Names => new[] { "leaderboard" };
public bool Execute(CommandString cmd, MessageEventArgs args)
public async Task<bool> 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);

View File

@ -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<string> Names => new[] { "status" };
public bool Execute(CommandString cmd, MessageEventArgs args)
public async Task<bool> 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);

View File

@ -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)