mirror of
https://github.com/Jetsparrow/antiantiswearingbot.git
synced 2026-01-20 23:16:08 +03:00
Switch to aspnet WebApplication
This commit is contained in:
parent
354876985d
commit
4090adef78
5
.gitignore
vendored
5
.gitignore
vendored
@ -41,6 +41,5 @@ Thumbs.db
|
||||
*.dotCover
|
||||
|
||||
#secret config
|
||||
karma.cfg.json
|
||||
*secrets.ini
|
||||
*.secret.json
|
||||
secrets.json
|
||||
secrets.*.json
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace AntiAntiSwearingBot.Tests
|
||||
@ -8,13 +11,12 @@ namespace AntiAntiSwearingBot.Tests
|
||||
public class DetectTests
|
||||
{
|
||||
Unbleeper ubl { get; }
|
||||
Config cfg { get; }
|
||||
SearchDictionary dict { get; }
|
||||
|
||||
public DetectTests()
|
||||
{
|
||||
cfg = Config.Load<Config>("aasb.cfg.json");
|
||||
dict = new SearchDictionary(cfg);
|
||||
|
||||
dict = new SearchDictionary(OptionsMonitor );
|
||||
ubl = new Unbleeper(dict, cfg.Unbleeper);
|
||||
}
|
||||
|
||||
|
||||
@ -1,42 +1,43 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Exceptions;
|
||||
using Telegram.Bot.Extensions.Polling;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using AntiAntiSwearingBot.Commands;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
|
||||
public class AntiAntiSwearingBot
|
||||
public class Aasb : IHostedService
|
||||
{
|
||||
Config Config { get; }
|
||||
SearchDictionary Dict { get; }
|
||||
Unbleeper Unbleeper { get; }
|
||||
ILogger Log { get; }
|
||||
public bool Started { get; private set; } = false;
|
||||
|
||||
public AntiAntiSwearingBot(Config cfg, SearchDictionary dict)
|
||||
public Aasb(ILogger<Aasb> log, IOptions<TelegramSettings> tgCfg, Unbleeper unbp)
|
||||
{
|
||||
Config = cfg;
|
||||
Dict = dict;
|
||||
Unbleeper = new Unbleeper(dict, cfg.Unbleeper);
|
||||
Log = log;
|
||||
TelegramSettings = tgCfg.Value;
|
||||
Unbleeper = unbp;
|
||||
}
|
||||
|
||||
TelegramSettings TelegramSettings { get; }
|
||||
TelegramBotClient TelegramBot { get; set; }
|
||||
ChatCommandRouter Router { get; set; }
|
||||
public User Me { get; private set; }
|
||||
|
||||
public async Task Init()
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Config.ApiKey))
|
||||
if (string.IsNullOrWhiteSpace(TelegramSettings.ApiKey))
|
||||
return;
|
||||
|
||||
TelegramBot = new TelegramBotClient(Config.ApiKey);
|
||||
TelegramBot = new TelegramBotClient(TelegramSettings.ApiKey);
|
||||
|
||||
Me = await TelegramBot.GetMeAsync();
|
||||
|
||||
|
||||
Log.LogInformation("Connected to Telegram as @{Username}", Me.Username);
|
||||
Router = new ChatCommandRouter(Me.Username);
|
||||
Router.Add(new LearnCommand(Dict), "learn");
|
||||
Router.Add(new UnlearnCommand(Dict), "unlearn");
|
||||
@ -46,16 +47,19 @@ public class AntiAntiSwearingBot
|
||||
HandleUpdateAsync,
|
||||
HandleErrorAsync,
|
||||
receiverOptions);
|
||||
|
||||
Log.LogInformation("AntiAntiSwearBot started!");
|
||||
Started = true;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await TelegramBot.CloseAsync();
|
||||
}
|
||||
|
||||
Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
|
||||
{
|
||||
var ErrorMessage = exception switch
|
||||
{
|
||||
ApiRequestException apiRequestException => $"Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
|
||||
_ => exception.ToString()
|
||||
};
|
||||
Console.WriteLine(ErrorMessage);
|
||||
Log.LogError(exception, "Exception while handling API message");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@ -76,7 +80,8 @@ public class AntiAntiSwearingBot
|
||||
await TelegramBot.SendTextMessageAsync(
|
||||
msg.Chat.Id,
|
||||
commandResponse,
|
||||
replyToMessageId: msg.MessageId);
|
||||
replyToMessageId: msg.MessageId,
|
||||
disableNotification: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -85,13 +90,13 @@ public class AntiAntiSwearingBot
|
||||
await TelegramBot.SendTextMessageAsync(
|
||||
msg.Chat.Id,
|
||||
unbleepResponse,
|
||||
replyToMessageId: msg.MessageId);
|
||||
replyToMessageId: msg.MessageId,
|
||||
disableNotification: true);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
Log.LogError(e, "Exception while handling message {0}", msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -10,10 +10,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Telegram.Bot.Extensions.Polling" Version="2.0.0-alpha.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="secrets.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="aasb.cfg.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
|
||||
@ -1,29 +1,28 @@
|
||||
namespace AntiAntiSwearingBot;
|
||||
|
||||
public class Config : ConfigBase
|
||||
public class ServiceSettings
|
||||
{
|
||||
public string ApiKey { get; private set; }
|
||||
public ProxySettings Proxy { get; private set; }
|
||||
public SearchDictionarySettings SearchDictionary { get; private set; }
|
||||
public UnbleeperSettings Unbleeper { get; private set; }
|
||||
public string Urls { get; set; }
|
||||
}
|
||||
|
||||
public struct UnbleeperSettings
|
||||
public class UnbleeperSettings
|
||||
{
|
||||
public string BleepedSwearsRegex { get; private set; }
|
||||
public int MinAmbiguousWordLength { get; private set; }
|
||||
public int MinWordLength { get; private set; }
|
||||
public string BleepedSwearsRegex { get; set; }
|
||||
public int MinAmbiguousWordLength { get; set; }
|
||||
public int MinWordLength { get; set; }
|
||||
}
|
||||
|
||||
public struct SearchDictionarySettings
|
||||
public class SearchDictionarySettings
|
||||
{
|
||||
public string DictionaryPath { get; private set; }
|
||||
public string DictionaryPath { get; set; }
|
||||
}
|
||||
|
||||
public struct ProxySettings
|
||||
public class TelegramSettings
|
||||
{
|
||||
public string Url { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
public string Login { get; private set; }
|
||||
public string Password { get; private set; }
|
||||
public string ApiKey { get; set; }
|
||||
public bool UseProxy { get; set; }
|
||||
public string Url { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string Login { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
|
||||
public abstract class ConfigBase
|
||||
{
|
||||
public static T Load<T>(params string[] paths) where T : ConfigBase, new()
|
||||
{
|
||||
var result = new T();
|
||||
var configJson = new JObject();
|
||||
var mergeSettings = new JsonMergeSettings
|
||||
{
|
||||
MergeArrayHandling = MergeArrayHandling.Union
|
||||
};
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
try { configJson.Merge(JObject.Parse(File.ReadAllText(path)), mergeSettings);}
|
||||
catch { }
|
||||
}
|
||||
|
||||
using (var sr = configJson.CreateReader())
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new PrivateSetterContractResolver()
|
||||
};
|
||||
JsonSerializer.CreateDefault(settings).Populate(sr, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class PrivateSetterContractResolver : DefaultContractResolver
|
||||
{
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var jProperty = base.CreateProperty(member, memberSerialization);
|
||||
if (jProperty.Writable)
|
||||
return jProperty;
|
||||
|
||||
jProperty.Writable = member.IsPropertyWithSetter();
|
||||
|
||||
return jProperty;
|
||||
}
|
||||
}
|
||||
|
||||
public class PrivateSetterCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var jProperty = base.CreateProperty(member, memberSerialization);
|
||||
if (jProperty.Writable)
|
||||
return jProperty;
|
||||
|
||||
jProperty.Writable = member.IsPropertyWithSetter();
|
||||
|
||||
return jProperty;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class MemberInfoExtensions
|
||||
{
|
||||
internal static bool IsPropertyWithSetter(this MemberInfo member)
|
||||
{
|
||||
var property = member as PropertyInfo;
|
||||
|
||||
return property?.GetSetMethod(true) != null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
public static class IServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddHostedSingleton<TService>(this IServiceCollection isc) where TService : class, IHostedService
|
||||
{
|
||||
return isc.AddSingleton<TService>().AddHostedService(svc => svc.GetRequiredService<TService>());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
|
||||
public readonly ref struct ReadLockToken
|
||||
{
|
||||
ReaderWriterLockSlim Lock { get; }
|
||||
public ReadLockToken(ReaderWriterLockSlim l) => (Lock = l).EnterReadLock();
|
||||
public void Dispose() => Lock.ExitReadLock();
|
||||
}
|
||||
|
||||
public readonly ref struct WriteLockToken
|
||||
{
|
||||
ReaderWriterLockSlim Lock { get; }
|
||||
public WriteLockToken(ReaderWriterLockSlim l) => (Lock = l).EnterWriteLock();
|
||||
public void Dispose() => Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
public static class ReaderWriterLockSlimExtensions
|
||||
{
|
||||
public static ReadLockToken GetReadLockToken(this ReaderWriterLockSlim l) => new ReadLockToken(l);
|
||||
public static WriteLockToken GetWriteLockToken(this ReaderWriterLockSlim l) => new WriteLockToken(l);
|
||||
}
|
||||
@ -3,3 +3,4 @@ global using System.Text;
|
||||
global using System.Linq;
|
||||
global using System.Collections.Generic;
|
||||
|
||||
global using Microsoft.Extensions.Options;
|
||||
@ -1,31 +1,34 @@
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using AntiAntiSwearingBot;
|
||||
|
||||
static void Log(string m) => Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}|{m}");
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
|
||||
Log("AntiAntiSwearBot starting....");
|
||||
|
||||
var cfg = Config.Load<Config>("aasb.cfg.json", "aasb.cfg.secret.json");
|
||||
var dict = new SearchDictionary(cfg);
|
||||
Log($"{dict.Count} words loaded.");
|
||||
var bot = new AntiAntiSwearingBot.AntiAntiSwearingBot(cfg, dict);
|
||||
bot.Init().Wait();
|
||||
Log($"Connected to Telegram as @{bot.Me.Username}");
|
||||
Log("AntiAntiSwearBot started! Press Ctrl-C to exit.");
|
||||
|
||||
ManualResetEvent quitEvent = new ManualResetEvent(false);
|
||||
try
|
||||
builder.WebHost.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
Console.CancelKeyPress += (sender, eArgs) => // ctrl-c
|
||||
{
|
||||
eArgs.Cancel = true;
|
||||
quitEvent.Set();
|
||||
};
|
||||
}
|
||||
catch { }
|
||||
var env = hostingContext.HostingEnvironment.EnvironmentName;
|
||||
config.AddJsonFile("secrets.json", optional: true, reloadOnChange: true);
|
||||
config.AddJsonFile($"secrets.{env}.json", optional: true, reloadOnChange: true);
|
||||
});
|
||||
|
||||
quitEvent.WaitOne(Timeout.Infinite);
|
||||
var cfg = builder.Configuration;
|
||||
var svc = builder.Services;
|
||||
|
||||
Console.WriteLine("Waiting for exit...");
|
||||
dict.Save();
|
||||
svc.Configure<SearchDictionarySettings>(cfg.GetSection("SearchDictionary"));
|
||||
svc.Configure<TelegramSettings>(cfg.GetSection("Telegram"));
|
||||
svc.Configure<UnbleeperSettings>(cfg.GetSection("Unbleeper"));
|
||||
|
||||
svc.AddHealthChecks().AddCheck<StartupHealthCheck>("Startup");
|
||||
svc.AddHostedSingleton<SearchDictionary>();
|
||||
svc.AddSingleton<Unbleeper>();
|
||||
svc.AddHostedSingleton<Aasb>();
|
||||
|
||||
var app = builder.Build();
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(cfg =>
|
||||
{
|
||||
cfg.MapHealthChecks("/health");
|
||||
});
|
||||
app.Run();
|
||||
|
||||
@ -7,9 +7,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<PublishDir>i:\aasb</PublishDir>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PublishDir>C:\Prog\releases\aasb</PublishDir>
|
||||
<SelfContained>false</SelfContained>
|
||||
<_IsPortable>true</_IsPortable>
|
||||
</PropertyGroup>
|
||||
|
||||
27
AntiAntiSwearingBot/Properties/launchSettings.json
Normal file
27
AntiAntiSwearingBot/Properties/launchSettings.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:50671/",
|
||||
"sslPort": 44398
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"AntiAntiSwearingBot": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,55 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
public class SearchDictionary
|
||||
public class SearchDictionary : BackgroundService
|
||||
{
|
||||
public SearchDictionary(Config cfg)
|
||||
public SearchDictionary(IOptionsMonitor<SearchDictionarySettings> cfg)
|
||||
{
|
||||
var s = cfg.SearchDictionary;
|
||||
path = s.DictionaryPath;
|
||||
tmppath = path + ".tmp";
|
||||
|
||||
Cfg = cfg;
|
||||
var path = cfg.CurrentValue.DictionaryPath;
|
||||
words = File.ReadAllLines(path).ToList();
|
||||
}
|
||||
|
||||
IOptionsMonitor<SearchDictionarySettings> Cfg { get; }
|
||||
ReaderWriterLockSlim DictLock = new();
|
||||
List<string> words;
|
||||
bool Changed = false;
|
||||
|
||||
public int Count => words.Count;
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
||||
if (Changed) Save();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (File.Exists(tmppath))
|
||||
File.Delete(tmppath);
|
||||
using var guard = DictLock.GetWriteLockToken();
|
||||
Changed = false;
|
||||
|
||||
var path = Cfg.CurrentValue.DictionaryPath;
|
||||
var tmppath = path + ".tmp";
|
||||
|
||||
File.WriteAllLines(tmppath, words);
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
File.Move(tmppath, path);
|
||||
File.Move(tmppath, path, overwrite: true);
|
||||
}
|
||||
|
||||
public struct WordMatch
|
||||
{
|
||||
public string Word;
|
||||
public int Distance;
|
||||
public int Rating;
|
||||
}
|
||||
public record struct WordMatch (string Word, int Distance, int Rating);
|
||||
|
||||
public WordMatch Match(string pattern)
|
||||
=> AllMatches(pattern).First();
|
||||
|
||||
public IEnumerable<WordMatch> AllMatches(string pattern)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
pattern = pattern.ToLowerInvariant();
|
||||
using var guard = DictLock.GetReadLockToken();
|
||||
return words
|
||||
.Select((w, i) => new WordMatch { Word = w, Distance = Language.LevenshteinDistance(pattern, w), Rating = i })
|
||||
.Select((w, i) => new WordMatch(w, Language.LevenshteinDistance(pattern.ToLowerInvariant(), w), i))
|
||||
.OrderBy(m => m.Distance)
|
||||
.ThenBy(m => m.Rating);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Learn(string word)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
using var guard = DictLock.GetWriteLockToken();
|
||||
Changed = true;
|
||||
|
||||
int index = words.IndexOf(word);
|
||||
if (index > 0)
|
||||
{
|
||||
@ -62,20 +80,12 @@ public class SearchDictionary
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Unlearn(string word)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
using var guard = DictLock.GetWriteLockToken();
|
||||
Changed = true;
|
||||
return words.Remove(word);
|
||||
}
|
||||
|
||||
#region service
|
||||
|
||||
readonly string path, tmppath;
|
||||
|
||||
object SyncRoot = new object();
|
||||
List<string> words;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
24
AntiAntiSwearingBot/StartupHealthCheck.cs
Normal file
24
AntiAntiSwearingBot/StartupHealthCheck.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
namespace AntiAntiSwearingBot;
|
||||
public class StartupHealthCheck : IHealthCheck
|
||||
{
|
||||
Aasb Bot { get; }
|
||||
|
||||
public StartupHealthCheck(Aasb bot)
|
||||
{
|
||||
Bot = bot;
|
||||
}
|
||||
|
||||
public Task<HealthCheckResult> CheckHealthAsync(
|
||||
HealthCheckContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (Bot.Started)
|
||||
return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
|
||||
else
|
||||
return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
|
||||
}
|
||||
}
|
||||
@ -7,10 +7,10 @@ public class Unbleeper
|
||||
SearchDictionary Dict { get; }
|
||||
UnbleeperSettings Cfg { get; }
|
||||
|
||||
public Unbleeper(SearchDictionary dict, UnbleeperSettings cfg)
|
||||
public Unbleeper(SearchDictionary dict, IOptions<UnbleeperSettings> cfg)
|
||||
{
|
||||
Dict = dict;
|
||||
Cfg = cfg;
|
||||
Cfg = cfg.Value;
|
||||
BleepedSwearsRegex = new Regex("^" + Cfg.BleepedSwearsRegex + "$", RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
@ -41,8 +41,9 @@ public class Unbleeper
|
||||
)
|
||||
.ToArray();
|
||||
|
||||
if (candidates.Any())
|
||||
{
|
||||
if (!candidates.Any())
|
||||
return null;
|
||||
|
||||
var response = new StringBuilder();
|
||||
for (int i = 0; i < candidates.Length; ++i)
|
||||
{
|
||||
@ -51,7 +52,4 @@ public class Unbleeper
|
||||
}
|
||||
return response.ToString();
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,11 @@
|
||||
{
|
||||
"Kestrel": {
|
||||
"Endpoints": {
|
||||
"Http": {
|
||||
"Url": "http://localhost:9999"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Unbleeper": {
|
||||
"BleepedSwearsRegex": "[а-яА-ЯёЁ@\\*#]+",
|
||||
"MinWordLength": 3,
|
||||
@ -6,5 +13,8 @@
|
||||
},
|
||||
"SearchDictionary": {
|
||||
"DictionaryPath": "dict/ObsceneDictionaryRu.txt"
|
||||
},
|
||||
"Telegram": {
|
||||
"UseProxy": false
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user