diff --git a/Geekbot.net/Commands/Utils/Quote/Quote.cs b/Geekbot.net/Commands/Utils/Quote/Quote.cs index 7a25b50..0310182 100644 --- a/Geekbot.net/Commands/Utils/Quote/Quote.cs +++ b/Geekbot.net/Commands/Utils/Quote/Quote.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Discord; using Discord.Commands; +using Geekbot.net.Database; using Geekbot.net.Lib; using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.Polyfills; @@ -15,12 +16,14 @@ namespace Geekbot.net.Commands.Utils.Quote public class Quote : ModuleBase { private readonly IErrorHandler _errorHandler; + private readonly DatabaseContext _database; private readonly IDatabase _redis; - public Quote(IDatabase redis, IErrorHandler errorHandler) + public Quote(IDatabase redis, IErrorHandler errorHandler, DatabaseContext database) { _redis = redis; _errorHandler = errorHandler; + _database = database; } [Command] @@ -30,16 +33,18 @@ namespace Geekbot.net.Commands.Utils.Quote { try { - var randomQuotes = _redis.SetMembers($"{Context.Guild.Id}:Quotes"); - if (!randomQuotes.Any()) + var s = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id)); + var totalQuotes = s.Count(); + + if (totalQuotes > 0) { await ReplyAsync("This server doesn't seem to have any quotes yet. You can add a quote with `!quote save @user` or `!quote save `"); return; } - var randomNumber = new Random().Next(randomQuotes.Length - 1); - var randomQuote = randomQuotes[randomNumber]; - var quote = JsonConvert.DeserializeObject(randomQuote); - var embed = QuoteBuilder(quote, randomNumber + 1); + var quote = s.Where(e => e.Id.Equals(new Random().Next(totalQuotes)))?.FirstOrDefault(); + + + var embed = QuoteBuilder(quote, 2); await ReplyAsync("", false, embed.Build()); } catch (Exception e) @@ -69,9 +74,10 @@ namespace Geekbot.net.Commands.Utils.Quote var lastMessage = await GetLastMessageByUser(user); if (lastMessage == null) return; + var quote = CreateQuoteObject(lastMessage); - var quoteStore = JsonConvert.SerializeObject(quote); - _redis.SetAdd($"{Context.Guild.Id}:Quotes", quoteStore); + await _database.Quotes.AddAsync(quote); + var embed = QuoteBuilder(quote); await ReplyAsync("**Quote Added**", false, embed.Build()); } @@ -103,8 +109,8 @@ namespace Geekbot.net.Commands.Utils.Quote } var quote = CreateQuoteObject(message); - var quoteStore = JsonConvert.SerializeObject(quote); - _redis.SetAdd($"{Context.Guild.Id}:Quotes", quoteStore); + await _database.Quotes.AddAsync(quote); + var embed = QuoteBuilder(quote); await ReplyAsync("**Quote Added**", false, embed.Build()); } @@ -154,35 +160,36 @@ namespace Geekbot.net.Commands.Utils.Quote } } - [Command("remove")] - [RequireUserPermission(GuildPermission.KickMembers)] - [RequireUserPermission(GuildPermission.ManageMessages)] - [RequireUserPermission(GuildPermission.ManageRoles)] - [Remarks(CommandCategories.Quotes)] - [Summary("Remove a quote (required mod permissions)")] - public async Task RemoveQuote([Summary("quoteId")] int id) - { - try - { - var quotes = _redis.SetMembers($"{Context.Guild.Id}:Quotes"); - var success = _redis.SetRemove($"{Context.Guild.Id}:Quotes", quotes[id - 1]); - if (success) - { - var quote = JsonConvert.DeserializeObject(quotes[id - 1]); - var embed = QuoteBuilder(quote); - await ReplyAsync($"**Removed #{id}**", false, embed.Build()); - } - else - { - await ReplyAsync("I couldn't find a quote with that id :disappointed:"); - } - } - catch (Exception e) - { - _errorHandler.HandleCommandException(e, Context, - "I couldn't find a quote with that id :disappointed:"); - } - } + [Command("remove")] + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireUserPermission(GuildPermission.ManageRoles)] + [Remarks(CommandCategories.Quotes)] + [Summary("Remove a quote (required mod permissions)")] + public async Task RemoveQuote([Summary("quoteId")] int id) + { + await ReplyAsync("Command currently Disabled"); + // try + // { + // var quotes = _redis.SetMembers($"{Context.Guild.Id}:Quotes"); + // var success = _redis.SetRemove($"{Context.Guild.Id}:Quotes", quotes[id - 1]); + // if (success) + // { + // var quote = JsonConvert.DeserializeObject(quotes[id - 1]); + // var embed = QuoteBuilder(quote); + // await ReplyAsync($"**Removed #{id}**", false, embed.Build()); + // } + // else + // { + // await ReplyAsync("I couldn't find a quote with that id :disappointed:"); + // } + // } + // catch (Exception e) + // { + // _errorHandler.HandleCommandException(e, Context, + // "I couldn't find a quote with that id :disappointed:"); + // } + } private async Task GetLastMessageByUser(IUser user) { @@ -203,7 +210,7 @@ namespace Geekbot.net.Commands.Utils.Quote } } - private EmbedBuilder QuoteBuilder(QuoteObjectDto quote, int id = 0) + private EmbedBuilder QuoteBuilder(QuoteModel quote, int id = 0) { var user = Context.Client.GetUserAsync(quote.UserId).Result ?? new UserPolyfillDto { Username = "Unknown User" }; var eb = new EmbedBuilder(); @@ -216,7 +223,7 @@ namespace Geekbot.net.Commands.Utils.Quote return eb; } - private QuoteObjectDto CreateQuoteObject(IMessage message) + private QuoteModel CreateQuoteObject(IMessage message) { string image; try @@ -228,8 +235,9 @@ namespace Geekbot.net.Commands.Utils.Quote image = null; } - return new QuoteObjectDto + return new QuoteModel() { + GuildId = Context.Guild.Id, UserId = message.Author.Id, Time = message.Timestamp.DateTime, Quote = message.Content, diff --git a/Geekbot.net/Database/DatabaseContext.cs b/Geekbot.net/Database/DatabaseContext.cs new file mode 100644 index 0000000..d2645a1 --- /dev/null +++ b/Geekbot.net/Database/DatabaseContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Geekbot.net.Database +{ + public class DatabaseContext : DbContext + { + public DbSet Quotes { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) +// .UseInMemoryDatabase(databaseName: "Geekbot"); + .UseMySql(@"Server=localhost;database=geekbot;uid=geekbot;"); + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/QuoteModel.cs b/Geekbot.net/Database/QuoteModel.cs new file mode 100644 index 0000000..ea42e93 --- /dev/null +++ b/Geekbot.net/Database/QuoteModel.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; + +namespace Geekbot.net.Database +{ + public class QuoteModel + { + [Key] + public int Id { get; set; } + public ulong GuildId { get; set; } + public ulong UserId { get; set; } + public string Quote { get; set; } + public DateTime Time { get; set; } + public string Image { get; set; } + } +} \ No newline at end of file diff --git a/Geekbot.net/Geekbot.net.csproj b/Geekbot.net/Geekbot.net.csproj index 90ff896..f8554c9 100755 --- a/Geekbot.net/Geekbot.net.csproj +++ b/Geekbot.net/Geekbot.net.csproj @@ -19,6 +19,9 @@ + + + @@ -31,6 +34,8 @@ + + 1.2.6 diff --git a/Geekbot.net/Lib/GeekbotExitCode.cs b/Geekbot.net/Lib/GeekbotExitCode.cs index e9e1210..d68aa4a 100644 --- a/Geekbot.net/Lib/GeekbotExitCode.cs +++ b/Geekbot.net/Lib/GeekbotExitCode.cs @@ -11,6 +11,7 @@ // Dependent Services RedisConnectionFailed = 301, + DatabaseConnectionFailed = 302, // Discord Related CouldNotLogin = 401 diff --git a/Geekbot.net/Lib/RunParameters.cs b/Geekbot.net/Lib/RunParameters.cs index 35c1a2a..1e1048b 100644 --- a/Geekbot.net/Lib/RunParameters.cs +++ b/Geekbot.net/Lib/RunParameters.cs @@ -22,5 +22,8 @@ namespace Geekbot.net.Lib [Option("token", Default = null, HelpText = "Set a new bot token")] public string Token { get; set; } + + [Option("in-memory", Default = false, HelpText = "Disables the web api")] + public bool InMemory { get; set; } } } \ No newline at end of file diff --git a/Geekbot.net/Program.cs b/Geekbot.net/Program.cs index 3a35d19..f1982c0 100755 --- a/Geekbot.net/Program.cs +++ b/Geekbot.net/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Net; using System.Reflection; using System.Text; @@ -7,6 +8,7 @@ using CommandLine; using Discord; using Discord.Commands; using Discord.WebSocket; +using Geekbot.net.Database; using Geekbot.net.Lib; using Geekbot.net.Lib.Audio; using Geekbot.net.Lib.Clients; @@ -18,6 +20,7 @@ using Geekbot.net.Lib.Logger; using Geekbot.net.Lib.Media; using Geekbot.net.Lib.ReactionListener; using Geekbot.net.Lib.UserRepository; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Nancy.Hosting.Self; using StackExchange.Redis; @@ -104,6 +107,18 @@ namespace Geekbot.net _firstStart = true; } + DatabaseContext database = null; + try + { + database = new DatabaseContext(); + database.Database.EnsureCreated(); + } + catch (Exception e) + { + logger.Error(LogSource.Geekbot, "Could not Connect to datbase", e); + Environment.Exit(GeekbotExitCode.DatabaseConnectionFailed.GetHashCode()); + } + _services = new ServiceCollection(); _userRepository = new UserRepository(_redis, logger); @@ -127,6 +142,7 @@ namespace Geekbot.net _services.AddSingleton(mtgManaConverter); _services.AddSingleton(wikipediaClient); _services.AddSingleton(audioUtils); + _services.AddSingleton(database); logger.Information(LogSource.Geekbot, "Connecting to Discord");