Update to AniList APIv2

+ Fixing some wrong results
+ (Beta)Added AniList Person infos
This commit is contained in:
DaniGTA 2018-02-10 21:32:32 +01:00
parent 46fc37da05
commit 57f5de0251
10 changed files with 676 additions and 405 deletions

View File

@ -1,110 +0,0 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
public class AniListApiClient
{
public static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1);
public class AccessToken
{
public string access_token { get; set; }
public int expires_in { get; set; }
}
private const string ApiUrl = "https://anilist.co/api";
private const string ClientId = "aphid-zmljg";
private const string ClientSecret = "M37YedMnMm9DQ2D9pLoEeqM2Ul";
private static readonly string RequestTokenUrl = $"{ApiUrl}/auth/access_token?grant_type=client_credentials&client_id={ClientId}&client_secret={ClientSecret}";
private static readonly string AnimeUrlFormat = $"{ApiUrl}/anime/{{0}}";
private static readonly string SearchUrlFormat = $"{ApiUrl}/anime/search/{{0}}";
private readonly IHttpClient _http;
private readonly ILogger _log;
private static string _accessToken;
private static DateTime _accessTokenExpires;
private IJsonSerializer _jsonSerializer;
public AniListApiClient(IHttpClient http, ILogManager logManager, IJsonSerializer jsonSerializer)
{
_http = http;
_jsonSerializer = jsonSerializer;
_log = logManager.GetLogger("AniList");
}
public Task<Anime> GetAnime(string id)
{
return Get<Anime>(string.Format(AnimeUrlFormat, id));
}
public Task<Anime[]> Search(string anime)
{
return Get<Anime[]>(string.Format(SearchUrlFormat, Uri.EscapeDataString(anime)));
}
private async Task<T> Get<T>(string url, int attemptsRemaining = 2)
{
if (DateTime.Now > _accessTokenExpires)
await RefreshAccessToken().ConfigureAwait(false);
try
{
var json = "";
string urlWithToken = url;
if (url.Contains("?"))
urlWithToken += $"&access_token={_accessToken}";
else
urlWithToken += $"?access_token={_accessToken}";
var _webRequest = WebRequest.Create(@"" + Uri.EscapeUriString(urlWithToken));
using (var _response = _webRequest.GetResponse())
using (var _content = _response.GetResponseStream())
using (var _reader = new StreamReader(_content))
{
json = _reader.ReadToEnd().Trim();
}
return _jsonSerializer.DeserializeFromString<T>(json);
}
catch
{
if (attemptsRemaining <= 1)
throw;
attemptsRemaining--;
await RefreshAccessToken().ConfigureAwait(false);
return await Get<T>(url, attemptsRemaining).ConfigureAwait(false);
}
}
private async Task RefreshAccessToken()
{
try
{
var options = new HttpRequestOptions
{
Url = RequestTokenUrl
};
using (var response = await _http.Post(options).ConfigureAwait(false))
{
var credentials = _jsonSerializer.DeserializeFromStream<AccessToken>(response.Content);
_accessToken = credentials.access_token;
_accessTokenExpires = DateTime.Now + TimeSpan.FromSeconds(credentials.expires_in);
}
}
catch (Exception e)
{
_log.ErrorException("Failed to retrieve API access token", e);
}
}
}
}

View File

@ -1,43 +0,0 @@
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
//public class AniListSeriesIdentityProvider : IItemIdentityProvider<SeriesInfo>
//{
// private readonly AniListApiClient _api;
// public AniListSeriesIdentityProvider(IHttpClient http, ILogManager logManager, IJsonSerializer jsonSerializer)
// {
// _api = new AniListApiClient(http, logManager, jsonSerializer);
// }
// public async Task Identify(SeriesInfo info)
// {
// if (!string.IsNullOrEmpty(info.ProviderIds.GetOrDefault(ProviderNames.AniList)) )
// return;
// if (string.IsNullOrEmpty(info.Name))
// return;
// try
// {
// var search = await _api.Search(info.Name);
// var cleaned = AniDbTitleMatcher.GetComparableName(info.Name);
// if (!search.Any() && String.Compare(info.Name, cleaned, StringComparison.OrdinalIgnoreCase) != 0)
// search = await _api.Search(cleaned);
// var first = search.FirstOrDefault();
// if (first == null)
// return;
// info.ProviderIds.Remove(ProviderNames.AniList);
// info.ProviderIds.Add(ProviderNames.AniList, first.id.ToString());
// }
// catch (Exception e)
// {
// System.Diagnostics.Debug.WriteLine(e);
// // ignore
// }
// }
//}
}

View File

@ -6,34 +6,66 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Plugins.Anime.Configuration;
using MediaBrowser.Plugins.Anime.Providers.AniDB.Identity;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Plugins.Anime.Providers.AniList.MediaBrowser.Plugins.Anime.Providers.AniList;
using MediaBrowser.Model.Serialization;
//API v2
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
public class AniListSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
{
private readonly IApplicationPaths _paths;
private readonly AniListApiClient _api;
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _paths;
private readonly ILogger _log;
public static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1);
private readonly api _api;
public int Order => -2;
public string Name => "AniList";
public static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1);
public AniListSeriesProvider(IHttpClient http, IApplicationPaths paths, ILogManager logManager, IJsonSerializer jsonSerializer)
public AniListSeriesProvider(IApplicationPaths appPaths, IHttpClient httpClient, ILogManager logManager, IJsonSerializer jsonSerializer)
{
_httpClient = http;
_paths = paths;
_api = new AniListApiClient(http, logManager, jsonSerializer);
_log = logManager.GetLogger("AniList");
_httpClient = httpClient;
_api = new api(jsonSerializer);
_paths = appPaths;
}
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>();
var aid = info.ProviderIds.GetOrDefault(ProviderNames.AniList);
if (string.IsNullOrEmpty(aid))
{
_log.Info("Start AniList... Searching(" + info.Name + ")");
aid = await _api.FindSeries(info.Name, cancellationToken);
}
if (!string.IsNullOrEmpty(aid))
{
RootObject WebContent = await _api.WebRequestAPI(_api.AniList_anime_link.Replace("{0}",aid));
result.Item = new Series();
result.HasMetadata = true;
result.People = await _api.getPersonInfo(WebContent.data.Media.id);
result.Item.ProviderIds.Add(ProviderNames.AniList, aid);
result.Item.Overview = WebContent.data.Media.description;
try
{
//AniList has a max rating of 5
result.Item.CommunityRating = (WebContent.data.Media.averageScore/10);
}
catch (Exception) { }
foreach (var genre in _api.Get_Genre(WebContent))
result.Item.AddGenre(genre);
GenreHelper.CleanupGenres(result.Item);
StoreImageUrl(aid, WebContent.data.Media.coverImage.large, "image");
}
return result;
}
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken)
@ -43,171 +75,22 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniList
var aid = searchInfo.ProviderIds.GetOrDefault(ProviderNames.AniList);
if (!string.IsNullOrEmpty(aid))
{
var anime = await _api.GetAnime(aid);
if (anime != null && !results.ContainsKey(aid))
results.Add(aid, ToSearchResult(anime));
if (!results.ContainsKey(aid))
results.Add(aid, await _api.GetAnime(aid));
}
if (!string.IsNullOrEmpty(searchInfo.Name))
{
var search = await _api.Search(searchInfo.Name);
foreach (var a in search)
List<string> ids = await _api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
foreach (string a in ids)
{
if (!results.ContainsKey(a.id.ToString()))
results.Add(a.id.ToString(), ToSearchResult(a));
}
var cleaned = AniDbTitleMatcher.GetComparableName(searchInfo.Name);
if (String.Compare(cleaned, searchInfo.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
search = await _api.Search(cleaned);
foreach (var a in search)
{
if (!results.ContainsKey(a.id.ToString()))
results.Add(a.id.ToString(), ToSearchResult(a));
}
results.Add(a, await _api.GetAnime(a));
}
}
return results.Values;
}
private RemoteSearchResult ToSearchResult(Anime anime)
{
var result = new RemoteSearchResult
{
Name = SelectName(anime, Plugin.Instance.Configuration.TitlePreference, "en")
};
result.ImageUrl = anime.image_url_lge;
result.SetProviderId(ProviderNames.AniList, anime.id.ToString());
result.SearchProviderName = Name;
DateTime start;
if (DateTime.TryParse(anime.start_date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out start))
result.PremiereDate = start;
return result;
}
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>();
var aid = info.ProviderIds.GetOrDefault(ProviderNames.AniList);
if (string.IsNullOrEmpty(aid) && !string.IsNullOrEmpty(info.Name))
{
var search = await _api.Search(info.Name);
foreach (var a in search)
{
if (string.IsNullOrEmpty(aid))
{
if (Equals_check.Compare_strings(a.title_english, info.Name))
aid = a.id.ToString();
if (Equals_check.Compare_strings(a.title_japanese, info.Name))
aid = a.id.ToString();
if (Equals_check.Compare_strings(a.title_romaji, info.Name))
aid = a.id.ToString();
_log.Log(LogSeverity.Info, a.title_romaji + "vs" + info.Name);
}
}
if (string.IsNullOrEmpty(aid))
{
var cleaned = AniDbTitleMatcher.GetComparableName(Equals_check.clear_name(info.Name));
if (String.Compare(cleaned, info.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
search = await _api.Search(cleaned);
foreach (var b in search)
{
if (Equals_check.Compare_strings(b.title_english, info.Name))
aid = b.id.ToString();
if (Equals_check.Compare_strings(b.title_japanese, info.Name))
aid = b.id.ToString();
if (Equals_check.Compare_strings(b.title_romaji, info.Name))
aid = b.id.ToString();
}
}
}
if (string.IsNullOrEmpty(aid))
{
search = await _api.Search(Equals_check.clear_name(info.Name));
foreach (var b in search)
{
if (Equals_check.Compare_strings(b.title_english, info.Name))
aid = b.id.ToString();
if (Equals_check.Compare_strings(b.title_japanese, info.Name))
aid = b.id.ToString();
if (Equals_check.Compare_strings(b.title_romaji, info.Name))
aid = b.id.ToString();
}
}
}
if (!string.IsNullOrEmpty(aid))
{
result.Item = new Series();
result.HasMetadata = true;
result.Item.ProviderIds.Add(ProviderNames.AniList, aid);
var anime = await _api.GetAnime(aid);
result.Item.Name = SelectName(anime, Plugin.Instance.Configuration.TitlePreference, info.MetadataLanguage ?? "en");
result.Item.Overview = anime.description;
DateTime start;
if (DateTime.TryParse(anime.start_date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out start))
result.Item.PremiereDate = start;
DateTime end;
if (DateTime.TryParse(anime.end_date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out end))
result.Item.EndDate = end;
if (anime.genres != null)
{
foreach (var genre in anime.genres)
if(!string.IsNullOrEmpty(genre))
result.Item.AddGenre(genre);
GenreHelper.CleanupGenres(result.Item);
}
if (!string.IsNullOrEmpty(anime.image_url_lge))
StoreImageUrl(aid, anime.image_url_lge, "image");
if (!string.IsNullOrEmpty(anime.image_url_banner))
StoreImageUrl(aid, anime.image_url_banner, "banner");
if (string.IsNullOrEmpty(result.Item.Name))
{
if (!string.IsNullOrEmpty(anime.title_romaji))
{
result.Item.Name = anime.title_romaji;
}
}
}
return result;
}
private string SelectName(Anime anime, TitlePreferenceType preference, string language)
{
if (preference == TitlePreferenceType.Localized && language == "en")
return anime.title_english;
if (preference == TitlePreferenceType.Japanese)
return anime.title_japanese;
return anime.title_romaji;
}
private void StoreImageUrl(string series, string url, string type)
{
var path = Path.Combine(_paths.CachePath, "anilist", type, series + ".txt");
@ -217,15 +100,6 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniList
File.WriteAllText(path, url);
}
public static async Task<string> GetSeriesImage(IApplicationPaths paths, string series, string type)
{
var path = Path.Combine(paths.CachePath, "anilist", type, series + ".txt");
if (File.Exists(path))
return await Task.Run(() => File.ReadAllText(path));
return null;
}
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
@ -235,74 +109,60 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniList
ResourcePool = ResourcePool
});
}
}
public class AniListSeriesImageProvider : IRemoteImageProvider
public class AniListSeriesImageProvider : IRemoteImageProvider
{
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
private readonly api _api;
public AniListSeriesImageProvider(IHttpClient httpClient, IApplicationPaths appPaths, IJsonSerializer jsonSerializer)
{
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
_httpClient = httpClient;
_appPaths = appPaths;
_api = new api(jsonSerializer);
}
public AniListSeriesImageProvider(IHttpClient httpClient, IApplicationPaths appPaths)
public string Name => "AniList";
public bool Supports(BaseItem item) => item is Series || item is Season;
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new[] { ImageType.Primary };
}
public Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var seriesId = item.GetProviderId(ProviderNames.AniList);
return GetImages(seriesId, cancellationToken);
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(string aid, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
if (!string.IsNullOrEmpty(aid))
{
_httpClient = httpClient;
_appPaths = appPaths;
}
public string Name => "AniList";
public bool Supports(BaseItem item) => item is Series || item is Season;
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new[] { ImageType.Primary, ImageType.Banner };
}
public Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var seriesId = item.GetProviderId(ProviderNames.AniList);
return GetImages(seriesId, cancellationToken);
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(string aid, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
if (!string.IsNullOrEmpty(aid))
var primary = _api.Get_ImageUrl(await _api.WebRequestAPI(_api.AniList_anime_link.Replace("{0}", aid)));
list.Add(new RemoteImageInfo
{
var primary = await GetSeriesImage(_appPaths, aid, "image");
if (!string.IsNullOrEmpty(primary))
{
list.Add(new RemoteImageInfo
{
ProviderName = Name,
Type = ImageType.Primary,
Url = primary
});
}
var banner = await GetSeriesImage(_appPaths, aid, "banner");
if (!string.IsNullOrEmpty(banner))
{
list.Add(new RemoteImageInfo
{
ProviderName = Name,
Type = ImageType.Banner,
Url = banner
});
}
}
return list;
}
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
{
CancellationToken = cancellationToken,
Url = url,
ResourcePool = ResourcePool
ProviderName = Name,
Type = ImageType.Primary,
Url = primary
});
}
return list;
}
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
{
CancellationToken = cancellationToken,
Url = url,
ResourcePool = AniListSeriesProvider.ResourcePool
});
}
}
}

View File

@ -1,20 +1,169 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text;
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
public class Anime
using System.Collections.Generic;
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
public int id { get; set; }
public string description { get; set; }
public string title_romaji { get; set; }
public string title_japanese { get; set; }
public string title_english { get; set; }
public string start_date { get; set; }
public string end_date { get; set; }
public string image_url_lge { get; set; }
public string image_url_banner { get; set; }
public List<string> genres { get; set; }
public int? duration { get; set; }
public string airing_status { get; set; }
public class Title
{
public string romaji { get; set; }
public string english { get; set; }
public string native { get; set; }
}
public class CoverImage
{
public string medium { get; set; }
public string large { get; set; }
}
public class StartDate
{
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
}
public class EndDate
{
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
}
public class Medium
{
public int id { get; set; }
public Title title { get; set; }
public CoverImage coverImage { get; set; }
public string format { get; set; }
public string type { get; set; }
public int averageScore { get; set; }
public int popularity { get; set; }
public int episodes { get; set; }
public string season { get; set; }
public string hashtag { get; set; }
public bool isAdult { get; set; }
public StartDate startDate { get; set; }
public EndDate endDate { get; set; }
public object bannerImage { get; set; }
public string status { get; set; }
public object chapters { get; set; }
public object volumes { get; set; }
public string description { get; set; }
public int meanScore { get; set; }
public List<string> genres { get; set; }
public List<object> synonyms { get; set; }
public object nextAiringEpisode { get; set; }
}
public class Page
{
public List<Medium> media { get; set; }
}
public class Data
{
public Page Page { get; set; }
public Media Media { get; set; }
}
public class Media
{
public Characters characters { get; set; }
public int popularity { get; set; }
public object hashtag { get; set; }
public bool isAdult { get; set; }
public int id { get; set; }
public Title title { get; set; }
public StartDate startDate { get; set; }
public EndDate endDate { get; set; }
public CoverImage coverImage { get; set; }
public object bannerImage { get; set; }
public string format { get; set; }
public string type { get; set; }
public string status { get; set; }
public int episodes { get; set; }
public object chapters { get; set; }
public object volumes { get; set; }
public string season { get; set; }
public string description { get; set; }
public int averageScore { get; set; }
public int meanScore { get; set; }
public List<string> genres { get; set; }
public List<object> synonyms { get; set; }
public object nextAiringEpisode { get; set; }
}
public class PageInfo
{
public int total { get; set; }
public int perPage { get; set; }
public bool hasNextPage { get; set; }
public int currentPage { get; set; }
public int lastPage { get; set; }
}
public class Name
{
public string first { get; set; }
public string last { get; set; }
}
public class Image
{
public string medium { get; set; }
public string large { get; set; }
}
public class Node
{
public int id { get; set; }
public Name name { get; set; }
public Image image { get; set; }
}
public class Name2
{
public string first { get; set; }
public string last { get; set; }
public string native { get; set; }
}
public class Image2
{
public string medium { get; set; }
public string large { get; set; }
}
public class VoiceActor
{
public int id { get; set; }
public Name2 name { get; set; }
public Image2 image { get; set; }
public string language { get; set; }
}
public class Edge
{
public Node node { get; set; }
public string role { get; set; }
public List<VoiceActor> voiceActors { get; set; }
}
public class Characters
{
public PageInfo pageInfo { get; set; }
public List<Edge> edges { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
}
}
}

View File

@ -0,0 +1,415 @@
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using MediaBrowser.Plugins.Anime.Configuration;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Plugins.Anime.Providers.AniList.MediaBrowser.Plugins.Anime.Providers.AniList;
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Plugins.Anime.Providers.AniList
{
/// <summary>
/// Based on the new API from AniList
/// 🛈 This code works with the API Interface (v2) from AniList
/// 🛈 https://anilist.gitbooks.io/anilist-apiv2-docs
/// 🛈 THIS IS AN UNOFFICAL API INTERFACE FOR EMBY
/// </summary>
public class api
{
private static IJsonSerializer _jsonSerializer;
public List<string> anime_search_names = new List<string>();
public List<string> anime_search_ids = new List<string>();
public string SearchLink = @"https://graphql.anilist.co/api/v2?query=
query ($query: String, $type: MediaType) {
Page {
media(search: $query, type: $type) {
id
title {
romaji
english
native
}
coverImage {
medium
large
}
format
type
averageScore
popularity
episodes
season
hashtag
isAdult
startDate {
year
month
day
}
endDate {
year
month
day
}
}
}
}&variables={ ""query"":""{0}"",""type"":""ANIME""}";
public string AniList_anime_link = @"https://graphql.anilist.co/api/v2?query=query($id: Int!, $type: MediaType) {
Media(id: $id, type: $type)
{
id
title {
romaji
english
native
userPreferred
}
startDate {
year
month
day
}
endDate {
year
month
day
}
coverImage {
large
medium
}
bannerImage
format
type
status
episodes
chapters
volumes
season
description
averageScore
meanScore
genres
synonyms
nextAiringEpisode {
airingAt
timeUntilAiring
episode
}
}
}&variables={ ""id"":""{0}"",""type"":""ANIME""}";
public string AniList_anime_char_link = @"https://graphql.anilist.co/api/v2?query=query($id: Int!, $type: MediaType, $page: Int = 1) {
Media(id: $id, type: $type) {
id
characters(page: $page, sort: [ROLE]) {
pageInfo {
total
perPage
hasNextPage
currentPage
lastPage
}
edges {
node {
id
name {
first
last
}
image {
medium
large
}
}
role
voiceActors {
id
name {
first
last
native
}
image {
medium
large
}
language
}
}
}
}
}&variables={ ""id"":""{0}"",""type"":""ANIME""}";
public api(IJsonSerializer jsonSerializer)
{
_jsonSerializer = jsonSerializer;
}
/// <summary>
/// API call to get the anime with the id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<RemoteSearchResult> GetAnime(string id)
{
RootObject WebContent = await WebRequestAPI(AniList_anime_link.Replace("{0}",id));
var result = new RemoteSearchResult
{
Name = ""
};
result.SearchProviderName = WebContent.data.Media.title.romaji;
result.ImageUrl = WebContent.data.Media.coverImage.large;
result.SetProviderId(ProviderNames.AniList, id);
result.Overview = WebContent.data.Media.description;
return result;
}
/// <summary>
/// API call to select the lang
/// </summary>
/// <param name="WebContent"></param>
/// <param name="preference"></param>
/// <param name="language"></param>
/// <returns></returns>
private string SelectName(RootObject WebContent, TitlePreferenceType preference, string language)
{
if (preference == TitlePreferenceType.Localized && language == "en")
return WebContent.data.Media.title.english;
if (preference == TitlePreferenceType.Japanese)
return WebContent.data.Media.title.native;
return WebContent.data.Media.title.romaji;
}
/// <summary>
/// API call to get the title with the right lang
/// </summary>
/// <param name="lang"></param>
/// <param name="WebContent"></param>
/// <returns></returns>
public string Get_title(string lang, RootObject WebContent)
{
switch (lang)
{
case "en":
return WebContent.data.Media.title.english;
case "jap":
return WebContent.data.Media.title.native;
//Default is jap_r
default:
return WebContent.data.Media.title.romaji;
}
}
public async Task<List<PersonInfo>> getPersonInfo(int id)
{
List<PersonInfo> lpi = new List<PersonInfo>();
RootObject WebContent = await WebRequestAPI(AniList_anime_char_link.Replace("{0}", id.ToString()));
foreach (Edge edge in WebContent.data.Media.characters.edges)
{
PersonInfo pi = new PersonInfo();
pi.Name = edge.node.name.first+" "+ edge.node.name.last;
pi.ItemId = ToGuid(edge.node.id);
pi.ImageUrl = edge.node.image.large;
pi.Role = edge.role;
}
return lpi;
}
/// <summary>
/// Convert int to Guid
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static Guid ToGuid(int value)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
/// <summary>
/// API call to get the genre of the anime
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public List<string> Get_Genre(RootObject WebContent)
{
return WebContent.data.Media.genres;
}
/// <summary>
/// API call to get the img url
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public string Get_ImageUrl(RootObject WebContent)
{
return WebContent.data.Media.coverImage.large;
}
/// <summary>
/// API call too get the rating
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public string Get_Rating(RootObject WebContent)
{
return (WebContent.data.Media.averageScore / 10).ToString();
}
/// <summary>
/// API call to get the description
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public string Get_Overview(RootObject WebContent)
{
return WebContent.data.Media.description;
}
/// <summary>
/// API call to search a title and return the right one back
/// </summary>
/// <param name="title"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<string> Search_GetSeries(string title, CancellationToken cancellationToken)
{
anime_search_names.Clear();
anime_search_ids.Clear();
string result = null;
RootObject WebContent = await WebRequestAPI(SearchLink.Replace("{0}", title));
foreach (Medium media in WebContent.data.Page.media) {
//get id
try
{
if (await Task.Run(() => Equals_check.Compare_strings(media.title.romaji, title)))
{
return media.id.ToString();
}
if (await Task.Run(() => Equals_check.Compare_strings(media.title.english, title)))
{
return media.id.ToString();
}
//Disabled due to false result.
/*if (await Task.Run(() => Equals_check.Compare_strings(media.title.native, title)))
{
return media.id.ToString();
}*/
int n;
if (Int32.TryParse(media.id.ToString(), out n))
{
anime_search_names.Add(media.title.romaji);
anime_search_ids.Add(media.id.ToString());
}
}
catch (Exception) { }
}
return result;
}
/// <summary>
/// API call to search a title and return a list back
/// </summary>
/// <param name="title"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<List<string>> Search_GetSeries_list(string title, CancellationToken cancellationToken)
{
List<string> result = new List<string>();
RootObject WebContent = await WebRequestAPI(SearchLink.Replace("{0}", title));
foreach (Medium media in WebContent.data.Page.media)
{
//get id
try
{
if (await Task.Run(() => Equals_check.Compare_strings(media.title.romaji, title)))
{
result.Add(media.id.ToString());
}
if (await Task.Run(() => Equals_check.Compare_strings(media.title.english, title)))
{
result.Add(media.id.ToString());
}
//Disabled due to false result.
/*if (await Task.Run(() => Equals_check.Compare_strings(media.title.native, title)))
{
result.Add(media.id.ToString());
}*/
}
catch (Exception) { }
}
return result;
}
/// <summary>
/// SEARCH Title
/// </summary>
public async Task<string> FindSeries(string title, CancellationToken cancellationToken)
{
string aid = await Search_GetSeries(title, cancellationToken);
if (!string.IsNullOrEmpty(aid))
{
return aid;
}
aid = await Search_GetSeries(Equals_check.clear_name(title), cancellationToken);
if (!string.IsNullOrEmpty(aid))
{
return aid;
}
return null;
}
/// <summary>
/// Simple regex
/// </summary>
public async Task<string> One_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
{
Regex _regex = regex;
int x = 0;
MatchCollection matches = await Task.Run(() => regex.Matches(match));
foreach (Match _match in matches)
{
if (x == match_int)
{
return await Task.Run(() => _match.Groups[group].Value.ToString());
}
x++;
}
return "";
}
/// <summary>
/// GET website content from the link
/// </summary>
public async Task<RootObject> WebRequestAPI(string link)
{
string _strContent = "";
using (WebClient client = new WebClient())
{
var values = new System.Collections.Specialized.NameValueCollection();
var response = await Task.Run(() => client.UploadValues(new Uri(link),values));
_strContent = System.Text.Encoding.Default.GetString(response);
}
RootObject data = _jsonSerializer.DeserializeFromString<RootObject>(_strContent);
return data;
}
}
}

View File

@ -95,7 +95,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
return false;
}
/// <summary>
/// Cut p(%) away from the string
/// </summary>