geekbot/Geekbot.net/Commands/Utils/Quote/Quote.cs

307 lines
12 KiB
C#
Raw Normal View History

2020-05-11 23:44:15 +02:00
using System;
2017-09-28 18:55:57 +02:00
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Geekbot.net.Database;
using Geekbot.net.Database.Models;
using Geekbot.net.Lib.CommandPreconditions;
using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions;
2019-05-12 15:29:22 +02:00
using Geekbot.net.Lib.Localization;
2018-05-06 02:43:23 +02:00
using Geekbot.net.Lib.Polyfills;
2019-05-11 01:18:22 +02:00
using Geekbot.net.Lib.RandomNumberGenerator;
2017-09-28 18:55:57 +02:00
namespace Geekbot.net.Commands.Utils.Quote
2017-09-28 18:55:57 +02:00
{
[Group("quote")]
[DisableInDirectMessage]
2017-09-28 18:55:57 +02:00
public class Quote : ModuleBase
{
2018-01-21 16:01:43 +01:00
private readonly IErrorHandler _errorHandler;
private readonly DatabaseContext _database;
2019-05-11 01:18:22 +02:00
private readonly IRandomNumberGenerator _randomNumberGenerator;
2019-05-12 15:29:22 +02:00
private readonly ITranslationHandler _translationHandler;
2017-12-29 01:53:50 +01:00
2019-05-12 15:29:22 +02:00
public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, ITranslationHandler translationHandler)
2017-09-28 18:55:57 +02:00
{
2018-01-21 16:01:43 +01:00
_errorHandler = errorHandler;
_database = database;
2019-05-11 01:18:22 +02:00
_randomNumberGenerator = randomNumberGenerator;
2019-05-12 15:29:22 +02:00
_translationHandler = translationHandler;
2017-09-28 18:55:57 +02:00
}
2017-12-29 01:53:50 +01:00
[Command]
2017-09-28 18:55:57 +02:00
[Summary("Return a random quoute from the database")]
2018-04-30 23:44:19 +02:00
public async Task GetRandomQuote()
2017-09-28 18:55:57 +02:00
{
try
{
var s = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())).ToList();
if (!s.Any())
2018-05-06 02:43:23 +02:00
{
2019-05-12 15:29:22 +02:00
var transContext = await _translationHandler.GetGuildContext(Context);
await ReplyAsync(transContext.GetString("NoQuotesFound"));
2018-05-06 02:43:23 +02:00
return;
}
var random = _randomNumberGenerator.Next(0, s.Count);
var quote = s[random];
var embed = QuoteBuilder(quote);
2017-09-28 18:55:57 +02:00
await ReplyAsync("", false, embed.Build());
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context, "Whoops, seems like the quote was to edgy to return");
2017-09-28 18:55:57 +02:00
}
}
2017-12-29 01:53:50 +01:00
2017-09-28 18:55:57 +02:00
[Command("save")]
[Summary("Save a quote from the last sent message by @user")]
public async Task SaveQuote([Summary("@someone")] IUser user)
2017-09-28 18:55:57 +02:00
{
try
{
2019-05-12 15:29:22 +02:00
var transContext = await _translationHandler.GetGuildContext(Context);
if (user.Id == Context.Message.Author.Id)
{
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("CannotSaveOwnQuotes"));
return;
}
2017-12-29 01:53:50 +01:00
if (user.IsBot)
{
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("CannotQuoteBots"));
return;
}
2017-12-29 01:53:50 +01:00
2018-04-30 23:44:19 +02:00
var lastMessage = await GetLastMessageByUser(user);
2018-05-06 02:43:23 +02:00
if (lastMessage == null) return;
2018-04-30 23:44:19 +02:00
var quote = CreateQuoteObject(lastMessage);
_database.Quotes.Add(quote);
2018-05-14 18:57:07 +02:00
await _database.SaveChangesAsync();
2018-04-30 23:44:19 +02:00
var embed = QuoteBuilder(quote);
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("QuoteAdded"), false, embed.Build());
2017-09-28 18:55:57 +02:00
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context,
2017-12-29 01:53:50 +01:00
"I counldn't find a quote from that user :disappointed:");
2017-09-28 18:55:57 +02:00
}
}
2017-12-29 01:53:50 +01:00
2017-09-28 18:55:57 +02:00
[Command("save")]
[Summary("Save a quote from a message id")]
public async Task SaveQuote([Summary("message-ID")] ulong messageId)
2017-09-28 18:55:57 +02:00
{
try
{
2019-05-12 15:29:22 +02:00
var transContext = await _translationHandler.GetGuildContext(Context);
2017-09-28 18:55:57 +02:00
var message = await Context.Channel.GetMessageAsync(messageId);
if (message.Author.Id == Context.Message.Author.Id)
{
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("CannotSaveOwnQuotes"));
return;
}
2017-12-29 01:53:50 +01:00
if (message.Author.IsBot)
{
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("CannotQuoteBots"));
return;
}
2017-12-29 01:53:50 +01:00
2018-04-30 23:44:19 +02:00
var quote = CreateQuoteObject(message);
_database.Quotes.Add(quote);
2018-05-14 18:57:07 +02:00
await _database.SaveChangesAsync();
2018-04-30 23:44:19 +02:00
var embed = QuoteBuilder(quote);
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("QuoteAdded"), false, embed.Build());
2017-09-28 18:55:57 +02:00
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context,
2017-12-29 01:53:50 +01:00
"I couldn't find a message with that id :disappointed:");
2017-09-28 18:55:57 +02:00
}
}
2017-12-29 01:53:50 +01:00
2017-09-28 18:55:57 +02:00
[Command("make")]
[Summary("Create a quote from the last sent message by @user")]
public async Task ReturnSpecifiedQuote([Summary("@someone")] IUser user)
2017-09-28 18:55:57 +02:00
{
try
{
2018-04-30 23:44:19 +02:00
var lastMessage = await GetLastMessageByUser(user);
2018-05-06 02:43:23 +02:00
if (lastMessage == null) return;
2018-04-30 23:44:19 +02:00
var quote = CreateQuoteObject(lastMessage);
var embed = QuoteBuilder(quote);
2017-09-28 18:55:57 +02:00
await ReplyAsync("", false, embed.Build());
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context,
2017-12-29 01:53:50 +01:00
"I counldn't find a quote from that user :disappointed:");
2017-09-28 18:55:57 +02:00
}
}
2017-12-29 01:53:50 +01:00
2017-09-28 18:55:57 +02:00
[Command("make")]
[Summary("Create a quote from a message id")]
public async Task ReturnSpecifiedQuote([Summary("message-ID")] ulong messageId)
2017-09-28 18:55:57 +02:00
{
try
{
var message = await Context.Channel.GetMessageAsync(messageId);
2018-04-30 23:44:19 +02:00
var quote = CreateQuoteObject(message);
var embed = QuoteBuilder(quote);
2017-09-28 18:55:57 +02:00
await ReplyAsync("", false, embed.Build());
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context,
2017-12-29 01:53:50 +01:00
"I couldn't find a message with that id :disappointed:");
2017-09-28 18:55:57 +02:00
}
}
2018-01-21 16:01:43 +01:00
[Command("remove")]
[RequireUserPermission(GuildPermission.ManageMessages)]
[Summary("Remove a quote (user needs the 'ManageMessages' permission)")]
public async Task RemoveQuote([Summary("quote-ID")] int id)
{
try
{
2019-05-12 15:29:22 +02:00
var transContext = await _translationHandler.GetGuildContext(Context);
var quote = _database.Quotes.Where(e => e.GuildId == Context.Guild.Id.AsLong() && e.InternalId == id)?.FirstOrDefault();
if (quote != null)
{
_database.Quotes.Remove(quote);
2018-05-14 18:57:07 +02:00
await _database.SaveChangesAsync();
var embed = QuoteBuilder(quote);
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("Removed", id), false, embed.Build());
}
else
{
2019-05-12 15:29:22 +02:00
await ReplyAsync(transContext.GetString("NotFoundWithId"));
}
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context, "I couldn't find a quote with that id :disappointed:");
}
}
2017-09-28 18:55:57 +02:00
2020-05-11 23:44:15 +02:00
[Command("stats")]
[Summary("Show quote stats for this server")]
public async Task GetQuoteStatsForServer()
{
try
{
2020-05-12 00:04:20 +02:00
// setup
2020-05-11 23:44:15 +02:00
var transContext = await _translationHandler.GetGuildContext(Context);
var eb = new EmbedBuilder();
eb.Author = new EmbedAuthorBuilder()
{
IconUrl = Context.Guild.IconUrl,
Name = $"{Context.Guild.Name} - {transContext.GetString("QuoteStats")}"
};
2020-05-12 00:04:20 +02:00
// gather data
2020-05-11 23:44:15 +02:00
var totalQuotes = _database.Quotes.Count(row => row.GuildId == Context.Guild.Id.AsLong());
if (totalQuotes == 0)
{
2020-05-12 00:04:20 +02:00
// no quotes, no stats, end of the road
2020-05-11 23:44:15 +02:00
await ReplyAsync(transContext.GetString("NoQuotesFound"));
return;
}
2020-05-12 00:04:20 +02:00
2020-05-11 23:44:15 +02:00
var mostQuotedPerson = _database.Quotes
.Where(row => row.GuildId == Context.Guild.Id.AsLong())
.GroupBy(row => row.UserId)
2020-05-12 00:04:20 +02:00
.Select(row => new { userId = row.Key, amount = row.Count()})
.OrderBy(row => row.amount)
.Last();
var mostQuotedPersonUser = Context.Client.GetUserAsync(mostQuotedPerson.userId.AsUlong()).Result ?? new UserPolyfillDto {Username = "Unknown User"};
2020-05-11 23:44:15 +02:00
var quotesByYear = _database.Quotes
.Where(row => row.GuildId == Context.Guild.Id.AsLong())
.GroupBy(row => row.Time.Year)
2020-05-12 00:04:20 +02:00
.Select(row => new { year = row.Key, amount = row.Count()})
.OrderBy(row => row.year);
// add data to the embed
eb.AddField(transContext.GetString("MostQuotesPerson"), $"{mostQuotedPersonUser.Username} ({mostQuotedPerson.amount})");
eb.AddInlineField(transContext.GetString("TotalQuotes"), totalQuotes);
2020-05-11 23:44:15 +02:00
foreach (var year in quotesByYear)
{
eb.AddInlineField(year.year.ToString(), year.amount);
}
await ReplyAsync("", false, eb.Build());
}
catch (Exception e)
{
await _errorHandler.HandleCommandException(e, Context);
}
}
2018-04-30 23:44:19 +02:00
private async Task<IMessage> GetLastMessageByUser(IUser user)
2017-09-28 18:55:57 +02:00
{
2018-05-06 02:43:23 +02:00
try
{
var list = Context.Channel.GetMessagesAsync().Flatten();
2018-05-17 22:06:58 +02:00
return await list.FirstOrDefault(msg =>
msg.Author.Id == user.Id &&
msg.Embeds.Count == 0 &&
msg.Id != Context.Message.Id &&
!msg.Content.ToLower().StartsWith("!"));
2018-05-06 02:43:23 +02:00
}
catch
{
await ReplyAsync($"No quoteable message have been sent by {user.Username} in this channel");
return null;
}
2017-09-28 18:55:57 +02:00
}
2017-12-29 01:53:50 +01:00
private EmbedBuilder QuoteBuilder(QuoteModel quote)
2017-09-28 18:55:57 +02:00
{
var user = Context.Client.GetUserAsync(quote.UserId.AsUlong()).Result ?? new UserPolyfillDto { Username = "Unknown User" };
2017-09-28 18:55:57 +02:00
var eb = new EmbedBuilder();
eb.WithColor(new Color(143, 167, 232));
eb.Title = $"#{quote.InternalId} | {user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}";
2018-04-30 23:44:19 +02:00
eb.Description = quote.Quote;
2017-09-28 18:55:57 +02:00
eb.ThumbnailUrl = user.GetAvatarUrl();
2018-04-30 23:44:19 +02:00
if (quote.Image != null) eb.ImageUrl = quote.Image;
2017-09-28 18:55:57 +02:00
return eb;
}
private QuoteModel CreateQuoteObject(IMessage message)
{
string image;
try
{
image = message.Attachments.First().Url;
}
catch (Exception)
{
image = null;
}
2017-12-29 01:53:50 +01:00
var last = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong()))
.OrderByDescending(e => e.InternalId).FirstOrDefault();
var internalId = 1;
if (last != null) internalId = last.InternalId + 1;
return new QuoteModel()
{
InternalId = internalId,
GuildId = Context.Guild.Id.AsLong(),
UserId = message.Author.Id.AsLong(),
2018-04-30 23:44:19 +02:00
Time = message.Timestamp.DateTime,
Quote = message.Content,
Image = image
};
}
2017-09-28 18:55:57 +02:00
}
}