NadekoBot/NadekoBot.Module.Searches/Searches.cs

831 lines
38 KiB
C#
Raw Normal View History

2016-08-15 23:38:28 +00:00
using Discord;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Net.Http;
using NadekoBot.Services;
using System.Threading.Tasks;
using System.Net;
using System.Collections.Generic;
using NadekoBot.Extensions;
using System.IO;
using AngleSharp;
using AngleSharp.Dom.Html;
using AngleSharp.Dom;
using Configuration = AngleSharp.Configuration;
using Discord.Commands;
2017-03-20 12:45:36 +00:00
using ImageSharp;
2017-07-17 19:42:36 +00:00
using NadekoBot.Common;
using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Searches.Common;
using NadekoBot.Modules.Searches.Services;
using NadekoBot.Common.Replacements;
using Discord.WebSocket;
2016-08-15 23:38:28 +00:00
namespace NadekoBot.Modules.Searches
{
2017-07-15 16:34:34 +00:00
public partial class Searches : NadekoTopLevelModule<SearchesService>
2016-08-15 23:38:28 +00:00
{
2017-05-27 08:19:27 +00:00
private readonly IBotCredentials _creds;
private readonly IGoogleApiService _google;
2017-07-15 16:34:34 +00:00
public Searches(IBotCredentials creds, IGoogleApiService google)
2017-05-27 08:19:27 +00:00
{
_creds = creds;
_google = google;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Say([Remainder]string message)
{
if (string.IsNullOrWhiteSpace(message))
return;
var rep = new ReplacementBuilder()
.WithDefault(Context.User, Context.Channel, Context.Guild, (DiscordSocketClient)Context.Client)
.Build();
if (CREmbed.TryParse(message, out var embedData))
{
rep.Replace(embedData);
try
{
await Context.Channel.EmbedAsync(embedData.ToEmbed(), embedData.PlainText?.SanitizeMentions() ?? "").ConfigureAwait(false);
}
catch (Exception ex)
{
_log.Warn(ex);
}
}
else
{
var msg = rep.Replace(message);
if (!string.IsNullOrWhiteSpace(msg))
{
await Context.Channel.SendConfirmAsync(msg).ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-31 10:55:12 +00:00
public async Task Weather([Remainder] string query)
2016-08-15 23:38:28 +00:00
{
2016-12-22 06:29:24 +00:00
if (string.IsNullOrWhiteSpace(query))
return;
2016-08-15 23:38:28 +00:00
string response;
response = await _service.Http.GetStringAsync($"http://api.openweathermap.org/data/2.5/weather?q={query}&appid=42cd627dd60debf25a5739e50a217d74&units=metric").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
2016-12-22 06:29:24 +00:00
var data = JsonConvert.DeserializeObject<WeatherData>(response);
2016-08-15 23:38:28 +00:00
2016-11-29 20:26:13 +00:00
var embed = new EmbedBuilder()
2017-07-17 19:42:36 +00:00
.AddField(fb => fb.WithName("🌍 " + Format.Bold(GetText("location"))).WithValue($"[{data.Name + ", " + data.Sys.Country}](https://openweathermap.org/city/{data.Id})").WithIsInline(true))
.AddField(fb => fb.WithName("📏 " + Format.Bold(GetText("latlong"))).WithValue($"{data.Coord.Lat}, {data.Coord.Lon}").WithIsInline(true))
.AddField(fb => fb.WithName("☁ " + Format.Bold(GetText("condition"))).WithValue(string.Join(", ", data.Weather.Select(w => w.Main))).WithIsInline(true))
.AddField(fb => fb.WithName("😓 " + Format.Bold(GetText("humidity"))).WithValue($"{data.Main.Humidity}%").WithIsInline(true))
.AddField(fb => fb.WithName("💨 " + Format.Bold(GetText("wind_speed"))).WithValue(data.Wind.Speed + " m/s").WithIsInline(true))
.AddField(fb => fb.WithName("🌡 " + Format.Bold(GetText("temperature"))).WithValue(data.Main.Temp + "°C").WithIsInline(true))
.AddField(fb => fb.WithName("🔆 " + Format.Bold(GetText("min_max"))).WithValue($"{data.Main.TempMin}°C - {data.Main.TempMax}°C").WithIsInline(true))
.AddField(fb => fb.WithName("🌄 " + Format.Bold(GetText("sunrise"))).WithValue($"{data.Sys.Sunrise.ToUnixTimestamp():HH:mm} UTC").WithIsInline(true))
.AddField(fb => fb.WithName("🌇 " + Format.Bold(GetText("sunset"))).WithValue($"{data.Sys.Sunset.ToUnixTimestamp():HH:mm} UTC").WithIsInline(true))
2016-12-22 06:29:24 +00:00
.WithOkColor()
2017-07-17 19:42:36 +00:00
.WithFooter(efb => efb.WithText("Powered by openweathermap.org").WithIconUrl($"http://openweathermap.org/img/w/{data.Weather[0].Icon}.png"));
2016-12-17 00:16:14 +00:00
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
public async Task Time([Remainder] string arg)
{
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(arg) || string.IsNullOrWhiteSpace(_creds.GoogleApiKey))
return;
var res = await _service.Http.GetStringAsync($"https://maps.googleapis.com/maps/api/geocode/json?address={arg}&key={_creds.GoogleApiKey}").ConfigureAwait(false);
var obj = JsonConvert.DeserializeObject<GeolocationResult>(res);
var currentSeconds = DateTime.UtcNow.UnixTimestamp();
var timeRes = await _service.Http.GetStringAsync($"https://maps.googleapis.com/maps/api/timezone/json?location={obj.results[0].Geometry.Location.Lat},{obj.results[0].Geometry.Location.Lng}&timestamp={currentSeconds}&key={_creds.GoogleApiKey}").ConfigureAwait(false);
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(timeRes);
var time = DateTime.UtcNow.AddSeconds(timeObj.DstOffset + timeObj.RawOffset);
await ReplyConfirmLocalized("time", Format.Bold(obj.results[0].FormattedAddress), Format.Code(time.ToString("HH:mm")), timeObj.TimeZoneName).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Youtube([Remainder] string query = null)
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
if (!await ValidateQuery(Context.Channel, query).ConfigureAwait(false)) return;
2017-06-13 12:21:24 +00:00
var result = (await _google.GetVideoLinksByKeywordAsync(query, 1)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(result))
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("no_results").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
return;
}
2016-12-17 00:16:14 +00:00
await Context.Channel.SendMessageAsync(result).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Imdb([Remainder] string query = null)
2016-08-15 23:38:28 +00:00
{
2016-12-17 00:16:14 +00:00
if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return;
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2016-10-15 21:11:45 +00:00
2017-05-27 08:19:27 +00:00
var movie = await OmdbProvider.FindMovie(query, _google);
2016-10-15 21:11:45 +00:00
if (movie == null)
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("imdb_fail").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
return;
}
2016-12-17 00:16:14 +00:00
await Context.Channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-16 18:43:57 +00:00
public async Task RandomCat()
2016-08-15 23:38:28 +00:00
{
var res = JObject.Parse(await _service.Http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false));
await Context.Channel.SendMessageAsync(Uri.EscapeUriString(res["file"].ToString())).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-16 18:43:57 +00:00
public async Task RandomDog()
2016-08-15 23:38:28 +00:00
{
await Context.Channel.SendMessageAsync("http://random.dog/" + await _service.Http.GetStringAsync("http://random.dog/woof")
.ConfigureAwait(false)).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2017-01-03 21:38:22 +00:00
public async Task Image([Remainder] string terms = null)
2016-08-15 23:38:28 +00:00
{
2017-01-03 21:38:22 +00:00
terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms))
2016-08-15 23:38:28 +00:00
return;
2017-01-03 21:38:22 +00:00
2017-01-25 02:19:43 +00:00
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
try
{
2017-05-27 08:19:27 +00:00
var res = await _google.GetImageAsync(terms).ConfigureAwait(false);
var embed = new EmbedBuilder()
.WithOkColor()
2017-02-24 16:10:44 +00:00
.WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch")
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithDescription(res.Link)
.WithImageUrl(res.Link)
2017-02-19 01:11:31 +00:00
.WithTitle(Context.User.ToString());
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
catch
{
_log.Warn("Falling back to Imgur search.");
2017-01-03 21:38:22 +00:00
var fullQueryLink = $"http://imgur.com/search?q={ terms }";
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
2017-01-03 21:38:22 +00:00
var elems = document.QuerySelectorAll("a.image-list-link");
2017-01-03 21:38:22 +00:00
if (!elems.Any())
return;
2017-01-03 21:38:22 +00:00
var img = (elems.FirstOrDefault()?.Children?.FirstOrDefault() as IHtmlImageElement);
2017-01-03 21:38:22 +00:00
if (img?.Source == null)
return;
2017-01-03 21:38:22 +00:00
var source = img.Source.Replace("b.", ".");
2017-01-03 21:38:22 +00:00
var embed = new EmbedBuilder()
.WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50))
.WithUrl(fullQueryLink)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithDescription(source)
.WithImageUrl(source)
2017-02-19 01:11:31 +00:00
.WithTitle(Context.User.ToString());
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2017-01-03 21:38:22 +00:00
public async Task RandomImage([Remainder] string terms = null)
2016-08-15 23:38:28 +00:00
{
2017-01-03 21:38:22 +00:00
terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms))
2016-08-15 23:38:28 +00:00
return;
2017-01-25 02:19:43 +00:00
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
try
{
2017-05-27 08:19:27 +00:00
var res = await _google.GetImageAsync(terms, new NadekoRandom().Next(0, 50)).ConfigureAwait(false);
var embed = new EmbedBuilder()
.WithOkColor()
2017-02-24 16:10:44 +00:00
.WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch")
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithDescription(res.Link)
.WithImageUrl(res.Link)
2017-02-19 01:11:31 +00:00
.WithTitle(Context.User.ToString());
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
catch
{
_log.Warn("Falling back to Imgur");
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
2017-01-03 21:38:22 +00:00
var fullQueryLink = $"http://imgur.com/search?q={ terms }";
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
2017-01-03 21:38:22 +00:00
var elems = document.QuerySelectorAll("a.image-list-link").ToList();
2017-01-03 21:38:22 +00:00
if (!elems.Any())
return;
2017-01-03 21:38:22 +00:00
var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement);
2017-01-03 21:38:22 +00:00
if (img?.Source == null)
return;
2017-01-03 21:38:22 +00:00
var source = img.Source.Replace("b.", ".");
2017-01-03 21:38:22 +00:00
var embed = new EmbedBuilder()
.WithOkColor()
2017-02-24 16:10:44 +00:00
.WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithDescription(source)
.WithImageUrl(source)
2017-02-19 01:11:31 +00:00
.WithTitle(Context.User.ToString());
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Lmgtfy([Remainder] string ffs = null)
2016-08-15 23:38:28 +00:00
{
if (string.IsNullOrWhiteSpace(ffs))
return;
2017-05-27 08:19:27 +00:00
await Context.Channel.SendConfirmAsync("<" + await _google.ShortenUrl($"http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }") + ">")
2016-08-15 23:38:28 +00:00
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-16 18:43:57 +00:00
public async Task Shorten([Remainder] string arg)
{
if (string.IsNullOrWhiteSpace(arg))
return;
2017-05-27 08:19:27 +00:00
var shortened = await _google.ShortenUrl(arg).ConfigureAwait(false);
if (shortened == arg)
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("shorten_fail").ConfigureAwait(false);
return;
}
await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
2017-02-24 16:10:44 +00:00
.AddField(efb => efb.WithName(GetText("original_url"))
.WithValue($"<{arg}>"))
2017-02-24 16:10:44 +00:00
.AddField(efb => efb.WithName(GetText("short_url"))
2016-12-16 18:43:57 +00:00
.WithValue($"<{shortened}>")))
2016-12-09 03:22:23 +00:00
.ConfigureAwait(false);
}
//private readonly Regex googleSearchRegex = new Regex(@"<h3 class=""r""><a href=""(?:\/url?q=)?(?<link>.*?)"".*?>(?<title>.*?)<\/a>.*?class=""st"">(?<text>.*?)<\/span>", RegexOptions.Compiled);
//private readonly Regex htmlReplace = new Regex(@"(?:<b>(.*?)<\/b>|<em>(.*?)<\/em>)", RegexOptions.Compiled);
2016-11-28 01:19:12 +00:00
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Google([Remainder] string terms = null)
2016-11-28 01:19:12 +00:00
{
terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms))
return;
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
var fullQueryLink = $"https://www.google.com/search?q={ terms }&gws_rd=cr,ssl";
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
var elems = document.QuerySelectorAll("div.g");
var resultsElem = document.QuerySelectorAll("#resultStats").FirstOrDefault();
var totalResults = resultsElem?.TextContent;
//var time = resultsElem.Children.FirstOrDefault()?.TextContent
//^ this doesn't work for some reason, <nobr> is completely missing in parsed collection
if (!elems.Any())
return;
var results = elems.Select<IElement, GoogleSearchResult?>(elem =>
{
2017-02-17 13:43:32 +00:00
var aTag = (elem.Children.FirstOrDefault()?.Children.FirstOrDefault() as IHtmlAnchorElement); // <h3> -> <a>
var href = aTag?.Href;
var name = aTag?.TextContent;
if (href == null || name == null)
return null;
var txt = elem.QuerySelectorAll(".st").FirstOrDefault()?.TextContent;
if (txt == null)
return null;
return new GoogleSearchResult(name, href, txt);
}).Where(x => x != null).Take(5);
var embed = new EmbedBuilder()
.WithOkColor()
2017-02-24 16:10:44 +00:00
.WithAuthor(eab => eab.WithName(GetText("search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink)
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
2017-02-17 13:43:32 +00:00
.WithTitle(Context.User.ToString())
.WithFooter(efb => efb.WithText(totalResults));
2016-12-28 17:30:08 +00:00
var desc = await Task.WhenAll(results.Select(async res =>
2017-05-27 08:19:27 +00:00
$"[{Format.Bold(res?.Title)}]({(await _google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n"))
2016-12-28 17:30:08 +00:00
.ConfigureAwait(false);
2017-02-24 16:10:44 +00:00
await Context.Channel.EmbedAsync(embed.WithDescription(string.Concat(desc))).ConfigureAwait(false);
2016-11-28 01:19:12 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2017-02-24 16:10:44 +00:00
public async Task MagicTheGathering([Remainder] string name)
2016-11-27 17:00:37 +00:00
{
var arg = name;
if (string.IsNullOrWhiteSpace(arg))
return;
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2016-11-27 17:00:37 +00:00
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
2017-02-24 16:10:44 +00:00
var response = await http.GetStringAsync($"https://api.deckbrew.com/mtg/cards?name={Uri.EscapeUriString(arg)}")
.ConfigureAwait(false);
2016-11-27 17:00:37 +00:00
try
{
2017-01-29 21:54:27 +00:00
var items = JArray.Parse(response).ToArray();
if (items == null || items.Length == 0)
2016-11-27 17:00:37 +00:00
throw new KeyNotFoundException("Cannot find a card by that name");
2017-01-29 21:54:27 +00:00
var item = items[new NadekoRandom().Next(0, items.Length)];
2017-05-27 08:19:27 +00:00
var storeUrl = await _google.ShortenUrl(item["store_url"].ToString());
var cost = item["cost"].ToString();
var desc = item["text"].ToString();
2017-02-24 16:10:44 +00:00
var types = string.Join(",\n", item["types"].ToObject<string[]>());
var img = item["editions"][0]["image_url"].ToString();
var embed = new EmbedBuilder().WithOkColor()
.WithTitle(item["name"].ToString())
.WithDescription(desc)
2016-12-16 18:43:57 +00:00
.WithImageUrl(img)
2017-02-24 16:10:44 +00:00
.AddField(efb => efb.WithName(GetText("store_url")).WithValue(storeUrl).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("cost")).WithValue(cost).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("types")).WithValue(types).WithIsInline(true));
2017-05-27 08:19:27 +00:00
//.AddField(efb => efb.WithName("Store Url").WithValue(await _google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true));
2016-12-17 00:16:14 +00:00
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
2016-11-27 17:00:37 +00:00
}
catch
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("card_not_found").ConfigureAwait(false);
2016-11-27 17:00:37 +00:00
}
}
}
[NadekoCommand, Usage, Description, Aliases]
2017-02-24 16:10:44 +00:00
public async Task Hearthstone([Remainder] string name)
{
var arg = name;
if (string.IsNullOrWhiteSpace(arg))
return;
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(_creds.MashapeKey))
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return;
}
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
2017-05-27 08:19:27 +00:00
http.DefaultRequestHeaders.Add("X-Mashape-Key", _creds.MashapeKey);
2017-02-24 16:10:44 +00:00
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}")
.ConfigureAwait(false);
try
{
var items = JArray.Parse(response).Shuffle().ToList();
2017-07-18 16:26:55 +00:00
var images = new List<Image<Rgba32>>();
if (items == null)
throw new KeyNotFoundException("Cannot find a card by that name");
foreach (var item in items.Where(item => item.HasValues && item["img"] != null).Take(4))
{
2017-01-29 21:54:27 +00:00
await Task.Run(async () =>
{
2017-01-29 21:54:27 +00:00
using (var sr = await http.GetStreamAsync(item["img"].ToString()))
{
var imgStream = new MemoryStream();
await sr.CopyToAsync(imgStream);
imgStream.Position = 0;
2017-07-18 16:26:55 +00:00
images.Add(ImageSharp.Image.Load(imgStream));
2017-01-29 21:54:27 +00:00
}
}).ConfigureAwait(false);
}
string msg = null;
if (items.Count > 4)
{
2017-02-24 16:10:44 +00:00
msg = GetText("hs_over_x", 4);
}
var ms = new MemoryStream();
2017-07-18 16:26:55 +00:00
await Task.Run(() => images.AsEnumerable().Merge().SaveAsPng(ms));
ms.Position = 0;
2016-12-17 00:16:14 +00:00
await Context.Channel.SendFileAsync(ms, arg + ".png", msg).ConfigureAwait(false);
}
catch (Exception ex)
{
_log.Error(ex);
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("error_occured").ConfigureAwait(false);
}
}
}
2016-08-15 23:38:28 +00:00
2016-12-03 01:25:42 +00:00
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Yodify([Remainder] string query = null)
2016-12-03 01:25:42 +00:00
{
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(_creds.MashapeKey))
2016-12-03 01:25:42 +00:00
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
2016-12-03 01:25:42 +00:00
return;
}
2017-02-24 16:10:44 +00:00
if (string.IsNullOrWhiteSpace(query))
2016-12-03 01:25:42 +00:00
return;
2017-02-24 16:10:44 +00:00
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2016-12-03 01:25:42 +00:00
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
2017-05-27 08:19:27 +00:00
http.DefaultRequestHeaders.Add("X-Mashape-Key", _creds.MashapeKey);
2016-12-03 01:25:42 +00:00
http.DefaultRequestHeaders.Add("Accept", "text/plain");
2017-02-24 16:10:44 +00:00
var res = await http.GetStringAsync($"https://yoda.p.mashape.com/yoda?sentence={Uri.EscapeUriString(query)}").ConfigureAwait(false);
2016-12-03 01:25:42 +00:00
try
{
var embed = new EmbedBuilder()
.WithUrl("http://www.yodaspeak.co.uk/")
.WithAuthor(au => au.WithName("Yoda").WithIconUrl("http://www.yodaspeak.co.uk/yoda-small1.gif"))
.WithDescription(res)
.WithOkColor();
2016-12-17 00:16:14 +00:00
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
2016-12-03 01:25:42 +00:00
}
catch
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("yodify_error").ConfigureAwait(false);
2016-12-03 01:25:42 +00:00
}
}
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task UrbanDict([Remainder] string query = null)
2016-08-15 23:38:28 +00:00
{
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(_creds.MashapeKey))
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return;
}
2017-02-24 16:10:44 +00:00
if (string.IsNullOrWhiteSpace(query))
2016-08-15 23:38:28 +00:00
return;
2017-02-24 16:10:44 +00:00
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("Accept", "application/json");
2017-02-24 16:10:44 +00:00
var res = await http.GetStringAsync($"http://api.urbandictionary.com/v0/define?term={Uri.EscapeUriString(query)}").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
try
{
var items = JObject.Parse(res);
var item = items["list"][0];
var word = item["word"].ToString();
var def = item["definition"].ToString();
var link = item["permalink"].ToString();
var embed = new EmbedBuilder().WithOkColor()
.WithUrl(link)
.WithAuthor(eab => eab.WithIconUrl("http://i.imgur.com/nwERwQE.jpg").WithName(word))
.WithDescription(def);
2016-12-17 00:16:14 +00:00
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
catch
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("ud_error").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
}
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-31 10:55:12 +00:00
public async Task Define([Remainder] string word)
2016-12-25 16:46:36 +00:00
{
if (string.IsNullOrWhiteSpace(word))
return;
var res = await _service.Http.GetStringAsync("http://api.pearson.com/v2/dictionaries/entries?headword=" + WebUtility.UrlEncode(word.Trim())).ConfigureAwait(false);
2016-12-25 16:46:36 +00:00
var data = JsonConvert.DeserializeObject<DefineModel>(res);
2016-12-25 16:46:36 +00:00
var sense = data.Results.FirstOrDefault(x => x.Senses?[0].Definition != null)?.Senses[0];
2016-12-25 16:46:36 +00:00
if (sense?.Definition == null)
{
await ReplyErrorLocalized("define_unknown").ConfigureAwait(false);
return;
}
2016-12-25 16:46:36 +00:00
var definition = sense.Definition.ToString();
if (!(sense.Definition is string))
definition = ((JArray)JToken.Parse(sense.Definition.ToString())).First.ToString();
2016-12-25 16:46:36 +00:00
var embed = new EmbedBuilder().WithOkColor()
.WithTitle(GetText("define") + " " + word)
.WithDescription(definition)
.WithFooter(efb => efb.WithText(sense.Gramatical_info?.type));
2016-12-25 16:46:36 +00:00
if (sense.Examples != null)
embed.AddField(efb => efb.WithName(GetText("example")).WithValue(sense.Examples.First().text));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
2016-12-25 16:46:36 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2017-02-24 16:10:44 +00:00
public async Task Hashtag([Remainder] string query)
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
if (string.IsNullOrWhiteSpace(query))
return;
2017-02-24 16:10:44 +00:00
2017-05-27 08:19:27 +00:00
if (string.IsNullOrWhiteSpace(_creds.MashapeKey))
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
return;
}
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2017-02-24 16:10:44 +00:00
string res;
2016-08-15 23:38:28 +00:00
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
2017-05-27 08:19:27 +00:00
http.DefaultRequestHeaders.Add("X-Mashape-Key", _creds.MashapeKey);
2017-02-24 16:10:44 +00:00
res = await http.GetStringAsync($"https://tagdef.p.mashape.com/one.{Uri.EscapeUriString(query)}.json").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
2016-08-16 14:53:38 +00:00
2016-08-15 23:38:28 +00:00
try
{
var items = JObject.Parse(res);
var item = items["defs"]["def"];
2017-02-14 13:30:21 +00:00
//var hashtag = item["hashtag"].ToString();
var link = item["uri"].ToString();
var desc = item["text"].ToString();
2016-12-31 10:55:12 +00:00
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithAuthor(eab => eab.WithUrl(link)
.WithIconUrl("http://res.cloudinary.com/urbandictionary/image/upload/a_exif,c_fit,h_200,w_200/v1394975045/b8oszuu3tbq7ebyo7vo1.jpg")
.WithName(query))
.WithDescription(desc))
.ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
catch
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("hashtag_error").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-16 18:43:57 +00:00
public async Task Catfact()
2016-08-15 23:38:28 +00:00
{
var response = await _service.Http.GetStringAsync("https://catfact.ninja/fact").ConfigureAwait(false);
if (response == null)
return;
var fact = JObject.Parse(response)["fact"].ToString();
await Context.Channel.SendConfirmAsync("🐈" + GetText("catfact"), fact).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2017-04-25 02:27:58 +00:00
[RequireContext(ContextType.Guild)]
public async Task Revav([Remainder] IGuildUser usr = null)
2016-08-15 23:38:28 +00:00
{
2016-10-19 10:59:17 +00:00
if (usr == null)
2017-04-25 02:27:58 +00:00
usr = (IGuildUser)Context.User;
await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.RealAvatarUrl()}").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Revimg([Remainder] string imageLink = null)
2016-08-15 23:38:28 +00:00
{
imageLink = imageLink?.Trim() ?? "";
if (string.IsNullOrWhiteSpace(imageLink))
return;
2016-12-17 00:16:14 +00:00
await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
[NadekoCommand, Usage, Description, Aliases]
public Task Safebooru([Remainder] string tag = null)
2017-01-01 12:28:35 +00:00
=> InternalDapiCommand(Context.Message, tag, DapiSearchType.Safebooru);
2016-08-15 23:38:28 +00:00
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Wiki([Remainder] string query = null)
2016-08-15 23:38:28 +00:00
{
query = query?.Trim();
if (string.IsNullOrWhiteSpace(query))
return;
using (var http = new HttpClient())
{
var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query));
var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
if (data.Query.Pages[0].Missing)
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("wiki_page_not_found").ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
else
await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
}
[NadekoCommand, Usage, Description, Aliases]
2016-12-17 00:16:14 +00:00
public async Task Color([Remainder] string color = null)
2016-09-14 12:34:10 +00:00
{
color = color?.Trim().Replace("#", "");
2017-01-05 12:49:50 +00:00
if (string.IsNullOrWhiteSpace(color))
2016-09-14 12:34:10 +00:00
return;
2017-07-18 16:26:55 +00:00
Rgba32 clr;
2017-06-15 18:04:15 +00:00
try
{
2017-07-18 16:26:55 +00:00
clr = Rgba32.FromHex(color);
2017-06-15 18:04:15 +00:00
}
catch
{
await ReplyErrorLocalized("hex_invalid").ConfigureAwait(false);
return;
}
2017-07-18 16:26:55 +00:00
var img = new ImageSharp.Image<Rgba32>(50, 50);
2016-09-14 12:34:10 +00:00
2017-06-15 18:04:15 +00:00
img.BackgroundColor(clr);
2016-09-14 12:34:10 +00:00
2017-02-24 16:10:44 +00:00
await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png").ConfigureAwait(false);
2016-09-14 12:34:10 +00:00
}
2016-08-15 23:38:28 +00:00
[NadekoCommand, Usage, Description, Aliases]
2017-04-25 02:27:58 +00:00
[RequireContext(ContextType.Guild)]
public async Task Videocall(params IGuildUser[] users)
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
var allUsrs = users.Append(Context.User);
var allUsrsArray = allUsrs.ToArray();
var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString()));
str += new NadekoRandom().Next();
foreach (var usr in allUsrsArray)
2016-08-15 23:38:28 +00:00
{
2017-07-05 15:38:38 +00:00
await (await usr.GetOrCreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
}
[NadekoCommand, Usage, Description, Aliases]
2017-04-25 04:53:03 +00:00
[RequireContext(ContextType.Guild)]
public async Task Avatar([Remainder] IGuildUser usr = null)
2016-08-15 23:38:28 +00:00
{
if (usr == null)
2017-04-25 04:53:03 +00:00
usr = (IGuildUser)Context.User;
2016-08-15 23:38:28 +00:00
var avatarUrl = usr.RealAvatarUrl();
2017-05-27 08:19:27 +00:00
var shortenedAvatarUrl = await _google.ShortenUrl(avatarUrl).ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.AddField(efb => efb.WithName("Username").WithValue(usr.ToString()).WithIsInline(false))
.AddField(efb => efb.WithName("Avatar Url").WithValue(shortenedAvatarUrl).WithIsInline(false))
.WithThumbnailUrl(avatarUrl), Context.User.Mention).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
}
2016-11-06 22:58:04 +00:00
[NadekoCommand, Usage, Description, Aliases]
2017-02-24 16:10:44 +00:00
public async Task Wikia(string target, [Remainder] string query)
2016-11-06 22:58:04 +00:00
{
2016-11-09 16:59:44 +00:00
if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query))
2016-11-06 22:58:04 +00:00
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("wikia_input_error").ConfigureAwait(false);
2016-11-06 22:58:04 +00:00
return;
}
2016-12-16 18:43:57 +00:00
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
2016-11-06 22:58:04 +00:00
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
2016-11-09 18:28:26 +00:00
try
2016-11-06 22:58:04 +00:00
{
2016-11-09 18:28:26 +00:00
var res = await http.GetStringAsync($"http://www.{Uri.EscapeUriString(target)}.wikia.com/api/v1/Search/List?query={Uri.EscapeUriString(query)}&limit=25&minArticleQuality=10&batch=1&namespaces=0%2C14").ConfigureAwait(false);
2016-11-06 22:58:04 +00:00
var items = JObject.Parse(res);
2016-11-09 18:28:26 +00:00
var found = items["items"][0];
2017-02-24 16:10:44 +00:00
var response = $@"`{GetText("title")}` {found["title"]}
`{GetText("quality")}` {found["quality"]}
2017-05-27 08:19:27 +00:00
`{GetText("url")}:` {await _google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
await Context.Channel.SendMessageAsync(response).ConfigureAwait(false);
2016-11-06 22:58:04 +00:00
}
catch
{
2017-02-24 16:10:44 +00:00
await ReplyErrorLocalized("wikia_error").ConfigureAwait(false);
2016-11-06 22:58:04 +00:00
}
}
}
2016-08-15 23:38:28 +00:00
2017-02-24 16:10:44 +00:00
//[NadekoCommand, Usage, Description, Aliases]
//public async Task MCPing([Remainder] string query2 = null)
//{
// var query = query2;
// if (string.IsNullOrWhiteSpace(query))
// return;
// await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
// using (var http = new HttpClient())
// {
// http.DefaultRequestHeaders.Clear();
// var ip = query.Split(':')[0];
// var port = query.Split(':')[1];
// var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
// try
// {
// var items = JObject.Parse(res);
// var sb = new StringBuilder();
// var ping = (int)Math.Ceiling(double.Parse(items["latency"].ToString()));
// sb.AppendLine($"`Server:` {query}");
// sb.AppendLine($"`Version:` {items["version"]["name"]} / Protocol {items["version"]["protocol"]}");
// sb.AppendLine($"`Description:` {items["description"]}");
// sb.AppendLine($"`Online Players:` {items["players"]["online"]}/{items["players"]["max"]}");
// sb.Append($"`Latency:` {ping}");
// await Context.Channel.SendMessageAsync(sb.ToString());
// }
// catch
// {
// await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
// }
// }
//}
//[NadekoCommand, Usage, Description, Aliases]
//public async Task MCQ([Remainder] string query = null)
//{
// var arg = query;
// if (string.IsNullOrWhiteSpace(arg))
// {
// await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
// return;
// }
// await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
// using (var http = new HttpClient())
// {
// http.DefaultRequestHeaders.Clear();
// try
// {
// var ip = arg.Split(':')[0];
// var port = arg.Split(':')[1];
// var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
// var items = JObject.Parse(res);
// var sb = new StringBuilder();
// sb.AppendLine($"`Server:` {arg} 〘Status: {items["status"]}〙");
// sb.AppendLine("`Player List (First 5):`");
// foreach (var item in items["Playerlist"].Take(5))
// {
// sb.AppendLine($":rosette: {item}");
// }
// sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
// sb.AppendLine($"`Plugins:` {items["Plugins"]}");
// sb.Append($"`Version:` {items["Version"]}");
// await Context.Channel.SendMessageAsync(sb.ToString());
// }
// catch
// {
// await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
// }
// }
//}
2016-08-15 23:38:28 +00:00
2017-02-24 16:10:44 +00:00
public async Task InternalDapiCommand(IUserMessage umsg, string tag, DapiSearchType type)
{
var channel = umsg.Channel;
tag = tag?.Trim() ?? "";
2017-07-17 02:37:51 +00:00
var imgObj = await _service.DapiSearch(tag, type, Context.Guild?.Id).ConfigureAwait(false);
if (imgObj == null)
2017-02-24 16:10:44 +00:00
await channel.SendErrorAsync(umsg.Author.Mention + " " + GetText("no_results"));
else
await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithDescription($"{umsg.Author.Mention} [{tag ?? "url"}]({imgObj.FileUrl})")
.WithImageUrl(imgObj.FileUrl)
.WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false);
}
2017-02-24 16:10:44 +00:00
public async Task<bool> ValidateQuery(IMessageChannel ch, string query)
2016-08-15 23:38:28 +00:00
{
2017-02-24 16:10:44 +00:00
if (!string.IsNullOrWhiteSpace(query)) return true;
await ch.SendErrorAsync(GetText("specify_search_params")).ConfigureAwait(false);
2016-08-15 23:38:28 +00:00
return false;
}
}
}