// 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)}```"); }
// 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); }
/// <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); }
// "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; } }