public async Task DerpiTagsNoLink() { // Trigger "user is typing..." message. await Context.Channel.TriggerTypingAsync(); // Check if an a "~derpi" search has been made in this channel yet. if (Global.LastDerpiID.ContainsKey(Context.Channel.Id)) { // Handmade link + the channel ID to get the last stored ID. string builtLink = "https://derpibooru.org/api/v1/json/search/images?q=id%3A" + Global.LastDerpiID[Context.Channel.Id] + "&filter_id=56027"; // Retrieves JSON and saves as string. string JSONresponse = Get.Derpibooru(builtLink).Result; // Finally makes the derpibooru object to leverage DerpiTagsDisplay(). DerpiRoot DerpiResponse = JsonConvert.DeserializeObject <DerpiRoot>(JSONresponse); // Check if the ID existed or yielded any results. if (DerpiResponse.images.Count < 1) { await ReplyAsync("No results found, please call `~derpi` again or post another link!"); } else { await DerpiTagsDisplay(DerpiResponse.images[0]); } } else { await ReplyAsync("You need to call `~derpi` (`~d` for short) or post a link before I can hoof over the tags!"); } }
public async Task DerpiTags([Remainder] string search) { // Broadcasts "User is typing..." message to Discord channel. await Context.Channel.TriggerTypingAsync(); // Image ID placeholder. int imageID; // First, check if search term is an image ID. An integer. if (int.TryParse(search, out imageID)) { // Continue as normal, imageID is stored in the variable. } // Second, if not an integer, test if it is a valid Booru URL. else if (Global.IsBooruUrl(search)) { // 1. Attempt to parse Integer ID from Booru URL. imageID = Global.ExtractBooruId(search); // 2a. Unparseable, quit early and apologize to user. if (imageID == -1) { await ReplyAsync("Sorry, I couldn't understand the URL you gave me. Please try again with another URL, or contact Hoovier if something is wrong."); await ReplyAsync("If you think this was in error, please contact Hoovier with the request you made."); return; } // 2b. Continue as normal, imageID is stored in the variable. } // Lastly, if not a valid Booru URL or ID, output a gentle error message. else { await ReplyAsync("Sorry, I couldn't understand the URL you gave me. Please try again with another URL, or contact Hoovier if something is wrong."); return; } // If you reach here, the "else" return case didn't happen and we can query Derpibooru. // We can use imageID to uniformly query DerpiBooru. string requestUrl = DerpiHelper.BuildDerpiUrl(this.baseURL, new Dictionary <string, string>() { { "filter_id", "56027" }, { "q", $"id:{imageID}" }, }); string DerpiJson = Get.Derpibooru(requestUrl).Result; DerpiRoot DerpiResponse = JsonConvert.DeserializeObject <DerpiRoot>(DerpiJson); if (DerpiResponse.images.Count == 0) { await ReplyAsync("No results! The ID or URL provided might have had a typo or is deleted no longer exists."); await ReplyAsync("If you think this was in error, please contact Hoovier with the request you made."); } else { await DerpiTagsDisplay(DerpiResponse.images[0]); } }
public async Task ArtistNoLink() { await Context.Channel.TriggerTypingAsync(); // Get last Derpibooru Image ID from global cache. int imageID; // Check if an a "~derpi" search has been made in this channel yet. if (!Global.LastDerpiID.ContainsKey(Context.Channel.Id)) { await ReplyAsync("You need to call `~derpi` (`~d` for short) to get some results before I can hoof you over more silly!"); return; } // Try to parse the global cache into an integer ID. if (int.TryParse(Global.LastDerpiID[Context.Channel.Id], out imageID)) { string requestUrl = DerpiHelper.BuildDerpiUrl(this.baseURL, new Dictionary <string, string>() { { "filter_id", "178065" }, { "q", $"id:{imageID}" }, }); string DerpiJson = Get.Derpibooru(requestUrl).Result; DerpiRoot DerpiResponse = JsonConvert.DeserializeObject <DerpiRoot>(DerpiJson); if (DerpiResponse.images.Count == 0) { // Given ID does not exist. await ReplyAsync("No results! The tag may be misspelled, or the results could be filtered out due to channel!"); } else { // Get artist Tag Link(s) and print image URL as well. bool safeOnly = !DBTransaction.isChannelWhitelisted(Context.Channel.Id) && !Context.IsPrivate; string artistLinks = DerpiHelper.BuildArtistTags(DerpiResponse.images[0], true, !safeOnly); await ReplyAsync($"https://derpibooru.org/{imageID}\n{artistLinks}"); } } else { // Can't get an ID from cache. await ReplyAsync("No results! The tag may be misspelled, or the results could be filtered out due to channel!"); } }
public async Task DerpistAsync([Remainder] string search) { await Context.Channel.TriggerTypingAsync(); // Same base query as ~derpi, discounting sorting and asking for less results. Dictionary <string, string> queryParams = new Dictionary <string, string>() { { "filter_id", "178065" }, { "per_page", "1" }, { "page", "1" }, { "q", search }, }; // Build the full request URL. string requestUrl = DerpiHelper.BuildDerpiUrl(this.baseURL, queryParams); // Make the request, and parse the JSON into a C#-friendly object. DerpiRoot results = JsonConvert.DeserializeObject <DerpiRoot>(Get.Derpibooru(requestUrl).Result); await ReplyAsync($"Total results: {results.total}"); }
public async Task DerpiLuckyMulti(int num, [Remainder] string search) { // Broadcasts "User is typing..." message to Discord channel. await Context.Channel.TriggerTypingAsync(); // Limit ~lucky amounts. if (num < 1 || num > 5) { await ReplyAsync("You need to pick a number bigger than 0 and no more than 5"); return; } // Set up the base query parameters. // Sorted randomly, gets "num" amount of items! Dictionary <string, string> queryParams = new Dictionary <string, string>() { { "filter_id", "178065" }, { "sf", "random" }, { "sd", "desc" }, { "per_page", num.ToString() }, { "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); // Deserialize (from JSON to DerpibooruResponse.RootObject) the Derpibooru search results. DerpiRoot DerpiResponse = JsonConvert.DeserializeObject <DerpiRoot>(Get.Derpibooru(requestUrl).Result); // Actual request an. Try-catch to softly catch exceptions. try { if (DerpiResponse.images.Count == 0) { await ReplyAsync("No results! The tag may be misspelled, or the results could be filtered out due to channel!"); return; } else if (DerpiResponse.images.Count < num) { await ReplyAsync($"Not enough results to post {num}, but here is what we have found!"); } // Print all results of the search! // Sorted randomly by Derpibooru already, and will be between 1-5 elements. string message = $"Listing {DerpiResponse.images.Count} results\n"; message += String.Join("\n", DerpiResponse.images.Select( element => element.representations.full)); await ReplyAsync(message); } catch { await ReplyAsync("Sorry! Something went wrong, your search terms are probably incorrect."); return; } }
// "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; } }