img and rimg will use google images first. if it fails, then fallback to imgur closes #970
This commit is contained in:
		@@ -115,33 +115,50 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(terms))
 | 
			
		||||
                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 config = Configuration.Default.WithDefaultLoader();
 | 
			
		||||
            var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
 | 
			
		||||
                var fullQueryLink = $"http://imgur.com/search?q={ terms }";
 | 
			
		||||
                var config = Configuration.Default.WithDefaultLoader();
 | 
			
		||||
                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())
 | 
			
		||||
                return;
 | 
			
		||||
                if (!elems.Any())
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
            var img = (elems.FirstOrDefault()?.Children?.FirstOrDefault() as IHtmlImageElement);
 | 
			
		||||
                var img = (elems.FirstOrDefault()?.Children?.FirstOrDefault() as IHtmlImageElement);
 | 
			
		||||
 | 
			
		||||
            if (img?.Source == null)
 | 
			
		||||
                return;
 | 
			
		||||
                if (img?.Source == null)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
            var source = img.Source.Replace("b.", ".");
 | 
			
		||||
                var source = img.Source.Replace("b.", ".");
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
                .WithTitle(Context.User.Mention);
 | 
			
		||||
            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                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)
 | 
			
		||||
                    .WithTitle(Context.User.Mention);
 | 
			
		||||
                await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -150,34 +167,50 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            terms = terms?.Trim();
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(terms))
 | 
			
		||||
                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 config = Configuration.Default.WithDefaultLoader();
 | 
			
		||||
            var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);
 | 
			
		||||
                var elems = document.QuerySelectorAll("a.image-list-link").ToList();
 | 
			
		||||
 | 
			
		||||
            var elems = document.QuerySelectorAll("a.image-list-link").ToList();
 | 
			
		||||
                if (!elems.Any())
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
            if (!elems.Any())
 | 
			
		||||
                return;
 | 
			
		||||
                var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement);
 | 
			
		||||
 | 
			
		||||
            var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement);
 | 
			
		||||
                if (img?.Source == null)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
            if (img?.Source == null)
 | 
			
		||||
                return;
 | 
			
		||||
                var source = img.Source.Replace("b.", ".");
 | 
			
		||||
 | 
			
		||||
            var source = img.Source.Replace("b.", ".");
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
                .WithTitle(Context.User.Mention);
 | 
			
		||||
            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                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)
 | 
			
		||||
                    .WithTitle(Context.User.Mention);
 | 
			
		||||
                await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -260,7 +293,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                .WithTitle(Context.User.Mention)
 | 
			
		||||
                .WithFooter(efb => efb.WithText(totalResults));
 | 
			
		||||
 | 
			
		||||
            var desc = await Task.WhenAll(results.Select(async res => 
 | 
			
		||||
            var desc = await Task.WhenAll(results.Select(async res =>
 | 
			
		||||
                    $"[{Format.Bold(res?.Title)}]({(await NadekoBot.Google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n"))
 | 
			
		||||
                .ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.EmbedAsync(embed.WithDescription(String.Concat(desc))).ConfigureAwait(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,19 @@ using System.Text.RegularExpressions;
 | 
			
		||||
using Google.Apis.Urlshortener.v1;
 | 
			
		||||
using Google.Apis.Urlshortener.v1.Data;
 | 
			
		||||
using NLog;
 | 
			
		||||
using Google.Apis.Customsearch.v1;
 | 
			
		||||
using Google.Apis.Customsearch.v1.Data;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Impl
 | 
			
		||||
{
 | 
			
		||||
    public class GoogleApiService : IGoogleApiService
 | 
			
		||||
    {
 | 
			
		||||
        const string search_engine_id = "018084019232060951019:hs5piey28-e";
 | 
			
		||||
 | 
			
		||||
        private YouTubeService yt;
 | 
			
		||||
        private UrlshortenerService sh;
 | 
			
		||||
        private CustomsearchService cs;
 | 
			
		||||
        
 | 
			
		||||
        private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
        public GoogleApiService()
 | 
			
		||||
@@ -22,13 +28,14 @@ namespace NadekoBot.Services.Impl
 | 
			
		||||
            var bcs = new BaseClientService.Initializer
 | 
			
		||||
            {
 | 
			
		||||
                ApplicationName = "Nadeko Bot",
 | 
			
		||||
                ApiKey = NadekoBot.Credentials.GoogleApiKey
 | 
			
		||||
                ApiKey = NadekoBot.Credentials.GoogleApiKey,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
 | 
			
		||||
            yt = new YouTubeService(bcs);
 | 
			
		||||
            sh = new UrlshortenerService(bcs);
 | 
			
		||||
            cs = new CustomsearchService(bcs);
 | 
			
		||||
        }
 | 
			
		||||
        public async Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1)
 | 
			
		||||
        {
 | 
			
		||||
@@ -150,7 +157,7 @@ namespace NadekoBot.Services.Impl
 | 
			
		||||
            return toReturn;
 | 
			
		||||
        }
 | 
			
		||||
        //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();
 | 
			
		||||
 | 
			
		||||
@@ -179,5 +186,34 @@ namespace NadekoBot.Services.Impl
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user