mirror of
https://github.com/jellyfin/jellyfin-plugin-anisearch.git
synced 2024-11-26 23:50:40 +00:00
commit
01558ff5da
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ TestResults
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
.vs/
|
||||
x64/
|
||||
*_i.c
|
||||
*_p.c
|
||||
|
0
.vs/MediaBrowser.Plugins.Anime/v15/sqlite3/db.lock
Normal file
0
.vs/MediaBrowser.Plugins.Anime/v15/sqlite3/db.lock
Normal file
Binary file not shown.
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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'">
|
||||
|
@ -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))
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
386
MediaBrowser.Plugins.Anime/Providers/AniList/api.cs
Normal file
386
MediaBrowser.Plugins.Anime/Providers/AniList/api.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user