mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	Nhentai removed as it's currently unfixable, closes #396
This commit is contained in:
		@@ -22,6 +22,6 @@ public interface ISearchImagesService
 | 
			
		||||
    ValueTask<bool> ToggleBlacklistTag(ulong guildId, string tag);
 | 
			
		||||
    ValueTask<string[]> GetBlacklistedTags(ulong guildId);
 | 
			
		||||
    Task<UrlReply> Butts();
 | 
			
		||||
    Task<Gallery> GetNhentaiByIdAsync(uint id);
 | 
			
		||||
    Task<Gallery> GetNhentaiBySearchAsync(string search);
 | 
			
		||||
    // Task<Gallery> GetNhentaiByIdAsync(uint id);
 | 
			
		||||
    // Task<Gallery> GetNhentaiBySearchAsync(string search);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
using NadekoBot.Modules.Searches.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Nsfw;
 | 
			
		||||
 | 
			
		||||
public interface INhentaiService
 | 
			
		||||
{
 | 
			
		||||
    Task<Gallery?> GetAsync(uint id);
 | 
			
		||||
    Task<IReadOnlyList<uint>> GetIdsBySearchAsync(string search);
 | 
			
		||||
}
 | 
			
		||||
// using NadekoBot.Modules.Searches.Common;
 | 
			
		||||
//
 | 
			
		||||
// namespace NadekoBot.Modules.Nsfw;
 | 
			
		||||
//
 | 
			
		||||
// public interface INhentaiService
 | 
			
		||||
// {
 | 
			
		||||
//     Task<Gallery?> GetAsync(uint id);
 | 
			
		||||
//     Task<IReadOnlyList<uint>> GetIdsBySearchAsync(string search);
 | 
			
		||||
// }
 | 
			
		||||
@@ -1,115 +1,115 @@
 | 
			
		||||
using AngleSharp.Html.Dom;
 | 
			
		||||
using AngleSharp.Html.Parser;
 | 
			
		||||
using NadekoBot.Modules.Searches.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Nsfw;
 | 
			
		||||
 | 
			
		||||
public sealed class NhentaiScraperService : INhentaiService, INService
 | 
			
		||||
{
 | 
			
		||||
    private readonly IHttpClientFactory _httpFactory;
 | 
			
		||||
 | 
			
		||||
    private static readonly HtmlParser _htmlParser = new(new()
 | 
			
		||||
    {
 | 
			
		||||
        IsScripting = false,
 | 
			
		||||
        IsEmbedded = false,
 | 
			
		||||
        IsSupportingProcessingInstructions = false,
 | 
			
		||||
        IsKeepingSourceReferences = false,
 | 
			
		||||
        IsNotSupportingFrames = true
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    public NhentaiScraperService(IHttpClientFactory httpFactory)
 | 
			
		||||
    {
 | 
			
		||||
        _httpFactory = httpFactory;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private HttpClient GetHttpClient()
 | 
			
		||||
    {
 | 
			
		||||
        var http = _httpFactory.CreateClient();
 | 
			
		||||
        http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36");
 | 
			
		||||
        http.DefaultRequestHeaders.Add("Cookie", "cf_clearance=I5pR71P4wJkRBFTLFjBndI.GwfKwT.Gx06uS8XNmRJo-1657214595-0-150; csrftoken=WMWRLtsQtBVQYvYkbqXKJHI9T1JwWCdd3tNhoxHn7aHLUYHAqe60XFUKAoWsJtda");
 | 
			
		||||
        return http;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public async Task<Gallery?> GetAsync(uint id)
 | 
			
		||||
    {
 | 
			
		||||
        using var http = GetHttpClient();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var url = $"https://nhentai.net/g/{id}/";
 | 
			
		||||
            var strRes = await http.GetStringAsync(url);
 | 
			
		||||
            var doc = await _htmlParser.ParseDocumentAsync(strRes);
 | 
			
		||||
 | 
			
		||||
            var title = doc.QuerySelector("#info .title")?.TextContent;
 | 
			
		||||
            var fullTitle = doc.QuerySelector("meta[itemprop=\"name\"]")?.Attributes["content"]?.Value
 | 
			
		||||
                            ?? title;
 | 
			
		||||
            var thumb = (doc.QuerySelector("#cover a img") as IHtmlImageElement)?.Dataset["src"];
 | 
			
		||||
 | 
			
		||||
            var tagsElem = doc.QuerySelector("#tags");
 | 
			
		||||
            
 | 
			
		||||
            var pageCount = tagsElem?.QuerySelector("a.tag[href^=\"/search/?q=pages\"] span")?.TextContent;
 | 
			
		||||
            var likes = doc.QuerySelector(".buttons .btn-disabled.btn.tooltip span span")?.TextContent?.Trim('(', ')');
 | 
			
		||||
            var uploadedAt = (tagsElem?.QuerySelector(".tag-container .tags time.nobold") as IHtmlTimeElement)?.DateTime;
 | 
			
		||||
 | 
			
		||||
            var tags = tagsElem?.QuerySelectorAll(".tag-container .tags > a.tag[href^=\"/tag\"]")
 | 
			
		||||
                .Cast<IHtmlAnchorElement>()
 | 
			
		||||
                .Select(x => new Tag()
 | 
			
		||||
                {
 | 
			
		||||
                    Name = x.QuerySelector("span:first-child")?.TextContent,
 | 
			
		||||
                    Url = $"https://nhentai.net{x.PathName}"
 | 
			
		||||
                })
 | 
			
		||||
                .ToArray();
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(fullTitle))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            if (!int.TryParse(pageCount, out var pc))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            if (!int.TryParse(likes, out var lc))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            if (!DateTime.TryParse(uploadedAt, out var ua))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            return new Gallery(id,
 | 
			
		||||
                url,
 | 
			
		||||
                fullTitle,
 | 
			
		||||
                title,
 | 
			
		||||
                thumb,
 | 
			
		||||
                pc,
 | 
			
		||||
                lc,
 | 
			
		||||
                ua,
 | 
			
		||||
                tags);
 | 
			
		||||
        }
 | 
			
		||||
        catch (HttpRequestException)
 | 
			
		||||
        {
 | 
			
		||||
            Log.Warning("Nhentai with id {NhentaiId} not found", id);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task<IReadOnlyList<uint>> GetIdsBySearchAsync(string search)
 | 
			
		||||
    {
 | 
			
		||||
        using var http = GetHttpClient();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var url = $"https://nhentai.net/search/?q={Uri.EscapeDataString(search)}&sort=popular-today";
 | 
			
		||||
            var strRes = await http.GetStringAsync(url);
 | 
			
		||||
            var doc = await _htmlParser.ParseDocumentAsync(strRes);
 | 
			
		||||
 | 
			
		||||
            var elems = doc.QuerySelectorAll(".container .gallery a")
 | 
			
		||||
                .Cast<IHtmlAnchorElement>()
 | 
			
		||||
                .Where(x => x.PathName.StartsWith("/g/"))
 | 
			
		||||
                .Select(x => x.PathName[3..^1])
 | 
			
		||||
                .Select(uint.Parse)
 | 
			
		||||
                .ToArray();
 | 
			
		||||
            
 | 
			
		||||
            return elems;
 | 
			
		||||
        }
 | 
			
		||||
        catch (HttpRequestException)
 | 
			
		||||
        {
 | 
			
		||||
            Log.Warning("Nhentai search for {NhentaiSearch} failed", search);
 | 
			
		||||
            return Array.Empty<uint>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
// using AngleSharp.Html.Dom;
 | 
			
		||||
// using AngleSharp.Html.Parser;
 | 
			
		||||
// using NadekoBot.Modules.Searches.Common;
 | 
			
		||||
//
 | 
			
		||||
// namespace NadekoBot.Modules.Nsfw;
 | 
			
		||||
//
 | 
			
		||||
// public sealed class NhentaiScraperService : INhentaiService, INService
 | 
			
		||||
// {
 | 
			
		||||
//     private readonly IHttpClientFactory _httpFactory;
 | 
			
		||||
//
 | 
			
		||||
//     private static readonly HtmlParser _htmlParser = new(new()
 | 
			
		||||
//     {
 | 
			
		||||
//         IsScripting = false,
 | 
			
		||||
//         IsEmbedded = false,
 | 
			
		||||
//         IsSupportingProcessingInstructions = false,
 | 
			
		||||
//         IsKeepingSourceReferences = false,
 | 
			
		||||
//         IsNotSupportingFrames = true
 | 
			
		||||
//     });
 | 
			
		||||
//
 | 
			
		||||
//     public NhentaiScraperService(IHttpClientFactory httpFactory)
 | 
			
		||||
//     {
 | 
			
		||||
//         _httpFactory = httpFactory;
 | 
			
		||||
//     }
 | 
			
		||||
//
 | 
			
		||||
//     private HttpClient GetHttpClient()
 | 
			
		||||
//     {
 | 
			
		||||
//         var http = _httpFactory.CreateClient();
 | 
			
		||||
//         http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36");
 | 
			
		||||
//         http.DefaultRequestHeaders.Add("Cookie", "cf_clearance=I5pR71P4wJkRBFTLFjBndI.GwfKwT.Gx06uS8XNmRJo-1657214595-0-150; csrftoken=WMWRLtsQtBVQYvYkbqXKJHI9T1JwWCdd3tNhoxHn7aHLUYHAqe60XFUKAoWsJtda");
 | 
			
		||||
//         return http;
 | 
			
		||||
//     }
 | 
			
		||||
//     
 | 
			
		||||
//     public async Task<Gallery?> GetAsync(uint id)
 | 
			
		||||
//     {
 | 
			
		||||
//         using var http = GetHttpClient();
 | 
			
		||||
//         try
 | 
			
		||||
//         {
 | 
			
		||||
//             var url = $"https://nhentai.net/g/{id}/";
 | 
			
		||||
//             var strRes = await http.GetStringAsync(url);
 | 
			
		||||
//             var doc = await _htmlParser.ParseDocumentAsync(strRes);
 | 
			
		||||
//
 | 
			
		||||
//             var title = doc.QuerySelector("#info .title")?.TextContent;
 | 
			
		||||
//             var fullTitle = doc.QuerySelector("meta[itemprop=\"name\"]")?.Attributes["content"]?.Value
 | 
			
		||||
//                             ?? title;
 | 
			
		||||
//             var thumb = (doc.QuerySelector("#cover a img") as IHtmlImageElement)?.Dataset["src"];
 | 
			
		||||
//
 | 
			
		||||
//             var tagsElem = doc.QuerySelector("#tags");
 | 
			
		||||
//             
 | 
			
		||||
//             var pageCount = tagsElem?.QuerySelector("a.tag[href^=\"/search/?q=pages\"] span")?.TextContent;
 | 
			
		||||
//             var likes = doc.QuerySelector(".buttons .btn-disabled.btn.tooltip span span")?.TextContent?.Trim('(', ')');
 | 
			
		||||
//             var uploadedAt = (tagsElem?.QuerySelector(".tag-container .tags time.nobold") as IHtmlTimeElement)?.DateTime;
 | 
			
		||||
//
 | 
			
		||||
//             var tags = tagsElem?.QuerySelectorAll(".tag-container .tags > a.tag[href^=\"/tag\"]")
 | 
			
		||||
//                 .Cast<IHtmlAnchorElement>()
 | 
			
		||||
//                 .Select(x => new Tag()
 | 
			
		||||
//                 {
 | 
			
		||||
//                     Name = x.QuerySelector("span:first-child")?.TextContent,
 | 
			
		||||
//                     Url = $"https://nhentai.net{x.PathName}"
 | 
			
		||||
//                 })
 | 
			
		||||
//                 .ToArray();
 | 
			
		||||
//
 | 
			
		||||
//             if (string.IsNullOrWhiteSpace(fullTitle))
 | 
			
		||||
//                 return null;
 | 
			
		||||
//
 | 
			
		||||
//             if (!int.TryParse(pageCount, out var pc))
 | 
			
		||||
//                 return null;
 | 
			
		||||
//
 | 
			
		||||
//             if (!int.TryParse(likes, out var lc))
 | 
			
		||||
//                 return null;
 | 
			
		||||
//
 | 
			
		||||
//             if (!DateTime.TryParse(uploadedAt, out var ua))
 | 
			
		||||
//                 return null;
 | 
			
		||||
//
 | 
			
		||||
//             return new Gallery(id,
 | 
			
		||||
//                 url,
 | 
			
		||||
//                 fullTitle,
 | 
			
		||||
//                 title,
 | 
			
		||||
//                 thumb,
 | 
			
		||||
//                 pc,
 | 
			
		||||
//                 lc,
 | 
			
		||||
//                 ua,
 | 
			
		||||
//                 tags);
 | 
			
		||||
//         }
 | 
			
		||||
//         catch (HttpRequestException)
 | 
			
		||||
//         {
 | 
			
		||||
//             Log.Warning("Nhentai with id {NhentaiId} not found", id);
 | 
			
		||||
//             return null;
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
//
 | 
			
		||||
//     public async Task<IReadOnlyList<uint>> GetIdsBySearchAsync(string search)
 | 
			
		||||
//     {
 | 
			
		||||
//         using var http = GetHttpClient();
 | 
			
		||||
//         try
 | 
			
		||||
//         {
 | 
			
		||||
//             var url = $"https://nhentai.net/search/?q={Uri.EscapeDataString(search)}&sort=popular-today";
 | 
			
		||||
//             var strRes = await http.GetStringAsync(url);
 | 
			
		||||
//             var doc = await _htmlParser.ParseDocumentAsync(strRes);
 | 
			
		||||
//
 | 
			
		||||
//             var elems = doc.QuerySelectorAll(".container .gallery a")
 | 
			
		||||
//                 .Cast<IHtmlAnchorElement>()
 | 
			
		||||
//                 .Where(x => x.PathName.StartsWith("/g/"))
 | 
			
		||||
//                 .Select(x => x.PathName[3..^1])
 | 
			
		||||
//                 .Select(uint.Parse)
 | 
			
		||||
//                 .ToArray();
 | 
			
		||||
//             
 | 
			
		||||
//             return elems;
 | 
			
		||||
//         }
 | 
			
		||||
//         catch (HttpRequestException)
 | 
			
		||||
//         {
 | 
			
		||||
//             Log.Warning("Nhentai search for {NhentaiSearch} failed", search);
 | 
			
		||||
//             return Array.Empty<uint>();
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
@@ -360,67 +360,65 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    [RequireContext(ContextType.Guild)]
 | 
			
		||||
    [RequireNsfw(Group = "nsfw_or_dm")]
 | 
			
		||||
    [RequireContext(ContextType.DM, Group = "nsfw_or_dm")]
 | 
			
		||||
    [Priority(1)]
 | 
			
		||||
    public async Task Nhentai(uint id)
 | 
			
		||||
    {
 | 
			
		||||
        var g = await _service.GetNhentaiByIdAsync(id);
 | 
			
		||||
 | 
			
		||||
        if (g is null)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.not_found);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await SendNhentaiGalleryInternalAsync(g);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    [RequireContext(ContextType.Guild)]
 | 
			
		||||
    [RequireNsfw(Group = "nsfw_or_dm")]
 | 
			
		||||
    [RequireContext(ContextType.DM, Group = "nsfw_or_dm")]
 | 
			
		||||
    [Priority(0)]
 | 
			
		||||
    public async Task Nhentai([Leftover] string query)
 | 
			
		||||
    {
 | 
			
		||||
        var g = await _service.GetNhentaiBySearchAsync(query);
 | 
			
		||||
 | 
			
		||||
        if (g is null)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.not_found);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await SendNhentaiGalleryInternalAsync(g);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async Task SendNhentaiGalleryInternalAsync(Gallery g)
 | 
			
		||||
    {
 | 
			
		||||
        var count = 0;
 | 
			
		||||
        var tagString = g.Tags.Shuffle()
 | 
			
		||||
                         .Select(tag => $"[{tag.Name}]({tag.Url})")
 | 
			
		||||
                         .TakeWhile(tag => (count += tag.Length) < 1000)
 | 
			
		||||
                         .Join(" ");
 | 
			
		||||
 | 
			
		||||
        var embed = _eb.Create()
 | 
			
		||||
            .WithTitle(g.Title)
 | 
			
		||||
            .WithDescription(g.FullTitle)
 | 
			
		||||
            .WithImageUrl(g.Thumbnail)
 | 
			
		||||
            .WithUrl(g.Url)
 | 
			
		||||
            .AddField(GetText(strs.favorites), g.Likes, true)
 | 
			
		||||
            .AddField(GetText(strs.pages), g.PageCount, true)
 | 
			
		||||
            .AddField(GetText(strs.tags),
 | 
			
		||||
                string.IsNullOrWhiteSpace(tagString)
 | 
			
		||||
                    ? "?"
 | 
			
		||||
                    : tagString,
 | 
			
		||||
                true)
 | 
			
		||||
            .WithFooter(g.UploadedAt.ToString("f"))
 | 
			
		||||
            .WithOkColor();
 | 
			
		||||
 | 
			
		||||
        await ctx.Channel.EmbedAsync(embed);
 | 
			
		||||
    }
 | 
			
		||||
    // [RequireNsfw(Group = "nsfw_or_dm")]
 | 
			
		||||
    // [RequireContext(ContextType.DM, Group = "nsfw_or_dm")]
 | 
			
		||||
    // [Priority(1)]
 | 
			
		||||
    // public async Task Nhentai(uint id)
 | 
			
		||||
    // {
 | 
			
		||||
    //     var g = await _service.GetNhentaiByIdAsync(id);
 | 
			
		||||
    //
 | 
			
		||||
    //     if (g is null)
 | 
			
		||||
    //     {
 | 
			
		||||
    //         await ReplyErrorLocalizedAsync(strs.not_found);
 | 
			
		||||
    //         return;
 | 
			
		||||
    //     }
 | 
			
		||||
    //
 | 
			
		||||
    //     await SendNhentaiGalleryInternalAsync(g);
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // [Cmd]
 | 
			
		||||
    // [RequireContext(ContextType.Guild)]
 | 
			
		||||
    // [RequireNsfw(Group = "nsfw_or_dm")]
 | 
			
		||||
    // [RequireContext(ContextType.DM, Group = "nsfw_or_dm")]
 | 
			
		||||
    // [Priority(0)]
 | 
			
		||||
    // public async Task Nhentai([Leftover] string query)
 | 
			
		||||
    // {
 | 
			
		||||
    //     var g = await _service.GetNhentaiBySearchAsync(query);
 | 
			
		||||
    //
 | 
			
		||||
    //     if (g is null)
 | 
			
		||||
    //     {
 | 
			
		||||
    //         await ReplyErrorLocalizedAsync(strs.not_found);
 | 
			
		||||
    //         return;
 | 
			
		||||
    //     }
 | 
			
		||||
    //
 | 
			
		||||
    //     await SendNhentaiGalleryInternalAsync(g);
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // private async Task SendNhentaiGalleryInternalAsync(Gallery g)
 | 
			
		||||
    // {
 | 
			
		||||
    //     var count = 0;
 | 
			
		||||
    //     var tagString = g.Tags.Shuffle()
 | 
			
		||||
    //                      .Select(tag => $"[{tag.Name}]({tag.Url})")
 | 
			
		||||
    //                      .TakeWhile(tag => (count += tag.Length) < 1000)
 | 
			
		||||
    //                      .Join(" ");
 | 
			
		||||
    //
 | 
			
		||||
    //     var embed = _eb.Create()
 | 
			
		||||
    //         .WithTitle(g.Title)
 | 
			
		||||
    //         .WithDescription(g.FullTitle)
 | 
			
		||||
    //         .WithImageUrl(g.Thumbnail)
 | 
			
		||||
    //         .WithUrl(g.Url)
 | 
			
		||||
    //         .AddField(GetText(strs.favorites), g.Likes, true)
 | 
			
		||||
    //         .AddField(GetText(strs.pages), g.PageCount, true)
 | 
			
		||||
    //         .AddField(GetText(strs.tags),
 | 
			
		||||
    //             string.IsNullOrWhiteSpace(tagString)
 | 
			
		||||
    //                 ? "?"
 | 
			
		||||
    //                 : tagString,
 | 
			
		||||
    //             true)
 | 
			
		||||
    //         .WithFooter(g.UploadedAt.ToString("f"))
 | 
			
		||||
    //         .WithOkColor();
 | 
			
		||||
    //
 | 
			
		||||
    //     await ctx.Channel.EmbedAsync(embed);
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    private async Task InternalDapiCommand(
 | 
			
		||||
        string[] tags,
 | 
			
		||||
 
 | 
			
		||||
@@ -19,17 +19,15 @@ public class SearchImagesService : ISearchImagesService, INService
 | 
			
		||||
    private readonly SearchImageCacher _cache;
 | 
			
		||||
    private readonly IHttpClientFactory _httpFactory;
 | 
			
		||||
    private readonly DbService _db;
 | 
			
		||||
    private readonly INhentaiService _nh;
 | 
			
		||||
 | 
			
		||||
    private readonly object _taglock = new();
 | 
			
		||||
 | 
			
		||||
    public SearchImagesService(
 | 
			
		||||
        DbService db,
 | 
			
		||||
        SearchImageCacher cacher,
 | 
			
		||||
        IHttpClientFactory httpFactory,
 | 
			
		||||
        INhentaiService nh)
 | 
			
		||||
        IHttpClientFactory httpFactory
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        _nh = nh;
 | 
			
		||||
        _db = db;
 | 
			
		||||
        _rng = new NadekoRandom();
 | 
			
		||||
        _cache = cacher;
 | 
			
		||||
@@ -277,6 +275,7 @@ public class SearchImagesService : ISearchImagesService, INService
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    #region Nhentai
 | 
			
		||||
 | 
			
		||||
    public Task<Gallery?> GetNhentaiByIdAsync(uint id)
 | 
			
		||||
@@ -294,4 +293,5 @@ public class SearchImagesService : ISearchImagesService, INService
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
@@ -664,8 +664,6 @@ avatar:
 | 
			
		||||
  - av
 | 
			
		||||
hentai:
 | 
			
		||||
  - hentai
 | 
			
		||||
nhentai:
 | 
			
		||||
  - nhentai
 | 
			
		||||
danbooru:
 | 
			
		||||
  - danbooru
 | 
			
		||||
derpibooru:
 | 
			
		||||
 
 | 
			
		||||
@@ -1117,11 +1117,6 @@ hentai:
 | 
			
		||||
  desc: "Shows a hentai image from a random website (gelbooru, danbooru, konachan or yandere) with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags. Only 1 tag allowed."
 | 
			
		||||
  args:
 | 
			
		||||
    - "yuri"
 | 
			
		||||
nhentai:
 | 
			
		||||
  desc: "Shows basic information about a hentai with the specified id, or a valid nhentai search query."
 | 
			
		||||
  args:
 | 
			
		||||
    - "273426"
 | 
			
		||||
    - "cute girl"
 | 
			
		||||
autohentai:
 | 
			
		||||
  desc: "Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tag groups. Random group will be chosen every time the image is sent. Max 2 tags per group. 20 seconds minimum. Provide no parameters to disable."
 | 
			
		||||
  args:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user