Merge pull request #4 from DaniGTA/master

Update to AniList Api v2
This commit is contained in:
Luke 2018-03-02 17:09:34 -05:00 committed by GitHub
commit 01558ff5da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1099 additions and 730 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ TestResults
# Build results
[Dd]ebug/
[Rr]elease/
.vs/
x64/
*_i.c
*_p.c

View File

@ -36,7 +36,7 @@ namespace MediaBrowser.Plugins.Anime.Configuration
public bool UseAnidbOrderingWithSeasons { get; set; }
public string MyAnimeList_API_Name { get; set; }
public string MyAnimeList_API_Pw { get; set; }
public int AniDB_wait_time { get; set; }
public PluginConfiguration()
{
TitlePreference = TitlePreferenceType.Localized;
@ -47,6 +47,7 @@ namespace MediaBrowser.Plugins.Anime.Configuration
UseAnidbOrderingWithSeasons = false;
MyAnimeList_API_Name = "";
MyAnimeList_API_Pw = "";
AniDB_wait_time = 0;
}
}
}

View File

@ -39,93 +39,104 @@
</label>
<input id="chkMaxGenres" name="chkMaxGenres" type="number" min="0" value="maxGenres" />
</li>
<li>
<label for="chkMyAnimeList_API_Name">
MyAnimeList Name. -not rly needed
</label>
<input id="chkMyAnimeList_API_Name" name="chkMyAnimeList_API_Name" type="text" value="" disabled/>
</li>
<li>
<label for="chkMyAnimeList_API_Pw">
MyAnimeList Pw. -not rly needed
</label>
<input id="chkMyAnimeList_API_Pw" name="chkMyAnimeList_API_Pw" type="password" value="" disabled/>
</li>
<li>
<label for="chkAnidbSeasonOne">
Use AniDB Odering with Seasons
</label>
<input id="chkAnidbSeasonOne" name="chkAnidbSeasonOne" type="checkbox" value="anidbSeasonOne" />
</li>
<li>
<button type="submit" data-theme="b">Save</button>
<button type="button" onclick=" history.back(); ">Cancel</button>
</li>
</ul>
</form>
<!--
<li>
<label for="chkMyAnimeList_API_Name">
MyAnimeList Name. -not rly needed
</label>
<input id="chkMyAnimeList_API_Name" name="chkMyAnimeList_API_Name" type="text" value="" disabled />
</li>
<li>
<label for="chkMyAnimeList_API_Pw">
MyAnimeList Pw. -not rly needed
</label>
<input id="chkMyAnimeList_API_Pw" name="chkMyAnimeList_API_Pw" type="password" value="" disabled />
</li>
-->
<li>
<label for="chkAniDB_wait_time">
AniDB wait time too prevent IP ban (in ms (1000 = 1 Second))
</label>
<input id="chkAniDB_wait_time" name="chkAniDB_wait_time" type="number" value="0"/>
</li>
<li>
<label for="chkAnidbSeasonOne">
Use AniDB Odering with Seasons
</label>
<input id="chkAnidbSeasonOne" name="chkAnidbSeasonOne" type="checkbox" value="anidbSeasonOne" />
</li>
<li>
<button type="submit" data-theme="b">Save</button>
<button type="button" onclick=" history.back(); ">Cancel</button>
</li>
</ul>
</form>
</div>
</div>
</div>
<script type="text/javascript">
var AnimeConfigurationPage =
{
pluginUniqueId: "1d0dddf7-1877-4473-8d7b-03f7dac1e559",
<script type="text/javascript">
var AnimeConfigurationPage =
{
pluginUniqueId: "1d0dddf7-1877-4473-8d7b-03f7dac1e559",
virtualFolders: [],
physicalFolders: [],
virtualFolders: [],
physicalFolders: [],
loadConfiguration: function() {
Dashboard.showLoadingMsg();
loadConfiguration: function() {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(AnimeConfigurationPage.pluginUniqueId).then(function (config) {
var page = $.mobile.activePage;
$('#titleLanguage', page).val(config.TitlePreference).change();
$('#chkAutomaticUpdates', page).checked(config.AllowAutomaticMetadataUpdates).checkboxradio("refresh");
$('#chkTidyGenres', page).checked(config.TidyGenreList).checkboxradio("refresh");
//$('#chkMyAnimeList_API_Name', page, val(config.MyAnimeList_API_Name)).change();
//$('#chkMyAnimeList_API_Pw', page, val(config.MyAnimeList_API_Pw)).change();
$('#chkMaxGenres', page).val(config.MaxGenres).change();
$('#chkMoveExcessGenresToTags', page).checked(config.MoveExcessGenresToTags).checkboxradio("refresh");
$('#chkAnidbSeasonOne', page).checked(config.UseAnidbOrderingWithSeasons).checkboxradio("refresh");
$('#chkAniDB_wait_time', page).val(config.AniDB_wait_time).change();
Dashboard.hideLoadingMsg();
});
},
saveConfiguration: function() {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(AnimeConfigurationPage.pluginUniqueId).then(function (config) {
var page = $.mobile.activePage;
$('#titleLanguage', page).val(config.TitlePreference).change();
$('#chkAutomaticUpdates', page).checked(config.AllowAutomaticMetadataUpdates).checkboxradio("refresh");
$('#chkTidyGenres', page).checked(config.TidyGenreList).checkboxradio("refresh");
$('#chkMyAnimeList_API_Name', page, val(config.MyAnimeList_API_Name)).change();
$('#chkMyAnimeList_API_Pw', page, val(config.MyAnimeList_API_Pw)).change();
$('#chkMaxGenres', page).val(config.MaxGenres).change();
$('#chkMoveExcessGenresToTags', page).checked(config.MoveExcessGenresToTags).checkboxradio("refresh");
$('#chkAnidbSeasonOne', page).checked(config.UseAnidbOrderingWithSeasons).checkboxradio("refresh");
ApiClient.getPluginConfiguration(AnimeConfigurationPage.pluginUniqueId).then(function(config) {
Dashboard.hideLoadingMsg();
});
},
saveConfiguration: function() {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
ApiClient.getPluginConfiguration(AnimeConfigurationPage.pluginUniqueId).then(function(config) {
config.TitlePreference = $('#titleLanguage', page).val();
config.AllowAutomaticMetadataUpdates = $('#chkAutomaticUpdates', page).prop('checked');
config.TidyGenreList = $('#chkTidyGenres').prop('checked');
config.MaxGenres = $('#chkMaxGenres').val();
config.MaxGenres = $('#chkNames').val();
config.MyAnimeList_API_Name = $('#chkMyAnimeList_API_Name').val();
config.MyAnimeList_API_Pw= $('#chkMyAnimeList_API_Pw').val();
config.MoveExcessGenresToTags = $('#chkMoveExcessGenresToTags').prop('checked');
config.UseAnidbOrderingWithSeasons = $('#chkAnidbSeasonOne').prop('checked');
ApiClient.updatePluginConfiguration(AnimeConfigurationPage.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result);
config.TitlePreference = $('#titleLanguage', page).val();
config.AllowAutomaticMetadataUpdates = $('#chkAutomaticUpdates', page).prop('checked');
config.TidyGenreList = $('#chkTidyGenres').prop('checked');
config.MaxGenres = $('#chkMaxGenres').val();
config.MaxGenres = $('#chkNames').val();
//config.MyAnimeList_API_Name = $('#chkMyAnimeList_API_Name').val();
//config.MyAnimeList_API_Pw= $('#chkMyAnimeList_API_Pw').val();
config.MoveExcessGenresToTags = $('#chkMoveExcessGenresToTags').prop('checked');
config.UseAnidbOrderingWithSeasons = $('#chkAnidbSeasonOne').prop('checked');
config.AniDB_wait_time = $('chkAniDB_wait_time').val();
ApiClient.updatePluginConfiguration(AnimeConfigurationPage.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result);
});
});
});
},
};
},
};
$('#animeConfigurationPage').on('pageshow', function () {
AnimeConfigurationPage.loadConfiguration();
});
$('#animeConfigurationPage').on('pageshow', function () {
AnimeConfigurationPage.loadConfiguration();
});
$('#animeConfigurationForm').on('submit', function () {
AnimeConfigurationPage.saveConfiguration();
return false;
});
</script>
</div>
</body>
</html>
$('#animeConfigurationForm').on('submit', function () {
AnimeConfigurationPage.saveConfiguration();
return false;
});
</script>
</div>
</body>
</html>

View File

@ -2,8 +2,8 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net46;</TargetFrameworks>
<AssemblyVersion>1.2.3.0</AssemblyVersion>
<FileVersion>1.2.3.0</FileVersion>
<AssemblyVersion>1.2.4.0</AssemblyVersion>
<FileVersion>1.2.4.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">

View File

@ -82,7 +82,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Identity
var client = new WebClient();
await AniDbSeriesProvider.RequestLimiter.Tick();
await Task.Run(() => Thread.Sleep(Plugin.Instance.Configuration.AniDB_wait_time));
using (var stream = await client.OpenReadTaskAsync(TitlesUrl))
using (var unzipped = new GZipStream(stream, CompressionMode.Decompress))
using (var writer = File.Open(titlesFile, FileMode.Create, FileAccess.Write))
@ -102,7 +102,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Identity
var client = new WebClient();
await AniDbSeriesProvider.RequestLimiter.Tick();
await Task.Run(() => Thread.Sleep(Plugin.Instance.Configuration.AniDB_wait_time));
using (var stream = await client.OpenReadTaskAsync(TitlesUrl))
using (var unzipped = new GZipStream(stream, CompressionMode.Decompress))
using (var writer = File.Open(titlesFile, FileMode.Create, FileAccess.Write))

View File

@ -75,8 +75,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Identity
private string LookupAniDbId(string title)
{
TitleInfo info;
if (_titles.TryGetValue(title, out info))
if (_titles.TryGetValue(title, out TitleInfo info))
{
return info.AniDbId;
}
@ -86,10 +85,9 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Identity
public static TitleInfo GetTitleInfos(string title)
{
TitleInfo info;
if (!string.IsNullOrEmpty(title))
{
if (_titles.TryGetValue(title, out info))
if (_titles.TryGetValue(title, out TitleInfo info))
{
return info;
}
@ -208,9 +206,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Identity
{
var type = ParseType(reader.GetAttribute("type"));
TitleInfo currentTitleInfo;
if (!_titles.TryGetValue(title, out currentTitleInfo) || (int)currentTitleInfo.Type < (int)type)
if (!_titles.TryGetValue(title, out TitleInfo currentTitleInfo) || (int)currentTitleInfo.Type < (int)type)
{
_titles[title] = new TitleInfo { AniDbId = aid, Type = type, Title = title };
}

View File

@ -66,8 +66,11 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
var aid = info.ProviderIds.GetOrDefault(ProviderNames.AniDb);
if (string.IsNullOrEmpty(aid) && !string.IsNullOrEmpty(info.Name))
{
aid = Equals_check.Fast_xml_search(info.Name, info.Name, true);
aid = Equals_check.Fast_xml_search(Equals_check.clear_name(info.Name), Equals_check.clear_name(info.Name), true);
aid = await Equals_check.Fast_xml_search(info.Name, info.Name, cancellationToken, true);
if (string.IsNullOrEmpty(aid))
{
aid = await Equals_check.Fast_xml_search(await Equals_check.Clear_name(info.Name, cancellationToken), await Equals_check.Clear_name(info.Name, cancellationToken), cancellationToken, true);
}
}
if (!string.IsNullOrEmpty(aid))
@ -166,8 +169,8 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
if (!string.IsNullOrWhiteSpace(val))
{
DateTime date;
if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out date))
if (DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out DateTime date))
{
date = date.ToUniversalTime();
series.PremiereDate = date;
@ -181,8 +184,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
if (!string.IsNullOrWhiteSpace(endDate))
{
DateTime date;
if (DateTime.TryParse(endDate, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out date))
if (DateTime.TryParse(endDate, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out DateTime date))
{
date = date.ToUniversalTime();
series.EndDate = date;
@ -276,8 +278,8 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "episode")
{
int id;
if (int.TryParse(reader.GetAttribute("id"), out id) && IgnoredCategoryIds.Contains(id))
if (int.TryParse(reader.GetAttribute("id"), out int id) && IgnoredCategoryIds.Contains(id))
continue;
using (var episodeSubtree = reader.ReadSubtree())
@ -312,16 +314,14 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "category")
{
int weight;
if (!int.TryParse(reader.GetAttribute("weight"), out weight) || weight < 400)
if (!int.TryParse(reader.GetAttribute("weight"), out int weight) || weight < 400)
continue;
int id;
if (int.TryParse(reader.GetAttribute("id"), out id) && IgnoredCategoryIds.Contains(id))
if (int.TryParse(reader.GetAttribute("id"), out int id) && IgnoredCategoryIds.Contains(id))
continue;
int parentId;
if (int.TryParse(reader.GetAttribute("parentid"), out parentId) && IgnoredCategoryIds.Contains(parentId))
if (int.TryParse(reader.GetAttribute("parentid"), out int parentId) && IgnoredCategoryIds.Contains(parentId))
continue;
using (var categorySubtree = reader.ReadSubtree())
@ -360,8 +360,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
{
if (idSubtree.NodeType == XmlNodeType.Element && idSubtree.Name == "identifier")
{
int id;
if (int.TryParse(idSubtree.ReadElementContentAsString(), out id))
if (int.TryParse(idSubtree.ReadElementContentAsString(), out int id))
ids.Add(id);
}
}
@ -455,12 +454,12 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
{
if (reader.Name == "permanent")
{
float rating;
if (float.TryParse(
reader.ReadElementContentAsString(),
NumberStyles.AllowDecimalPoint,
CultureInfo.InvariantCulture,
out rating))
out float rating))
{
series.CommunityRating = (float)Math.Round(rating, 1);
}
@ -518,8 +517,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
{
// todo find nationality of person and conditionally reverse name order
string mappedType;
if (!_typeMappings.TryGetValue(type, out mappedType))
if (!_typeMappings.TryGetValue(type, out string mappedType))
{
mappedType = type;
}
@ -555,7 +553,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniDB.Metadata
};
await RequestLimiter.Tick();
await Task.Run(() => Thread.Sleep(Plugin.Instance.Configuration.AniDB_wait_time));
using (var stream = await httpClient.Get(requestOptions).ConfigureAwait(false))
using (var unzipped = new GZipStream(stream, CompressionMode.Decompress))
using (var reader = new StreamReader(unzipped, Encoding.UTF8, true))

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, cancellationToken);
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,386 @@
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;
private const 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""}";
private const 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, CancellationToken cancellationToken)
{
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 = await ToGuid(edge.node.id, cancellationToken);
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 async static Task<Guid> ToGuid(int value, CancellationToken cancellationToken)
{
byte[] bytes = new byte[16];
await Task.Run(() => BitConverter.GetBytes(value).CopyTo(bytes, 0), cancellationToken);
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)
{
string result = null;
RootObject WebContent = await WebRequestAPI(SearchLink.Replace("{0}", title));
foreach (Medium media in WebContent.data.Page.media) {
//get id
try
{
if (await Equals_check.Compare_strings(media.title.romaji, title, cancellationToken))
{
return media.id.ToString();
}
if (await Equals_check.Compare_strings(media.title.english, title, cancellationToken))
{
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();
}*/
}
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 Equals_check.Compare_strings(media.title.romaji, title, cancellationToken))
{
result.Add(media.id.ToString());
}
if (await Equals_check.Compare_strings(media.title.english, title, cancellationToken))
{
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(await Equals_check.Clear_name(title, cancellationToken), cancellationToken);
if (!string.IsNullOrEmpty(aid))
{
return aid;
}
return null;
}
/// <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

@ -38,27 +38,27 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
if (string.IsNullOrEmpty(aid))
{
_log.Info("Start AniSearch... Searching(" + info.Name + ")");
aid = await api.FindSeries(info.Name, cancellationToken);
aid = await Api.FindSeries(info.Name, cancellationToken);
}
if (!string.IsNullOrEmpty(aid))
{
string WebContent = await api.WebRequestAPI(api.AniSearch_anime_link + aid);
string WebContent = await Api.WebRequestAPI(Api.AniSearch_anime_link + aid);
result.Item = new Series();
result.HasMetadata = true;
result.Item.ProviderIds.Add(ProviderNames.AniSearch, aid);
result.Item.Overview = await api.Get_Overview(WebContent);
result.Item.Overview = await Api.Get_Overview(WebContent);
try
{
//AniSearch has a max rating of 5
result.Item.CommunityRating = (float.Parse(await api.Get_Rating(WebContent), System.Globalization.CultureInfo.InvariantCulture) * 2);
result.Item.CommunityRating = (float.Parse(await Api.Get_Rating(WebContent), System.Globalization.CultureInfo.InvariantCulture) * 2);
}
catch (Exception) { }
foreach (var genre in await api.Get_Genre(WebContent))
foreach (var genre in await Api.Get_Genre(WebContent))
result.Item.AddGenre(genre);
GenreHelper.CleanupGenres(result.Item);
StoreImageUrl(aid, await api.Get_ImageUrl(WebContent), "image");
StoreImageUrl(aid, await Api.Get_ImageUrl(WebContent), "image");
}
return result;
}
@ -71,15 +71,15 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
if (!string.IsNullOrEmpty(aid))
{
if (!results.ContainsKey(aid))
results.Add(aid, await api.GetAnime(aid));
results.Add(aid, await Api.GetAnime(aid));
}
if (!string.IsNullOrEmpty(searchInfo.Name))
{
List<string> ids = await api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
List<string> ids = await Api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
foreach (string a in ids)
{
results.Add(a, await api.GetAnime(a));
results.Add(a, await Api.GetAnime(a));
}
}
@ -138,7 +138,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
if (!string.IsNullOrEmpty(aid))
{
var primary = await api.Get_ImageUrl(await api.WebRequestAPI(api.AniSearch_anime_link + aid));
var primary = await Api.Get_ImageUrl(await Api.WebRequestAPI(Api.AniSearch_anime_link + aid));
list.Add(new RemoteImageInfo
{
ProviderName = Name,

View File

@ -14,7 +14,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
/// API for http://anisearch.de a german anime database
/// 🛈 Anisearch does not have an API interface to work with
/// </summary>
internal class api
internal class Api
{
public static List<string> anime_search_names = new List<string>();
public static List<string> anime_search_ids = new List<string>();
@ -172,12 +172,11 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
a_name = Regex.Replace(await One_line_regex(new Regex(@"((<a|<d).*?>)(.*?)(<\/a>|<\/div>)"), result_text, 3, _x), "<.*?>", String.Empty);
if (a_name != "")
{
if (await Task.Run(() => Equals_check.Compare_strings(a_name, title)))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
return id;
}
int n;
if (Int32.TryParse(id, out n))
if (Int32.TryParse(id, out int n))
{
anime_search_names.Add(a_name);
anime_search_ids.Add(id);
@ -220,13 +219,12 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
a_name = Regex.Replace(await One_line_regex(new Regex(@"((<a|<d).*?>)(.*?)(<\/a>|<\/div>)"), result_text, 3, _x), "<.*?>", String.Empty);
if (a_name != "")
{
if (Equals_check.Compare_strings(a_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
result.Add(id);
return result;
}
int n;
if (Int32.TryParse(id, out n))
if (Int32.TryParse(id, out int n))
{
result.Add(id);
}
@ -255,14 +253,14 @@ namespace MediaBrowser.Plugins.Anime.Providers.AniSearch
foreach (string a_name in anime_search_names)
{
if (Equals_check.Compare_strings(a_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
return anime_search_ids[x];
}
x++;
}
}
aid = await Search_GetSeries(Equals_check.clear_name(title), cancellationToken);
aid = await Search_GetSeries(await Equals_check.Clear_name(title, cancellationToken), cancellationToken);
if (!string.IsNullOrEmpty(aid))
{
return aid;

View File

@ -19,6 +19,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
private readonly ILogger _log;
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _paths;
private readonly Api _api;
public static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1);
public static string provider_name = ProviderNames.MyAnimeList;
public int Order => -5;
@ -26,6 +27,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
public MyAnimeListSeriesProvider(IApplicationPaths appPaths, IHttpClient httpClient, ILogManager logManager)
{
_api = new Api(logManager);
_log = logManager.GetLogger("MyAnimeList");
_httpClient = httpClient;
_paths = appPaths;
@ -39,24 +41,24 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
if (string.IsNullOrEmpty(aid))
{
_log.Info("Start MyAnimeList... Searching(" + info.Name + ")");
aid = await api.FindSeries(info.Name, cancellationToken);
aid = await _api.FindSeries(info.Name, cancellationToken);
}
if (!string.IsNullOrEmpty(aid))
{
string WebContent = await api.WebRequestAPI(api.anime_link + aid);
string WebContent = await _api.WebRequestAPI(_api.anime_link + aid, cancellationToken);
result.Item = new Series();
result.HasMetadata = true;
result.Item.ProviderIds.Add(provider_name, aid);
result.Item.Overview = await api.Get_OverviewAsync(WebContent);
result.Item.Overview = await _api.Get_OverviewAsync(WebContent);
result.ResultLanguage = "eng";
try
{
result.Item.CommunityRating = float.Parse(await api.Get_RatingAsync(WebContent), System.Globalization.CultureInfo.InvariantCulture);
result.Item.CommunityRating = float.Parse(await _api.Get_RatingAsync(WebContent), System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception) { }
foreach (var genre in await api.Get_GenreAsync(WebContent))
foreach (var genre in await _api.Get_GenreAsync(WebContent))
{
if (!string.IsNullOrEmpty(genre))
{
@ -64,7 +66,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
}
}
GenreHelper.CleanupGenres(result.Item);
StoreImageUrl(aid, await api.Get_ImageUrlAsync(WebContent), "image");
StoreImageUrl(aid, await _api.Get_ImageUrlAsync(WebContent), "image");
}
return result;
}
@ -77,15 +79,14 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
if (!string.IsNullOrEmpty(aid))
{
if (!results.ContainsKey(aid))
results.Add(aid, await api.GetAnime(aid, cancellationToken));
results.Add(aid, await _api.GetAnime(aid, cancellationToken));
}
if (!string.IsNullOrEmpty(searchInfo.Name))
{
List<string> ids = await api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
List<string> ids = await _api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
foreach (string a in ids)
{
results.Add(a, await api.GetAnime(a, cancellationToken));
results.Add(a, await _api.GetAnime(a, cancellationToken));
}
}
@ -116,10 +117,12 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
{
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
private readonly Api _api;
public static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1);
public MyAnimeListSeriesImageProvider(IHttpClient httpClient, IApplicationPaths appPaths)
public MyAnimeListSeriesImageProvider(IHttpClient httpClient, IApplicationPaths appPaths, ILogManager logManager)
{
_api = new Api(logManager);
_httpClient = httpClient;
_appPaths = appPaths;
}
@ -145,7 +148,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
if (!string.IsNullOrEmpty(aid))
{
var primary = await api.Get_ImageUrlAsync(await api.WebRequestAPI(api.anime_link + aid));
var primary = await _api.Get_ImageUrlAsync(await _api.WebRequestAPI(_api.anime_link + aid, cancellationToken));
list.Add(new RemoteImageInfo
{
ProviderName = Name,

View File

@ -1,4 +1,5 @@
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
using MediaBrowser.Plugins.Anime.Configuration;
using System;
@ -14,16 +15,18 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <summary>
/// This API use the WebContent of MyAnimelist and the API of MyAnimelist
/// </summary>
internal class api
public class Api
{
public static List<string> anime_search_names = new List<string>();
public static List<string> anime_search_ids = new List<string>();
public List<string> anime_search_names = new List<string>();
public List<string> anime_search_ids = new List<string>();
private static ILogManager _log;
//Use API too search
public static string SearchLink = "https://myanimelist.net/api/anime/search.xml?q={0}";
public string SearchLink = "https://myanimelist.net/api/anime/search.xml?q={0}";
//Web Fallback search
public string FallbackSearchLink= "https://myanimelist.net/search/all?q={0}";
//No API funktion exist too get anime
public static string anime_link = "https://myanimelist.net/anime/info/";
public string anime_link = "https://myanimelist.net/anime/";
/// <summary>
/// WebContent API call to get a anime with id
@ -31,16 +34,20 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<RemoteSearchResult> GetAnime(string id, CancellationToken cancellationToken)
public Api(ILogManager logManager)
{
string WebContent = await WebRequestAPI(anime_link + id);
_log = logManager;
}
public async Task<RemoteSearchResult> GetAnime(string id, CancellationToken cancellationToken)
{
string WebContent = await WebRequestAPI(anime_link + id, cancellationToken);
var result = new RemoteSearchResult
{
Name = await SelectName(WebContent, Plugin.Instance.Configuration.TitlePreference, "en", cancellationToken)
};
result.SearchProviderName = WebUtility.HtmlDecode(await one_line_regex(new Regex("<span itemprop=\"name\">" + @"(.*?)<"), WebContent));
result.SearchProviderName = WebUtility.HtmlDecode(await One_line_regex(new Regex("<span itemprop=\"name\">" + @"(.*?)<"), WebContent));
result.ImageUrl = await Get_ImageUrlAsync(WebContent);
result.SetProviderId(MyAnimeListSeriesProvider.provider_name, id);
result.Overview = await Get_OverviewAsync(WebContent);
@ -56,14 +63,10 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private static async Task<string> SelectName(string WebContent, TitlePreferenceType preference, string language, CancellationToken cancellationToken)
private async Task<string> SelectName(string WebContent, TitlePreferenceType preference, string language, CancellationToken cancellationToken)
{
if (preference == TitlePreferenceType.Localized && language == "en")
return await Get_title("en", WebContent);
if (preference == TitlePreferenceType.Localized && language == "de")
return await Get_title("de", WebContent);
if (preference == TitlePreferenceType.Localized && language == "ger")
return await Get_title("de", WebContent);
if (preference == TitlePreferenceType.Japanese)
return await Get_title("jap", WebContent);
@ -76,19 +79,19 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="lang"></param>
/// <param name="WebContent"></param>
/// <returns></returns>
public static async Task<string> Get_title(string lang, string WebContent)
public async Task<string> Get_title(string lang, string WebContent)
{
switch (lang)
{
case "en":
return WebUtility.HtmlDecode(await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"English:<\/span>(?s)(.*?)<"), WebContent)));
return WebUtility.HtmlDecode(await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"English:<\/span>(?s)(.*?)<"), WebContent)));
case "jap":
return WebUtility.HtmlDecode(await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"Japanese:<\/span>(?s)(.*?)<"), WebContent)));
return WebUtility.HtmlDecode(await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"Japanese:<\/span>(?s)(.*?)<"), WebContent)));
//Default is jap_r
default:
return WebUtility.HtmlDecode(await one_line_regex(new Regex("<span itemprop=\"name\">" + @"(.*?)<"), WebContent));
return WebUtility.HtmlDecode(await One_line_regex(new Regex("<span itemprop=\"name\">" + @"(.*?)<"), WebContent));
}
}
@ -97,12 +100,12 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public static async Task<List<string>> Get_GenreAsync(string WebContent)
public async Task<List<string>> Get_GenreAsync(string WebContent)
{
List<string> result = new List<string>();
try
{
List<string> result = new List<string>();
string Genres = await one_line_regex(new Regex(@"\.setTargeting\(" + "\"genres\"" + @", \[(.*?)\])"), WebContent);
string Genres = await One_line_regex(new Regex(@"\.setTargeting\(" + "\"genres\"" + @", \[(.*?)\])"), WebContent);
int x = 1;
Genres = Genres.Replace("\"", "");
foreach (string Genre in Genres.Split(','))
@ -117,9 +120,8 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
}
catch (Exception)
{
List<string> test = new List<string>();
test.Add("");
return test;
result.Add("");
return result;
}
}
@ -127,9 +129,9 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// WebContent API call get rating
/// </summary>
/// <param name="WebContent"></param>
public static async Task<string> Get_RatingAsync(string WebContent)
public async Task<string> Get_RatingAsync(string WebContent)
{
return await one_line_regex(new Regex("<span itemprop=\"ratingValue\">" + @"(.*?)<"), WebContent);
return await One_line_regex(new Regex("<span itemprop=\"ratingValue\">" + @"(.*?)<"), WebContent);
}
/// <summary>
@ -137,9 +139,9 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public static async Task<string> Get_ImageUrlAsync(string WebContent)
public async Task<string> Get_ImageUrlAsync(string WebContent)
{
return await one_line_regex(new Regex("src=\"" + @"(?s)(.*?)" + "\""), await one_line_regex(new Regex(" < div style=\"text - align: center; \">" + @"(?s)(.*?)alt="), WebContent));
return await One_line_regex(new Regex("src=\"" + @"(?s)(.*?)" + "\""), await One_line_regex(new Regex(" < div style=\"text - align: center; \">" + @"(?s)(.*?)alt="), WebContent));
}
/// <summary>
@ -147,9 +149,9 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// </summary>
/// <param name="WebContent"></param>
/// <returns></returns>
public static async Task<string> Get_OverviewAsync(string WebContent)
public async Task<string> Get_OverviewAsync(string WebContent)
{
return System.Net.WebUtility.HtmlDecode(await one_line_regex(new Regex("\"og: description\" content=\"" + @"(.*?)" + "\">"), WebContent));
return System.Net.WebUtility.HtmlDecode(await One_line_regex(new Regex("itemprop=\\"+'"'+"description\\"+'"'+@">(.*?)<\/span>"), WebContent));
}
/// <summary>
@ -158,46 +160,44 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="title"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<string> Search_GetSeries(string title, CancellationToken cancellationToken)
public async Task<string> Search_GetSeries(string title, CancellationToken cancellationToken)
{
anime_search_names.Clear();
anime_search_ids.Clear();
string result = null;
string result_text = null;
string WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(title)), Plugin.Instance.Configuration.MyAnimeList_API_Name, Plugin.Instance.Configuration.MyAnimeList_API_Pw);
//API
if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.MyAnimeList_API_Name) && !string.IsNullOrEmpty(Plugin.Instance.Configuration.MyAnimeList_API_Pw))
{
string WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(title)), cancellationToken, Plugin.Instance.Configuration.MyAnimeList_API_Name, Plugin.Instance.Configuration.MyAnimeList_API_Pw);
int x = 0;
while (result_text != "")
{
result_text = await one_line_regex(new Regex(@"<entry>(.*?)<\/entry>"), WebContent, 1, x);
result_text = await One_line_regex(new Regex(@"<entry>(.*?)<\/entry>"), WebContent, 1, x);
if (result_text != "")
{
//get id
string id = await one_line_regex(new Regex(@"<id>(.*?)<\/id>"), result_text);
string a_name = await one_line_regex(new Regex(@"<title>(.*?)<\/title>"), result_text);
string b_name = await one_line_regex(new Regex(@"<english>(.*?)<\/english>"), result_text);
string c_name = await one_line_regex(new Regex(@"<synonyms>(.*?)<\/synonyms>"), result_text);
string id = await One_line_regex(new Regex(@"<id>(.*?)<\/id>"), result_text);
string a_name = await One_line_regex(new Regex(@"<title>(.*?)<\/title>"), result_text);
string b_name = await One_line_regex(new Regex(@"<english>(.*?)<\/english>"), result_text);
string c_name = await One_line_regex(new Regex(@"<synonyms>(.*?)<\/synonyms>"), result_text);
if (Equals_check.Compare_strings(a_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
result = id;
return result;
return id;
}
if (Equals_check.Compare_strings(b_name, title))
if (await Equals_check.Compare_strings(b_name, title, cancellationToken))
{
result = id;
return result;
return id;
}
foreach (string d_name in c_name.Split(';'))
{
if (Equals_check.Compare_strings(d_name, title))
if (await Equals_check.Compare_strings(d_name, title, cancellationToken))
{
result = id;
return result;
return id;
}
}
int n;
if (Int32.TryParse(id, out n))
if (Int32.TryParse(id, out int n))
{
anime_search_names.Add(a_name);
anime_search_ids.Add(id);
@ -205,7 +205,43 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
}
x++;
}
return result;
}
else
{
//Fallback to Web
string WebContent = await WebRequestAPI(string.Format(FallbackSearchLink, Uri.EscapeUriString(title)), cancellationToken);
string Regex_id = "-";
int x = 0;
while (!string.IsNullOrEmpty(Regex_id))
{
Regex_id = "";
Regex_id = await One_line_regex(new Regex(@"(#revInfo(.*?)" + '"' + "(>(.*?)<))"), WebContent, 2, x);
String Regex_name = await One_line_regex(new Regex(@"(#revInfo(.*?)" + '"' + "(>(.*?)<))"), WebContent, 4, x);
if (!string.IsNullOrEmpty(Regex_id) && !string.IsNullOrEmpty(Regex_name))
{
try
{
int.Parse(Regex_id);
if (await Equals_check.Compare_strings(Regex_name, title, cancellationToken))
{
return Regex_id;
}
}
catch (Exception)
{
//AnyLog
}
}
else
{
Regex_id = "";
}
x++;
}
}
return "";
}
/// <summary>
@ -214,48 +250,82 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="title"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<List<string>> Search_GetSeries_list(string title, CancellationToken cancellationToken)
public async Task<List<string>> Search_GetSeries_list(string title, CancellationToken cancellationToken)
{
List<string> result = new List<string>();
string result_text = null;
string WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(title)), Plugin.Instance.Configuration.MyAnimeList_API_Name, Plugin.Instance.Configuration.MyAnimeList_API_Pw);
int x = 0;
while (result_text != "")
//API
if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.MyAnimeList_API_Name) && !string.IsNullOrEmpty(Plugin.Instance.Configuration.MyAnimeList_API_Pw))
{
result_text = await one_line_regex(new Regex(@"<entry>(.*?)<\/entry>"), WebContent, 1, x);
if (result_text != "")
string WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(title)), cancellationToken, Plugin.Instance.Configuration.MyAnimeList_API_Name, Plugin.Instance.Configuration.MyAnimeList_API_Pw);
int x = 0;
while (result_text != "")
{
//get id
string id = await one_line_regex(new Regex(@"<id>(.*?)<\/id>"), result_text);
string a_name = await one_line_regex(new Regex(@"<title>(.*?)<\/title>"), result_text);
string b_name = await one_line_regex(new Regex(@"<english>(.*?)<\/english>"), result_text);
string c_name = await one_line_regex(new Regex(@"<synonyms>(.*?)<\/synonyms>"), result_text);
result_text = await One_line_regex(new Regex(@"<entry>(.*?)<\/entry>"), WebContent, 1, x);
if (result_text != "")
{
//get id
string id = await One_line_regex(new Regex(@"<id>(.*?)<\/id>"), result_text);
string a_name = await One_line_regex(new Regex(@"<title>(.*?)<\/title>"), result_text);
string b_name = await One_line_regex(new Regex(@"<english>(.*?)<\/english>"), result_text);
string c_name = await One_line_regex(new Regex(@"<synonyms>(.*?)<\/synonyms>"), result_text);
if (Equals_check.Compare_strings(a_name, title))
{
result.Add(id);
return result;
}
if (Equals_check.Compare_strings(b_name, title))
{
result.Add(id);
return result;
}
foreach (string d_name in c_name.Split(';'))
{
if (Equals_check.Compare_strings(d_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
result.Add(id);
return result;
}
if (await Equals_check.Compare_strings(b_name, title, cancellationToken))
{
result.Add(id);
return result;
}
foreach (string d_name in c_name.Split(';'))
{
if (await Equals_check.Compare_strings(d_name, title, cancellationToken))
{
result.Add(id);
return result;
}
}
if (Int32.TryParse(id, out int n))
{
result.Add(id);
}
}
int n;
if (Int32.TryParse(id, out n))
{
result.Add(id);
}
x++;
}
x++;
}
else
{
//Fallback to Web
string WebContent = await WebRequestAPI(string.Format(FallbackSearchLink, Uri.EscapeUriString(title)), cancellationToken);
string regex_id = "-";
int x = 0;
while (!string.IsNullOrEmpty(regex_id))
{
regex_id = "";
regex_id=await One_line_regex(new Regex(@"(#revInfo(.*?)"+'"'+"(>(.*?)<))"), WebContent, 2, x);
if (!string.IsNullOrEmpty(regex_id))
{
try
{
int.Parse(regex_id);
if (await Equals_check.Compare_strings(await One_line_regex(new Regex(@"(#revInfo(.*?)" + '"' + "(>(.*?)<))"), WebContent, 4, x), title, cancellationToken))
{
result.Add(regex_id);
return result;
}
}
catch (Exception)
{
//AnyLog
}
}
x++;
}
}
return result;
}
@ -266,7 +336,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="title"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<string> FindSeries(string title, CancellationToken cancellationToken)
public async Task<string> FindSeries(string title, CancellationToken cancellationToken)
{
string aid = await Search_GetSeries(title, cancellationToken);
if (!string.IsNullOrEmpty(aid))
@ -279,14 +349,14 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
foreach (string a_name in anime_search_names)
{
if (Equals_check.Compare_strings(a_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
return anime_search_ids[x];
}
x++;
}
}
aid = await Search_GetSeries(Equals_check.clear_name(title), cancellationToken);
aid = await Search_GetSeries(await Equals_check.Clear_name(title, cancellationToken), cancellationToken);
if (!string.IsNullOrEmpty(aid))
{
return aid;
@ -303,7 +373,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="group"></param>
/// <param name="match_int"></param>
/// <returns></returns>
public static async Task<string> one_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
public async Task<string> One_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
{
Regex _regex = regex;
int x = 0;
@ -326,15 +396,15 @@ namespace MediaBrowser.Plugins.Anime.Providers.MyAnimeList
/// <param name="name"></param>
/// <param name="pw"></param>
/// <returns></returns>
public static async Task<string> WebRequestAPI(string link, string name = null, string pw = null)
public async Task<string> WebRequestAPI(string link, CancellationToken cancellationToken, string name = null, string pw = null)
{
try
{
string encoded = await Task.Run(() => Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(name + ":" + pw)));
string encoded = await Task.Run(() => Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(name + ":" + pw)), cancellationToken);
string _strContent;
using (WebClient client = new WebClient())
{
if (!await Task.Run(() => string.IsNullOrEmpty(name)) && !await Task.Run(() => string.IsNullOrEmpty(pw)))
if (!await Task.Run(() => string.IsNullOrEmpty(name), cancellationToken) && !await Task.Run(() => string.IsNullOrEmpty(pw), cancellationToken))
{
client.Headers.Add("Authorization", "Basic " + encoded);
}

View File

@ -39,27 +39,27 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
if (string.IsNullOrEmpty(aid))
{
_log.Info("Start Proxer... Searching(" + info.Name + ")");
aid = await api.FindSeries(info.Name, cancellationToken);
aid = await Api.FindSeries(info.Name, cancellationToken);
}
if (!string.IsNullOrEmpty(aid))
{
string WebContent = await api.WebRequestAPI(api.Proxer_anime_link + aid);
string WebContent = await Api.WebRequestAPI(Api.Proxer_anime_link + aid);
result.Item = new Series();
result.HasMetadata = true;
result.Item.ProviderIds.Add(provider_name, aid);
result.Item.Overview = await api.Get_Overview(WebContent);
result.Item.Overview = await Api.Get_Overview(WebContent);
result.ResultLanguage = "ger";
try
{
result.Item.CommunityRating = float.Parse(await api.Get_Rating(WebContent), System.Globalization.CultureInfo.InvariantCulture);
result.Item.CommunityRating = float.Parse(await Api.Get_Rating(WebContent), System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception) { }
foreach (var genre in await api.Get_Genre(WebContent))
foreach (var genre in await Api.Get_Genre(WebContent))
result.Item.AddGenre(genre);
GenreHelper.CleanupGenres(result.Item);
StoreImageUrl(aid, await api.Get_ImageUrl(WebContent), "image");
StoreImageUrl(aid, await Api.Get_ImageUrl(WebContent), "image");
}
return result;
}
@ -72,15 +72,15 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
if (!string.IsNullOrEmpty(aid))
{
if (!results.ContainsKey(aid))
results.Add(aid, await api.GetAnime(aid));
results.Add(aid, await Api.GetAnime(aid));
}
if (!string.IsNullOrEmpty(searchInfo.Name))
{
List<string> ids = await api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
List<string> ids = await Api.Search_GetSeries_list(searchInfo.Name, cancellationToken);
foreach (string a in ids)
{
results.Add(a, await api.GetAnime(a));
results.Add(a, await Api.GetAnime(a));
}
}
@ -139,7 +139,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
if (!string.IsNullOrEmpty(aid))
{
var primary = api.Get_ImageUrl(await api.WebRequestAPI(api.Proxer_anime_link + aid));
var primary = Api.Get_ImageUrl(await Api.WebRequestAPI(Api.Proxer_anime_link + aid));
list.Add(new RemoteImageInfo
{
ProviderName = Name,

View File

@ -14,7 +14,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
/// API for http://proxer.me/ german anime database.
/// 🛈 Proxer does not have an API interface to work with
/// </summary>
internal class api
internal class Api
{
public static List<string> anime_search_names = new List<string>();
public static List<string> anime_search_ids = new List<string>();
@ -35,7 +35,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
Name = await SelectName(WebContent, Plugin.Instance.Configuration.TitlePreference, "en")
};
result.SearchProviderName = await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"<td><b>Original Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
result.SearchProviderName = await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"<td><b>Original Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
result.ImageUrl = await Get_ImageUrl(WebContent);
result.SetProviderId(ProxerSeriesProvider.provider_name, id);
result.Overview = await Get_Overview(WebContent);
@ -75,18 +75,18 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
switch (lang)
{
case "en":
return await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"<td><b>Englischer Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
return await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"<td><b>Englischer Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
case "de":
return await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"<td><b>Deutscher Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
return await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"<td><b>Deutscher Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
case "jap":
return await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"<td><b>Japanischer Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
return await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"<td><b>Japanischer Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
//Default is jap_r
default:
return await one_line_regex(new Regex(@">([\S\s]*?)<"), await one_line_regex(new Regex(@"<td><b>Original Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
return await One_line_regex(new Regex(@">([\S\s]*?)<"), await One_line_regex(new Regex(@"<td><b>Original Titel<\/b><\/td>([\S\s]*?)\/td>"), WebContent));
}
}
@ -98,12 +98,12 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
public static async Task<List<string>> Get_Genre(string WebContent)
{
List<string> result = new List<string>();
string Genres = await one_line_regex(new Regex(@"<b>Genre<\/b>((?:.*?\r?\n?)*)<\/tr>"), WebContent);
string Genres = await One_line_regex(new Regex(@"<b>Genre<\/b>((?:.*?\r?\n?)*)<\/tr>"), WebContent);
int x = 1;
string Proxer_Genre = null;
while (Proxer_Genre != "")
{
Proxer_Genre = await one_line_regex(new Regex("\">" + @"((?:.*?\r?\n?)*)<"), Genres, 1, x);
Proxer_Genre = await One_line_regex(new Regex("\">" + @"((?:.*?\r?\n?)*)<"), Genres, 1, x);
if (Proxer_Genre != "")
{
result.Add(Proxer_Genre);
@ -120,7 +120,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
/// <returns></returns>
public static async Task<string> Get_Rating(string WebContent)
{
return await one_line_regex(new Regex("<span class=\"average\">" + @"(.*?)<"), WebContent);
return await One_line_regex(new Regex("<span class=\"average\">" + @"(.*?)<"), WebContent);
}
/// <summary>
@ -130,7 +130,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
/// <returns></returns>
public static async Task<string> Get_ImageUrl(string WebContent)
{
return "http://" + await one_line_regex(new Regex("<img src=\"" + @"\/\/((?:.*?\r?\n?)*)" + "\""), WebContent);
return "http://" + await One_line_regex(new Regex("<img src=\"" + @"\/\/((?:.*?\r?\n?)*)" + "\""), WebContent);
}
/// <summary>
@ -140,7 +140,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
/// <returns></returns>
public static async Task<string> Get_Overview(string WebContent)
{
return await one_line_regex(new Regex(@"Beschreibung:<\/b><br>((?:.*?\r?\n?)*)<\/td>"), WebContent);
return await One_line_regex(new Regex(@"Beschreibung:<\/b><br>((?:.*?\r?\n?)*)<\/td>"), WebContent);
}
/// <summary>
@ -158,7 +158,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
string WebContent = "";
if (bettersearchresults)
{
WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(Equals_check.Half_string(title, 4,60))));
WebContent = await WebRequestAPI(string.Format(SearchLink, Uri.EscapeUriString(await Equals_check.Half_string(title, cancellationToken, 4,60))));
}
else
{
@ -167,19 +167,18 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
int x = 0;
while (result_text != "")
{
result_text = await one_line_regex(new Regex("<tr align=\"" + @"left(.*?)tr>"), WebContent, 1, x);
result_text = await One_line_regex(new Regex("<tr align=\"" + @"left(.*?)tr>"), WebContent, 1, x);
if (result_text != "")
{
//get id
string id = await one_line_regex(new Regex("class=\"entry" + @"(.*?)" + "\">"), result_text);
string a_name = await one_line_regex(new Regex("#top\">" + @"(.*?)</a>"), result_text);
if (Equals_check.Compare_strings(a_name, title))
string id = await One_line_regex(new Regex("class=\"entry" + @"(.*?)" + "\">"), result_text);
string a_name = await One_line_regex(new Regex("#top\">" + @"(.*?)</a>"), result_text);
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
result = id;
return result;
}
int n;
if (Int32.TryParse(id, out n))
if (Int32.TryParse(id, out int n))
{
anime_search_names.Add(a_name);
anime_search_ids.Add(id);
@ -205,20 +204,19 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
int x = 0;
while (result_text != "")
{
result_text = await one_line_regex(new Regex("<tr align=\"" + @"left(.*?)tr>"), WebContent, 1, x);
result_text = await One_line_regex(new Regex("<tr align=\"" + @"left(.*?)tr>"), WebContent, 1, x);
if (result_text != "")
{
//get id
string id = await one_line_regex(new Regex("class=\"entry" + @"(.*?)" + "\">"), result_text);
string a_name = await one_line_regex(new Regex("#top\">" + @"(.*?)</a>"), result_text);
if (Equals_check.Compare_strings(a_name, title))
string id = await One_line_regex(new Regex("class=\"entry" + @"(.*?)" + "\">"), result_text);
string a_name = await One_line_regex(new Regex("#top\">" + @"(.*?)</a>"), result_text);
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
result.Add(id);
return result;
}
int n;
if (Int32.TryParse(id, out n))
if (Int32.TryParse(id, out int n))
{
result.Add(id);
}
@ -247,19 +245,19 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
foreach (string a_name in anime_search_names)
{
if (Equals_check.Compare_strings(a_name, title))
if (await Equals_check.Compare_strings(a_name, title, cancellationToken))
{
return anime_search_ids[x];
}
x++;
}
}
aid = await Search_GetSeries(Equals_check.clear_name(title), cancellationToken,true);
aid = await Search_GetSeries(await Equals_check.Clear_name(title, cancellationToken), cancellationToken,true);
if (!string.IsNullOrEmpty(aid))
{
return aid;
}
aid = await Search_GetSeries(Equals_check.clear_name_step2(title), cancellationToken,true);
aid = await Search_GetSeries(await Equals_check.Clear_name_step2(title, cancellationToken), cancellationToken,true);
if (!string.IsNullOrEmpty(aid))
{
return aid;
@ -275,7 +273,7 @@ namespace MediaBrowser.Plugins.Anime.Providers.Proxer
/// <param name="group"></param>
/// <param name="match_int"></param>
/// <returns></returns>
public static async Task<string> one_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
public static async Task<string> One_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
{
Regex _regex = regex;
int x = 0;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
@ -24,11 +25,11 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static string clear_name(string a)
public async static Task<string> Clear_name(string a, CancellationToken cancellationToken)
{
try
{
a = a.Trim().Replace(one_line_regex(new Regex(@"(?s) \(.*?\)"), a.Trim(), 0), "");
a = a.Trim().Replace(await One_line_regex(new Regex(@"(?s) \(.*?\)"), a.Trim(), cancellationToken, 0), "");
}
catch (Exception)
{ }
@ -37,9 +38,11 @@ namespace MediaBrowser.Plugins.Anime.Providers
a = a.Replace("`", "");
a = a.Replace("'", "");
a = a.Replace("&", "and");
a = a.Replace("(", "");
a = a.Replace(")", "");
try
{
a = a.Replace(one_line_regex(new Regex(@"(?s)(S[0-9]+)"), a.Trim()), one_line_regex(new Regex(@"(?s)S([0-9]+)"), a.Trim()));
a = a.Replace(await One_line_regex(new Regex(@"(?s)(S[0-9]+)"), a.Trim(), cancellationToken), await One_line_regex(new Regex(@"(?s)S([0-9]+)"), a.Trim(), cancellationToken));
}
catch (Exception)
{
@ -53,11 +56,11 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static string clear_name_step2(string a)
public async static Task<string> Clear_name_step2(string a, CancellationToken cancellationToken)
{
try
{
a = a.Trim().Replace(one_line_regex(new Regex(@"(?s) \(.*?\)"), a.Trim(), 0), "");
a = a.Trim().Replace(await One_line_regex(new Regex(@"(?s) \(.*?\)"), a.Trim(), cancellationToken, 0), "");
}
catch (Exception)
{ }
@ -69,6 +72,8 @@ namespace MediaBrowser.Plugins.Anime.Providers
a = a.Replace(":", "");
a = a.Replace("␣", "");
a = a.Replace("2wei", "zwei");
a = a.Replace("3rei", "drei");
a = a.Replace("4ier", "vier");
return a;
}
@ -78,20 +83,20 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool Compare_strings(string a, string b)
public async static Task<bool> Compare_strings(string a, string b, CancellationToken cancellationToken)
{
if (!string.IsNullOrEmpty(a) && !string.IsNullOrEmpty(b))
{
if (simple_compare(a, b))
if (await Simple_compare(a, b, cancellationToken))
return true;
if (Fast_xml_search(a, b))
if (await Fast_xml_search(a, b, cancellationToken))
return true;
return false;
}
return false;
}
/// <summary>
/// Cut p(%) away from the string
/// </summary>
@ -99,10 +104,10 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <param name="min_lenght"></param>
/// <param name="p"></param>
/// <returns></returns>
public static string Half_string(string string_, int min_lenght = 0, int p = 50)
public async static Task<string> Half_string(string string_, CancellationToken cancellationToken, int min_lenght = 0, int p = 50)
{
decimal length = 0;
if ((int)((decimal)string_.Length - (((decimal)string_.Length / 100m) * (decimal)p)) > min_lenght)
if (await Task.Run(() => ((int)((decimal)string_.Length - (((decimal)string_.Length / 100m) * (decimal)p)) > min_lenght), cancellationToken))
{
length = (decimal)string_.Length - (((decimal)string_.Length / 100m) * (decimal)p);
}
@ -128,7 +133,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <param name="group"></param>
/// <param name="match_int"></param>
/// <returns></returns>
public static string one_line_regex(Regex regex, string match, int group = 1, int match_int = 0)
public async static Task<string> One_line_regex(Regex regex, string match, CancellationToken cancellationToken, int group = 1, int match_int = 0)
{
Regex _regex = regex;
int x = 0;
@ -136,7 +141,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
{
if (x == match_int)
{
return _match.Groups[group].Value.ToString();
return await Task.Run(() => _match.Groups[group].Value.ToString(), cancellationToken);
}
x++;
}
@ -147,24 +152,24 @@ namespace MediaBrowser.Plugins.Anime.Providers
///Return true if a and b match return false if not
///It loads the titles.xml on exceptions
/// </summary>
private static bool Fast_xml_search(string a, string b, bool return_AniDBid = false, bool retry = false)
private async static Task<bool> Fast_xml_search(string a, string b, CancellationToken cancellationToken, bool return_AniDBid = false, bool retry = false)
{
//Get AID aid=\"([s\S].*)\">
try
{
List<string> pre_aid = new List<string>();
string xml = File.ReadAllText(get_anidb_xml_file());
string xml = File.ReadAllText(Get_anidb_xml_file());
int x = 0;
string s1 = "-";
string s2 = "-";
while (!string.IsNullOrEmpty(s1) && !string.IsNullOrEmpty(s2))
{
s1 = one_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(Half_string(a, 4))), xml, 1, x);
s1 = await One_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(await Half_string(a, cancellationToken,4))), xml, cancellationToken,1, x);
if (s1 != "")
{
pre_aid.Add(s1);
}
s2 = one_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(Half_string(b, 4))), xml, 1, x);
s2 = await One_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(await Half_string(b, cancellationToken,4))), xml, cancellationToken, 1, x);
if (s1 != "")
{
if (s1 != s2)
@ -176,11 +181,11 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
foreach (string _aid in pre_aid)
{
XElement doc = XElement.Parse("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>" + "<animetitles>" + one_line_regex(new Regex("<anime aid=\"" + _aid + "\">" + @"(?s)(.*?)<\/anime>"), xml, 0) + "</animetitles>");
XElement doc = await Task.Run(async () => XElement.Parse("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>" + "<animetitles>" + await One_line_regex(await Task.Run(() => new Regex("<anime aid=\"" + _aid + "\">" + @"(?s)(.*?)<\/anime>"), cancellationToken), xml, cancellationToken, 0) + "</animetitles>"), cancellationToken);
var a_ = from page in doc.Elements("anime")
where _aid == page.Attribute("aid").Value
select page;
if (simple_compare(a_.Elements("title"), b) && simple_compare(a_.Elements("title"), a))
if (await Simple_compare( a_.Elements("title"), b, cancellationToken) && await Simple_compare(a_.Elements("title"), a, cancellationToken))
{
return true;
}
@ -195,8 +200,8 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
else
{
Task.Run(() => AniDbTitleDownloader.Load_static(new System.Threading.CancellationToken()));
return Fast_xml_search(a, b, false, true);
await Task.Run(() => AniDbTitleDownloader.Load_static(cancellationToken), cancellationToken);
return await Fast_xml_search(a, b, cancellationToken, false, true);
}
}
}
@ -204,24 +209,24 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <summary>
/// Return the AniDB ID if a and b match
/// </summary>
public static string Fast_xml_search(string a, string b, bool return_AniDBid, int x_ = 0)
public async static Task<string> Fast_xml_search(string a, string b, CancellationToken cancellationToken, bool return_AniDBid, int x_ = 0)
{
//Get AID aid=\"([s\S].*)\">
try
{
List<string> pre_aid = new List<string>();
string xml = File.ReadAllText(get_anidb_xml_file());
string xml = File.ReadAllText(Get_anidb_xml_file());
int x = 0;
string s1 = "-";
string s2 = "-";
while (!string.IsNullOrEmpty(s1) && !string.IsNullOrEmpty(s2))
{
s1 = one_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(Half_string(a, 4))), xml, 1, x);
s1 = await One_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(await Half_string(a, cancellationToken, 4))), xml, cancellationToken, 1, x);
if (s1 != "")
{
pre_aid.Add(s1);
}
s2 = one_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(Half_string(b, 4))), xml, 1, x);
s2 = await One_line_regex(new Regex("<anime aid=" + "\"" + @"(\d+)" + "\"" + @">(?>[^<>]+|<(?!\/anime>)[^<>]*>)*?" + Regex.Escape(await Half_string(b, cancellationToken, 4))), xml, cancellationToken, 1, x);
if (s1 != "")
{
if (s1 != s2)
@ -233,11 +238,11 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
foreach (string _aid in pre_aid)
{
XElement doc = XElement.Parse("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>" + "<animetitles>" + one_line_regex(new Regex("<anime aid=\"" + _aid + "\">" + @"(?s)(.*?)<\/anime>"), xml, 0) + "</animetitles>");
XElement doc = XElement.Parse("<?xml version=\"1.0\" encoding=\"UTF - 8\"?>" + "<animetitles>" +await One_line_regex(new Regex("<anime aid=\"" + _aid + "\">" + @"(?s)(.*?)<\/anime>"), xml, cancellationToken,0, 0) + "</animetitles>");
var a_ = from page in doc.Elements("anime")
where _aid == page.Attribute("aid").Value
select page;
if (simple_compare(a_.Elements("title"), b) && simple_compare(a_.Elements("title"), a))
if (await Simple_compare(a_.Elements("title"), b, cancellationToken) && await Simple_compare(a_.Elements("title"), a, cancellationToken))
{
return _aid;
}
@ -252,8 +257,8 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
else
{
Task.Run(() => AniDbTitleDownloader.Load_static(new System.Threading.CancellationToken()));
return Fast_xml_search(a, b, true, 1);
await Task.Run(() => AniDbTitleDownloader.Load_static(cancellationToken), cancellationToken);
return await Fast_xml_search(a, b, cancellationToken, true, 1);
}
}
}
@ -262,7 +267,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// get file Path from anidb xml file
/// </summary>
/// <returns></returns>
private static string get_anidb_xml_file()
private static string Get_anidb_xml_file()
{
return AniDbTitleDownloader.TitlesFilePath_;
}
@ -271,7 +276,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// Compare 2 Strings, and it just works
/// SeriesA S2 == SeriesA Second Season | True;
/// </summary>
private static bool simple_compare(string a, string b, bool fastmode = false)
private async static Task<bool> Simple_compare(string a, string b, CancellationToken cancellationToken, bool fastmode = false)
{
if (fastmode)
{
@ -284,9 +289,9 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
}
if (Core_compare(a, b))
if (await Core_compare(a, b, cancellationToken))
return true;
if (Core_compare(b, a))
if (await Core_compare(b, a, cancellationToken))
return true;
return false;
@ -295,7 +300,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <summary>
/// Compare 2 Strings, and it just works
/// </summary>
private static bool Core_compare(string a, string b)
private async static Task<bool> Core_compare(string a, string b, CancellationToken cancellationToken)
{
if (a == b)
return true;
@ -303,9 +308,9 @@ namespace MediaBrowser.Plugins.Anime.Providers
a = a.ToLower().Replace(" ", "").Trim().Replace(".", "");
b = b.ToLower().Replace(" ", "").Trim().Replace(".", "");
if (clear_name(a) == clear_name(b))
if (await Clear_name(a, cancellationToken) == await Clear_name(b, cancellationToken))
return true;
if (clear_name_step2(a) == clear_name_step2(b))
if (await Clear_name_step2(a, cancellationToken) == await Clear_name_step2(b, cancellationToken))
return true;
if (a.Replace("-", " ") == b.Replace("-", " "))
return true;
@ -313,19 +318,19 @@ namespace MediaBrowser.Plugins.Anime.Providers
return true;
if (a.Replace("2", "secondseason") == b.Replace("2", "secondseason"))
return true;
if (convert_symbols_too_numbers(a, "I") == convert_symbols_too_numbers(b, "I"))
if (await Convert_symbols_too_numbers(a, "I", cancellationToken) == await Convert_symbols_too_numbers(b, "I", cancellationToken))
return true;
if (convert_symbols_too_numbers(a, "!") == convert_symbols_too_numbers(b, "!"))
if (await Convert_symbols_too_numbers(a, "!", cancellationToken) == await Convert_symbols_too_numbers(b, "!", cancellationToken))
return true;
if (a.Replace("ndseason", "") == b.Replace("ndseason", ""))
return true;
if (a.Replace("ndseason", "") == b)
return true;
if (one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 2) + one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 3) == one_line_regex(new Regex(@"((.*)s([0 - 9]))"), b, 2) + one_line_regex(new Regex(@"((.*)s([0 - 9]))"), b, 3))
if (!string.IsNullOrEmpty(one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 2) + one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 3)))
if (await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 2) + await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 3) == await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), b, cancellationToken, 2) + await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), b, cancellationToken, 3))
if (!string.IsNullOrEmpty(await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 2) + await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 3)))
return true;
if (one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 2) + one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 3) == b)
if (!string.IsNullOrEmpty(one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 2) + one_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, 3)))
if (await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 2) + await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 3) == b)
if (!string.IsNullOrEmpty(await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 2) + await One_line_regex(new Regex(@"((.*)s([0 - 9]))"), a, cancellationToken, 3)))
return true;
if (a.Replace("rdseason", "") == b.Replace("rdseason", ""))
return true;
@ -333,7 +338,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
return true;
try
{
if (a.Replace("2", "secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b.Replace("2", "secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), b, 0), ""))
if (a.Replace("2", "secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b.Replace("2", "secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), b, cancellationToken, 0), ""))
return true;
}
catch (Exception)
@ -341,7 +346,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace("2", "secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b)
if (a.Replace("2", "secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b)
return true;
}
catch (Exception)
@ -349,7 +354,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace(" 2", ":secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b.Replace(" 2", ":secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), b, 0), ""))
if (a.Replace(" 2", ":secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b.Replace(" 2", ":secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), b, cancellationToken, 0), ""))
return true;
}
catch (Exception)
@ -357,7 +362,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace(" 2", ":secondseason").Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b)
if (a.Replace(" 2", ":secondseason").Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b)
return true;
}
catch (Exception)
@ -365,7 +370,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b.Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), b, 0), ""))
if (a.Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b.Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), b, cancellationToken, 0), ""))
return true;
}
catch (Exception)
@ -373,7 +378,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "") == b)
if (a.Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "") == b)
return true;
}
catch (Exception)
@ -381,7 +386,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (b.Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), b, 0), "").Replace(" 2", ": second Season") == a)
if (b.Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), b, cancellationToken, 0), "").Replace(" 2", ": second Season") == a)
return true;
}
catch (Exception)
@ -397,7 +402,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
}
try
{
if (a.Replace(one_line_regex(new Regex(@"(?s)\(.*?\)"), a, 0), "").Replace(" 2", ":secondseason") == b)
if (a.Replace(await One_line_regex(new Regex(@"(?s)\(.*?\)"), a, cancellationToken, 0), "").Replace(" 2", ":secondseason") == b)
return true;
}
catch (Exception)
@ -412,7 +417,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <param name="input"></param>
/// <param name="symbol"></param>
/// <returns></returns>
private static string convert_symbols_too_numbers(string input, string symbol)
private async static Task<string> Convert_symbols_too_numbers(string input, string symbol, CancellationToken cancellationToken)
{
try
{
@ -421,7 +426,7 @@ namespace MediaBrowser.Plugins.Anime.Providers
int highest_number = 0;
while (!string.IsNullOrEmpty(regex_c))
{
regex_c = one_line_regex(new Regex(@"(" + symbol + @"+)"), input.ToLower().Trim(), 1, x).Trim();
regex_c = (await One_line_regex(new Regex(@"(" + symbol + @"+)"), input.ToLower().Trim(), cancellationToken, 1, x)).Trim();
if (highest_number < regex_c.Count())
highest_number = regex_c.Count();
x++;
@ -452,14 +457,60 @@ namespace MediaBrowser.Plugins.Anime.Providers
/// <param name="a_"></param>
/// <param name="b"></param>
/// <returns></returns>
private static bool simple_compare(IEnumerable<XElement> a_, string b)
private async static Task<bool> Simple_compare(IEnumerable<XElement> a_, string b, CancellationToken cancellationToken)
{
foreach (XElement a in a_)
bool ignore_date = true;
string a_date = "";
string b_date = "";
string b_date_ = await One_line_regex(new Regex(@"([0-9][0-9][0-9][0-9])"), b, cancellationToken);
if (!string.IsNullOrEmpty(b_date_))
{
if (simple_compare(a.Value, b, true))
return true;
b_date = b_date_;
}
if (!string.IsNullOrEmpty(b_date))
{
foreach (XElement a in a_)
{
if (ignore_date)
{
string a_date_ = await One_line_regex(new Regex(@"([0-9][0-9][0-9][0-9])"), a.Value, cancellationToken);
if (!string.IsNullOrEmpty(a_date_))
{
a_date = a_date_;
ignore_date = false;
}
}
}
}
if (!ignore_date)
{
if (a_date.Trim()==b_date.Trim())
{
foreach (XElement a in a_)
{
if (await Simple_compare(a.Value, b, cancellationToken, true))
return true;
}
}
else
{
return false;
}
return false;
}
else
{
foreach (XElement a in a_)
{
if (ignore_date)
{
if (await Simple_compare(a.Value, b, cancellationToken, true))
return true;
}
}
return false;
}
return false;
}
}
}