img and rimg will use google images first. if it fails, then fallback to imgur closes #970

This commit is contained in:
Kwoth 2017-01-24 18:30:21 +01:00
parent c34338458c
commit c898027952
2 changed files with 113 additions and 44 deletions

View File

@ -115,33 +115,50 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(terms)) if (string.IsNullOrWhiteSpace(terms))
return; return;
terms = WebUtility.UrlEncode(terms).Replace(' ', '+'); try
{
var res = await NadekoBot.Google.GetImageAsync(terms).ConfigureAwait(false);
var embed = new EmbedBuilder()
.WithOkColor()
.WithAuthor(eab => eab.WithName("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)
.WithTitle(Context.User.Mention);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
catch
{
_log.Warn("Falling back to Imgur search.");
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
var fullQueryLink = $"http://imgur.com/search?q={ terms }"; var fullQueryLink = $"http://imgur.com/search?q={ terms }";
var config = Configuration.Default.WithDefaultLoader(); var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink); var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
var elems = document.QuerySelectorAll("a.image-list-link"); var elems = document.QuerySelectorAll("a.image-list-link");
if (!elems.Any()) if (!elems.Any())
return; return;
var img = (elems.FirstOrDefault()?.Children?.FirstOrDefault() as IHtmlImageElement); var img = (elems.FirstOrDefault()?.Children?.FirstOrDefault() as IHtmlImageElement);
if (img?.Source == null) if (img?.Source == null)
return; return;
var source = img.Source.Replace("b.", "."); var source = img.Source.Replace("b.", ".");
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50)) .WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50))
.WithUrl(fullQueryLink) .WithUrl(fullQueryLink)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?")) .WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithDescription(source) .WithDescription(source)
.WithImageUrl(source) .WithImageUrl(source)
.WithTitle(Context.User.Mention); .WithTitle(Context.User.Mention);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -150,34 +167,50 @@ namespace NadekoBot.Modules.Searches
terms = terms?.Trim(); terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms)) if (string.IsNullOrWhiteSpace(terms))
return; return;
try
{
var res = await NadekoBot.Google.GetImageAsync(terms, new NadekoRandom().Next(0, 50)).ConfigureAwait(false);
var embed = new EmbedBuilder()
.WithOkColor()
.WithAuthor(eab => eab.WithName("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)
.WithTitle(Context.User.Mention);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
catch
{
_log.Warn("Falling back to Imgur");
terms = WebUtility.UrlEncode(terms).Replace(' ', '+');
terms = WebUtility.UrlEncode(terms).Replace(' ', '+'); var fullQueryLink = $"http://imgur.com/search?q={ terms }";
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
var fullQueryLink = $"http://imgur.com/search?q={ terms }"; var elems = document.QuerySelectorAll("a.image-list-link").ToList();
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
var elems = document.QuerySelectorAll("a.image-list-link").ToList(); if (!elems.Any())
return;
if (!elems.Any()) var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement);
return;
var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement); if (img?.Source == null)
return;
if (img?.Source == null) var source = img.Source.Replace("b.", ".");
return;
var source = img.Source.Replace("b.", "."); var embed = new EmbedBuilder()
.WithOkColor()
var embed = new EmbedBuilder() .WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50))
.WithOkColor() .WithUrl(fullQueryLink)
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50)) .WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithUrl(fullQueryLink) .WithDescription(source)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?")) .WithImageUrl(source)
.WithDescription(source) .WithTitle(Context.User.Mention);
.WithImageUrl(source) await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
.WithTitle(Context.User.Mention); }
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -8,13 +8,19 @@ using System.Text.RegularExpressions;
using Google.Apis.Urlshortener.v1; using Google.Apis.Urlshortener.v1;
using Google.Apis.Urlshortener.v1.Data; using Google.Apis.Urlshortener.v1.Data;
using NLog; using NLog;
using Google.Apis.Customsearch.v1;
using Google.Apis.Customsearch.v1.Data;
namespace NadekoBot.Services.Impl namespace NadekoBot.Services.Impl
{ {
public class GoogleApiService : IGoogleApiService public class GoogleApiService : IGoogleApiService
{ {
const string search_engine_id = "018084019232060951019:hs5piey28-e";
private YouTubeService yt; private YouTubeService yt;
private UrlshortenerService sh; private UrlshortenerService sh;
private CustomsearchService cs;
private Logger _log { get; } private Logger _log { get; }
public GoogleApiService() public GoogleApiService()
@ -22,13 +28,14 @@ namespace NadekoBot.Services.Impl
var bcs = new BaseClientService.Initializer var bcs = new BaseClientService.Initializer
{ {
ApplicationName = "Nadeko Bot", ApplicationName = "Nadeko Bot",
ApiKey = NadekoBot.Credentials.GoogleApiKey ApiKey = NadekoBot.Credentials.GoogleApiKey,
}; };
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
yt = new YouTubeService(bcs); yt = new YouTubeService(bcs);
sh = new UrlshortenerService(bcs); sh = new UrlshortenerService(bcs);
cs = new CustomsearchService(bcs);
} }
public async Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1) public async Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1)
{ {
@ -150,7 +157,7 @@ namespace NadekoBot.Services.Impl
return toReturn; return toReturn;
} }
//todo AsyncEnumerable //todo AsyncEnumerable
public async Task<IReadOnlyDictionary<string,TimeSpan>> GetVideoDurationsAsync(IEnumerable<string> videoIds) public async Task<IReadOnlyDictionary<string, TimeSpan>> GetVideoDurationsAsync(IEnumerable<string> videoIds)
{ {
var videoIdsList = videoIds as List<string> ?? videoIds.ToList(); var videoIdsList = videoIds as List<string> ?? videoIds.ToList();
@ -179,5 +186,34 @@ namespace NadekoBot.Services.Impl
return toReturn; return toReturn;
} }
public struct ImageResult
{
public Result.ImageData Image { get; }
public string Link { get; }
public ImageResult(Result.ImageData image, string link)
{
this.Image = image;
this.Link = link;
}
}
public async Task<ImageResult> GetImageAsync(string query, int start = 0)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
var req = cs.Cse.List(query);
req.Cx = search_engine_id;
req.Num = 1;
req.Fields = "items(image(contextLink,thumbnailLink),link)";
req.SearchType = CseResource.ListRequest.SearchTypeEnum.Image;
req.Start = start;
var search = await req.ExecuteAsync().ConfigureAwait(false);
return new ImageResult(search.Items[0].Image, search.Items[0].Link);
}
} }
} }