Revert "Merge branch 'aio' into better-search"

This reverts commit 638ee89de4, reversing
changes made to 287dc3e967.
This commit is contained in:
Nils Fürniß 2022-03-15 13:42:08 +01:00
parent 638ee89de4
commit 01db7a0dfd
No known key found for this signature in database
GPG Key ID: 79CB1318699409FF
6 changed files with 255 additions and 66 deletions

View File

@ -46,8 +46,6 @@ namespace Jellyfin.Plugin.AniDB.Configuration
public int TitleSimilarityThreshold { get; set; }
public bool IgnoreSeason { get; set; }
public int MaxGenres { get; set; }
public bool TidyGenreList { get; set; }

View File

@ -26,13 +26,6 @@
<option id="optLanguageJapaneseRomaji" value="JapaneseRomaji">Romaji</option>
</select>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="chkIgnoreSeason" name="chkIgnoreSeason" type="checkbox" is="emby-checkbox" />
<span>Ignore Season</span>
</label>
<div class="fieldDescription">AniDB doesn't support seasons. If checked, it will treat every season like season one, except for specials.</div>
</div>
<div class="inputContainer">
<label class="inputeLabel inputLabelUnfocused" for="chkTitleSimilarityThreshold">Title Similarity Threshold</label>
<input id="chkTitleSimilarityThreshold" name="chkTitleSimilarityThreshold" type="number" is="emby-input" min="0" />
@ -94,7 +87,6 @@
document.getElementById('titleLanguage').value = config.TitlePreference;
document.getElementById('originalTitleLanguage').value = config.OriginalTitlePreference;
document.getElementById('chkTitleSimilarityThreshold').value = config.TitleSimilarityThreshold;
document.getElementById('chkIgnoreSeason').checked = config.IgnoreSeason;
document.getElementById('chkMaxGenres').value = config.MaxGenres;
document.getElementById('chkTitleCaseGenres').checked = config.TitleCaseGenres;
document.getElementById('chkTidyGenres').checked = config.TidyGenreList;
@ -113,7 +105,6 @@
config.TitlePreference = document.getElementById('titleLanguage').value;
config.OriginalTitlePreference = document.getElementById('originalTitleLanguage').value;
config.TitleSimilarityThreshold = document.getElementById('chkTitleSimilarityThreshold').value;
config.IgnoreSeason = document.getElementById('chkIgnoreSeason').checked;
config.MaxGenres = document.getElementById('chkMaxGenres').value;
config.TitleCaseGenres = document.getElementById('chkTitleCaseGenres').checked;
config.TidyGenreList = document.getElementById('chkTidyGenres').checked;

View File

@ -0,0 +1,50 @@
using System.Text.RegularExpressions;
namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Converter
{
public struct AniDbEpisodeIdentity
{
private static readonly Regex _regex = new Regex(@"(?<series>\d+):(?<type>[S])?(?<epno>\d+)(-(?<epnoend>\d+))?");
public AniDbEpisodeIdentity(string id)
{
this = Parse(id).Value;
}
public AniDbEpisodeIdentity(string seriesId, int episodeNumber, int? episodeNumberEnd, string episodeType)
{
SeriesId = seriesId;
EpisodeNumber = episodeNumber;
EpisodeNumberEnd = episodeNumberEnd;
EpisodeType = episodeType;
}
public string SeriesId { get; private set; }
public int EpisodeNumber { get; private set; }
public int? EpisodeNumberEnd { get; private set; }
public string EpisodeType { get; private set; }
public override string ToString()
{
return string.Format("{0}:{1}{2}",
SeriesId,
EpisodeType ?? "",
EpisodeNumber + (EpisodeNumberEnd != null ? "-" + EpisodeNumberEnd.Value.ToString() : ""));
}
public static AniDbEpisodeIdentity? Parse(string id)
{
var match = _regex.Match(id);
if (match.Success)
{
return new AniDbEpisodeIdentity(
match.Groups["series"].Value,
int.Parse(match.Groups["epno"].Value),
match.Groups["epnoend"].Success ? int.Parse(match.Groups["epnoend"].Value) : (int?)null,
match.Groups["type"].Success ? match.Groups["type"].Value : null);
}
return null;
}
}
}

View File

@ -0,0 +1,71 @@
using System;
namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Converter
{
public struct TvdbEpisodeIdentity
{
public TvdbEpisodeIdentity(string id)
: this()
{
this = Parse(id).Value;
}
public TvdbEpisodeIdentity(string seriesId, int? seasonIndex, int episodeNumber, int? episodeNumberEnd)
: this()
{
SeriesId = seriesId;
SeasonIndex = seasonIndex;
EpisodeNumber = episodeNumber;
EpisodeNumberEnd = episodeNumberEnd;
}
public string SeriesId { get; private set; }
public int? SeasonIndex { get; private set; }
public int EpisodeNumber { get; private set; }
public int? EpisodeNumberEnd { get; private set; }
public override string ToString()
{
return string.Format("{0}:{1}:{2}",
SeriesId,
SeasonIndex != null ? SeasonIndex.Value.ToString() : "A",
EpisodeNumber + (EpisodeNumberEnd != null ? "-" + EpisodeNumberEnd.Value.ToString() : ""));
}
public static TvdbEpisodeIdentity? Parse(string id)
{
if (string.IsNullOrEmpty(id))
{
return null;
}
try
{
var parts = id.Split(':');
var series = parts[0];
var season = parts[1] != "A" ? (int?)int.Parse(parts[1]) : null;
int index;
int? indexEnd;
var split = parts[2].IndexOf("-", StringComparison.OrdinalIgnoreCase);
if (split != -1)
{
index = int.Parse(parts[2].Substring(0, split));
indexEnd = int.Parse(parts[2].Substring(split + 1));
}
else
{
index = int.Parse(parts[2]);
indexEnd = null;
}
return new TvdbEpisodeIdentity(series, season, index, indexEnd);
}
catch
{
return null;
}
}
}
}

View File

@ -6,6 +6,8 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Jellyfin.Plugin.AniDB.Providers.AniDB.Converter;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
@ -30,38 +32,30 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
_configurationManager = configurationManager;
}
public string Name => "AniDB";
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var result = new MetadataResult<Episode>();
var animeId = info.SeriesProviderIds.GetOrDefault(ProviderNames.AniDb);
if (string.IsNullOrEmpty(animeId))
var aniDbId = info.ProviderIds.GetOrDefault(ProviderNames.AniDb);
if (string.IsNullOrEmpty(aniDbId))
{
return result;
}
var seriesFolder = await FindSeriesFolder(animeId, cancellationToken);
var id = AniDbEpisodeIdentity.Parse(aniDbId);
if (id == null)
{
return result;
}
var seriesFolder = await FindSeriesFolder(id.Value.SeriesId, cancellationToken);
if (string.IsNullOrEmpty(seriesFolder))
{
return result;
}
if (!Plugin.Instance.Configuration.IgnoreSeason && info.ParentIndexNumber > 1)
{
return result;
}
string episodeType = "";
if (info.ParentIndexNumber == 0)
{
episodeType = "S";
}
var xml = GetEpisodeXmlFile(info.IndexNumber, episodeType, seriesFolder);
var xml = GetEpisodeXmlFile(id.Value.EpisodeNumber, id.Value.EpisodeType, seriesFolder);
if (xml == null || !xml.Exists)
{
return result;
@ -77,39 +71,71 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
await ParseEpisodeXml(xml, result.Item, info.MetadataLanguage).ConfigureAwait(false);
if (id.Value.EpisodeNumberEnd != null && id.Value.EpisodeNumberEnd > id.Value.EpisodeNumber)
{
for (var i = id.Value.EpisodeNumber + 1; i <= id.Value.EpisodeNumberEnd; i++)
{
var additionalXml = GetEpisodeXmlFile(i, id.Value.EpisodeType, seriesFolder);
if (additionalXml == null || !additionalXml.Exists)
{
continue;
}
await ParseAdditionalEpisodeXml(additionalXml, result.Item, info.MetadataLanguage).ConfigureAwait(false);
}
}
return result;
}
public string Name => "AniDB";
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
if (!searchInfo.IndexNumber.HasValue || !searchInfo.ParentIndexNumber.HasValue)
var list = new List<RemoteSearchResult>();
var id = AniDbEpisodeIdentity.Parse(searchInfo.ProviderIds.GetOrDefault(ProviderNames.AniDb));
if (id == null)
{
return new List<RemoteSearchResult>();
return list;
}
var metadataResult = await GetMetadata(searchInfo, cancellationToken).ConfigureAwait(false);
await AniDbSeriesProvider.GetSeriesData(
_configurationManager.ApplicationPaths,
id.Value.SeriesId,
cancellationToken).ConfigureAwait(false);
if (!metadataResult.HasMetadata)
try
{
return new List<RemoteSearchResult>();
}
var metadataResult = await GetMetadata(searchInfo, cancellationToken).ConfigureAwait(false);
var item = metadataResult.Item;
return new[]
{
new RemoteSearchResult
if (metadataResult.HasMetadata)
{
IndexNumber = item.IndexNumber,
Name = item.Name,
ParentIndexNumber = item.ParentIndexNumber,
PremiereDate = item.PremiereDate,
ProductionYear = item.ProductionYear,
ProviderIds = item.ProviderIds,
SearchProviderName = Name,
IndexNumberEnd = item.IndexNumberEnd
var item = metadataResult.Item;
list.Add(new RemoteSearchResult
{
IndexNumber = item.IndexNumber,
Name = item.Name,
ParentIndexNumber = item.ParentIndexNumber,
PremiereDate = item.PremiereDate,
ProductionYear = item.ProductionYear,
ProviderIds = item.ProviderIds,
SearchProviderName = Name,
IndexNumberEnd = item.IndexNumberEnd
});
}
};
}
catch (FileNotFoundException)
{
// Don't fail the provider because this will just keep on going and going.
}
catch (DirectoryNotFoundException)
{
// Don't fail the provider because this will just keep on going and going.
}
return list;
}
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
@ -118,6 +144,69 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
return imageProvider.GetImageResponse(url, cancellationToken);
}
private async Task ParseAdditionalEpisodeXml(FileInfo xml, Episode episode, string metadataLanguage)
{
var settings = new XmlReaderSettings
{
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
ValidationType = ValidationType.None
};
using (var streamReader = xml.OpenText())
using (var reader = XmlReader.Create(streamReader, settings))
{
await reader.MoveToContentAsync().ConfigureAwait(false);
var titles = new List<Title>();
while (await reader.ReadAsync().ConfigureAwait(false))
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "length":
var length = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrEmpty(length))
{
long duration;
if (long.TryParse(length, out duration))
{
episode.RunTimeTicks += TimeSpan.FromMinutes(duration).Ticks;
}
}
break;
case "title":
var language = reader.GetAttribute("xml:lang");
var name = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);
titles.Add(new Title
{
Language = language,
Type = "main",
Name = name
});
break;
}
}
}
var title = titles.Localize(Plugin.Instance.Configuration.TitlePreference, metadataLanguage).Name;
if (!string.IsNullOrEmpty(title))
{
title = ", " + title;
episode.Name += Plugin.Instance.Configuration.AniDbReplaceGraves
? title.Replace('`', '\'')
: title;
}
}
}
private async Task<string> FindSeriesFolder(string seriesId, CancellationToken cancellationToken)
{
var seriesDataPath = await AniDbSeriesProvider.GetSeriesData(_configurationManager.ApplicationPaths, seriesId, cancellationToken).ConfigureAwait(false);
@ -128,7 +217,6 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
{
var settings = new XmlReaderSettings
{
Async = true,
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
@ -196,18 +284,12 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
Name = name
});
break;
case "summary":
var overview = AniDbSeriesProvider.ReplaceNewLine(reader.ReadElementContentAsString());
episode.Overview = Plugin.Instance.Configuration.AniDbReplaceGraves ? overview.Replace('`', '\'') : overview;
break;
}
}
}
var title = titles.Localize(Configuration.TitlePreferenceType.Localized, preferredMetadataLanguage).Name;
var title = titles.Localize(Plugin.Instance.Configuration.TitlePreference, preferredMetadataLanguage).Name;
if (!string.IsNullOrEmpty(title))
{
episode.Name = Plugin.Instance.Configuration.AniDbReplaceGraves

View File

@ -202,7 +202,6 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
{
date = date.ToUniversalTime();
series.PremiereDate = date;
series.ProductionYear = date.Year;
}
}
@ -251,10 +250,9 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
break;
case "description":
var description = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);
description = description.TrimStart('*').Trim();
series.Overview = ReplaceNewLine(StripAniDbLinks(
Plugin.Instance.Configuration.AniDbReplaceGraves ? description.Replace('`', '\'') : description));
series.Overview = ReplaceLineFeedWithNewLine(
StripAniDbLinks(
await reader.ReadElementContentAsStringAsync().ConfigureAwait(false)));
break;
@ -410,9 +408,9 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
return AniDbUrlRegex.Replace(text, "${name}");
}
public static string ReplaceNewLine(string text)
public static string ReplaceLineFeedWithNewLine(string text)
{
return text.Replace("\n", "<br>");
return text.Replace("\n", Environment.NewLine);
}
private async Task ParseActors(MetadataResult<Series> series, XmlReader reader)
@ -523,8 +521,7 @@ namespace Jellyfin.Plugin.AniDB.Providers.AniDB.Metadata
}
else
{
series.AddPerson(CreatePerson(
Plugin.Instance.Configuration.AniDbReplaceGraves ? name.Replace('`', '\'') : name, type));
series.AddPerson(CreatePerson(name, type));
}
}
}