* Renamed "LeveledDebug" to "Alligator", cuz its funny name

* Changed debug writing to trace writing inside "Alligator"
* Added "HostedTelegramBotInfo" representing hosted version of ITelegramBotInfo. Provides access to services and configuration
* Filters now can acces services and configuration using new "HostedTelegramBotInfo" through context.BotInfo property
This commit is contained in:
2025-08-01 13:50:21 +04:00
parent 16e599bed8
commit 49310439e0
10 changed files with 84 additions and 45 deletions
@@ -0,0 +1,17 @@
using Microsoft.Extensions.Configuration;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegrator.Configuration;
namespace Telegrator.Hosting
{
public class HostedTelegramBotInfo(ITelegramBotClient client, IServiceProvider services, IConfigurationManager configuration) : ITelegramBotInfo
{
/// <inheritdoc/>
public User User { get; } = client.GetMe().Result;
public IServiceProvider Services { get; } = services;
public IConfigurationManager Configuration { get; } = configuration;
}
}
+9
View File
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Text; using System.Text;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Configuration;
using Telegrator.Hosting.Components; using Telegrator.Hosting.Components;
using Telegrator.Hosting.Providers; using Telegrator.Hosting.Providers;
using Telegrator.MadiatorCore; using Telegrator.MadiatorCore;
@@ -39,12 +40,20 @@ namespace Telegrator.Hosting
/// <param name="handlers"></param> /// <param name="handlers"></param>
internal TelegramBotHost(HostApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers) internal TelegramBotHost(HostApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers)
{ {
// Registering this host in services for easy access
RegisterHostServices(hostApplicationBuilder, handlers); RegisterHostServices(hostApplicationBuilder, handlers);
// Building proxy hoster
_innerHost = hostApplicationBuilder.Build(); _innerHost = hostApplicationBuilder.Build();
// Initializing bot info, as it requires to make a request via tg bot
Services.GetRequiredService<ITelegramBotInfo>();
// Reruesting services for this host
_updateRouter = Services.GetRequiredService<IUpdateRouter>(); _updateRouter = Services.GetRequiredService<IUpdateRouter>();
_logger = Services.GetRequiredService<ILogger<TelegramBotHost>>(); _logger = Services.GetRequiredService<ILogger<TelegramBotHost>>();
// Logging registering handlers in DEBUG purposes
LogHandlers(handlers); LogHandlers(handlers);
} }
+3 -2
View File
@@ -47,8 +47,9 @@ namespace Telegrator.Hosting
services.AddSingleton<IAwaitingProvider, HostAwaitingProvider>(); services.AddSingleton<IAwaitingProvider, HostAwaitingProvider>();
services.AddSingleton<IHandlersProvider, HostHandlersProvider>(); services.AddSingleton<IHandlersProvider, HostHandlersProvider>();
services.AddSingleton<IUpdateRouter, HostUpdateRouter>(); services.AddSingleton<IUpdateRouter, HostUpdateRouter>();
services.AddSingleton<ITelegramBotInfo, TelegramBotInfo>(services => new TelegramBotInfo(services.GetRequiredService<ITelegramBotClient>().GetMe().Result)); //services.AddSingleton<ITelegramBotInfo, TelegramBotInfo>(services => new TelegramBotInfo(services.GetRequiredService<ITelegramBotClient>().GetMe().Result));
services.AddSingleton<ITelegramBotInfo, HostedTelegramBotInfo>();
return services; return services;
} }
@@ -3,14 +3,14 @@
namespace Telegrator namespace Telegrator
{ {
/// <summary> /// <summary>
/// Telegrator's Debug logger helper /// Telegrator's FUNNY debug logger helper
/// </summary> /// </summary>
public static class LeveledDebug public static class Alligator
{ {
/// <summary> /// <summary>
/// Gets or sets flags of what debug messages to write /// Gets or sets flags of what debug messages to write
/// </summary> /// </summary>
public static DebugLevel IndentFlags { get; set; } = DebugLevel.None; public static DebugLevel Allowed { get; set; } = DebugLevel.None;
/// <summary> /// <summary>
/// Writes debug message if Indent level has Router flag /// Writes debug message if Indent level has Router flag
@@ -18,8 +18,8 @@ namespace Telegrator
/// <param name="message"></param> /// <param name="message"></param>
public static void RouterWriteLine(string message) public static void RouterWriteLine(string message)
{ {
if (IndentFlags.HasFlag(DebugLevel.Router)) if (Allowed.HasFlag(DebugLevel.Router))
Debug.WriteLine(message); Trace.WriteLine(message);
} }
/// <summary> /// <summary>
@@ -29,8 +29,8 @@ namespace Telegrator
/// <param name="args"></param> /// <param name="args"></param>
public static void RouterWriteLine(string message, params object[] args) public static void RouterWriteLine(string message, params object[] args)
{ {
if (IndentFlags.HasFlag(DebugLevel.Router)) if (Allowed.HasFlag(DebugLevel.Router))
Debug.WriteLine(message, args); Trace.WriteLine(string.Format(message, args));
} }
/// <summary> /// <summary>
@@ -39,8 +39,8 @@ namespace Telegrator
/// <param name="message"></param> /// <param name="message"></param>
public static void ProviderWriteLine(string message) public static void ProviderWriteLine(string message)
{ {
if (IndentFlags.HasFlag(DebugLevel.Providers)) if (Allowed.HasFlag(DebugLevel.Providers))
Debug.WriteLine(message); Trace.WriteLine(message);
} }
/// <summary> /// <summary>
@@ -50,8 +50,8 @@ namespace Telegrator
/// <param name="args"></param> /// <param name="args"></param>
public static void ProviderWriteLine(string message, params object[] args) public static void ProviderWriteLine(string message, params object[] args)
{ {
if (IndentFlags.HasFlag(DebugLevel.Providers)) if (Allowed.HasFlag(DebugLevel.Providers))
Debug.WriteLine(message, args); Trace.WriteLine(string.Format(message, args));
} }
/// <summary> /// <summary>
@@ -60,8 +60,8 @@ namespace Telegrator
/// <param name="message"></param> /// <param name="message"></param>
public static void FilterWriteLine(string message) public static void FilterWriteLine(string message)
{ {
if (IndentFlags.HasFlag(DebugLevel.Filters)) if (Allowed.HasFlag(DebugLevel.Filters))
Debug.WriteLine(message); Trace.WriteLine(message);
} }
/// <summary> /// <summary>
@@ -71,8 +71,8 @@ namespace Telegrator
/// <param name="args"></param> /// <param name="args"></param>
public static void FilterWriteLine(string message, params object[] args) public static void FilterWriteLine(string message, params object[] args)
{ {
if (IndentFlags.HasFlag(DebugLevel.Filters)) if (Allowed.HasFlag(DebugLevel.Filters))
Debug.WriteLine(message, args); Trace.WriteLine(string.Format(message, args));
} }
/// <summary> /// <summary>
@@ -81,8 +81,8 @@ namespace Telegrator
/// <param name="message"></param> /// <param name="message"></param>
public static void PoolWriteLine(string message) public static void PoolWriteLine(string message)
{ {
if (IndentFlags.HasFlag(DebugLevel.HandlersPool)) if (Allowed.HasFlag(DebugLevel.HandlersPool))
Debug.WriteLine(message); Trace.WriteLine(message);
} }
/// <summary> /// <summary>
@@ -92,8 +92,20 @@ namespace Telegrator
/// <param name="args"></param> /// <param name="args"></param>
public static void PoolWriteLine(string message, params object[] args) public static void PoolWriteLine(string message, params object[] args)
{ {
if (IndentFlags.HasFlag(DebugLevel.HandlersPool)) if (Allowed.HasFlag(DebugLevel.HandlersPool))
Debug.WriteLine(message, args); Trace.WriteLine(string.Format(message, args));
}
public static void WriteLine(DebugLevel level, string message)
{
if (Allowed.HasFlag(level))
Trace.WriteLine(message);
}
public static void WriteLine(DebugLevel level, string message, params object[] args)
{
if (Allowed.HasFlag(level))
Trace.WriteLine(string.Format(message, args));
} }
} }
} }
@@ -47,7 +47,7 @@ namespace Telegrator.Filters.Components
if (!filter.CanPass(context)) if (!filter.CanPass(context))
{ {
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter) if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]); Alligator.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]);
return false; return false;
} }
@@ -49,7 +49,7 @@ namespace Telegrator.Filters.Components
if (!filter.CanPass(context)) if (!filter.CanPass(context))
{ {
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter) if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]); Alligator.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]);
return false; return false;
} }
@@ -39,7 +39,7 @@
if (!filter.CanPass(context)) if (!filter.CanPass(context))
{ {
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter) if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]); Alligator.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, context.Data["handler_name"]);
return false; return false;
} }
@@ -47,7 +47,7 @@ namespace Telegrator.MadiatorCore.Descriptors
{ {
if (!UpdateValidator.CanPass(filterContext)) if (!UpdateValidator.CanPass(filterContext))
{ {
LeveledDebug.FilterWriteLine("(E) UpdateValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id); Alligator.FilterWriteLine("(E) UpdateValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
return false; return false;
} }
@@ -59,7 +59,7 @@ namespace Telegrator.MadiatorCore.Descriptors
{ {
if (!StateKeeperValidator.CanPass(filterContext)) if (!StateKeeperValidator.CanPass(filterContext))
{ {
LeveledDebug.FilterWriteLine("(E) StateKeeperValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id); Alligator.FilterWriteLine("(E) StateKeeperValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
return false; return false;
} }
@@ -74,7 +74,7 @@ namespace Telegrator.MadiatorCore.Descriptors
if (!filter.CanPass(filterContext)) if (!filter.CanPass(filterContext))
{ {
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter) if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} for Update ({2}) didnt pass!", filter.GetType().Name, filterContext.Data["handler_name"], filterContext.Update.Id); Alligator.FilterWriteLine("(E) {0} filter of {1} for Update ({2}) didnt pass!", filter.GetType().Name, filterContext.Data["handler_name"], filterContext.Update.Id);
return false; return false;
} }
+15 -15
View File
@@ -84,7 +84,7 @@ namespace Telegrator.Polling
/// <returns>A task representing the asynchronous error handling operation.</returns> /// <returns>A task representing the asynchronous error handling operation.</returns>
public virtual Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken) public virtual Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken)
{ {
LeveledDebug.RouterWriteLine("Handling exception {0}", exception.GetType().Name); Alligator.RouterWriteLine("Handling exception {0}", exception.GetType().Name);
ExceptionHandler?.HandleException(botClient, exception, source, cancellationToken); ExceptionHandler?.HandleException(botClient, exception, source, cancellationToken);
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -99,7 +99,7 @@ namespace Telegrator.Polling
public virtual Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) public virtual Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{ {
// Logging // Logging
LeveledDebug.RouterWriteLine("Received Update ({0}) of type \"{1}\"", update.Id, update.Type); Alligator.RouterWriteLine("Received Update ({0}) of type \"{1}\"", update.Id, update.Type);
LogUpdate(update); LogUpdate(update);
try try
@@ -114,24 +114,24 @@ namespace Telegrator.Polling
// Chicking if awaiting handlers has exclusive routing // Chicking if awaiting handlers has exclusive routing
if (Options.ExclusiveAwaitingHandlerRouting) if (Options.ExclusiveAwaitingHandlerRouting)
{ {
LeveledDebug.RouterWriteLine("Receiving Update ({0}) completed with only awaiting handlers", update.Id); Alligator.RouterWriteLine("Receiving Update ({0}) completed with only awaiting handlers", update.Id);
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
// Queuing reagular handlers for execution // Queuing reagular handlers for execution
HandlersPool.Enqueue(GetHandlers(HandlersProvider, this, botClient, update, cancellationToken)); HandlersPool.Enqueue(GetHandlers(HandlersProvider, this, botClient, update, cancellationToken));
LeveledDebug.RouterWriteLine("Receiving Update ({0}) finished", update.Id); Alligator.RouterWriteLine("Receiving Update ({0}) finished", update.Id);
return Task.CompletedTask; return Task.CompletedTask;
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
LeveledDebug.RouterWriteLine("Receiving Update ({0}) cancelled", update.Id); Alligator.RouterWriteLine("Receiving Update ({0}) cancelled", update.Id);
return Task.CompletedTask; return Task.CompletedTask;
} }
catch (Exception ex) catch (Exception ex)
{ {
LeveledDebug.RouterWriteLine("Receiving Update ({0}) finished with exception {1}", update.Id, ex.Message); Alligator.RouterWriteLine("Receiving Update ({0}) finished with exception {1}", update.Id, ex.Message);
ExceptionHandler?.HandleException(botClient, ex, HandleErrorSource.PollingError, cancellationToken); ExceptionHandler?.HandleException(botClient, ex, HandleErrorSource.PollingError, cancellationToken);
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -149,22 +149,22 @@ namespace Telegrator.Polling
/// <returns>A collection of described handler information for the update</returns> /// <returns>A collection of described handler information for the update</returns>
protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default) protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
{ {
LeveledDebug.RouterWriteLine("Requested handlers for UpdateType.{0}", update.Type); Alligator.RouterWriteLine("Requested handlers for UpdateType.{0}", update.Type);
if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors)) if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors))
{ {
LeveledDebug.RouterWriteLine("No registered, providing Any"); Alligator.RouterWriteLine("No registered, providing Any");
provider.TryGetDescriptorList(UpdateType.Unknown, out descriptors); provider.TryGetDescriptorList(UpdateType.Unknown, out descriptors);
} }
if (descriptors == null || descriptors.Count == 0) if (descriptors == null || descriptors.Count == 0)
{ {
LeveledDebug.RouterWriteLine("No handlers provided"); Alligator.RouterWriteLine("No handlers provided");
return []; return [];
} }
IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken); IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
LeveledDebug.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name); Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
LeveledDebug.RouterWriteLine("Described handlers : {0}", string.Join(", ", described)); Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
return described; return described;
} }
@@ -183,7 +183,7 @@ namespace Telegrator.Polling
{ {
try try
{ {
LeveledDebug.RouterWriteLine("Describing descriptors of descriptorsList.HandlingType.{0} for Update ({1})", descriptors.HandlingType, update.Id); Alligator.RouterWriteLine("Describing descriptors of descriptorsList.HandlingType.{0} for Update ({1})", descriptors.HandlingType, update.Id);
foreach (HandlerDescriptor descriptor in descriptors.Reverse()) foreach (HandlerDescriptor descriptor in descriptors.Reverse())
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
@@ -198,7 +198,7 @@ namespace Telegrator.Polling
} }
finally finally
{ {
LeveledDebug.RouterWriteLine("Describing for Update ({0}) finished", update.Id); Alligator.RouterWriteLine("Describing for Update ({0}) finished", update.Id);
} }
} }
@@ -252,7 +252,7 @@ namespace Telegrator.Polling
if (msg.Sticker != null) if (msg.Sticker != null)
sb.AppendFormat(" with sticker '{0}'", msg.Sticker.Emoji); sb.AppendFormat(" with sticker '{0}'", msg.Sticker.Emoji);
LeveledDebug.RouterWriteLine(sb.ToString()); Alligator.RouterWriteLine(sb.ToString());
break; break;
} }
@@ -267,7 +267,7 @@ namespace Telegrator.Polling
if (cq.From != null) if (cq.From != null)
sb.AppendFormat(" with data '{0}'", cq.Data); sb.AppendFormat(" with data '{0}'", cq.Data);
LeveledDebug.RouterWriteLine(sb.ToString()); Alligator.RouterWriteLine(sb.ToString());
break; break;
} }
} }
+3 -3
View File
@@ -40,7 +40,7 @@ namespace Telegrator.Providers
AllowedTypes = handlers.AllowedTypes; AllowedTypes = handlers.AllowedTypes;
HandlersDictionary = handlers.Values.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType); HandlersDictionary = handlers.Values.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
Options = options ?? throw new ArgumentNullException(nameof(options)); Options = options ?? throw new ArgumentNullException(nameof(options));
LeveledDebug.ProviderWriteLine("{0} created!", GetType().Name); Alligator.ProviderWriteLine("{0} created!", GetType().Name);
} }
/// <summary> /// <summary>
@@ -54,7 +54,7 @@ namespace Telegrator.Providers
AllowedTypes = Update.AllTypes; AllowedTypes = Update.AllTypes;
HandlersDictionary = handlers.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType); HandlersDictionary = handlers.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
Options = options ?? throw new ArgumentNullException(nameof(options)); Options = options ?? throw new ArgumentNullException(nameof(options));
LeveledDebug.ProviderWriteLine("{0} created!", GetType().Name); Alligator.ProviderWriteLine("{0} created!", GetType().Name);
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -76,7 +76,7 @@ namespace Telegrator.Providers
} }
catch catch
{ {
LeveledDebug.ProviderWriteLine("Failed to create instance of {0}", descriptor.ToString()); Alligator.ProviderWriteLine("Failed to create instance of {0}", descriptor.ToString());
throw; throw;
} }
} }