Use Helper Methods for provider url parsing
This commit is contained in:
parent
954148eb6d
commit
14cbd22fbe
|
@ -4,6 +4,7 @@ using System;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using MediaBrowser.Common.Providers;
|
||||
|
||||
namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
|
@ -43,8 +44,8 @@ namespace Emby.Server.Implementations.Library
|
|||
// for imdbid we also accept pattern matching
|
||||
if (string.Equals(attribute, "imdbid", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var m = Regex.Match(str, "tt([0-9]{7,8})", RegexOptions.IgnoreCase);
|
||||
return m.Success ? m.Value : null;
|
||||
var match = ProviderIdParsers.TryParseImdbId(str, out var imdbId);
|
||||
return match ? imdbId : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
119
MediaBrowser.Common/Providers/ProviderIdParsers.cs
Normal file
119
MediaBrowser.Common/Providers/ProviderIdParsers.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace MediaBrowser.Common.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Parsers for provider ids.
|
||||
/// </summary>
|
||||
public static class ProviderIdParsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses an IMDb id from a string.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to parse.</param>
|
||||
/// <param name="imdbId">The parsed IMDb id.</param>
|
||||
/// <returns>True if parsing was successful, false otherwise.</returns>
|
||||
public static bool TryParseImdbId(string text, [NotNullWhen(true)] out string? imdbId)
|
||||
{
|
||||
var span = text.AsSpan();
|
||||
var tt = "tt".AsSpan();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var ttPos = span.IndexOf(tt);
|
||||
if (ttPos == -1)
|
||||
{
|
||||
imdbId = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
span = span.Slice(ttPos + tt.Length);
|
||||
|
||||
int i = 0;
|
||||
// IMDb id has a maximum of 8 digits
|
||||
int max = span.Length > 8 ? 8 : span.Length;
|
||||
for (; i < max; i++)
|
||||
{
|
||||
var c = span[i];
|
||||
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IMDb id has a minimum of 7 digits
|
||||
if (i >= 7)
|
||||
{
|
||||
imdbId = string.Concat(tt, span.Slice(0, i));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses an TMDb id from a movie url.
|
||||
/// </summary>
|
||||
/// <param name="text">The text with the url to parse.</param>
|
||||
/// <param name="tmdbId">The parsed TMDb id.</param>
|
||||
/// <returns>True if parsing was successful, false otherwise.</returns>
|
||||
public static bool TryParseTmdbMovieId(string text, [NotNullWhen(true)] out string? tmdbId)
|
||||
=> TryParseProviderId(text, "themoviedb.org/movie/", out tmdbId);
|
||||
|
||||
/// <summary>
|
||||
/// Parses an TMDb id from a series url.
|
||||
/// </summary>
|
||||
/// <param name="text">The text with the url to parse.</param>
|
||||
/// <param name="tmdbId">The parsed TMDb id.</param>
|
||||
/// <returns>True if parsing was successful, false otherwise.</returns>
|
||||
public static bool TryParseTmdbSeriesId(string text, [NotNullWhen(true)] out string? tmdbId)
|
||||
=> TryParseProviderId(text, "themoviedb.org/tv/", out tmdbId);
|
||||
|
||||
/// <summary>
|
||||
/// Parses an TVDb id from a url.
|
||||
/// </summary>
|
||||
/// <param name="text">The text with the url to parse.</param>
|
||||
/// <param name="tvdbId">The parsed TVDb id.</param>
|
||||
/// <returns>True if parsing was successful, false otherwise.</returns>
|
||||
public static bool TryParseTvdbId(string text, [NotNullWhen(true)] out string? tvdbId)
|
||||
=> TryParseProviderId(text, "thetvdb.com/?tab=series&id=", out tvdbId);
|
||||
|
||||
private static bool TryParseProviderId(string text, string searchString, [NotNullWhen(true)] out string? providerId)
|
||||
{
|
||||
var span = text.AsSpan();
|
||||
var searchSpan = searchString.AsSpan();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var searchPos = span.IndexOf(searchSpan);
|
||||
if (searchPos == -1)
|
||||
{
|
||||
providerId = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
span = span.Slice(searchPos + searchSpan.Length);
|
||||
|
||||
int i = 0;
|
||||
for (; i < span.Length; i++)
|
||||
{
|
||||
var c = span[i];
|
||||
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= 1)
|
||||
{
|
||||
providerId = span.Slice(0, i).ToString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,11 +6,12 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Providers;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
|
@ -63,8 +64,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
|
||||
protected virtual bool SupportsUrlAfterClosingXmlTag => false;
|
||||
|
||||
protected virtual string TmdbRegex => "themoviedb\\.org\\/movie\\/([0-9]+)";
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata for an item from one xml file.
|
||||
/// </summary>
|
||||
|
@ -220,31 +219,29 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
|
||||
protected void ParseProviderLinks(T item, string xml)
|
||||
{
|
||||
// IMDB:
|
||||
// https://www.imdb.com/title/tt4154796
|
||||
var imdbRegex = Regex.Match(xml, "tt([0-9]{7,8})", RegexOptions.Compiled);
|
||||
if (imdbRegex.Success)
|
||||
if (ProviderIdParsers.TryParseImdbId(xml, out var imdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProvider.Imdb, imdbRegex.Value);
|
||||
item.SetProviderId(MetadataProvider.Imdb, imdbId);
|
||||
}
|
||||
|
||||
// TMDB:
|
||||
// https://www.themoviedb.org/movie/30287-fallo (movie)
|
||||
// https://www.themoviedb.org/tv/1668-friends (tv)
|
||||
var tmdbRegex = Regex.Match(xml, TmdbRegex, RegexOptions.Compiled);
|
||||
if (tmdbRegex.Success)
|
||||
if (item is Movie)
|
||||
{
|
||||
item.SetProviderId(MetadataProvider.Tmdb, tmdbRegex.Groups[1].Value);
|
||||
if (ProviderIdParsers.TryParseTmdbMovieId(xml, out var tmdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProvider.Tmdb, tmdbId);
|
||||
}
|
||||
}
|
||||
|
||||
// TVDB:
|
||||
// https://www.thetvdb.com/?tab=series&id=121361
|
||||
if (item is Series)
|
||||
{
|
||||
var tvdbRegex = Regex.Match(xml, "thetvdb\\.com\\/\\?tab=series\\&id=([0-9]+)", RegexOptions.Compiled);
|
||||
if (tvdbRegex.Success)
|
||||
if (ProviderIdParsers.TryParseTmdbSeriesId(xml, out var tmdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProvider.Tvdb, tvdbRegex.Groups[1].Value);
|
||||
item.SetProviderId(MetadataProvider.Tmdb, tmdbId);
|
||||
}
|
||||
|
||||
if (ProviderIdParsers.TryParseTvdbId(xml, out var tvdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProvider.Tvdb, tvdbId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
/// <inheritdoc />
|
||||
protected override bool SupportsUrlAfterClosingXmlTag => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string TmdbRegex => "themoviedb\\.org\\/tv\\/([0-9]+)";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Series> itemResult)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
using MediaBrowser.Common.Providers;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Common.Tests.Providers
|
||||
{
|
||||
public class ProviderIdParserTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("tt123456", false, null)]
|
||||
[InlineData("tt1234567", true, "tt1234567")]
|
||||
[InlineData("tt12345678", true, "tt12345678")]
|
||||
[InlineData("https://www.imdb.com/title/tt123456", false, null)]
|
||||
[InlineData("https://www.imdb.com/title/tt1234567", true, "tt1234567")]
|
||||
[InlineData("https://www.imdb.com/title/tt12345678", true, "tt12345678")]
|
||||
[InlineData(@"multiline\nhttps://www.imdb.com/title/tt1234567", true, "tt1234567")]
|
||||
[InlineData(@"multiline\nhttps://www.imdb.com/title/tt12345678", true, "tt12345678")]
|
||||
[InlineData("Jellyfin", false, null)]
|
||||
[InlineData("tt1234567tt7654321", true, "tt1234567")]
|
||||
[InlineData("tt12345678tt7654321", true, "tt12345678")]
|
||||
public void Parse_Imdb(string text, bool shouldSucceed, string? imdbId)
|
||||
{
|
||||
var succeeded = ProviderIdParsers.TryParseImdbId(text, out string? parsedId);
|
||||
Assert.Equal(shouldSucceed, succeeded);
|
||||
Assert.Equal(imdbId, parsedId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://www.themoviedb.org/movie/30287-fallo", true, "30287")]
|
||||
[InlineData("themoviedb.org/movie/30287", true, "30287")]
|
||||
[InlineData("https://www.themoviedb.org/movie/fallo-30287", false, null)]
|
||||
[InlineData("https://www.themoviedb.org/tv/1668-friends", false, null)]
|
||||
public void Parse_TmdbMovie(string text, bool shouldSucceed, string? tmdbId)
|
||||
{
|
||||
var succeeded = ProviderIdParsers.TryParseTmdbMovieId(text, out string? parsedId);
|
||||
Assert.Equal(shouldSucceed, succeeded);
|
||||
Assert.Equal(tmdbId, parsedId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://www.themoviedb.org/tv/1668-friends", true, "1668")]
|
||||
[InlineData("themoviedb.org/tv/1668", true, "1668")]
|
||||
[InlineData("https://www.themoviedb.org/tv/friends-1668", false, null)]
|
||||
[InlineData("https://www.themoviedb.org/movie/30287-fallo", false, null)]
|
||||
public void Parse_TmdbSeries(string text, bool shouldSucceed, string? tmdbId)
|
||||
{
|
||||
var succeeded = ProviderIdParsers.TryParseTmdbSeriesId(text, out string? parsedId);
|
||||
Assert.Equal(shouldSucceed, succeeded);
|
||||
Assert.Equal(tmdbId, parsedId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://www.thetvdb.com/?tab=series&id=121361", true, "121361")]
|
||||
[InlineData("thetvdb.com/?tab=series&id=121361", true, "121361")]
|
||||
[InlineData("thetvdb.com/?tab=series&id=Jellyfin121361", false, null)]
|
||||
[InlineData("https://www.themoviedb.org/tv/1668-friends", false, null)]
|
||||
public void Parse_Tvdb(string text, bool shouldSucceed, string? tvdbId)
|
||||
{
|
||||
var succeeded = ProviderIdParsers.TryParseTvdbId(text, out string? parsedId);
|
||||
Assert.Equal(shouldSucceed, succeeded);
|
||||
Assert.Equal(tvdbId, parsedId);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user