using AngleSharp;
using AngleSharp.Html.Dom;
using NadekoBot.Core.Services;
using NadekoBot.Modules.Searches.Common;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Serilog;
namespace NadekoBot.Modules.Searches.Services
{
public class AnimeSearchService : INService
{
private readonly IDataCache _cache;
private readonly IHttpClientFactory _httpFactory;
public AnimeSearchService(IDataCache cache, IHttpClientFactory httpFactory)
{
_cache = cache;
_httpFactory = httpFactory;
}
public async Task GetAnimeData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
var link = "https://aniapi.nadeko.bot/anime/" + Uri.EscapeDataString(query.Replace("/", " ", StringComparison.InvariantCulture));
link = link.ToLowerInvariant();
var (ok, data) = await _cache.TryGetAnimeDataAsync(link).ConfigureAwait(false);
if (!ok)
{
using (var http = _httpFactory.CreateClient())
{
data = await http.GetStringAsync(link).ConfigureAwait(false);
}
await _cache.SetAnimeDataAsync(link, data).ConfigureAwait(false);
}
return JsonConvert.DeserializeObject(data);
}
catch
{
return null;
}
}
public async Task GetNovelData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
query = query.Replace(" ", "-", StringComparison.InvariantCulture);
try
{
var link = "http://www.novelupdates.com/series/" + Uri.EscapeDataString(query.Replace("/", " ", StringComparison.InvariantCulture));
link = link.ToLowerInvariant();
var (ok, data) = await _cache.TryGetNovelDataAsync(link).ConfigureAwait(false);
if (!ok)
{
var config = Configuration.Default.WithDefaultLoader();
using (var document = await BrowsingContext.New(config).OpenAsync(link).ConfigureAwait(false))
{
var imageElem = document.QuerySelector("div.seriesimg > img");
if (imageElem == null)
return null;
var imageUrl = ((IHtmlImageElement)imageElem).Source;
var descElem = document.QuerySelector("div#editdescription > p");
var desc = descElem.InnerHtml;
var genres = document.QuerySelector("div#seriesgenre").Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var authors = document
.QuerySelector("div#showauthors")
.Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var score = ((IHtmlSpanElement)document
.QuerySelector("h5.seriesother > span.uvotes"))
.InnerHtml;
var status = document
.QuerySelector("div#editstatus")
.InnerHtml;
var title = document
.QuerySelector("div.w-blog-content > div.seriestitlenu")
.InnerHtml;
var obj = new NovelResult()
{
Description = desc,
Authors = authors,
Genres = genres,
ImageUrl = imageUrl,
Link = link,
Score = score,
Status = status,
Title = title,
};
await _cache.SetNovelDataAsync(link,
JsonConvert.SerializeObject(obj)).ConfigureAwait(false);
return obj;
}
}
return JsonConvert.DeserializeObject(data);
}
catch (Exception ex)
{
Log.Error(ex, "Error getting novel data");
return null;
}
}
public async Task GetMangaData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
var link = "https://aniapi.nadeko.bot/manga/" + Uri.EscapeDataString(query.Replace("/", " ", StringComparison.InvariantCulture));
link = link.ToLowerInvariant();
var (ok, data) = await _cache.TryGetAnimeDataAsync(link).ConfigureAwait(false);
if (!ok)
{
using (var http = _httpFactory.CreateClient())
{
data = await http.GetStringAsync(link).ConfigureAwait(false);
}
await _cache.SetAnimeDataAsync(link, data).ConfigureAwait(false);
}
return JsonConvert.DeserializeObject(data);
}
catch
{
return null;
}
}
}
}