From 1f265e9b653ad6d741565ccfa676c734f98bfd68 Mon Sep 17 00:00:00 2001 From: Alexander Salamatov Date: Sun, 5 Jan 2025 19:24:57 +0300 Subject: [PATCH] update tools and fixes --- src/.config/dotnet-tools.json | 5 ++- src/Directory.Packages.props | 11 +++-- src/SpinRallyBot.Bot/Services/BotInit.cs | 12 +++--- src/SpinRallyBot.Bot/SpinRallyBot.Bot.csproj | 2 - src/SpinRallyBot.Bot/Utils/UserExtensions.cs | 13 ++++-- .../PostgresDbContextModelSnapshot.cs | 2 +- .../SqliteDbContextModelSnapshot.cs | 4 +- .../SpinRallyBot.Utils.csproj | 2 +- src/SpinRallyBot.Utils/StringExtensions.cs | 41 ++++++++++++++++++- .../HostApplicationBuilderExtensions.cs | 28 +++++-------- src/SpinRallyBot/SpinRallyBot.csproj | 1 + 11 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/.config/dotnet-tools.json b/src/.config/dotnet-tools.json index 40d4373..4f48799 100644 --- a/src/.config/dotnet-tools.json +++ b/src/.config/dotnet-tools.json @@ -3,10 +3,11 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "8.0.10", + "version": "9.0.0", "commands": [ "dotnet-ef" - ] + ], + "rollForward": false } } } \ No newline at end of file diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 224936f..2976937 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -15,7 +15,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -33,9 +32,10 @@ - + - + + @@ -46,8 +46,7 @@ - - + @@ -56,4 +55,4 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file diff --git a/src/SpinRallyBot.Bot/Services/BotInit.cs b/src/SpinRallyBot.Bot/Services/BotInit.cs index 930fe6a..391ec32 100644 --- a/src/SpinRallyBot.Bot/Services/BotInit.cs +++ b/src/SpinRallyBot.Bot/Services/BotInit.cs @@ -3,20 +3,20 @@ namespace SpinRallyBot.Services; internal class BotInit : IHostedService { private readonly ITelegramBotClient _botClient; private readonly ILogger _logger; - private readonly IScopedMediator _mediator; + private readonly IServiceProvider _serviceProvider; - public BotInit(ITelegramBotClient botClient, - ILogger logger, - IScopedMediator mediator) { + public BotInit(ITelegramBotClient botClient, ILogger logger, IServiceProvider serviceProvider) { _botClient = botClient; _logger = logger; - _mediator = mediator; + _serviceProvider = serviceProvider; } public async Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Initialize bot (commands, etc)"); await InitCommands(cancellationToken); - await _mediator.Send(new InitUpdaterJob(false), cancellationToken); + await using AsyncServiceScope scope = _serviceProvider.CreateAsyncScope(); + var mediator = scope.ServiceProvider.GetRequiredService(); + await mediator.Send(new InitUpdaterJob(false), cancellationToken); } public Task StopAsync(CancellationToken cancellationToken) { diff --git a/src/SpinRallyBot.Bot/SpinRallyBot.Bot.csproj b/src/SpinRallyBot.Bot/SpinRallyBot.Bot.csproj index e70a61c..36a752d 100644 --- a/src/SpinRallyBot.Bot/SpinRallyBot.Bot.csproj +++ b/src/SpinRallyBot.Bot/SpinRallyBot.Bot.csproj @@ -2,13 +2,11 @@ - - diff --git a/src/SpinRallyBot.Bot/Utils/UserExtensions.cs b/src/SpinRallyBot.Bot/Utils/UserExtensions.cs index 8eefd7f..f8bdbdf 100644 --- a/src/SpinRallyBot.Bot/Utils/UserExtensions.cs +++ b/src/SpinRallyBot.Bot/Utils/UserExtensions.cs @@ -1,11 +1,16 @@ -using Telegram.Bot.Extensions.Markup; - namespace SpinRallyBot.Utils; public static class UserExtensions { + private static string MentionMarkdown(ChatId userId, string name, ParseMode parseMode = ParseMode.Markdown) { + string tgLink = $"tg://user?id={userId}"; + return parseMode == ParseMode.Markdown + ? $"[{name}]({tgLink})" + : $"[{StringExtensions.EscapeMarkdown(name, parseMode)}]({tgLink})"; + } + public static string ToMentionMarkdownV2(this User user) { - return Tools.MentionMarkdown(user.Id, - user.Username is not null ? $"@{user.Username}" : $"{user.FirstName} {user.LastName}".Trim(), + return MentionMarkdown( + user.Id, user.Username is not null ? $"@{user.Username}" : $"{user.FirstName} {user.LastName}".Trim(), ParseMode.MarkdownV2); } } diff --git a/src/SpinRallyBot.Database.Postgres/Migrations/PostgresDbContextModelSnapshot.cs b/src/SpinRallyBot.Database.Postgres/Migrations/PostgresDbContextModelSnapshot.cs index c06a902..6fd7ee7 100644 --- a/src/SpinRallyBot.Database.Postgres/Migrations/PostgresDbContextModelSnapshot.cs +++ b/src/SpinRallyBot.Database.Postgres/Migrations/PostgresDbContextModelSnapshot.cs @@ -18,7 +18,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) #pragma warning disable 612, 618 modelBuilder .HasAnnotation("Npgsql:CollationDefinition:case_insensitive", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("ProductVersion", "9.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); diff --git a/src/SpinRallyBot.Database.Sqlite/Migrations/SqliteDbContextModelSnapshot.cs b/src/SpinRallyBot.Database.Sqlite/Migrations/SqliteDbContextModelSnapshot.cs index 1a6da06..e826b1c 100644 --- a/src/SpinRallyBot.Database.Sqlite/Migrations/SqliteDbContextModelSnapshot.cs +++ b/src/SpinRallyBot.Database.Sqlite/Migrations/SqliteDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ partial class SqliteDbContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "9.0.0"); modelBuilder.Entity("SpinRallyBot.Models.BackNavigationEntity", b => { @@ -78,7 +78,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("PlayerUrl"); - b.ToTable("Players"); + b.ToTable("Players", (string)null); }); modelBuilder.Entity("SpinRallyBot.Models.SubscriptionEntity", b => diff --git a/src/SpinRallyBot.Utils/SpinRallyBot.Utils.csproj b/src/SpinRallyBot.Utils/SpinRallyBot.Utils.csproj index 59aa644..959b532 100644 --- a/src/SpinRallyBot.Utils/SpinRallyBot.Utils.csproj +++ b/src/SpinRallyBot.Utils/SpinRallyBot.Utils.csproj @@ -1,5 +1,5 @@ - + diff --git a/src/SpinRallyBot.Utils/StringExtensions.cs b/src/SpinRallyBot.Utils/StringExtensions.cs index b9e2a9e..28aee82 100644 --- a/src/SpinRallyBot.Utils/StringExtensions.cs +++ b/src/SpinRallyBot.Utils/StringExtensions.cs @@ -1,10 +1,47 @@ -using Telegram.Bot.Extensions.Markup; +using System.Collections.Immutable; +using System.Text.RegularExpressions; using Telegram.Bot.Types.Enums; namespace SpinRallyBot; public static class StringExtensions { + private static ImmutableDictionary<(ParseMode parseMode, MessageEntityType? entityType), string> Escaped => + new Dictionary<(ParseMode parseMode, MessageEntityType? entityType), string> { + { (ParseMode.Markdown, null), Regex.Escape("_*`[") }, + { (ParseMode.MarkdownV2, MessageEntityType.Pre), Regex.Escape("""\`""") }, + { (ParseMode.MarkdownV2, MessageEntityType.Code), Regex.Escape("""\`""") }, + { (ParseMode.MarkdownV2, MessageEntityType.TextLink), Regex.Escape("""\)""") }, { + (ParseMode.MarkdownV2, null), + Regex.Escape(str: """\_*()~`>#+-=|{}.![]""") + .Replace("]", "\\]", StringComparison.Ordinal) + .Replace("-", "\\-", StringComparison.Ordinal) + }, + }.ToImmutableDictionary(); + + public static string EscapeMarkdown( + string text, + ParseMode parseMode = ParseMode.Markdown, + MessageEntityType? entityType = default) { + string escaped = (parseMode, entityType) switch { + (ParseMode.Markdown, _) => Escaped[(ParseMode.Markdown, null)], + (ParseMode.MarkdownV2, MessageEntityType.Pre) => Escaped[(ParseMode.MarkdownV2, MessageEntityType.Pre)], + (ParseMode.MarkdownV2, MessageEntityType.Code) => Escaped[(ParseMode.MarkdownV2, MessageEntityType.Code)], + (ParseMode.MarkdownV2, MessageEntityType.TextLink) => Escaped[ + (ParseMode.MarkdownV2, MessageEntityType.TextLink)], + (ParseMode.MarkdownV2, _) => Escaped[(ParseMode.MarkdownV2, null)], + _ => throw new ArgumentException("Only ParseMode.Markdown and ParseMode.MarkdownV2 allowed.", + nameof(parseMode)), + }; + + return Regex.Replace( + input: text, + pattern: $"([{escaped}])", + replacement: """\$1""", + RegexOptions.CultureInvariant, + matchTimeout: TimeSpan.FromSeconds(1)); + } + public static string ToEscapedMarkdownV2(this string str) { - return Tools.EscapeMarkdown(str, ParseMode.MarkdownV2); + return EscapeMarkdown(str, ParseMode.MarkdownV2); } } diff --git a/src/SpinRallyBot/HostApplicationBuilderExtensions.cs b/src/SpinRallyBot/HostApplicationBuilderExtensions.cs index 286581c..bc0b872 100644 --- a/src/SpinRallyBot/HostApplicationBuilderExtensions.cs +++ b/src/SpinRallyBot/HostApplicationBuilderExtensions.cs @@ -1,10 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; +using System.Text.Json; using Quartz; using Serilog.Enrichers.Sensitive; using SpinRallyBot.Events.PlayerRatingChangedConsumers; using SpinRallyBot.Serilog; using SpinRallyBot.Subscriptions; +using Telegram.Bot; namespace SpinRallyBot; @@ -45,12 +45,12 @@ public static HostApplicationBuilder AddMassTransit(this HostApplicationBuilder if (builder.Configuration["AMQP_URI"] is { } amqpUri) { x.UsingRabbitMq((context, cfg) => { cfg.Host(amqpUri); - ConfigureNewtonsoft(cfg); + cfg.ConfigureJsonSerializerOptions(AddJsonBotApiJsonSerializerOptions); cfg.ConfigureEndpoints(context); }); } else { x.UsingInMemory((context, cfg) => { - ConfigureNewtonsoft(cfg); + cfg.ConfigureJsonSerializerOptions(AddJsonBotApiJsonSerializerOptions); cfg.ConfigureEndpoints(context); }); } @@ -62,19 +62,6 @@ public static HostApplicationBuilder AddMassTransit(this HostApplicationBuilder return builder; } - private static void ConfigureNewtonsoft(IBusFactoryConfigurator cfg) { - cfg.UseNewtonsoftJsonSerializer(); - cfg.ConfigureNewtonsoftJsonSerializer(_ => new JsonSerializerSettings { - NullValueHandling = NullValueHandling.Include, - ContractResolver = new CamelCasePropertyNamesContractResolver { - IgnoreSerializableAttribute = true, - IgnoreShouldSerializeMembers = true - }, - DateFormatHandling = DateFormatHandling.IsoDateFormat, - DateTimeZoneHandling = DateTimeZoneHandling.Unspecified - }); - } - public static HostApplicationBuilder AddQuartz(this HostApplicationBuilder builder) { builder.Services.AddQuartz(q => { q.MisfireThreshold = TimeSpan.FromHours(1); @@ -97,8 +84,15 @@ public static HostApplicationBuilder AddQuartz(this HostApplicationBuilder build default: throw new Exception($"Unsupported provider: {provider}"); } + + s.UseSystemTextJsonSerializer(); }); }); return builder; } + + private static JsonSerializerOptions AddJsonBotApiJsonSerializerOptions(JsonSerializerOptions options) { + JsonBotAPI.Configure(options); + return options; + } } diff --git a/src/SpinRallyBot/SpinRallyBot.csproj b/src/SpinRallyBot/SpinRallyBot.csproj index f03ad1f..3e78a7f 100644 --- a/src/SpinRallyBot/SpinRallyBot.csproj +++ b/src/SpinRallyBot/SpinRallyBot.csproj @@ -23,6 +23,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive +