geekbot/Geekbot.net/Commands/User/Ranking/Rank.cs

166 lines
6.1 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
2018-05-10 17:56:43 +02:00
using Geekbot.net.Database;
using Geekbot.net.Lib.AlmostRedis;
using Geekbot.net.Lib.Converters;
using Geekbot.net.Lib.ErrorHandling;
2018-05-10 17:56:43 +02:00
using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.UserRepository;
using StackExchange.Redis;
2018-05-03 21:20:49 +02:00
namespace Geekbot.net.Commands.User.Ranking
{
public class Rank : ModuleBase
{
2017-12-29 01:53:50 +01:00
private readonly IEmojiConverter _emojiConverter;
private readonly IErrorHandler _errorHandler;
2018-05-10 17:56:43 +02:00
private readonly DatabaseContext _database;
private readonly IUserRepository _userRepository;
private readonly IAlmostRedis _redis;
2017-12-29 01:53:50 +01:00
2018-05-13 21:33:48 +02:00
public Rank(DatabaseContext database, IErrorHandler errorHandler, IUserRepository userRepository,
IEmojiConverter emojiConverter, IAlmostRedis redis)
{
2018-05-10 17:56:43 +02:00
_database = database;
_errorHandler = errorHandler;
_userRepository = userRepository;
2017-11-06 23:55:28 +01:00
_emojiConverter = emojiConverter;
_redis = redis;
}
2017-12-29 01:53:50 +01:00
[Command("rank", RunMode = RunMode.Async)]
[Summary("get user top 10 in messages or karma")]
2018-05-03 21:20:49 +02:00
public async Task RankCmd([Summary("type")] string typeUnformated = "messages", [Summary("amount")] int amount = 10)
{
try
{
2018-05-10 17:56:43 +02:00
RankType type;
try
{
type = Enum.Parse<RankType>(typeUnformated.ToLower());
}
catch
{
2017-12-29 01:03:38 +01:00
await ReplyAsync("Valid types are '`messages`' '`karma`', '`rolls`'");
return;
}
2017-12-29 01:53:50 +01:00
2018-05-10 17:56:43 +02:00
var replyBuilder = new StringBuilder();
if (amount > 20)
{
2018-05-10 17:56:43 +02:00
replyBuilder.AppendLine(":warning: Limiting to 20\n");
amount = 20;
}
2018-05-10 17:56:43 +02:00
Dictionary<ulong, int> list;
2017-12-29 01:53:50 +01:00
2018-05-10 17:56:43 +02:00
switch (type)
{
2018-05-10 17:56:43 +02:00
case RankType.messages:
list = GetMessageList(amount);
break;
case RankType.karma:
list = GetKarmaList(amount);
break;
case RankType.rolls:
list = GetRollsList(amount);
break;
default:
await ReplyAsync("Valid types are '`messages`' '`karma`', '`rolls`'");
return;
}
2018-05-10 17:56:43 +02:00
if (!list.Any())
{
2018-05-10 17:56:43 +02:00
await ReplyAsync($"No {type} found on this server");
return;
}
2018-05-10 17:56:43 +02:00
var highscoreUsers = new Dictionary<RankUserDto, int>();
var failedToRetrieveUser = false;
2018-05-10 17:56:43 +02:00
foreach (var user in list)
{
try
{
2018-05-10 17:56:43 +02:00
var guildUser = _userRepository.Get(user.Key);
if (guildUser?.Username != null)
{
2018-05-10 17:56:43 +02:00
highscoreUsers.Add(new RankUserDto
{
Username = guildUser.Username,
Discriminator = guildUser.Discriminator
2018-05-10 17:56:43 +02:00
}, user.Value);
}
else
{
2018-05-10 17:56:43 +02:00
highscoreUsers.Add(new RankUserDto
{
2018-05-10 17:56:43 +02:00
Id = user.Key.ToString()
}, user.Value);
failedToRetrieveUser = true;
}
}
2018-05-10 17:56:43 +02:00
catch
{
2018-05-10 17:56:43 +02:00
// ignore
}
}
2017-12-29 01:53:50 +01:00
if (failedToRetrieveUser) replyBuilder.AppendLine(":warning: Couldn't get all userdata\n");
replyBuilder.AppendLine($":bar_chart: **{type} Highscore for {Context.Guild.Name}**");
var highscorePlace = 1;
foreach (var user in highscoreUsers)
{
replyBuilder.Append(highscorePlace < 11
2018-04-30 23:44:19 +02:00
? $"{_emojiConverter.NumberToEmoji(highscorePlace)} "
: $"`{highscorePlace}.` ");
replyBuilder.Append(user.Key.Username != null
? $"**{user.Key.Username}#{user.Key.Discriminator}**"
: $"**{user.Key.Id}**");
2018-05-10 17:56:43 +02:00
replyBuilder.Append($" - {user.Value} {type}\n");
2017-12-29 01:53:50 +01:00
highscorePlace++;
}
2017-12-29 01:53:50 +01:00
await ReplyAsync(replyBuilder.ToString());
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
}
}
2018-05-10 17:56:43 +02:00
private Dictionary<ulong, int> GetMessageList(int amount)
{
return _redis.Db
2018-05-13 21:33:48 +02:00
.HashGetAll($"{Context.Guild.Id}:Messages").ToDictionary().Take(amount + 1)
.Where(user => !user.Key.Equals(0))
.ToDictionary(user => ulong.Parse(user.Key), user => int.Parse(user.Value));
2018-05-10 17:56:43 +02:00
}
private Dictionary<ulong, int> GetKarmaList(int amount)
{
2018-05-13 21:33:48 +02:00
return _database.Karma
2018-05-10 17:56:43 +02:00
.Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong()))
.OrderByDescending(o => o.Karma)
2018-05-13 21:33:48 +02:00
.Take(amount)
.ToDictionary(key => key.UserId.AsUlong(), key => key.Karma);
2018-05-10 17:56:43 +02:00
}
private Dictionary<ulong, int> GetRollsList(int amount)
{
2018-05-13 21:33:48 +02:00
return _database.Rolls
2018-05-10 17:56:43 +02:00
.Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong()))
.OrderByDescending(o => o.Rolls)
2018-05-13 21:33:48 +02:00
.Take(amount)
.ToDictionary(key => key.UserId.AsUlong(), key => key.Rolls);
2018-05-10 17:56:43 +02:00
}
}
2017-04-12 21:49:04 +02:00
}