mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-19 17:32:38 +01:00
Fix: Use indexer's Multi Languages setting for pushed releases
(cherry picked from commit 35a2bc940328bf61b39dd0012867bdaa564ee489) Fixed: Calculating Custom Formats with languages in queue (cherry picked from commit 8af12cc4e7f71cf169392cd86ccf0eb81f6b375c) Closes #10273 Closes #10321
This commit is contained in:
parent
df77474314
commit
bc918ed3b5
@ -1,8 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download.Aggregation.Aggregators;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.TorrentRss;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
@ -61,6 +64,143 @@ public void should_return_parsed_language()
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().Equal(_remoteMovie.ParsedMovieInfo.Languages);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_multi_languages_when_indexer_id_has_multi_languages_configuration()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
var indexerDefinition = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
|
||||
};
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(1))
|
||||
.Returns(indexerDefinition);
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { }, releaseTitle);
|
||||
_remoteMovie.Release.IndexerId = 1;
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage, Language.French });
|
||||
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Get(1), Times.Once());
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_multi_languages_from_indexer_with_id_when_indexer_id_and_name_are_set()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
var indexerDefinition1 = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Name = "MyIndexer1",
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
|
||||
};
|
||||
var indexerDefinition2 = new IndexerDefinition
|
||||
{
|
||||
Id = 2,
|
||||
Name = "MyIndexer2",
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.German.Id } }
|
||||
};
|
||||
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(1))
|
||||
.Returns(indexerDefinition1);
|
||||
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.All())
|
||||
.Returns(new List<IndexerDefinition>() { indexerDefinition1, indexerDefinition2 });
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { }, releaseTitle);
|
||||
_remoteMovie.Release.IndexerId = 1;
|
||||
_remoteMovie.Release.Indexer = "MyIndexer2";
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage, Language.French });
|
||||
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Get(1), Times.Once());
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_multi_languages_when_indexer_name_has_multi_languages_configuration()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
var indexerDefinition = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Name = "MyIndexer (Prowlarr)",
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
|
||||
};
|
||||
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.FindByName("MyIndexer (Prowlarr)"))
|
||||
.Returns(indexerDefinition);
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { }, releaseTitle);
|
||||
_remoteMovie.Release.Indexer = "MyIndexer (Prowlarr)";
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage, Language.French });
|
||||
Mocker.GetMock<IIndexerFactory>().Verify(c => c.FindByName("MyIndexer (Prowlarr)"), Times.Once());
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_multi_languages_when_release_as_unknown_as_default_language_and_indexer_has_multi_languages_configuration()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
var indexerDefinition = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
|
||||
};
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(1))
|
||||
.Returns(indexerDefinition);
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { Language.Unknown }, releaseTitle);
|
||||
_remoteMovie.Release.IndexerId = 1;
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage, Language.French });
|
||||
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Get(1), Times.Once());
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_original_when_indexer_has_no_multi_languages_configuration()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
var indexerDefinition = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Settings = new TorrentRssIndexerSettings { }
|
||||
};
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(1))
|
||||
.Returns(indexerDefinition);
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { }, releaseTitle);
|
||||
_remoteMovie.Release.IndexerId = 1;
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage });
|
||||
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Get(1), Times.Once());
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_original_when_no_indexer_value()
|
||||
{
|
||||
var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup";
|
||||
|
||||
_remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List<Language> { }, releaseTitle);
|
||||
_remoteMovie.Release.Title = releaseTitle;
|
||||
|
||||
Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List<Language> { _movie.MovieMetadata.Value.OriginalLanguage });
|
||||
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_exclude_language_that_is_part_of_episode_title_when_release_tokens_contains_episode_title()
|
||||
{
|
||||
|
@ -7,6 +7,8 @@
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.TorrentRss;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.Events;
|
||||
using NzbDrone.Core.Parser;
|
||||
@ -84,6 +86,77 @@ public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_
|
||||
trackedDownload.RemoteMovie.Movie.Id.Should().Be(3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_indexer()
|
||||
{
|
||||
var episodeHistory = new MovieHistory()
|
||||
{
|
||||
DownloadId = "35238",
|
||||
SourceTitle = "TV Series S01",
|
||||
MovieId = 3,
|
||||
EventType = MovieHistoryEventType.Grabbed,
|
||||
};
|
||||
episodeHistory.Data.Add("indexer", "MyIndexer (Prowlarr)");
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
.Setup(s => s.FindByDownloadId(It.Is<string>(sr => sr == "35238")))
|
||||
.Returns(new List<MovieHistory>()
|
||||
{
|
||||
episodeHistory
|
||||
});
|
||||
|
||||
var indexerDefinition = new IndexerDefinition
|
||||
{
|
||||
Id = 1,
|
||||
Name = "MyIndexer (Prowlarr)",
|
||||
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
|
||||
};
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(indexerDefinition.Id))
|
||||
.Returns(indexerDefinition);
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.All())
|
||||
.Returns(new List<IndexerDefinition>() { indexerDefinition });
|
||||
|
||||
var remoteEpisode = new RemoteMovie
|
||||
{
|
||||
Movie = new Movie() { Id = 3 },
|
||||
ParsedMovieInfo = new ParsedMovieInfo()
|
||||
{
|
||||
MovieTitles = new List<string> { "A Movie" },
|
||||
Year = 1998
|
||||
}
|
||||
};
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), It.IsAny<int>(), null))
|
||||
.Returns(remoteEpisode);
|
||||
|
||||
var client = new DownloadClientDefinition()
|
||||
{
|
||||
Id = 1,
|
||||
Protocol = DownloadProtocol.Torrent
|
||||
};
|
||||
|
||||
var item = new DownloadClientItem()
|
||||
{
|
||||
Title = "A Movie 1998",
|
||||
DownloadId = "35238",
|
||||
DownloadClientInfo = new DownloadClientItemClientInfo
|
||||
{
|
||||
Protocol = client.Protocol,
|
||||
Id = client.Id,
|
||||
Name = client.Name
|
||||
}
|
||||
};
|
||||
|
||||
var trackedDownload = Subject.TrackDownload(client, item);
|
||||
|
||||
trackedDownload.Should().NotBeNull();
|
||||
trackedDownload.RemoteMovie.Should().NotBeNull();
|
||||
trackedDownload.RemoteMovie.Release.Should().NotBeNull();
|
||||
trackedDownload.RemoteMovie.Release.Indexer.Should().Be("MyIndexer (Prowlarr)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_unmap_tracked_download_if_movie_deleted()
|
||||
{
|
||||
|
44
src/NzbDrone.Core.Test/Indexers/IndexerRepositoryFixture.cs
Normal file
44
src/NzbDrone.Core.Test/Indexers/IndexerRepositoryFixture.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Indexers
|
||||
{
|
||||
[TestFixture]
|
||||
public class IndexerRepositoryFixture : DbTest<IndexerRepository, IndexerDefinition>
|
||||
{
|
||||
private void GivenIndexers()
|
||||
{
|
||||
var indexers = Builder<IndexerDefinition>.CreateListOfSize(2)
|
||||
.All()
|
||||
.With(c => c.Id = 0)
|
||||
.TheFirst(1)
|
||||
.With(x => x.Name = "MyIndexer (Prowlarr)")
|
||||
.TheNext(1)
|
||||
.With(x => x.Name = "My Second Indexer (Prowlarr)")
|
||||
.BuildList();
|
||||
|
||||
Subject.InsertMany(indexers);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_finds_with_name()
|
||||
{
|
||||
GivenIndexers();
|
||||
var found = Subject.FindByName("MyIndexer (Prowlarr)");
|
||||
found.Should().NotBeNull();
|
||||
found.Name.Should().Be("MyIndexer (Prowlarr)");
|
||||
found.Id.Should().Be(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_find_with_incorrect_case_name()
|
||||
{
|
||||
GivenIndexers();
|
||||
var found = Subject.FindByName("myindexer (prowlarr)");
|
||||
found.Should().BeNull();
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
@ -10,10 +12,13 @@ namespace NzbDrone.Core.Download.Aggregation.Aggregators
|
||||
{
|
||||
public class AggregateLanguages : IAggregateRemoteMovie
|
||||
{
|
||||
private readonly IIndexerFactory _indexerFactory;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public AggregateLanguages(Logger logger)
|
||||
public AggregateLanguages(IIndexerFactory indexerFactory,
|
||||
Logger logger)
|
||||
{
|
||||
_indexerFactory = indexerFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -66,6 +71,26 @@ public RemoteMovie Aggregate(RemoteMovie remoteMovie)
|
||||
languages = languages.Except(languagesToRemove).ToList();
|
||||
}
|
||||
|
||||
if ((languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown)) && releaseInfo?.Title?.IsNotNullOrWhiteSpace() == true)
|
||||
{
|
||||
IndexerDefinition indexer = null;
|
||||
|
||||
if (releaseInfo is { IndexerId: > 0 })
|
||||
{
|
||||
indexer = _indexerFactory.Get(releaseInfo.IndexerId);
|
||||
}
|
||||
else if (releaseInfo.Indexer?.IsNotNullOrWhiteSpace() == true)
|
||||
{
|
||||
indexer = _indexerFactory.FindByName(releaseInfo.Indexer);
|
||||
}
|
||||
|
||||
if (indexer?.Settings is IIndexerSettings settings && settings.MultiLanguages.Any() && Parser.Parser.HasMultipleLanguages(releaseInfo.Title))
|
||||
{
|
||||
// Use indexer setting for Multi-languages
|
||||
languages = settings.MultiLanguages.Select(i => (Language)i).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
// Use movie language as fallback if we couldn't parse a language
|
||||
if (languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown))
|
||||
{
|
||||
|
@ -124,8 +124,6 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
|
||||
if (parsedMovieInfo != null)
|
||||
{
|
||||
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", 0, null);
|
||||
|
||||
_aggregationService.Augment(trackedDownload.RemoteMovie);
|
||||
}
|
||||
|
||||
var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId);
|
||||
@ -156,17 +154,24 @@ public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, Do
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedDownload.RemoteMovie != null &&
|
||||
Enum.TryParse(grabbedEvent?.Data?.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags))
|
||||
if (trackedDownload.RemoteMovie != null)
|
||||
{
|
||||
trackedDownload.RemoteMovie.Release ??= new ReleaseInfo();
|
||||
trackedDownload.RemoteMovie.Release.IndexerFlags = flags;
|
||||
trackedDownload.RemoteMovie.Release.Indexer = trackedDownload.Indexer;
|
||||
trackedDownload.RemoteMovie.Release.Title = trackedDownload.RemoteMovie.ParsedMovieInfo?.ReleaseTitle;
|
||||
|
||||
if (Enum.TryParse(grabbedEvent?.Data?.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags))
|
||||
{
|
||||
trackedDownload.RemoteMovie.Release.IndexerFlags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate custom formats
|
||||
if (trackedDownload.RemoteMovie != null)
|
||||
{
|
||||
_aggregationService.Augment(trackedDownload.RemoteMovie);
|
||||
|
||||
// Calculate custom formats
|
||||
trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(trackedDownload.RemoteMovie, downloadItem.TotalSize);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
@ -19,8 +18,6 @@ namespace NzbDrone.Core.Indexers
|
||||
public abstract class IndexerBase<TSettings> : IIndexer
|
||||
where TSettings : IIndexerSettings, new()
|
||||
{
|
||||
private static readonly Regex MultiRegex = new (@"[_. ](?<multi>multi)[_. ]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
protected readonly IIndexerStatusService _indexerStatusService;
|
||||
protected readonly IConfigService _configService;
|
||||
protected readonly IParsingService _parsingService;
|
||||
@ -83,7 +80,7 @@ protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> re
|
||||
result.ForEach(c =>
|
||||
{
|
||||
// Use multi languages from setting if ReleaseInfo languages is empty
|
||||
if (c.Languages.Empty() && MultiRegex.IsMatch(c.Title) && settings.MultiLanguages.Any())
|
||||
if (c.Languages.Empty() && settings.MultiLanguages.Any() && Parser.Parser.HasMultipleLanguages(c.Title))
|
||||
{
|
||||
c.Languages = settings.MultiLanguages.Select(i => (Language)i).ToList();
|
||||
}
|
||||
|
@ -13,10 +13,12 @@ public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
|
||||
List<IIndexer> RssEnabled(bool filterBlockedIndexers = true);
|
||||
List<IIndexer> AutomaticSearchEnabled(bool filterBlockedIndexers = true);
|
||||
List<IIndexer> InteractiveSearchEnabled(bool filterBlockedIndexers = true);
|
||||
IndexerDefinition FindByName(string name);
|
||||
}
|
||||
|
||||
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
|
||||
{
|
||||
private readonly IIndexerRepository _indexerRepository;
|
||||
private readonly IIndexerStatusService _indexerStatusService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
@ -28,6 +30,7 @@ public IndexerFactory(IIndexerStatusService indexerStatusService,
|
||||
Logger logger)
|
||||
: base(providerRepository, providers, container, eventAggregator, logger)
|
||||
{
|
||||
_indexerRepository = providerRepository;
|
||||
_indexerStatusService = indexerStatusService;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -82,6 +85,11 @@ public List<IIndexer> InteractiveSearchEnabled(bool filterBlockedIndexers = true
|
||||
return enabledIndexers.ToList();
|
||||
}
|
||||
|
||||
public IndexerDefinition FindByName(string name)
|
||||
{
|
||||
return _indexerRepository.FindByName(name);
|
||||
}
|
||||
|
||||
private IEnumerable<IIndexer> FilterBlockedIndexers(IEnumerable<IIndexer> indexers)
|
||||
{
|
||||
var blockedIndexers = _indexerStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NzbDrone.Core.Datastore;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
@ -6,6 +7,7 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
public interface IIndexerRepository : IProviderRepository<IndexerDefinition>
|
||||
{
|
||||
IndexerDefinition FindByName(string name);
|
||||
}
|
||||
|
||||
public class IndexerRepository : ProviderRepository<IndexerDefinition>, IIndexerRepository
|
||||
@ -14,5 +16,10 @@ public IndexerRepository(IMainDatabase database, IEventAggregator eventAggregato
|
||||
: base(database, eventAggregator)
|
||||
{
|
||||
}
|
||||
|
||||
public IndexerDefinition FindByName(string name)
|
||||
{
|
||||
return Query(i => i.Name == name).SingleOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +171,9 @@ public static class Parser
|
||||
private static readonly Regex RequestInfoRegex = new Regex(@"^(?:\[.+?\])+", RegexOptions.Compiled);
|
||||
|
||||
private static readonly string[] Numbers = new[] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
||||
|
||||
private static readonly Regex MultiRegex = new (@"[_. ](?<multi>multi)[_. ]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static Dictionary<string, string> _umlautMappings = new Dictionary<string, string>
|
||||
{
|
||||
{ "ö", "oe" },
|
||||
@ -584,6 +587,11 @@ public static string RemoveFileExtension(string title)
|
||||
return title;
|
||||
}
|
||||
|
||||
public static bool HasMultipleLanguages(string title)
|
||||
{
|
||||
return MultiRegex.IsMatch(title);
|
||||
}
|
||||
|
||||
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
||||
{
|
||||
if (!matchCollection[0].Groups["title"].Success || matchCollection[0].Groups["title"].Value == "(")
|
||||
|
Loading…
Reference in New Issue
Block a user