.nsfwtbl added. You can now blacklist tags which are used in nsfw commands.

This commit is contained in:
Master Kwoth 2017-07-21 03:04:44 +02:00
parent 0131b7713e
commit 0d216ad78a
10 changed files with 1891 additions and 3 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class nsfwblacklist : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "NsfwBlacklitedTag",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(nullable: true),
GuildConfigId = table.Column<int>(nullable: true),
Tag = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_NsfwBlacklitedTag", x => x.Id);
table.ForeignKey(
name: "FK_NsfwBlacklitedTag_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_NsfwBlacklitedTag_GuildConfigId",
table: "NsfwBlacklitedTag",
column: "GuildConfigId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "NsfwBlacklitedTag");
}
}
}

View File

@ -2,7 +2,9 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Services.Database; using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Migrations namespace NadekoBot.Migrations
{ {
@ -798,6 +800,24 @@ namespace NadekoBot.Migrations
b.ToTable("MutedUserId"); b.ToTable("MutedUserId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklitedTag", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime?>("DateAdded");
b.Property<int?>("GuildConfigId");
b.Property<string>("Tag");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("NsfwBlacklitedTag");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -1502,6 +1522,13 @@ namespace NadekoBot.Migrations
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklitedTag", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("NsfwBlacklistedTags")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{ {
b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next") b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next")

View File

@ -0,0 +1,12 @@
using System;
namespace NadekoBot.Modules.NSFW.Exceptions
{
public class TagBlacklistedException : Exception
{
public TagBlacklistedException() : base("Tag you used is blacklisted.")
{
}
}
}

View File

@ -13,6 +13,7 @@ using NadekoBot.Common.Attributes;
using NadekoBot.Common.Collections; using NadekoBot.Common.Collections;
using NadekoBot.Modules.Searches.Common; using NadekoBot.Modules.Searches.Common;
using NadekoBot.Modules.Searches.Services; using NadekoBot.Modules.Searches.Services;
using NadekoBot.Modules.NSFW.Exceptions;
namespace NadekoBot.Modules.NSFW namespace NadekoBot.Modules.NSFW
{ {
@ -26,7 +27,16 @@ namespace NadekoBot.Modules.NSFW
var rng = new NadekoRandom(); var rng = new NadekoRandom();
var arr = Enum.GetValues(typeof(DapiSearchType)); var arr = Enum.GetValues(typeof(DapiSearchType));
var type = (DapiSearchType)arr.GetValue(new NadekoRandom().Next(2, arr.Length)); var type = (DapiSearchType)arr.GetValue(new NadekoRandom().Next(2, arr.Length));
var img = await _service.DapiSearch(tag, type, Context.Guild?.Id, true).ConfigureAwait(false); ImageCacherObject img;
try
{
img = await _service.DapiSearch(tag, type, Context.Guild?.Id, true).ConfigureAwait(false);
}
catch (TagBlacklistedException)
{
await ReplyErrorLocalized("blacklisted_tag").ConfigureAwait(false);
return;
}
if (img == null) if (img == null)
{ {
@ -179,9 +189,42 @@ namespace NadekoBot.Modules.NSFW
} }
} }
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task NsfwTagBlacklist([Remainder] string tag = null)
{
if (string.IsNullOrWhiteSpace(tag))
{
var blTags = _service.GetBlacklistedTags(Context.Guild.Id);
await Context.Channel.SendConfirmAsync(GetText("blacklisted_tag_list"),
blTags.Any()
? string.Join(", ", blTags)
: "-").ConfigureAwait(false);
}
else
{
tag = tag.Trim().ToLowerInvariant();
var added = _service.ToggleBlacklistedTag(Context.Guild.Id, tag);
if(added)
await ReplyConfirmLocalized("blacklisted_tag_add", tag).ConfigureAwait(false);
else
await ReplyConfirmLocalized("blacklisted_tag_remove", tag).ConfigureAwait(false);
}
}
public async Task InternalDapiCommand(string tag, DapiSearchType type, bool forceExplicit) public async Task InternalDapiCommand(string tag, DapiSearchType type, bool forceExplicit)
{ {
var imgObj = await _service.DapiSearch(tag, type, Context.Guild?.Id, forceExplicit).ConfigureAwait(false); ImageCacherObject imgObj;
try
{
imgObj = await _service.DapiSearch(tag, type, Context.Guild?.Id, forceExplicit).ConfigureAwait(false);
}
catch (TagBlacklistedException)
{
await ReplyErrorLocalized("blacklisted_tag").ConfigureAwait(false);
return;
}
if (imgObj == null) if (imgObj == null)
await ReplyErrorLocalized("not_found").ConfigureAwait(false); await ReplyErrorLocalized("not_found").ConfigureAwait(false);

View File

@ -10,6 +10,11 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Modules.Searches.Common; using NadekoBot.Modules.Searches.Common;
using NadekoBot.Common.Collections;
using NadekoBot.Services.Database.Models;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Modules.NSFW.Exceptions;
namespace NadekoBot.Modules.Searches.Services namespace NadekoBot.Modules.Searches.Services
{ {
@ -33,13 +38,20 @@ namespace NadekoBot.Modules.Searches.Services
private readonly ConcurrentDictionary<ulong?, SearchImageCacher> _imageCacher = new ConcurrentDictionary<ulong?, SearchImageCacher>(); private readonly ConcurrentDictionary<ulong?, SearchImageCacher> _imageCacher = new ConcurrentDictionary<ulong?, SearchImageCacher>();
public SearchesService(DiscordSocketClient client, IGoogleApiService google, DbService db) private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
public SearchesService(DiscordSocketClient client, IGoogleApiService google, DbService db, IEnumerable<GuildConfig> gcs)
{ {
_client = client; _client = client;
_google = google; _google = google;
_db = db; _db = db;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>(
gcs.ToDictionary(
x => x.GuildId,
x => new HashSet<string>(x.NsfwBlacklistedTags.Select(y => y.Tag))));
//translate commands //translate commands
_client.MessageReceived += (msg) => _client.MessageReceived += (msg) =>
{ {
@ -117,10 +129,48 @@ namespace NadekoBot.Modules.Searches.Services
public Task<ImageCacherObject> DapiSearch(string tag, DapiSearchType type, ulong? guild, bool isExplicit = false) public Task<ImageCacherObject> DapiSearch(string tag, DapiSearchType type, ulong? guild, bool isExplicit = false)
{ {
if (guild.HasValue && GetBlacklistedTags(guild.Value)
.Any(x => tag.ToLowerInvariant().Contains(x)))
{
throw new TagBlacklistedException();
}
var cacher = _imageCacher.GetOrAdd(guild, (key) => new SearchImageCacher()); var cacher = _imageCacher.GetOrAdd(guild, (key) => new SearchImageCacher());
return cacher.GetImage(tag, isExplicit, type); return cacher.GetImage(tag, isExplicit, type);
} }
public HashSet<string> GetBlacklistedTags(ulong guildId)
{
if (_blacklistedTags.TryGetValue(guildId, out var tags))
return tags;
return new HashSet<string>();
}
public bool ToggleBlacklistedTag(ulong guildId, string tag)
{
var tagObj = new NsfwBlacklitedTag
{
Tag = tag
};
bool added;
using (var uow = _db.UnitOfWork)
{
var gc = uow.GuildConfigs.For(guildId, set => set.Include(y => y.NsfwBlacklistedTags));
if (gc.NsfwBlacklistedTags.Add(tagObj))
added = true;
else
{
gc.NsfwBlacklistedTags.Remove(tagObj);
added = false;
}
var newTags = new HashSet<string>(gc.NsfwBlacklistedTags.Select(x => x.Tag));
_blacklistedTags.AddOrUpdate(guildId, newTags, delegate { return newTags; });
uow.Complete();
}
return added;
}
} }
public struct UserChannelPair public struct UserChannelPair

View File

@ -3582,4 +3582,13 @@
<data name="botconfigedit_desc" xml:space="preserve"> <data name="botconfigedit_desc" xml:space="preserve">
<value>Sets one of available bot config settings to a specified value. Use the command without any parameters to get a list of available settings.</value> <value>Sets one of available bot config settings to a specified value. Use the command without any parameters to get a list of available settings.</value>
</data> </data>
<data name="nsfwtagblacklist_cmd" xml:space="preserve">
<value>nsfwtagbl nsfwtbl</value>
</data>
<data name="nsfwtagblacklist_usage" xml:space="preserve">
<value>`{0}nsfwtbl poop`</value>
</data>
<data name="nsfwtagblacklist_desc" xml:space="preserve">
<value>Toggles whether the tag is blacklisted or not in nsfw searches. Provide no parameters to see the list of blacklisted tags.</value>
</data>
</root> </root>

View File

@ -78,6 +78,7 @@ namespace NadekoBot.Services.Database.Models
public bool WarningsInitialized { get; set; } public bool WarningsInitialized { get; set; }
public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; } public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; } public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
public HashSet<NsfwBlacklitedTag> NsfwBlacklistedTags { get; set; } = new HashSet<NsfwBlacklitedTag>();
public List<ShopEntry> ShopEntries { get; set; } public List<ShopEntry> ShopEntries { get; set; }
public ulong? GameVoiceChannel { get; set; } = null; public ulong? GameVoiceChannel { get; set; } = null;
@ -88,6 +89,23 @@ namespace NadekoBot.Services.Database.Models
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
} }
public class NsfwBlacklitedTag : DbEntity
{
public string Tag { get; set; }
public override int GetHashCode()
{
return Tag.GetHashCode();
}
public override bool Equals(object obj)
{
return obj is NsfwBlacklitedTag x
? x.Tag == Tag
: false;
}
}
public class SlowmodeIgnoredUser : DbEntity public class SlowmodeIgnoredUser : DbEntity
{ {
public ulong UserId { get; set; } public ulong UserId { get; set; }

View File

@ -46,6 +46,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl
.ThenInclude(x => x.IgnoredChannels) .ThenInclude(x => x.IgnoredChannels)
.Include(gc => gc.FollowedStreams) .Include(gc => gc.FollowedStreams)
.Include(gc => gc.StreamRole) .Include(gc => gc.StreamRole)
.Include(gc => gc.NsfwBlacklistedTags)
.ToList(); .ToList();
/// <summary> /// <summary>

View File

@ -38,6 +38,10 @@
"customreactions_redacted_too_long": "Redecated because it's too long.", "customreactions_redacted_too_long": "Redecated because it's too long.",
"nsfw_autohentai_stopped": "Autohentai stopped.", "nsfw_autohentai_stopped": "Autohentai stopped.",
"nsfw_not_found": "No results found.", "nsfw_not_found": "No results found.",
"nsfw_blacklisted_tag_list": "List of blacklisted tags:",
"nsfw_blacklisted_tag": "One or more tags you've used are blacklisted",
"nsfw_blacklisted_tag_add": "Nsfw tag {0} is now blacklisted.",
"nsfw_blacklisted_tag_remove": "Nsfw tag {0} is no longer blacklisted.",
"pokemon_already_fainted": "{0} has already fainted.", "pokemon_already_fainted": "{0} has already fainted.",
"pokemon_already_full": "{0} already has full HP.", "pokemon_already_full": "{0} already has full HP.",
"pokemon_already_that_type": "Your type is already {0}", "pokemon_already_that_type": "Your type is already {0}",