Refactored searches, created first (inactive) permission checkers

This commit is contained in:
Master Kwoth 2016-02-10 14:39:11 +01:00
parent bbb336f1a3
commit afe929430a
11 changed files with 348 additions and 270 deletions

View File

@ -8,6 +8,7 @@ using Discord;
using NadekoBot.Modules; using NadekoBot.Modules;
using System.IO; using System.IO;
using System.Drawing; using System.Drawing;
using NadekoBot.Classes;
namespace NadekoBot.Extensions { namespace NadekoBot.Extensions {
public static class Extensions public static class Extensions
@ -152,7 +153,7 @@ namespace NadekoBot.Extensions {
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="source"></param> /// <param name="source"></param>
/// <param name="action"></param> /// <param name="action"></param>
public static async Task<string> ShortenUrl(this string str) => await Searches.ShortenUrl(str); public static async Task<string> ShortenUrl(this string str) => await SearchHelper.ShortenUrl(str);
/// <summary> /// <summary>
/// Gets the program runtime /// Gets the program runtime

View File

@ -19,7 +19,7 @@ namespace NadekoBot.Classes.Music {
if (string.IsNullOrWhiteSpace(NadekoBot.creds.SoundCloudClientID)) if (string.IsNullOrWhiteSpace(NadekoBot.creds.SoundCloudClientID))
throw new ArgumentNullException(nameof(NadekoBot.creds.SoundCloudClientID)); throw new ArgumentNullException(nameof(NadekoBot.creds.SoundCloudClientID));
var response = await Modules.Searches.GetResponseAsync($"http://api.soundcloud.com/resolve?url={url}&client_id={NadekoBot.creds.SoundCloudClientID}"); var response = await SearchHelper.GetResponseAsync($"http://api.soundcloud.com/resolve?url={url}&client_id={NadekoBot.creds.SoundCloudClientID}");
var responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject<SoundCloudVideo>(response); var responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject<SoundCloudVideo>(response);
if (responseObj?.Kind != "track") if (responseObj?.Kind != "track")

View File

@ -78,7 +78,7 @@ namespace NadekoBot.Classes.Music {
if (OnResolving != null) if (OnResolving != null)
OnResolving(); OnResolving();
var links = await Searches.FindYoutubeUrlByKeywords(Query); var links = await SearchHelper.FindYoutubeUrlByKeywords(Query);
var allVideos = await YouTube.Default.GetAllVideosAsync(links); var allVideos = await YouTube.Default.GetAllVideosAsync(links);
var videos = allVideos.Where(v => v.AdaptiveKind == AdaptiveKind.Audio); var videos = allVideos.Where(v => v.AdaptiveKind == AdaptiveKind.Audio);
var video = videos var video = videos

View File

@ -0,0 +1,18 @@
using Discord.Commands.Permissions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
namespace NadekoBot.Classes.PermissionCheckers {
class NSFWPermissionChecker : PermissionChecker<NSFWPermissionChecker> {
public override bool CanRun(Command command, User user, Channel channel, out string error) {
error = string.Empty;
Console.WriteLine(command.Category);
return false;
}
}
}

View File

@ -0,0 +1,17 @@
using Discord.Commands.Permissions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
namespace NadekoBot.Classes.PermissionCheckers {
abstract class PermissionChecker<T> : IPermissionChecker where T : new() {
public static readonly T _instance = new T();
public static T Instance => _instance;
public abstract bool CanRun(Command command, User user, Channel channel, out string error);
}
}

View File

@ -0,0 +1,219 @@
using NadekoBot.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace NadekoBot.Classes {
static class SearchHelper {
public static async Task<Stream> GetResponseStream(string v) {
var wr = (HttpWebRequest)WebRequest.Create(v);
try {
return (await (wr).GetResponseAsync()).GetResponseStream();
} catch (Exception ex) {
Console.WriteLine("error in getresponse stream " + ex);
return null;
}
}
public static async Task<string> GetResponseAsync(string v) =>
await new StreamReader((await ((HttpWebRequest)WebRequest.Create(v)).GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
public static async Task<string> GetResponseAsync(string v, IEnumerable<Tuple<string, string>> headers) {
var wr = (HttpWebRequest)WebRequest.Create(v);
foreach (var header in headers) {
wr.Headers.Add(header.Item1, header.Item2);
}
return await new StreamReader((await wr.GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
}
private static string token = "";
public static async Task<AnimeResult> GetAnimeQueryResultLink(string query) {
try {
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
RefreshAnilistToken();
rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
rq.AddParameter("access_token", token);
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
rq = new RestSharp.RestRequest("anime/" + smallObj["id"]);
rq.AddParameter("access_token", token);
return await Task.Run(() => JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content));
} catch (Exception) {
return null;
}
}
//todo kick out RestSharp and make it truly async
public static async Task<MangaResult> GetMangaQueryResultLink(string query) {
try {
RefreshAnilistToken();
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq = new RestSharp.RestRequest("/manga/search/" + Uri.EscapeUriString(query));
rq.AddParameter("access_token", token);
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
rq = new RestSharp.RestRequest("manga/" + smallObj["id"]);
rq.AddParameter("access_token", token);
return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(cl.Execute(rq).Content));
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
return null;
}
}
private static void RefreshAnilistToken() {
try {
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq.AddParameter("grant_type", "client_credentials");
rq.AddParameter("client_id", "kwoth-w0ki9");
rq.AddParameter("client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z");
var exec = cl.Execute(rq);
token = JObject.Parse(exec.Content)["access_token"].ToString();
} catch (Exception ex) {
Console.WriteLine($"Failed refreshing anilist token:\n {ex}");
}
}
public static async Task<bool> ValidateQuery(Discord.Channel ch, string query) {
if (string.IsNullOrEmpty(query.Trim())) {
await ch.Send("Please specify search parameters.");
return false;
}
return true;
}
public static async Task<string> FindYoutubeUrlByKeywords(string v) {
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return @"https://www.youtube.com/watch?v=dQw4w9WgXcQ";
}
try {
//maybe it is already a youtube url, in which case we will just extract the id and prepend it with youtube.com?v=
var match = new Regex("(?:youtu\\.be\\/|v=)(?<id>[\\da-zA-Z\\-_]*)").Match(v);
if (match.Length > 1) {
string str = $"http://www.youtube.com?v={ match.Groups["id"].Value }";
return str;
}
WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey);
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
return "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString();
} catch (Exception ex) {
Console.WriteLine($"Error in findyoutubeurl: {ex.Message}");
return string.Empty;
}
}
public static async Task<string> GetPlaylistIdByKeyword(string v) {
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return string.Empty;
}
try {
WebRequest wr = WebRequest.Create($"https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q={Uri.EscapeDataString(v)}&type=playlist&key={NadekoBot.creds.GoogleAPIKey}");
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
return obj.items[0].id.playlistId.ToString();
} catch (Exception ex) {
Console.WriteLine($"Error in GetPlaylistId: {ex.Message}");
return string.Empty;
}
}
public static async Task<List<string>> GetVideoIDs(string v) {
List<string> toReturn = new List<string>();
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return toReturn;
}
try {
WebRequest wr = WebRequest.Create($"https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&maxResults={25}&playlistId={v}&key={ NadekoBot.creds.GoogleAPIKey }");
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
foreach (var item in obj.items) {
toReturn.Add("http://www.youtube.com/watch?v=" + item.contentDetails.videoId);
}
return toReturn;
} catch (Exception ex) {
Console.WriteLine($"Error in GetPlaylistId: {ex.Message}");
return new List<string>();
}
}
public static async Task<string> GetDanbooruImageLink(string tag) {
try {
var rng = new Random();
if (tag == "loli") //loli doesn't work for some reason atm
tag = "flat_chest";
var webpage = await GetResponseAsync($"http://danbooru.donmai.us/posts?page={ rng.Next(0, 30) }&tags={ tag.Replace(" ", "_") }");
var matches = Regex.Matches(webpage, "data-large-file-url=\"(?<id>.*?)\"");
return await $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl();
} catch (Exception) {
return null;
}
}
public static async Task<string> GetGelbooruImageLink(string tag) {
try {
var rng = new Random();
var url = $"http://gelbooru.com/index.php?page=post&s=list&pid={ rng.Next(0, 15) * 42 }&tags={ tag.Replace(" ", "_") }";
var webpage = await GetResponseAsync(url); // first extract the post id and go to that posts page
var matches = Regex.Matches(webpage, "span id=\"s(?<id>\\d*)\"");
var postLink = $"http://gelbooru.com/index.php?page=post&s=view&id={ matches[rng.Next(0, matches.Count)].Groups["id"].Value }";
webpage = await GetResponseAsync(postLink);
//now extract the image from post page
var match = Regex.Match(webpage, "\"(?<url>http://simg4.gelbooru.com//images.*?)\"");
return match.Groups["url"].Value;
} catch (Exception) {
return null;
}
}
public static async Task<string> ShortenUrl(string url) {
if (NadekoBot.GoogleAPIKey == null || NadekoBot.GoogleAPIKey == "") return url;
try {
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
string json = "{\"longUrl\":\"" + url + "\"}";
streamWriter.Write(json);
}
var httpResponse = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
string responseText = await streamReader.ReadToEndAsync();
string MATCH_PATTERN = @"""id"": ?""(?<id>.+)""";
return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
}
} catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
}
}
}

View File

@ -8,6 +8,7 @@ using System.Collections.Concurrent;
using NadekoBot.Classes.Music; using NadekoBot.Classes.Music;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Classes;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
class Music : DiscordModule { class Music : DiscordModule {
@ -172,7 +173,7 @@ namespace NadekoBot.Modules {
await e.Send("💢 You need to be in the voice channel on this server."); await e.Send("💢 You need to be in the voice channel on this server.");
return; return;
} }
var ids = await Searches.GetVideoIDs(await Searches.GetPlaylistIdByKeyword(e.GetArg("playlist"))); var ids = await SearchHelper.GetVideoIDs(await SearchHelper.GetPlaylistIdByKeyword(e.GetArg("playlist")));
//todo TEMPORARY SOLUTION, USE RESOLVE QUEUE IN THE FUTURE //todo TEMPORARY SOLUTION, USE RESOLVE QUEUE IN THE FUTURE
var msg = await e.Send($"🎵 Attempting to queue **{ids.Count}** songs".SnPl(ids.Count)); var msg = await e.Send($"🎵 Attempting to queue **{ids.Count}** songs".SnPl(ids.Count));
foreach (var id in ids) { foreach (var id in ids) {

71
NadekoBot/Modules/NSFW.cs Normal file
View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Modules;
using NadekoBot.Extensions;
using NadekoBot.Classes.PermissionCheckers;
using Discord.Commands;
using Newtonsoft.Json.Linq;
using NadekoBot.Classes;
namespace NadekoBot.Modules {
class NSFW : DiscordModule {
private Random _r = new Random();
public NSFW() : base() {
}
public override void Install(ModuleManager manager) {
manager.CreateCommands("", cgb => {
cgb.CreateCommand("~hentai")
.Description("Shows a random NSFW hentai image from gelbooru and danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(":heart: Gelbooru: " + await SearchHelper.GetGelbooruImageLink(tag));
await e.Send(":heart: Danbooru: " + await SearchHelper.GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~danbooru")
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(await SearchHelper.GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~gelbooru")
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(await SearchHelper.GetGelbooruImageLink(tag));
});
cgb.CreateCommand("~cp")
.Description("We all know where this will lead you to.")
.Parameter("anything", ParameterType.Unparsed)
.Do(async e => {
await e.Send("http://i.imgur.com/MZkY1md.jpg");
});
cgb.CreateCommand("~boobs")
.Description("Real adult content.")
.Do(async e => {
try {
var obj = JArray.Parse(await SearchHelper.GetResponseAsync($"http://api.oboobs.ru/boobs/{_r.Next(0, 9304)}"))[0];
await e.Send($"http://media.oboobs.ru/{ obj["preview"].ToString() }");
} catch (Exception ex) {
await e.Send($"💢 {ex.Message}");
}
});
});
}
}
}

View File

@ -9,6 +9,8 @@ using Newtonsoft.Json;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Collections.Generic; using System.Collections.Generic;
using NadekoBot.Classes.PermissionCheckers;
using NadekoBot.Classes;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
class Searches : DiscordModule { class Searches : DiscordModule {
@ -29,9 +31,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed) .Parameter("query", ParameterType.Unparsed)
.Description("Searches youtubes and shows the first result") .Description("Searches youtubes and shows the first result")
.Do(async e => { .Do(async e => {
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")))) return;
var str = await ShortenUrl(await FindYoutubeUrlByKeywords(e.GetArg("query"))); var str = await SearchHelper.ShortenUrl(await SearchHelper.FindYoutubeUrlByKeywords(e.GetArg("query")));
if (string.IsNullOrEmpty(str.Trim())) { if (string.IsNullOrEmpty(str.Trim())) {
await e.Send("Query failed"); await e.Send("Query failed");
return; return;
@ -44,9 +46,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed) .Parameter("query", ParameterType.Unparsed)
.Description("Queries anilist for an anime and shows the first result.") .Description("Queries anilist for an anime and shows the first result.")
.Do(async e => { .Do(async e => {
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")))) return;
var result = await GetAnimeQueryResultLink(e.GetArg("query")); var result = await SearchHelper.GetAnimeQueryResultLink(e.GetArg("query"));
if (result == null) { if (result == null) {
await e.Send("Failed to find that anime."); await e.Send("Failed to find that anime.");
return; return;
@ -60,9 +62,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed) .Parameter("query", ParameterType.Unparsed)
.Description("Queries anilist for a manga and shows the first result.") .Description("Queries anilist for a manga and shows the first result.")
.Do(async e => { .Do(async e => {
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")))) return;
var result = await GetMangaQueryResultLink(e.GetArg("query")); var result = await SearchHelper.GetMangaQueryResultLink(e.GetArg("query"));
if (result == null) { if (result == null) {
await e.Send("Failed to find that anime."); await e.Send("Failed to find that anime.");
return; return;
@ -90,7 +92,7 @@ namespace NadekoBot.Modules {
return; return;
try { try {
var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&fields=items%2Flink&key={NadekoBot.creds.GoogleAPIKey}"; var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&fields=items%2Flink&key={NadekoBot.creds.GoogleAPIKey}";
var obj = JObject.Parse(await GetResponseAsync(reqString)); var obj = JObject.Parse(await SearchHelper.GetResponseAsync(reqString));
await e.Send(obj["items"][0]["link"].ToString()); await e.Send(obj["items"][0]["link"].ToString());
} catch (Exception ex) { } catch (Exception ex) {
await e.Send($"💢 {ex.Message}"); await e.Send($"💢 {ex.Message}");
@ -105,57 +107,12 @@ namespace NadekoBot.Modules {
return; return;
try { try {
var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&start={ _r.Next(1, 150) }&fields=items%2Flink&key={NadekoBot.creds.GoogleAPIKey}"; var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&start={ _r.Next(1, 150) }&fields=items%2Flink&key={NadekoBot.creds.GoogleAPIKey}";
var obj = JObject.Parse(await GetResponseAsync(reqString)); var obj = JObject.Parse(await SearchHelper.GetResponseAsync(reqString));
await e.Send(obj["items"][0]["link"].ToString()); await e.Send(obj["items"][0]["link"].ToString());
} catch (Exception ex) { } catch (Exception ex) {
await e.Send($"💢 {ex.Message}"); await e.Send($"💢 {ex.Message}");
} }
}); });
cgb.CreateCommand("~hentai")
.Description("Shows a random NSFW hentai image from gelbooru and danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(":heart: Gelbooru: " + await GetGelbooruImageLink(tag));
await e.Send(":heart: Danbooru: " + await GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~danbooru")
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(await GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~gelbooru")
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
if (tag == null)
tag = "";
await e.Send(await GetGelbooruImageLink(tag));
});
cgb.CreateCommand("~cp")
.Description("We all know where this will lead you to.")
.Parameter("anything", ParameterType.Unparsed)
.Do(async e => {
await e.Send("http://i.imgur.com/MZkY1md.jpg");
});
cgb.CreateCommand("~boobs")
.Description("Real adult content.")
.Do(async e => {
try {
var obj = JArray.Parse(await GetResponseAsync($"http://api.oboobs.ru/boobs/{_r.Next(0, 9304)}"))[0];
await e.Send($"http://media.oboobs.ru/{ obj["preview"].ToString() }");
} catch (Exception ex) {
await e.Send($"💢 {ex.Message}");
}
});
cgb.CreateCommand("lmgtfy") cgb.CreateCommand("lmgtfy")
.Alias("~lmgtfy") .Alias("~lmgtfy")
.Description("Google something for an idiot.") .Description("Google something for an idiot.")
@ -175,7 +132,7 @@ namespace NadekoBot.Modules {
return; return;
} }
await e.Channel.SendIsTyping(); await e.Channel.SendIsTyping();
var res = await GetResponseAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}", var res = await SearchHelper.GetResponseAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}",
new Tuple<string, string>[] { new Tuple<string, string>[] {
new Tuple<string, string>("X-Mashape-Key", NadekoBot.creds.MashapeKey), new Tuple<string, string>("X-Mashape-Key", NadekoBot.creds.MashapeKey),
}); });
@ -192,7 +149,7 @@ namespace NadekoBot.Modules {
if (!item.HasValues || item["img"] == null) if (!item.HasValues || item["img"] == null)
continue; continue;
cnt++; cnt++;
images.Add(System.Drawing.Bitmap.FromStream(await GetResponseStream(item["img"].ToString()))); images.Add(System.Drawing.Bitmap.FromStream(await SearchHelper.GetResponseStream(item["img"].ToString())));
} }
if (items.Count > 4) { if (items.Count > 4) {
await e.Send("⚠ Found over 4 images. Showing random 4."); await e.Send("⚠ Found over 4 images. Showing random 4.");
@ -246,216 +203,5 @@ namespace NadekoBot.Modules {
*/ */
}); });
} }
public static async Task<Stream> GetResponseStream(string v) {
var wr = (HttpWebRequest)WebRequest.Create(v);
try {
return (await (wr).GetResponseAsync()).GetResponseStream();
} catch (Exception ex) {
Console.WriteLine("error in getresponse stream " + ex);
return null;
}
}
public static async Task<string> GetResponseAsync(string v) =>
await new StreamReader((await ((HttpWebRequest)WebRequest.Create(v)).GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
public static async Task<string> GetResponseAsync(string v, IEnumerable<Tuple<string, string>> headers) {
var wr = (HttpWebRequest)WebRequest.Create(v);
foreach (var header in headers) {
wr.Headers.Add(header.Item1, header.Item2);
}
return await new StreamReader((await wr.GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
}
private string token = "";
private async Task<AnimeResult> GetAnimeQueryResultLink(string query) {
try {
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
RefreshAnilistToken();
rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
rq.AddParameter("access_token", token);
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
rq = new RestSharp.RestRequest("anime/" + smallObj["id"]);
rq.AddParameter("access_token", token);
return await Task.Run(() => JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content));
} catch (Exception) {
return null;
}
}
//todo kick out RestSharp and make it truly async
private async Task<MangaResult> GetMangaQueryResultLink(string query) {
try {
RefreshAnilistToken();
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq = new RestSharp.RestRequest("/manga/search/" + Uri.EscapeUriString(query));
rq.AddParameter("access_token", token);
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
rq = new RestSharp.RestRequest("manga/" + smallObj["id"]);
rq.AddParameter("access_token", token);
return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(cl.Execute(rq).Content));
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
return null;
}
}
private void RefreshAnilistToken() {
try {
var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq.AddParameter("grant_type", "client_credentials");
rq.AddParameter("client_id", "kwoth-w0ki9");
rq.AddParameter("client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z");
var exec = cl.Execute(rq);
/*
Console.WriteLine($"Server gave me content: { exec.Content }\n{ exec.ResponseStatus } -> {exec.ErrorMessage} ");
Console.WriteLine($"Err exception: {exec.ErrorException}");
Console.WriteLine($"Inner: {exec.ErrorException.InnerException}");
*/
token = JObject.Parse(exec.Content)["access_token"].ToString();
} catch (Exception ex) {
Console.WriteLine($"Failed refreshing anilist token:\n {ex}");
}
}
private static async Task<bool> ValidateQuery(Discord.Channel ch, string query) {
if (string.IsNullOrEmpty(query.Trim())) {
await ch.Send("Please specify search parameters.");
return false;
}
return true;
}
public static async Task<string> FindYoutubeUrlByKeywords(string v) {
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return @"https://www.youtube.com/watch?v=dQw4w9WgXcQ";
}
try {
//maybe it is already a youtube url, in which case we will just extract the id and prepend it with youtube.com?v=
var match = new Regex("(?:youtu\\.be\\/|v=)(?<id>[\\da-zA-Z\\-_]*)").Match(v);
if (match.Length > 1) {
string str = $"http://www.youtube.com?v={ match.Groups["id"].Value }";
return str;
}
WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey);
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
return "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString();
} catch (Exception ex) {
Console.WriteLine($"Error in findyoutubeurl: {ex.Message}");
return string.Empty;
}
}
public static async Task<string> GetPlaylistIdByKeyword(string v) {
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return string.Empty;
}
try {
WebRequest wr = WebRequest.Create($"https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q={Uri.EscapeDataString(v)}&type=playlist&key={NadekoBot.creds.GoogleAPIKey}");
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
return obj.items[0].id.playlistId.ToString();
} catch (Exception ex) {
Console.WriteLine($"Error in GetPlaylistId: {ex.Message}");
return string.Empty;
}
}
public static async Task<List<string>> GetVideoIDs(string v) {
List<string> toReturn = new List<string>();
if (NadekoBot.GoogleAPIKey == "" || NadekoBot.GoogleAPIKey == null) {
Console.WriteLine("ERROR: No google api key found. Playing `Never gonna give you up`.");
return toReturn;
}
try {
WebRequest wr = WebRequest.Create($"https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&maxResults={25}&playlistId={v}&key={ NadekoBot.creds.GoogleAPIKey }");
var sr = new StreamReader((await wr.GetResponseAsync()).GetResponseStream());
dynamic obj = JObject.Parse(await sr.ReadToEndAsync());
foreach (var item in obj.items) {
toReturn.Add("http://www.youtube.com/watch?v=" + item.contentDetails.videoId);
}
return toReturn;
} catch (Exception ex) {
Console.WriteLine($"Error in GetPlaylistId: {ex.Message}");
return new List<string>();
}
}
public async Task<string> GetDanbooruImageLink(string tag) {
try {
var rng = new Random();
if (tag == "loli") //loli doesn't work for some reason atm
tag = "flat_chest";
var webpage = await GetResponseAsync($"http://danbooru.donmai.us/posts?page={ rng.Next(0, 30) }&tags={ tag.Replace(" ", "_") }");
var matches = Regex.Matches(webpage, "data-large-file-url=\"(?<id>.*?)\"");
return await $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl();
} catch (Exception) {
return null;
}
}
public async Task<string> GetGelbooruImageLink(string tag) {
try {
var rng = new Random();
var url = $"http://gelbooru.com/index.php?page=post&s=list&pid={ rng.Next(0, 15) * 42 }&tags={ tag.Replace(" ", "_") }";
var webpage = await GetResponseAsync(url); // first extract the post id and go to that posts page
var matches = Regex.Matches(webpage, "span id=\"s(?<id>\\d*)\"");
var postLink = $"http://gelbooru.com/index.php?page=post&s=view&id={ matches[rng.Next(0, matches.Count)].Groups["id"].Value }";
webpage = await GetResponseAsync(postLink);
//now extract the image from post page
var match = Regex.Match(webpage, "\"(?<url>http://simg4.gelbooru.com//images.*?)\"");
return match.Groups["url"].Value;
} catch (Exception) {
return null;
}
}
public static async Task<string> ShortenUrl(string url) {
if (NadekoBot.GoogleAPIKey == null || NadekoBot.GoogleAPIKey == "") return url;
try {
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
string json = "{\"longUrl\":\"" + url + "\"}";
streamWriter.Write(json);
}
var httpResponse = (await httpWebRequest.GetResponseAsync()) as HttpWebResponse;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
string responseText = await streamReader.ReadToEndAsync();
string MATCH_PATTERN = @"""id"": ?""(?<id>.+)""";
return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
}
} catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
}
} }
} }

View File

@ -95,6 +95,7 @@ namespace NadekoBot {
modules.Add(new Searches(), "Searches", ModuleFilter.None); modules.Add(new Searches(), "Searches", ModuleFilter.None);
if (loadTrello) if (loadTrello)
modules.Add(new Trello(), "Trello", ModuleFilter.None); modules.Add(new Trello(), "Trello", ModuleFilter.None);
modules.Add(new NSFW(), "NSFW", ModuleFilter.None);
//run the bot //run the bot
client.ExecuteAndWait(async () => { client.ExecuteAndWait(async () => {

View File

@ -132,6 +132,9 @@
<Compile Include="Classes\Music\MusicControls.cs" /> <Compile Include="Classes\Music\MusicControls.cs" />
<Compile Include="Classes\Music\StreamRequest.cs" /> <Compile Include="Classes\Music\StreamRequest.cs" />
<Compile Include="Classes\Music\SoundCloud.cs" /> <Compile Include="Classes\Music\SoundCloud.cs" />
<Compile Include="Classes\PermissionCheckers\NSWFPermissionChecker.cs" />
<Compile Include="Classes\PermissionCheckers\PermissionChecker.cs" />
<Compile Include="Classes\SearchHelper.cs" />
<Compile Include="Classes\_DataModels\AnnouncementModel.cs" /> <Compile Include="Classes\_DataModels\AnnouncementModel.cs" />
<Compile Include="Classes\_DataModels\CommandModel.cs" /> <Compile Include="Classes\_DataModels\CommandModel.cs" />
<Compile Include="Classes\_DataModels\CurrencyStateModel.cs" /> <Compile Include="Classes\_DataModels\CurrencyStateModel.cs" />
@ -164,6 +167,7 @@
<Compile Include="Modules\Games.cs" /> <Compile Include="Modules\Games.cs" />
<Compile Include="Modules\Music.cs" /> <Compile Include="Modules\Music.cs" />
<Compile Include="Commands\PollCommand.cs" /> <Compile Include="Commands\PollCommand.cs" />
<Compile Include="Modules\NSFW.cs" />
<Compile Include="Modules\Searches.cs" /> <Compile Include="Modules\Searches.cs" />
<Compile Include="Modules\Trello.cs" /> <Compile Include="Modules\Trello.cs" />
<Compile Include="NadekoBot.cs" /> <Compile Include="NadekoBot.cs" />