Files
telegram-bot/modules/Reputation/Handler/Reputation.cs
T

221 lines
6.5 KiB
C#
Raw Normal View History

#nullable enable
using BotFramework.Attributes;
using BotFramework.Enums;
using BotFramework.Utils;
using Kruzya.TelegramBot.Core.Data;
using Kruzya.TelegramBot.Core.Extensions;
2023-07-20 21:22:35 +03:00
using Kruzya.TelegramBot.Core.Handler;
using Kruzya.TelegramBot.Core.Service;
using Microsoft.Extensions.Logging;
2022-02-16 07:37:03 +03:00
using Telegram.Bot;
using Telegram.Bot.Types;
2022-02-16 07:37:03 +03:00
using Telegram.Bot.Types.Enums;
namespace West.TelegramBot.Reputation.Handler;
public class Reputation : CommonHandler
{
private readonly UserService _userService;
private readonly ILogger _logger;
private readonly IReputation _reputationService;
2022-02-16 19:44:53 +03:00
private readonly IAntiFlood _antiFlood;
2022-02-14 14:39:55 +02:00
private static readonly List<string> RepUpChars = new()
{
"+",
"👍",
"👍🏼",
"👍🏽",
"👍🏾",
"👍🏿",
"👍🏻"
};
private static readonly List<string> RepDownChars = new()
{
"-",
"👎",
"👎🏼",
"👎🏽",
"👎🏾",
"👎🏿",
"👎🏻"
};
public Reputation(
CoreContext db,
UserService userService,
IReputation reputationService,
2022-02-16 19:44:53 +03:00
IAntiFlood antiFlood,
2022-02-14 14:39:55 +02:00
ILogger<Reputation> logger) : base(db)
{
_reputationService = reputationService;
_userService = userService;
2022-02-16 19:44:53 +03:00
_antiFlood = antiFlood;
_logger = logger;
}
2023-07-29 01:50:28 +03:00
[InChat(InChat.Public)]
[HandleCondition(ConditionType.Any)]
[Message(MessageFlag.HasText)]
[Message(MessageFlag.HasSticker)]
public async Task HandleReputation()
{
var text = Message?.Text;
2022-02-16 19:44:53 +03:00
if (string.IsNullOrEmpty(text))
{
text = Message?.Sticker?.Emoji;
}
if (text == null)
{
return;
}
2022-02-16 19:44:53 +03:00
var receiver = RepliedUser;
var canChangeRep = receiver is { IsBot: false } && !From.IsBot && receiver.Id != From.Id;
if (canChangeRep && (RepUpChars.Contains(text) || RepDownChars.Contains(text)))
{
2022-02-18 01:25:53 +02:00
if (!_userService.IsUserSuper(From) && !await Bot.IsUserAdminAsync(Chat, From))
2022-02-16 19:44:53 +03:00
{
if (_antiFlood.IsUserFlooding(Chat, From))
{
return;
}
_antiFlood.RecordAction(Chat, From);
2022-02-16 20:05:14 +03:00
if (_antiFlood.IsUserFlooding(Chat, From))
{
await Reply(new HtmlString()
2022-02-16 20:07:33 +03:00
.UserMention(From).Code(": пользователь отправлен в игнор.")
2022-02-16 20:05:14 +03:00
.ToString());
return;
}
2022-02-16 19:44:53 +03:00
}
2022-02-16 19:44:53 +03:00
var senderRepCount = await GetUserReputation(From);
if (senderRepCount < 0)
{
await Reply(new HtmlString()
.Code("Ты не можешь голосовать с отрицательной репутацией.")
.ToString()
);
return;
}
var diff = await _reputationService.GetReputationDiffAsync(Chat, From, receiver);
_logger.LogDebug("Calculated diff: {Diff}", diff);
string action;
if (RepUpChars.Contains(text))
{
action = "увеличил";
}
else
{
diff *= -1;
action = "уменьшил";
}
await _reputationService.IncrementReputationAsync(Chat, receiver, diff);
var receiverRepCount = await GetUserReputation(receiver!);
_logger.LogDebug("Updated value: {Value}", receiverRepCount);
await Reply($"{From.ToHtml()}<code>({await GetUserReputation(From)}) " +
$"{action} репутацию </code>{receiver.ToHtml()}<code>({Math.Round(receiverRepCount, 2)})</code>");
}
}
2023-07-29 01:50:28 +03:00
[InChat(InChat.Public)]
[ParametrizedCommand("setrep", CommandParseMode.Both)]
public async Task HandleSetRep(double reputation)
{
2022-04-23 21:42:17 +03:00
if (!CanModifyUserReputation(RepliedUser))
{
return;
}
2022-04-23 21:42:17 +03:00
await SendReputationModifyResponse(
await _reputationService.SetUserReputationAsync(Chat, RepliedUser, reputation)
);
}
2023-07-29 01:50:28 +03:00
[InChat(InChat.Public)]
[ParametrizedCommand("addrep", CommandParseMode.Both)]
2022-04-23 21:42:17 +03:00
public async Task HandleAddRep(double reputation)
{
if (!CanModifyUserReputation(RepliedUser))
{
return;
}
2022-04-23 21:42:17 +03:00
await SendReputationModifyResponse(
await _reputationService.IncrementReputationAsync(Chat, RepliedUser, reputation)
);
}
2023-07-29 01:50:28 +03:00
[InChat(InChat.Public)]
[Command("top", CommandParseMode.Both)]
2022-02-14 14:39:55 +02:00
public async Task HandleTop()
{
2024-05-19 22:40:34 +03:00
await Reply("This feature is currently disabled.");
return;
2022-02-14 14:39:55 +02:00
var msg = new HtmlString();
msg.TextBr("Топ репутации чата: ");
var i = 1;
foreach (var rep in await _reputationService.GetChatRatingAsync(Chat))
{
// TODO: there are should be more correct fix, but I want to fix this now, West, 18:04, 07.05.2022
User user;
try
{
user = await _userService.GetUser(rep.UserId, rep.ChatId);
}
catch
{
continue;
}
msg.Text($"{i}. ")
.Text($"{user.FirstName} {user.LastName}".Trim().HtmlEncode())
.Text($" ({rep.Value})").Br();
2022-02-14 14:39:55 +02:00
i++;
}
2023-01-02 19:01:03 +02:00
await Bot.SendTextMessageAsync(Chat!, msg.ToString(), parseMode: ParseMode.Html,
2022-02-16 07:37:03 +03:00
disableNotification: true);
2022-02-14 14:39:55 +02:00
}
2022-04-23 21:42:17 +03:00
private async Task SendReputationModifyResponse(double reputation)
{
await Reply(
new HtmlString()
.Code("Пользователю ")
.UserMention(RepliedUser)
.Code($" установлена репутация: {reputation}")
.ToString()
);
}
private bool CanModifyUserReputation(User? user)
{
if (!_userService.IsUserSuper(From))
{
2022-12-14 12:58:12 +02:00
_logger.LogWarning("{User} attempted to modify reputation in {Chat}",
From.ToLog(),
Chat.ToLog()
);
2022-04-23 21:42:17 +03:00
return false;
}
return user is {IsBot: false};
}
private async Task<double> GetUserReputation(User user)
{
return await _reputationService.GetUserReputationAsync(Chat, user);
}
}