[reputation] Move reputation to separate module.

This commit is contained in:
West14
2022-02-14 00:18:53 +02:00
parent 6f02031e65
commit a4a44198c5
20 changed files with 595 additions and 228 deletions
+175
View File
@@ -0,0 +1,175 @@
#nullable enable
using BotFramework.Attributes;
using BotFramework.Enums;
using BotFramework.Utils;
using Kruzya.TelegramBot.Core;
using Kruzya.TelegramBot.Core.Data;
using Kruzya.TelegramBot.Core.Extensions;
using Kruzya.TelegramBot.Core.Service;
using Microsoft.Extensions.Logging;
using Telegram.Bot;
using Telegram.Bot.Types;
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;
private static readonly List<string> RepUpChars = new()
{
"+",
"👍",
"👍🏼",
"👍🏽",
"👍🏾",
"👍🏿",
"👍🏻"
};
private static readonly List<string> RepDownChars = new()
{
"-",
"👎",
"👎🏼",
"👎🏽",
"👎🏾",
"👎🏿",
"👎🏻"
};
public Reputation(
CoreContext db,
UserService userService,
IReputation reputationService,
ILogger<Reputation> logger
) : base(db)
{
_reputationService = reputationService;
_userService = userService;
_logger = logger;
}
[Command("whois", CommandParseMode.Both)]
public async Task HandleWhois()
{
var user = RepliedUser ?? From;
var message = $"{user.ToHtml()}\n";
if (user.IsBot)
{
message += "<code>Бот</code>";
}
else
{
message += $"<code>{await GetChatMemberStatusString(user)}</code>\n";
message += $"<code>Репутация: {await GetUserReputation(user)}\n";
message += $"Предупреждения: {(await GetWarnOption(user)).GetValue<int>()}</code>";
}
await Reply(message);
}
[Message(InChat.Public, MessageFlag.HasText | MessageFlag.HasSticker)]
public async Task HandleReputation()
{
var text = Message?.Text;
if (string.IsNullOrEmpty(text))
{
text = Message?.Sticker?.Emoji;
}
if (text == null)
{
return;
}
var receiver = RepliedUser;
var canChangeRep = receiver is { IsBot: false } && !From.IsBot && receiver.Id != From.Id;
if (canChangeRep && (RepUpChars.Contains(text) || RepDownChars.Contains(text)))
{
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>");
}
}
[ParametrizedCommand(InChat.Public, "setrep", CommandParseMode.Both)]
public async Task HandleSetRep(double reputation)
{
if (!_userService.IsUserSuper(From))
{
_logger.LogInformation("{User} attempted to call /setrep in {Chat}", From, Chat.Title);
return;
}
if (RepliedUser == null || RepliedUser.IsBot)
{
return;
}
reputation = await _reputationService.SetUserReputationAsync(Chat, RepliedUser, reputation);
await Reply(
new HtmlString()
.Code("Пользователю ")
.UserMention(RepliedUser)
.Code($" установлена репутация: {reputation}")
.ToString()
);
}
private async Task<double> GetUserReputation(User user)
{
return await _reputationService.GetUserReputationAsync(Chat, user);
}
private async Task<string> GetChatMemberStatusString(User user)
{
var customStatus = _userService.GetUserCustomStatus(user.Id);
if (customStatus != null)
{
return customStatus;
}
var chatMember = await Bot.GetChatMemberAsync(Chat.Id, user.Id);
return chatMember.Status switch
{
ChatMemberStatus.Creator => "Владелец",
ChatMemberStatus.Restricted => "Заблокированный",
ChatMemberStatus.Administrator => "Администратор",
_ => "Пользователь"
};
}
}