mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-14 11:23:42 +02:00
parent
5251db7224
commit
a75e10c4c9
@ -3,6 +3,7 @@
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using Sonarr.Http;
|
||||
using Sonarr.Http.REST;
|
||||
|
||||
namespace NzbDrone.Api.Parse
|
||||
{
|
||||
@ -21,6 +22,12 @@ private ParseResource Parse()
|
||||
{
|
||||
var title = Request.Query.Title.Value as string;
|
||||
var path = Request.Query.Path.Value as string;
|
||||
|
||||
if (path.IsNullOrWhiteSpace() && title.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new BadRequestException("title or path is missing");
|
||||
}
|
||||
|
||||
var parsedEpisodeInfo = path.IsNotNullOrWhiteSpace() ? Parser.ParsePath(path) : Parser.ParseTitle(title);
|
||||
|
||||
if (parsedEpisodeInfo == null)
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Moq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
@ -43,5 +45,18 @@ public void should_fallback_to_title_without_year_and_year_when_title_lookup_fai
|
||||
.Verify(s => s.FindByTitle(parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear,
|
||||
parsedEpisodeInfo.SeriesTitleInfo.Year), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_concatenated_title()
|
||||
{
|
||||
var series = new Series { TvdbId = 100 };
|
||||
Mocker.GetMock<ISeriesService>().Setup(v => v.FindByTitle("Welcome")).Returns(series);
|
||||
Mocker.GetMock<ISceneMappingService>().Setup(v => v.FindTvdbId("Mairimashita", It.IsAny<string>())).Returns(100);
|
||||
|
||||
var result = Subject.GetSeries("Welcome (Mairimashita).S01E01.720p.WEB-DL-Viva");
|
||||
|
||||
result.Should().NotBeNull();
|
||||
result.TvdbId.Should().Be(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,5 +5,6 @@ public class SeriesTitleInfo
|
||||
public string Title { get; set; }
|
||||
public string TitleWithoutYear { get; set; }
|
||||
public int Year { get; set; }
|
||||
public string[] AllTitles { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -385,6 +385,9 @@ public static class Parser
|
||||
private static readonly Regex YearInTitleRegex = new Regex(@"^(?<title>.+?)(?:\W|_)?(?<year>\d{4})",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex TitleComponentsRegex = new Regex(@"^(?<title>.+?) \((?<title>.+?)\)$",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex WordDelimiterRegex = new Regex(@"(\s|\.|,|_|-|=|\|)+", RegexOptions.Compiled);
|
||||
private static readonly Regex PunctuationRegex = new Regex(@"[^\w\s]", RegexOptions.Compiled);
|
||||
private static readonly Regex CommonWordRegex = new Regex(@"\b(a|an|the|and|or|of)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
@ -670,13 +673,19 @@ private static SeriesTitleInfo GetSeriesTitleInfo(string title)
|
||||
{
|
||||
seriesTitleInfo.TitleWithoutYear = title;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
seriesTitleInfo.TitleWithoutYear = match.Groups["title"].Value;
|
||||
seriesTitleInfo.Year = Convert.ToInt32(match.Groups["year"].Value);
|
||||
}
|
||||
|
||||
var matchComponents = TitleComponentsRegex.Match(seriesTitleInfo.TitleWithoutYear);
|
||||
|
||||
if (matchComponents.Success)
|
||||
{
|
||||
seriesTitleInfo.AllTitles = matchComponents.Groups["title"].Captures.OfType<Capture>().Select(v => v.Value).ToArray();
|
||||
}
|
||||
|
||||
return seriesTitleInfo;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,11 @@ public Series GetSeries(string title)
|
||||
|
||||
var series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
|
||||
if (series == null && parsedEpisodeInfo.SeriesTitleInfo.AllTitles != null)
|
||||
{
|
||||
series = GetSeriesByAllTitles(parsedEpisodeInfo);
|
||||
}
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear,
|
||||
@ -66,6 +71,49 @@ public Series GetSeries(string title)
|
||||
return series;
|
||||
}
|
||||
|
||||
private Series GetSeriesByAllTitles(ParsedEpisodeInfo parsedEpisodeInfo)
|
||||
{
|
||||
Series foundSeries = null;
|
||||
int? foundTvdbId = null;
|
||||
|
||||
// Match each title individually, they must all resolve to the same tvdbid
|
||||
foreach (var title in parsedEpisodeInfo.SeriesTitleInfo.AllTitles)
|
||||
{
|
||||
var series = _seriesService.FindByTitle(title);
|
||||
var tvdbId = series?.TvdbId;
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
tvdbId = _sceneMappingService.FindTvdbId(title, parsedEpisodeInfo.ReleaseTitle);
|
||||
}
|
||||
|
||||
if (!tvdbId.HasValue)
|
||||
{
|
||||
_logger.Trace("Title {0} not matching any series.", title);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (foundTvdbId.HasValue && tvdbId != foundTvdbId)
|
||||
{
|
||||
_logger.Trace("Title {0} both matches tvdbid {1} and {2}, no series selected.", parsedEpisodeInfo.SeriesTitle, foundTvdbId, tvdbId);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (foundSeries == null)
|
||||
{
|
||||
foundSeries = series;
|
||||
}
|
||||
foundTvdbId = tvdbId;
|
||||
}
|
||||
|
||||
if (foundSeries == null && foundTvdbId.HasValue)
|
||||
{
|
||||
foundSeries = _seriesService.FindByTvdbId(foundTvdbId.Value);
|
||||
}
|
||||
|
||||
return foundSeries;
|
||||
}
|
||||
|
||||
public RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null)
|
||||
{
|
||||
var remoteEpisode = new RemoteEpisode
|
||||
@ -270,6 +318,11 @@ private Series GetSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tv
|
||||
|
||||
series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
|
||||
if (series == null && parsedEpisodeInfo.SeriesTitleInfo.AllTitles != null)
|
||||
{
|
||||
series = GetSeriesByAllTitles(parsedEpisodeInfo);
|
||||
}
|
||||
|
||||
if (series == null && parsedEpisodeInfo.SeriesTitleInfo.Year > 0)
|
||||
{
|
||||
series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear, parsedEpisodeInfo.SeriesTitleInfo.Year);
|
||||
|
@ -3,6 +3,7 @@
|
||||
using Sonarr.Api.V3.Episodes;
|
||||
using Sonarr.Api.V3.Series;
|
||||
using Sonarr.Http;
|
||||
using Sonarr.Http.REST;
|
||||
|
||||
namespace Sonarr.Api.V3.Parse
|
||||
{
|
||||
@ -21,6 +22,12 @@ private ParseResource Parse()
|
||||
{
|
||||
var title = Request.Query.Title.Value as string;
|
||||
var path = Request.Query.Path.Value as string;
|
||||
|
||||
if (path.IsNullOrWhiteSpace() && title.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new BadRequestException("title or path is missing");
|
||||
}
|
||||
|
||||
var parsedEpisodeInfo = path.IsNotNullOrWhiteSpace() ? Parser.ParsePath(path) : Parser.ParseTitle(title);
|
||||
|
||||
if (parsedEpisodeInfo == null)
|
||||
|
Loading…
Reference in New Issue
Block a user