mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	Added .qdelauth - Delete all quotes by the specified author on this server. If you target yourself - no permission required
This commit is contained in:
		@@ -3,14 +3,12 @@ using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using NadekoBot.Common.Configs;
 | 
			
		||||
using NadekoBot.Common.ModuleBehaviors;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Modules.Administration;
 | 
			
		||||
using NadekoBot.Modules.Utility;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Collections.Immutable;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
using RunMode = Discord.Commands.RunMode;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								src/NadekoBot/Modules/Utility/Quote/IQuoteService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/NadekoBot/Modules/Utility/Quote/IQuoteService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
namespace NadekoBot.Modules.Utility;
 | 
			
		||||
 | 
			
		||||
public interface IQuoteService
 | 
			
		||||
{
 | 
			
		||||
    Task<int> DeleteAllAuthorQuotesAsync(ulong guildId, ulong userId);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
#nullable disable warnings
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
#nullable disable warnings
 | 
			
		||||
using NadekoBot.Common.Yml;
 | 
			
		||||
using NadekoBot.Db;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
@@ -22,23 +21,25 @@ public partial class Utility
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
        private static readonly ISerializer _exportSerializer = new SerializerBuilder()
 | 
			
		||||
                                                                .WithEventEmitter(args
 | 
			
		||||
                                                                    => new MultilineScalarFlowStyleEmitter(args))
 | 
			
		||||
                                                                .WithNamingConvention(
 | 
			
		||||
                                                                    CamelCaseNamingConvention.Instance)
 | 
			
		||||
                                                                .WithIndentedSequences()
 | 
			
		||||
                                                                .ConfigureDefaultValuesHandling(DefaultValuesHandling
 | 
			
		||||
                                                                    .OmitDefaults)
 | 
			
		||||
                                                                .DisableAliases()
 | 
			
		||||
                                                                .Build();
 | 
			
		||||
            .WithEventEmitter(args
 | 
			
		||||
                => new MultilineScalarFlowStyleEmitter(args))
 | 
			
		||||
            .WithNamingConvention(
 | 
			
		||||
                CamelCaseNamingConvention.Instance)
 | 
			
		||||
            .WithIndentedSequences()
 | 
			
		||||
            .ConfigureDefaultValuesHandling(DefaultValuesHandling
 | 
			
		||||
                .OmitDefaults)
 | 
			
		||||
            .DisableAliases()
 | 
			
		||||
            .Build();
 | 
			
		||||
 | 
			
		||||
        private readonly DbService _db;
 | 
			
		||||
        private readonly IHttpClientFactory _http;
 | 
			
		||||
        private readonly IQuoteService _qs;
 | 
			
		||||
 | 
			
		||||
        public QuoteCommands(DbService db, IHttpClientFactory http)
 | 
			
		||||
        public QuoteCommands(DbService db, IQuoteService qs, IHttpClientFactory http)
 | 
			
		||||
        {
 | 
			
		||||
            _db = db;
 | 
			
		||||
            _http = http;
 | 
			
		||||
            _qs = qs;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
@@ -108,7 +109,7 @@ public partial class Utility
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task QuoteShow(int id)
 | 
			
		||||
        {
 | 
			
		||||
            Quote quote;
 | 
			
		||||
            Quote? quote;
 | 
			
		||||
            await using (var uow = _db.GetDbContext())
 | 
			
		||||
            {
 | 
			
		||||
                quote = uow.Quotes.GetById(id);
 | 
			
		||||
@@ -127,13 +128,13 @@ public partial class Utility
 | 
			
		||||
 | 
			
		||||
        private async Task ShowQuoteData(Quote data)
 | 
			
		||||
            => await ctx.Channel.EmbedAsync(_eb.Create(ctx)
 | 
			
		||||
                                               .WithOkColor()
 | 
			
		||||
                                               .WithTitle(GetText(strs.quote_id($"#{data.Id}")))
 | 
			
		||||
                                               .AddField(GetText(strs.trigger), data.Keyword)
 | 
			
		||||
                                               .AddField(GetText(strs.response),
 | 
			
		||||
                                                   Format.Sanitize(data.Text).Replace("](", "]\\("))
 | 
			
		||||
                                               .WithFooter(
 | 
			
		||||
                                                   GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})"))));
 | 
			
		||||
                .WithOkColor()
 | 
			
		||||
                .WithTitle(GetText(strs.quote_id($"#{data.Id}")))
 | 
			
		||||
                .AddField(GetText(strs.trigger), data.Keyword)
 | 
			
		||||
                .AddField(GetText(strs.response),
 | 
			
		||||
                    Format.Sanitize(data.Text).Replace("](", "]\\("))
 | 
			
		||||
                .WithFooter(
 | 
			
		||||
                    GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})"))));
 | 
			
		||||
 | 
			
		||||
        private async Task QuoteSearchinternalAsync(string? keyword, string textOrAuthor)
 | 
			
		||||
        {
 | 
			
		||||
@@ -256,6 +257,28 @@ public partial class Utility
 | 
			
		||||
                await SendErrorAsync(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task QuoteDeleteAuthor(IUser user)
 | 
			
		||||
            => QuoteDeleteAuthor(user.Id);
 | 
			
		||||
        
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task QuoteDeleteAuthor(ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            var hasManageMessages = ((IGuildUser)ctx.Message.Author).GuildPermissions.ManageMessages;
 | 
			
		||||
 | 
			
		||||
            if (userId == ctx.User.Id || hasManageMessages)
 | 
			
		||||
            {
 | 
			
		||||
                var deleted = await _qs.DeleteAllAuthorQuotesAsync(ctx.Guild.Id, ctx.User.Id);
 | 
			
		||||
                await ReplyConfirmLocalizedAsync(strs.quotes_deleted_count(deleted));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await ReplyErrorLocalizedAsync(strs.insuf_perms_u);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.ManageMessages)]
 | 
			
		||||
@@ -288,7 +311,7 @@ public partial class Utility
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var exprsDict = quotes.GroupBy(x => x.Keyword)
 | 
			
		||||
                                  .ToDictionary(x => x.Key, x => x.Select(ExportedQuote.FromModel));
 | 
			
		||||
                .ToDictionary(x => x.Key, x => x.Select(ExportedQuote.FromModel));
 | 
			
		||||
 | 
			
		||||
            var text = PREPEND_EXPORT + _exportSerializer.Serialize(exprsDict).UnescapeUnicodeCodePoints();
 | 
			
		||||
 | 
			
		||||
@@ -303,7 +326,7 @@ public partial class Utility
 | 
			
		||||
#if GLOBAL_NADEKO
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
#endif
 | 
			
		||||
        public async Task QuotesImport([Leftover] string input = null)
 | 
			
		||||
        public async Task QuotesImport([Leftover] string? input = null)
 | 
			
		||||
        {
 | 
			
		||||
            input = input?.Trim();
 | 
			
		||||
 | 
			
		||||
@@ -357,14 +380,14 @@ public partial class Utility
 | 
			
		||||
            {
 | 
			
		||||
                var keyword = entry.Key;
 | 
			
		||||
                await uow.Quotes.AddRangeAsync(entry.Value.Where(quote => !string.IsNullOrWhiteSpace(quote.Txt))
 | 
			
		||||
                                                    .Select(quote => new Quote
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        GuildId = guildId,
 | 
			
		||||
                                                        Keyword = keyword,
 | 
			
		||||
                                                        Text = quote.Txt,
 | 
			
		||||
                                                        AuthorId = quote.Aid,
 | 
			
		||||
                                                        AuthorName = quote.An
 | 
			
		||||
                                                    }));
 | 
			
		||||
                    .Select(quote => new Quote
 | 
			
		||||
                    {
 | 
			
		||||
                        GuildId = guildId,
 | 
			
		||||
                        Keyword = keyword,
 | 
			
		||||
                        Text = quote.Txt,
 | 
			
		||||
                        AuthorId = quote.Aid,
 | 
			
		||||
                        AuthorName = quote.An
 | 
			
		||||
                    }));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await uow.SaveChangesAsync();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								src/NadekoBot/Modules/Utility/Quote/QuoteService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/NadekoBot/Modules/Utility/Quote/QuoteService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
#nullable disable warnings
 | 
			
		||||
using LinqToDB;
 | 
			
		||||
using LinqToDB.EntityFrameworkCore;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Utility;
 | 
			
		||||
 | 
			
		||||
public sealed class QuoteService : IQuoteService, INService
 | 
			
		||||
{
 | 
			
		||||
    private readonly DbService _db;
 | 
			
		||||
 | 
			
		||||
    public QuoteService(DbService db)
 | 
			
		||||
    {
 | 
			
		||||
        _db = db;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Delete all quotes created by the author in a guild
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="guildId">ID of the guild</param>
 | 
			
		||||
    /// <param name="userId">ID of the user</param>
 | 
			
		||||
    /// <returns>Number of deleted qutoes</returns>
 | 
			
		||||
    public async Task<int> DeleteAllAuthorQuotesAsync(ulong guildId, ulong userId)
 | 
			
		||||
    {
 | 
			
		||||
        await using var ctx = _db.GetDbContext();
 | 
			
		||||
        var deleted = await ctx.GetTable<Quote>()
 | 
			
		||||
            .Where(x => x.GuildId == guildId && x.AuthorId == userId)
 | 
			
		||||
            .DeleteAsync();
 | 
			
		||||
 | 
			
		||||
        return deleted;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -342,6 +342,9 @@ quoteid:
 | 
			
		||||
quotedelete:
 | 
			
		||||
  - quotedelete
 | 
			
		||||
  - qdel
 | 
			
		||||
quotedeleteauthor:
 | 
			
		||||
  - quotedeleteauthor
 | 
			
		||||
  - qdelauth
 | 
			
		||||
draw:
 | 
			
		||||
  - draw
 | 
			
		||||
drawnew:
 | 
			
		||||
 
 | 
			
		||||
@@ -628,6 +628,10 @@ quotedelete:
 | 
			
		||||
  desc: "Deletes a quote with the specified ID. You have to either have the Manage Messages permission or be the creator of the quote to delete it."
 | 
			
		||||
  args:
 | 
			
		||||
    - "123456"
 | 
			
		||||
quotedeleteauthor:
 | 
			
		||||
  desc: "Deletes all quotes by the specified author. If the author is not you, then ManageMessage server permission is required."
 | 
			
		||||
  args:
 | 
			
		||||
    - "@QuoteSpammer"
 | 
			
		||||
draw:
 | 
			
		||||
  desc: "Draws a card from this server's deck. You can draw up to 10 cards by supplying a number of cards to draw."
 | 
			
		||||
  args:
 | 
			
		||||
 
 | 
			
		||||
@@ -595,6 +595,7 @@
 | 
			
		||||
  "presence": "Presence",
 | 
			
		||||
  "presence_txt": "{0} Servers\n{1} Text Channels\n{2} Voice Channels",
 | 
			
		||||
  "quotes_deleted": "Deleted all quotes with {0} keyword.",
 | 
			
		||||
  "quotes_deleted_count": "Deleted {0} quotes.",
 | 
			
		||||
  "quotes_page": "Page {0} of quotes",
 | 
			
		||||
  "quotes_page_none": "No quotes found on that page.",
 | 
			
		||||
  "quotes_remove_none": "No quotes found which you can remove.",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user