From 3fd5042367e7b2c0b0214ca8b01b743ad455aec2 Mon Sep 17 00:00:00 2001 From: Kruzya Date: Sun, 8 Mar 2020 01:55:50 +0400 Subject: [PATCH 1/3] WiP storage for modules --- Core/Core.csproj | 1 + Core/Data/BotUser.cs | 25 +++++++ Core/Data/BotUserValue.cs | 42 +++++++++++ Core/Data/CoreContext.cs | 19 +++++ Core/GeneralHandler.cs | 75 +++++++++++++++++++ .../20200307215450_Initial.Designer.cs | 70 +++++++++++++++++ Core/Migrations/20200307215450_Initial.cs | 58 ++++++++++++++ Core/Migrations/CoreContextModelSnapshot.cs | 68 +++++++++++++++++ Core/Startup.cs | 6 ++ Core/appsettings.Development.json | 4 + .../Data/UrlLimitationsContext.cs | 7 ++ 11 files changed, 375 insertions(+) create mode 100644 Core/Data/BotUser.cs create mode 100644 Core/Data/BotUserValue.cs create mode 100644 Core/Data/CoreContext.cs create mode 100644 Core/GeneralHandler.cs create mode 100644 Core/Migrations/20200307215450_Initial.Designer.cs create mode 100644 Core/Migrations/20200307215450_Initial.cs create mode 100644 Core/Migrations/CoreContextModelSnapshot.cs create mode 100644 modules/UrlLimitations/Data/UrlLimitationsContext.cs diff --git a/Core/Core.csproj b/Core/Core.csproj index 21c37b2..d625025 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -8,6 +8,7 @@ + diff --git a/Core/Data/BotUser.cs b/Core/Data/BotUser.cs new file mode 100644 index 0000000..621c45f --- /dev/null +++ b/Core/Data/BotUser.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Kruzya.TelegramBot.Core.Data +{ + public class BotUser + { + /// + /// The unique bot user identifier. + /// + [Key] + public Guid BotUserId { get; set; } + + /// + /// The chat identifier where this user is related. + /// + public long ChatId { get; set; } + + /// + /// The Telegram User identifier. + /// + public int UserId { get; set; } + } +} \ No newline at end of file diff --git a/Core/Data/BotUserValue.cs b/Core/Data/BotUserValue.cs new file mode 100644 index 0000000..9a95827 --- /dev/null +++ b/Core/Data/BotUserValue.cs @@ -0,0 +1,42 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Kruzya.TelegramBot.Core.Data +{ + public class BotUserValue + { + [Key] + public Guid BotUserValueId { get; set; } + + public BotUser BotUser { get; set; } + public string Name { get; set; } + + public byte[] Value + { + get + { + var fmt = new BinaryFormatter(); + using var memStream = new MemoryStream(); + fmt.Serialize(memStream, data); + + return memStream.ToArray(); + } + set + { + var fmt = new BinaryFormatter(); + using var memStream = new MemoryStream(); + memStream.Write(value); + memStream.Position = 0; + + data = fmt.Deserialize(memStream); + } + } + + [NonSerialized] public object data; + + public T GetValue() => (T) data; + public void SetValue(T value) => data = value; + } +} \ No newline at end of file diff --git a/Core/Data/CoreContext.cs b/Core/Data/CoreContext.cs new file mode 100644 index 0000000..6b5f44c --- /dev/null +++ b/Core/Data/CoreContext.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; + +namespace Kruzya.TelegramBot.Core.Data +{ + public class CoreContext : DbContext + { + /// + /// The all known users. + /// + public DbSet Users { get; set; } + + public DbSet UserValues { get; set; } + + public CoreContext(DbContextOptions ctx) : base(ctx) + { + Database.Migrate(); + } + } +} \ No newline at end of file diff --git a/Core/GeneralHandler.cs b/Core/GeneralHandler.cs new file mode 100644 index 0000000..0a8c4cd --- /dev/null +++ b/Core/GeneralHandler.cs @@ -0,0 +1,75 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using BotFramework; +using BotFramework.Attributes; +using Kruzya.TelegramBot.Core.Data; +using Microsoft.EntityFrameworkCore; +using Telegram.Bot.Types; + +namespace Kruzya.TelegramBot.Core +{ + public class GeneralHandler : BotEventHandler + { + [AttributeUsage(AttributeTargets.Method)] + public sealed class HandleEverythingAttribute : HandlerAttribute + { + protected override bool CanHandle(HandlerParams param) + { + return true; + } + } + + protected readonly CoreContext databaseContext; + + public GeneralHandler(CoreContext dbCtx) + { + databaseContext = dbCtx; + } + + [HandleEverything] + public async Task Listener() + { + foreach (var message in new Message[] {RawUpdate.Message, RawUpdate.EditedMessage, RawUpdate.ChannelPost, RawUpdate.EditedChannelPost}) + { + if (message == null) + { + continue; + } + + await VerifyChatPair(message); + } + } + + public async Task VerifyChatPair(Message message) + { + await VerifyChatPair(message.Chat, message.From); + } + + public async Task VerifyChatPair(Chat chat, User user) + { + await VerifyChatPair(chat.Id, user.Id); + } + + public async Task VerifyChatPair(long chat, int user) + { + var hasEntry = await databaseContext.Users.AnyAsync(e => e.ChatId == chat && e.UserId == user); + if (hasEntry) + { + return; + } + + await MakeChatPair(chat, user); + } + + public async Task MakeChatPair(long chat, int user) + { + await databaseContext.Users.AddAsync(new BotUser() + { + ChatId = chat, + UserId = user, + BotUserId = new Guid() + }); + } + } +} \ No newline at end of file diff --git a/Core/Migrations/20200307215450_Initial.Designer.cs b/Core/Migrations/20200307215450_Initial.Designer.cs new file mode 100644 index 0000000..cc79c56 --- /dev/null +++ b/Core/Migrations/20200307215450_Initial.Designer.cs @@ -0,0 +1,70 @@ +// +using System; +using Kruzya.TelegramBot.Core.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kruzya.TelegramBot.Core.Migrations +{ + [DbContext(typeof(CoreContext))] + [Migration("20200307215450_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUser", b => + { + b.Property("BotUserId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("BotUserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.Property("BotUserValueId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BotUserId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longblob"); + + b.HasKey("BotUserValueId"); + + b.HasIndex("BotUserId"); + + b.ToTable("UserValues"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.HasOne("Kruzya.TelegramBot.Core.Data.BotUser", "BotUser") + .WithMany() + .HasForeignKey("BotUserId"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Core/Migrations/20200307215450_Initial.cs b/Core/Migrations/20200307215450_Initial.cs new file mode 100644 index 0000000..2b8e0a9 --- /dev/null +++ b/Core/Migrations/20200307215450_Initial.cs @@ -0,0 +1,58 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Kruzya.TelegramBot.Core.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + BotUserId = table.Column(nullable: false), + ChatId = table.Column(nullable: false), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.BotUserId); + }); + + migrationBuilder.CreateTable( + name: "UserValues", + columns: table => new + { + BotUserValueId = table.Column(nullable: false), + BotUserId = table.Column(nullable: true), + Name = table.Column(nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserValues", x => x.BotUserValueId); + table.ForeignKey( + name: "FK_UserValues_Users_BotUserId", + column: x => x.BotUserId, + principalTable: "Users", + principalColumn: "BotUserId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserValues_BotUserId", + table: "UserValues", + column: "BotUserId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserValues"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/Core/Migrations/CoreContextModelSnapshot.cs b/Core/Migrations/CoreContextModelSnapshot.cs new file mode 100644 index 0000000..827b255 --- /dev/null +++ b/Core/Migrations/CoreContextModelSnapshot.cs @@ -0,0 +1,68 @@ +// +using System; +using Kruzya.TelegramBot.Core.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kruzya.TelegramBot.Core.Migrations +{ + [DbContext(typeof(CoreContext))] + partial class CoreContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUser", b => + { + b.Property("BotUserId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("BotUserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.Property("BotUserValueId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BotUserId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longblob"); + + b.HasKey("BotUserValueId"); + + b.HasIndex("BotUserId"); + + b.ToTable("UserValues"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.HasOne("Kruzya.TelegramBot.Core.Data.BotUser", "BotUser") + .WithMany() + .HasForeignKey("BotUserId"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Core/Startup.cs b/Core/Startup.cs index f55e59c..4daa02f 100644 --- a/Core/Startup.cs +++ b/Core/Startup.cs @@ -1,7 +1,9 @@ using BotFramework; +using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -29,6 +31,10 @@ namespace Kruzya.TelegramBot.Core services.AddSingleton(_core); foreach (var module in _core.Modules) services.AddSingleton(module.GetType(), module); + // Add database context to DI. + services.AddDbContext(ctx => + ctx.UseMySql(_core.Configuration.GetConnectionString("DefaultConnection"))); + // Trigger module handlers. _core.Modules.ConfigureServices(services); } diff --git a/Core/appsettings.Development.json b/Core/appsettings.Development.json index 8983e0f..464b352 100644 --- a/Core/appsettings.Development.json +++ b/Core/appsettings.Development.json @@ -5,5 +5,9 @@ "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } + }, + + "ConnectionStrings": { + "DefaultConnection": "server=127.0.0.1;UserId=rider;Password=rider;database=rider;port=8889" } } diff --git a/modules/UrlLimitations/Data/UrlLimitationsContext.cs b/modules/UrlLimitations/Data/UrlLimitationsContext.cs new file mode 100644 index 0000000..de64347 --- /dev/null +++ b/modules/UrlLimitations/Data/UrlLimitationsContext.cs @@ -0,0 +1,7 @@ +namespace Kruzya.TelegramBot.UrlLimitations +{ + public class UrlLimitationsContext + { + + } +} \ No newline at end of file From 73cfe51312e09acf531878a3ab243fc6d8c804dc Mon Sep 17 00:00:00 2001 From: Kruzya Date: Sun, 8 Mar 2020 12:38:00 +0400 Subject: [PATCH 2/3] Migrate to database storage in UrlLimitations --- Core/Extensions/RepositoryExtension.cs | 66 ++++++++++++++++++- modules/UrlLimitations/Data/ChatMember.cs | 19 ------ .../Data/UrlLimitationsContext.cs | 7 -- modules/UrlLimitations/MessageExtension.cs | 64 ++++++++++++++++++ modules/UrlLimitations/MessageHandler.cs | 22 +++---- modules/UrlLimitations/UrlLimitations.cs | 6 +- modules/UrlLimitations/UserJoinHandler.cs | 15 +++-- 7 files changed, 151 insertions(+), 48 deletions(-) delete mode 100644 modules/UrlLimitations/Data/ChatMember.cs delete mode 100644 modules/UrlLimitations/Data/UrlLimitationsContext.cs create mode 100644 modules/UrlLimitations/MessageExtension.cs diff --git a/Core/Extensions/RepositoryExtension.cs b/Core/Extensions/RepositoryExtension.cs index 98bafd4..3b9c4f7 100644 --- a/Core/Extensions/RepositoryExtension.cs +++ b/Core/Extensions/RepositoryExtension.cs @@ -1,4 +1,6 @@ -using Microsoft.EntityFrameworkCore; +using System.Threading.Tasks; +using Kruzya.TelegramBot.Core.Data; +using Microsoft.EntityFrameworkCore; namespace Kruzya.TelegramBot.Core.Extensions { @@ -43,5 +45,67 @@ namespace Kruzya.TelegramBot.Core.Extensions } #endregion + + #region Core-context repository extensions + + #region BotUserValue + + #region FindOption + + public static async Task FindOption(this DbSet repository, long chatId, + string option) => await repository.FindOption(chatId, 0, option); + + public static async Task FindOption(this DbSet repository, BotUser user, + string option) => await repository.FindOption(user.ChatId, user.UserId, option); + + public static async Task FindOption(this DbSet repository, long chatId, int userId, + string option) => await repository.SingleOrDefaultAsync(e => + e.BotUser.ChatId == chatId && e.BotUser.UserId == userId && e.Name == option); + + #endregion + + #region FindOrCreateOption + + public static async Task FindOrCreateOption(this DbSet repository, long chatId, + string option) => await repository.FindOrCreateOption(chatId, 0, option); + + public static async Task FindOrCreateOption(this DbSet repository, BotUser user, + string option) => await repository.FindOrCreateOption(user.ChatId, user.UserId, option); + + public static async Task FindOrCreateOption(this DbSet repository, long chatId, + int userId, string option) + { + var opt = await repository.FindOption(chatId, userId, option); + if (opt == null) + { + opt = repository.Create(); + } + + return opt; + } + + #endregion + + #region SetOptionValue + + public static async Task SetOptionValue(this DbSet repository, long chatId, string option, + T val) => await repository.SetOptionValue(chatId, 0, option, val); + + public static async Task SetOptionValue(this DbSet repository, BotUser user, string option, + T val) => await repository.SetOptionValue(user.ChatId, user.UserId, option, val); + + public static async Task SetOptionValue(this DbSet repository, long chatId, int userId, + string option, T val) + { + var opt = await repository.FindOrCreateOption(chatId, userId, option); + opt.SetValue(val); + repository.Update(opt); + } + + #endregion + + #endregion + + #endregion } } \ No newline at end of file diff --git a/modules/UrlLimitations/Data/ChatMember.cs b/modules/UrlLimitations/Data/ChatMember.cs deleted file mode 100644 index cc8d906..0000000 --- a/modules/UrlLimitations/Data/ChatMember.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Telegram.Bot.Types; - -namespace Kruzya.TelegramBot.UrlLimitations -{ - public struct ChatMember - { - public long Chat; - public long User; - - public static ChatMember From(long chatId, long userId) - { - return new ChatMember() - { - Chat = chatId, - User = userId - }; - } - } -} \ No newline at end of file diff --git a/modules/UrlLimitations/Data/UrlLimitationsContext.cs b/modules/UrlLimitations/Data/UrlLimitationsContext.cs deleted file mode 100644 index de64347..0000000 --- a/modules/UrlLimitations/Data/UrlLimitationsContext.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Kruzya.TelegramBot.UrlLimitations -{ - public class UrlLimitationsContext - { - - } -} \ No newline at end of file diff --git a/modules/UrlLimitations/MessageExtension.cs b/modules/UrlLimitations/MessageExtension.cs new file mode 100644 index 0000000..e2ce906 --- /dev/null +++ b/modules/UrlLimitations/MessageExtension.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using BotFramework; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace Kruzya.TelegramBot.UrlLimitations +{ + public static class MessageExtension + { + public static async Task HasUnknownMention(this Message message, ITelegramBotClient bot) + { + foreach (var mention in message.Entities.Where(e => + e.Type == MessageEntityType.Mention || e.Type == MessageEntityType.TextMention)) + { + var userId = 0; + if (mention.Type == MessageEntityType.TextMention) + { + userId = mention.User.Id; + } + else + { + try + { + var chat = await bot.GetChatAsync( + new ChatId(message.Text.Substring(mention.Offset, mention.Length))); + + if (chat != null) + { + if (chat.Type != ChatType.Private) + { + return true; + } + + userId = Convert.ToInt32(chat.Id); + } + } + catch (Exception e) + { + return true; + } + } + + var status = (await bot.GetChatMemberAsync(message.Chat, userId)).Status; + + if ((new ChatMemberStatus[] + { + ChatMemberStatus.Administrator, ChatMemberStatus.Creator, ChatMemberStatus.Member, + ChatMemberStatus.Restricted + + // i'm not sure about "Restricted" + // maybe leaved members with some restrictions also can be "Restricted". + }).Any(e => e == status) == false) + { + return true; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/modules/UrlLimitations/MessageHandler.cs b/modules/UrlLimitations/MessageHandler.cs index a987b1c..7f18a5f 100644 --- a/modules/UrlLimitations/MessageHandler.cs +++ b/modules/UrlLimitations/MessageHandler.cs @@ -5,6 +5,7 @@ using BotFramework; using BotFramework.Attributes; using BotFramework.Setup; using Kruzya.TelegramBot.Core.Cache; +using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Microsoft.Extensions.Logging; using Telegram.Bot.Types; @@ -15,35 +16,34 @@ namespace Kruzya.TelegramBot.UrlLimitations public class MessageHandler : BotEventHandler { protected ILogger Logger; - protected MemoryCache ChatMembersCache; + protected readonly CoreContext dbCtx; - public MessageHandler(ILogger logger, MemoryCache chatMembersCache) + public MessageHandler(ILogger logger, CoreContext coreContext) { Logger = logger; - ChatMembersCache = chatMembersCache; + dbCtx = coreContext; } [TextMessage(InChat.Public)] - public void OnMessageReceived() + public async Task OnMessageReceived() { - UInt16 messageCount; - var chatMember = ChatMember.From(Chat.Id, From.Id); - if (!ChatMembersCache.TryGetValue(chatMember, out messageCount)) + var option = await dbCtx.UserValues.FindOption(Chat.Id, From.Id, "urlLimitations.messagesAfterJoin"); + if (option == null) { return; } + var messageCount = option.GetValue(); if (messageCount > 10) { - ChatMembersCache.SetValue(chatMember, 0, 0); + dbCtx.UserValues.Remove(option); return; } - messageCount++; - ChatMembersCache.SetValue(chatMember, messageCount); + option.SetValue(messageCount + 1); var message = RawUpdate.Message; if (message.Entities.Count(e => e.Type == MessageEntityType.Url || e.Type == MessageEntityType.TextLink) > - 0) + 0 || await message.HasUnknownMention(Bot)) { var targetChat = new ChatId(Chat.Id); Task.WaitAll(new Task[] { diff --git a/modules/UrlLimitations/UrlLimitations.cs b/modules/UrlLimitations/UrlLimitations.cs index e0158da..0ce910f 100644 --- a/modules/UrlLimitations/UrlLimitations.cs +++ b/modules/UrlLimitations/UrlLimitations.cs @@ -1,5 +1,6 @@ using System; using Kruzya.TelegramBot.Core; +using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Microsoft.Extensions.DependencyInjection; @@ -10,10 +11,5 @@ namespace Kruzya.TelegramBot.UrlLimitations public UrlLimitations(Core.Core core) : base(core) { } - - public override void ConfigureServices(IServiceCollection services) - { - services.AddMemoryCache(); - } } } \ No newline at end of file diff --git a/modules/UrlLimitations/UserJoinHandler.cs b/modules/UrlLimitations/UserJoinHandler.cs index 98bd0ff..bb293f1 100644 --- a/modules/UrlLimitations/UserJoinHandler.cs +++ b/modules/UrlLimitations/UserJoinHandler.cs @@ -1,25 +1,30 @@ using System; +using System.Threading.Tasks; using BotFramework; using BotFramework.Attributes; using BotFramework.Setup; using Kruzya.TelegramBot.Core.Cache; +using Kruzya.TelegramBot.Core.Data; +using Kruzya.TelegramBot.Core.Extensions; using Telegram.Bot.Types.Enums; namespace Kruzya.TelegramBot.UrlLimitations { public class UserJoinHandler : BotEventHandler { - protected MemoryCache ChatMembersCache; + protected readonly CoreContext dbCtx; - public UserJoinHandler(MemoryCache chatMembersCache) + public UserJoinHandler(CoreContext coreContext) { - ChatMembersCache = chatMembersCache; + dbCtx = coreContext; } [Message(MessageType.ChatMembersAdded, InChat.Public)] - public void OnChatMembersAdded() + public async Task OnChatMembersAdded() { - ChatMembersCache.SetValue(ChatMember.From(Chat.Id, From.Id), 0); + foreach (var member in RawUpdate.Message.NewChatMembers) + await dbCtx.UserValues.SetOptionValue(Chat.Id, member.Id, "urlLimitations.messagesAfterJoin", + 0); } } } \ No newline at end of file From 8681c7cf690df69851d1bd0dfcd9957df0e60a2a Mon Sep 17 00:00:00 2001 From: Kruzya Date: Mon, 9 Mar 2020 19:31:16 +0400 Subject: [PATCH 3/3] Scratch for running next callbacks in queue --- Core/Data/CoreContext.cs | 13 +++++++++++++ Core/Extensions/RepositoryExtension.cs | 19 +++++++++++++++++++ Core/GeneralHandler.cs | 2 ++ 3 files changed, 34 insertions(+) diff --git a/Core/Data/CoreContext.cs b/Core/Data/CoreContext.cs index 6b5f44c..900e0a4 100644 --- a/Core/Data/CoreContext.cs +++ b/Core/Data/CoreContext.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace Kruzya.TelegramBot.Core.Data @@ -11,6 +12,18 @@ namespace Kruzya.TelegramBot.Core.Data public DbSet UserValues { get; set; } + public override void Dispose() + { + SaveChanges(); + base.Dispose(); + } + + public override ValueTask DisposeAsync() + { + SaveChanges(); + return base.DisposeAsync(); + } + public CoreContext(DbContextOptions ctx) : base(ctx) { Database.Migrate(); diff --git a/Core/Extensions/RepositoryExtension.cs b/Core/Extensions/RepositoryExtension.cs index 3b9c4f7..dc53846 100644 --- a/Core/Extensions/RepositoryExtension.cs +++ b/Core/Extensions/RepositoryExtension.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Kruzya.TelegramBot.Core.Data; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; namespace Kruzya.TelegramBot.Core.Extensions { @@ -48,6 +49,23 @@ namespace Kruzya.TelegramBot.Core.Extensions #region Core-context repository extensions + #region BotUser + + public static async Task FindOrCreate(this DbSet repository, long chatId, int userId) + { + var user = await repository.SingleOrDefaultAsync(e => e.ChatId == chatId && e.UserId == userId); + if (user == null) + { + user = repository.Create(); + user.ChatId = chatId; + user.UserId = userId; + } + + return user; + } + + #endregion + #region BotUserValue #region FindOption @@ -79,6 +97,7 @@ namespace Kruzya.TelegramBot.Core.Extensions if (opt == null) { opt = repository.Create(); + opt.BotUser = await repository.GetService().Users.FindOrCreate(chatId, userId); } return opt; diff --git a/Core/GeneralHandler.cs b/Core/GeneralHandler.cs index 0a8c4cd..72bd5af 100644 --- a/Core/GeneralHandler.cs +++ b/Core/GeneralHandler.cs @@ -39,6 +39,8 @@ namespace Kruzya.TelegramBot.Core await VerifyChatPair(message); } + + throw new ArgumentException(); } public async Task VerifyChatPair(Message message)