diff --git a/NadekoBot/Classes/Extensions.cs b/NadekoBot/Classes/Extensions.cs
index cfbcb729..bf4374ad 100644
--- a/NadekoBot/Classes/Extensions.cs
+++ b/NadekoBot/Classes/Extensions.cs
@@ -8,6 +8,7 @@ using Discord;
using NadekoBot.Modules;
using System.IO;
using System.Drawing;
+using NadekoBot.Classes;
namespace NadekoBot.Extensions {
public static class Extensions
@@ -152,7 +153,7 @@ namespace NadekoBot.Extensions {
///
///
///
- public static async Task ShortenUrl(this string str) => await Searches.ShortenUrl(str);
+ public static async Task ShortenUrl(this string str) => await SearchHelper.ShortenUrl(str);
///
/// Gets the program runtime
diff --git a/NadekoBot/Classes/Music/SoundCloud.cs b/NadekoBot/Classes/Music/SoundCloud.cs
index b8a95690..207e45e6 100644
--- a/NadekoBot/Classes/Music/SoundCloud.cs
+++ b/NadekoBot/Classes/Music/SoundCloud.cs
@@ -19,7 +19,7 @@ namespace NadekoBot.Classes.Music {
if (string.IsNullOrWhiteSpace(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(response);
if (responseObj?.Kind != "track")
diff --git a/NadekoBot/Classes/Music/StreamRequest.cs b/NadekoBot/Classes/Music/StreamRequest.cs
index 1ee7692a..53fbd40d 100644
--- a/NadekoBot/Classes/Music/StreamRequest.cs
+++ b/NadekoBot/Classes/Music/StreamRequest.cs
@@ -78,7 +78,7 @@ namespace NadekoBot.Classes.Music {
if (OnResolving != null)
OnResolving();
- var links = await Searches.FindYoutubeUrlByKeywords(Query);
+ var links = await SearchHelper.FindYoutubeUrlByKeywords(Query);
var allVideos = await YouTube.Default.GetAllVideosAsync(links);
var videos = allVideos.Where(v => v.AdaptiveKind == AdaptiveKind.Audio);
var video = videos
diff --git a/NadekoBot/Classes/PermissionCheckers/NSWFPermissionChecker.cs b/NadekoBot/Classes/PermissionCheckers/NSWFPermissionChecker.cs
new file mode 100644
index 00000000..6d22f09c
--- /dev/null
+++ b/NadekoBot/Classes/PermissionCheckers/NSWFPermissionChecker.cs
@@ -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 {
+ public override bool CanRun(Command command, User user, Channel channel, out string error) {
+ error = string.Empty;
+ Console.WriteLine(command.Category);
+ return false;
+ }
+ }
+}
diff --git a/NadekoBot/Classes/PermissionCheckers/PermissionChecker.cs b/NadekoBot/Classes/PermissionCheckers/PermissionChecker.cs
new file mode 100644
index 00000000..61fa4d7c
--- /dev/null
+++ b/NadekoBot/Classes/PermissionCheckers/PermissionChecker.cs
@@ -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 : 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);
+ }
+}
diff --git a/NadekoBot/Classes/SearchHelper.cs b/NadekoBot/Classes/SearchHelper.cs
new file mode 100644
index 00000000..12197f55
--- /dev/null
+++ b/NadekoBot/Classes/SearchHelper.cs
@@ -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 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 GetResponseAsync(string v) =>
+ await new StreamReader((await ((HttpWebRequest)WebRequest.Create(v)).GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
+
+ public static async Task GetResponseAsync(string v, IEnumerable> 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 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(cl.Execute(rq).Content));
+ } catch (Exception) {
+ return null;
+ }
+ }
+ //todo kick out RestSharp and make it truly async
+ public static async Task 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(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 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 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=)(?[\\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 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> GetVideoIDs(string v) {
+ List toReturn = new List();
+ 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();
+ }
+ }
+
+
+ public static async Task 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=\"(?.*?)\"");
+
+ return await $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl();
+ } catch (Exception) {
+ return null;
+ }
+ }
+
+ public static async Task 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(?\\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, "\"(?http://simg4.gelbooru.com//images.*?)\"");
+ return match.Groups["url"].Value;
+ } catch (Exception) {
+ return null;
+ }
+ }
+
+ public static async Task 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"": ?""(?.+)""";
+ return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
+ }
+ } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
+ }
+ }
+}
diff --git a/NadekoBot/Modules/Music.cs b/NadekoBot/Modules/Music.cs
index f78f6c62..31f2c3e7 100644
--- a/NadekoBot/Modules/Music.cs
+++ b/NadekoBot/Modules/Music.cs
@@ -8,6 +8,7 @@ using System.Collections.Concurrent;
using NadekoBot.Classes.Music;
using Timer = System.Timers.Timer;
using System.Threading.Tasks;
+using NadekoBot.Classes;
namespace NadekoBot.Modules {
class Music : DiscordModule {
@@ -172,7 +173,7 @@ namespace NadekoBot.Modules {
await e.Send("💢 You need to be in the voice channel on this server.");
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
var msg = await e.Send($"🎵 Attempting to queue **{ids.Count}** songs".SnPl(ids.Count));
foreach (var id in ids) {
diff --git a/NadekoBot/Modules/NSFW.cs b/NadekoBot/Modules/NSFW.cs
new file mode 100644
index 00000000..44ca9d25
--- /dev/null
+++ b/NadekoBot/Modules/NSFW.cs
@@ -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}");
+ }
+ });
+ });
+ }
+ }
+}
diff --git a/NadekoBot/Modules/Searches.cs b/NadekoBot/Modules/Searches.cs
index 41e1b370..bb493797 100644
--- a/NadekoBot/Modules/Searches.cs
+++ b/NadekoBot/Modules/Searches.cs
@@ -9,6 +9,8 @@ using Newtonsoft.Json;
using Discord.Commands;
using NadekoBot.Extensions;
using System.Collections.Generic;
+using NadekoBot.Classes.PermissionCheckers;
+using NadekoBot.Classes;
namespace NadekoBot.Modules {
class Searches : DiscordModule {
@@ -29,9 +31,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed)
.Description("Searches youtubes and shows the first result")
.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())) {
await e.Send("Query failed");
return;
@@ -44,9 +46,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed)
.Description("Queries anilist for an anime and shows the first result.")
.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) {
await e.Send("Failed to find that anime.");
return;
@@ -60,9 +62,9 @@ namespace NadekoBot.Modules {
.Parameter("query", ParameterType.Unparsed)
.Description("Queries anilist for a manga and shows the first result.")
.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) {
await e.Send("Failed to find that anime.");
return;
@@ -90,7 +92,7 @@ namespace NadekoBot.Modules {
return;
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 obj = JObject.Parse(await GetResponseAsync(reqString));
+ var obj = JObject.Parse(await SearchHelper.GetResponseAsync(reqString));
await e.Send(obj["items"][0]["link"].ToString());
} catch (Exception ex) {
await e.Send($"💢 {ex.Message}");
@@ -105,57 +107,12 @@ namespace NadekoBot.Modules {
return;
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 obj = JObject.Parse(await GetResponseAsync(reqString));
+ var obj = JObject.Parse(await SearchHelper.GetResponseAsync(reqString));
await e.Send(obj["items"][0]["link"].ToString());
} catch (Exception ex) {
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")
.Alias("~lmgtfy")
.Description("Google something for an idiot.")
@@ -175,7 +132,7 @@ namespace NadekoBot.Modules {
return;
}
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[] {
new Tuple("X-Mashape-Key", NadekoBot.creds.MashapeKey),
});
@@ -192,7 +149,7 @@ namespace NadekoBot.Modules {
if (!item.HasValues || item["img"] == null)
continue;
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) {
await e.Send("⚠ Found over 4 images. Showing random 4.");
@@ -246,216 +203,5 @@ namespace NadekoBot.Modules {
*/
});
}
-
- public static async Task 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 GetResponseAsync(string v) =>
- await new StreamReader((await ((HttpWebRequest)WebRequest.Create(v)).GetResponseAsync()).GetResponseStream()).ReadToEndAsync();
-
- public static async Task GetResponseAsync(string v, IEnumerable> 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 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(cl.Execute(rq).Content));
- } catch (Exception) {
- return null;
- }
- }
- //todo kick out RestSharp and make it truly async
- private async Task 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(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 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 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=)(?[\\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 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> GetVideoIDs(string v) {
- List toReturn = new List();
- 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();
- }
- }
-
-
- public async Task 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=\"(?.*?)\"");
-
- return await $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl();
- } catch (Exception) {
- return null;
- }
- }
-
- public async Task 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(?\\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, "\"(?http://simg4.gelbooru.com//images.*?)\"");
- return match.Groups["url"].Value;
- } catch (Exception) {
- return null;
- }
- }
-
- public static async Task 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"": ?""(?.+)""";
- return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
- }
- } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
- }
}
}
diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs
index 0803f8cb..a5f03d62 100644
--- a/NadekoBot/NadekoBot.cs
+++ b/NadekoBot/NadekoBot.cs
@@ -95,6 +95,7 @@ namespace NadekoBot {
modules.Add(new Searches(), "Searches", ModuleFilter.None);
if (loadTrello)
modules.Add(new Trello(), "Trello", ModuleFilter.None);
+ modules.Add(new NSFW(), "NSFW", ModuleFilter.None);
//run the bot
client.ExecuteAndWait(async () => {
diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj
index 3b22dc87..90ce03c9 100644
--- a/NadekoBot/NadekoBot.csproj
+++ b/NadekoBot/NadekoBot.csproj
@@ -132,6 +132,9 @@
+
+
+
@@ -164,6 +167,7 @@
+