Пример #1
0
    // Formatter for the results of both ~dt variants. Not a discord-accessible method.
    private async Task DerpiTagsDisplay(DerpiSearch element)
    {
        // Get "Info" block, made up of the Artists list and Image Rating.
        string artists = DerpiHelper.BuildArtistTags(element);
        string rating  = DerpiHelper.GetImageRating(element.tags);

        // Display `~dt` info block and all image tags.
        await ReplyAsync($"Info: **{rating}, {artists}**\n\nAll tags: ```{String.Join(", ",element.tags)}```");
    }
Пример #2
0
    // Takes a Derpibooru singular search result node and returns a string message to be sent to Discord.
    /// <summary>Builds the artist tag section of most Derpibooru results.</summary>
    /// <param name="element">A Derpibooru Search Result Element.</param>
    /// <param name="artistAsLink">Whether or not to render it as a list of tags, or a list of links.</param>
    /// <param name="NSFW">Only valid if "artistAsLink" is true, then we need to flag if we are showing SFW results or not.</param>
    /// <returns>A string response consisting of the image element itself, and an artist tags block.</returns>
    public static string BuildDiscordResponse(DerpiSearch element, bool artistAsLink = false, bool NSFW = false)
    {
        // Get the full image URL in the format "//derpicdn.net/img/view/YYYY/M/d/IMAGE_ID.png"
        // Prepend the protocol, HTTPS, to the incomplete URL representation.
        string results = element.representations.full;

        //if its an ~artist command, respond with derpibooru/id link instead of derpicdn one
        if (artistAsLink)
        {
            results = "https://derpibooru.org/" + element.id;
        }

        // Get the artist block.
        string artistBlock = DerpiHelper.BuildArtistTags(element, artistAsLink, NSFW);

        // Add a newline in between if there are any results.
        if (!String.IsNullOrEmpty(artistBlock))
        {
            artistBlock = "\n" + artistBlock;
        }

        return(results + artistBlock);
    }
Пример #3
0
    /// <summary>Builds the artist tag section of most Derpibooru results.</summary>
    /// <param name="element">A Derpibooru Search Result Element.</param>
    /// <param name="artistAsLink">Whether or not to render it as a list of tags, or a list of links.</param>
    /// <param name="NSFW">Only valid if "artistAsLink" is true, then we need to flag if we are showing SFW results or not.</param>
    /// <returns>A string, either a list of artist names, or a list of URLs to artist tagged works.</returns>
    public static string BuildArtistTags(DerpiSearch element, bool artistAsLink = false, bool NSFW = false)
    {
        string artistResult;

        // Get a distilled list of artist tags from the full tag listing.
        string[] artistTags = element.tags.ToArray();
        artistTags = Array.FindAll(artistTags, tag => tag.Contains("artist:"));

        // Safety Suffix ("AND safe") filter.
        string safetySuffix = NSFW ? String.Empty : "+AND+safe";

        // Parse artist tag response accordingly.
        switch (artistTags.Length)
        {
        case 0:
            // Unedited screencaps uploaded have no artist tags.
            bool isScreencap = element.tags.Contains("screencap");
            artistResult = isScreencap ? String.Empty : "Problem finding artist";
            break;

        case 1:
            artistResult = artistTags[0].TrimStart();
            if (artistAsLink)
            {
                artistResult = $"https://derpibooru.org/search?q={artistResult}{safetySuffix}&filter_id=178065";
            }
            break;

        default:
            artistResult = artistAsLink
                    ? String.Join("\n", artistTags.Select(t => $"https://derpibooru.org/search?q={t.Trim()}{safetySuffix}&filter_id=178065"))
                    : String.Join(' ', artistTags);
            break;
        }

        return(artistResult);
    }
Пример #4
0
    // "Master" Derpibooru/~derpi searching method. Not a discord-accessible method.
    private async Task DerpiMaster(bool artistAsLink, int Sort, string search)
    {
        // Broadcasts "User is typing..." message to Discord channel.
        await Context.Channel.TriggerTypingAsync();

        // Validate that a valid sorting option was chosen.
        if (Sort < 0 || Sort >= this.sortingOptions.Length)
        {
            await ReplyAsync("Invalid sorting option: " + Sort + ". Please try again");

            return;
        }
        // Choose sorting method from the available list.
        string sortParam = this.sortingOptions[Sort];

        // Set up the base query parameters.
        // "q" is our search terms
        // "filter_id" is the filter against content banned by Discord TOS.
        Dictionary <string, string> queryParams = new Dictionary <string, string>()
        {
            { "filter_id", "178065" },
            { "sf", sortParam },
            { "sd", "desc" },
            { "per_page", "50" },
            { "page", "1" },
        };

        // If the channel is not on the list of NSFW enabled channels do not allow NSFW results.
        // the second part checks if the command was executed in DMS, DM channels do not have to be added to the NSFW enabled list.
        // In DMs the first check will fail, and so will the second, allowing for nsfw results to be displayed.
        bool safeOnly = !DBTransaction.isChannelWhitelisted(Context.Channel.Id) && !Context.IsPrivate;

        // Add search to the parameters list, with "AND safe" if it failed the NSFW check.
        queryParams.Add("q", safeOnly ? $"{search}+AND+safe" : search);

        // Build the full request URL.
        string requestUrl = DerpiHelper.BuildDerpiUrl(this.baseURL, queryParams);

        // Global.DerpiSearchCache is a dictionary-based cache with the last search result in that channel, if applicable.
        // Always stores results globally for other commands like ~next to keep track.
        Global.DerpiSearchCache[Context.Channel.Id] = Get.Derpibooru(requestUrl).Result;

        // Deserialize (from JSON to DerpibooruResponse.RootObject) the Derpibooru search results.
        DerpiRoot DerpiResponse = JsonConvert.DeserializeObject <DerpiRoot>(Global.DerpiSearchCache[Context.Channel.Id]);

        // Actual request an. Try-catch to softly catch exceptions.
        try {
            // Convert Search Array to a List, to use List functionality.
            List <DerpiSearch> imageList = DerpiResponse.images;
            if (imageList.Count == 0)
            {
                await ReplyAsync("No results! The tag may be misspelled, or the results could be filtered out due to channel!");

                return;
            }
            // Get random number generator and random entry.
            var rng  = new Random();
            int rand = rng.Next(imageList.Count);
            Global.DerpibooruSearchIndex[Context.Channel.Id] = rand + 1;
            DerpiSearch randomElement = imageList.ElementAt(rand);

            // Add image ID to Global.links.
            // TODO: Describe where this is used better?
            Global.LastDerpiID[Context.Channel.Id] = randomElement.id.ToString();
            RestUserMessage msg = await Context.Channel.SendMessageAsync(
                DerpiHelper.BuildDiscordResponse(randomElement, artistAsLink, !safeOnly)
                );

            await msg.AddReactionAsync(new Emoji("▶"));

            //set random info for running ~enext through emoji reactions.
            Global.derpiContext[Context.Channel.Id]        = Context;
            Global.derpiMessageToTrack[Context.Channel.Id] = msg.Id;
        } catch {
            await ReplyAsync("Sorry! Something went wrong, your search terms are probably incorrect.");

            return;
        }
    }