aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Library')
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs109
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs8
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs11
-rw-r--r--Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs32
-rw-r--r--Emby.Server.Implementations/Library/Validators/PeopleValidator.cs4
-rw-r--r--Emby.Server.Implementations/Library/Validators/YearsPostScanTask.cs57
7 files changed, 115 insertions, 108 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index a08c74474..4846a5768 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -462,7 +462,7 @@ namespace Emby.Server.Implementations.Library
if (parent != null)
{
- await parent.ValidateChildren(new Progress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
+ await parent.ValidateChildren(new SimpleProgress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
}
}
else if (parent != null)
@@ -1113,13 +1113,13 @@ namespace Emby.Server.Implementations.Library
progress.Report(.5);
// Start by just validating the children of the root, but go no further
- await RootFolder.ValidateChildren(new Progress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false);
+ await RootFolder.ValidateChildren(new SimpleProgress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false);
progress.Report(1);
await GetUserRootFolder().RefreshMetadata(cancellationToken).ConfigureAwait(false);
- await GetUserRootFolder().ValidateChildren(new Progress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false).ConfigureAwait(false);
+ await GetUserRootFolder().ValidateChildren(new SimpleProgress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false).ConfigureAwait(false);
progress.Report(2);
// Quickly scan CollectionFolders for changes
@@ -1204,25 +1204,24 @@ namespace Emby.Server.Implementations.Library
/// Gets the default view.
/// </summary>
/// <returns>IEnumerable{VirtualFolderInfo}.</returns>
- public IEnumerable<VirtualFolderInfo> GetVirtualFolders()
+ public List<VirtualFolderInfo> GetVirtualFolders()
{
- return GetView(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath);
+ return GetVirtualFolders(false);
}
- /// <summary>
- /// Gets the view.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>IEnumerable{VirtualFolderInfo}.</returns>
- private IEnumerable<VirtualFolderInfo> GetView(string path)
+ public List<VirtualFolderInfo> GetVirtualFolders(bool includeRefreshState)
{
var topLibraryFolders = GetUserRootFolder().Children.ToList();
- return _fileSystem.GetDirectoryPaths(path)
- .Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders));
+ var refreshQueue = includeRefreshState ? _providerManagerFactory().GetRefreshQueue() : null;
+
+ return _fileSystem.GetDirectoryPaths(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath)
+ .Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders, refreshQueue))
+ .OrderBy(i => i.Name)
+ .ToList();
}
- private VirtualFolderInfo GetVirtualFolderInfo(string dir, List<BaseItem> allCollectionFolders)
+ private VirtualFolderInfo GetVirtualFolderInfo(string dir, List<BaseItem> allCollectionFolders, Dictionary<Guid, Guid> refreshQueue)
{
var info = new VirtualFolderInfo
{
@@ -1248,6 +1247,13 @@ namespace Emby.Server.Implementations.Library
{
info.ItemId = libraryFolder.Id.ToString("N");
info.LibraryOptions = GetLibraryOptions(libraryFolder);
+
+ if (refreshQueue != null)
+ {
+ info.RefreshProgress = libraryFolder.GetRefreshProgress();
+
+ info.RefreshStatus = info.RefreshProgress.HasValue ? "Active" : refreshQueue.ContainsKey(libraryFolder.Id) ? "Queued" : "Idle";
+ }
}
return info;
@@ -2359,7 +2365,7 @@ namespace Emby.Server.Implementations.Library
public bool IsVideoFile(string path, LibraryOptions libraryOptions)
{
- var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new NullLogger());
+ var resolver = new VideoResolver(GetNamingOptions(), new NullLogger());
return resolver.IsVideoFile(path);
}
@@ -2370,7 +2376,7 @@ namespace Emby.Server.Implementations.Library
public bool IsAudioFile(string path, LibraryOptions libraryOptions)
{
- var parser = new AudioFileParser(GetNamingOptions(libraryOptions));
+ var parser = new AudioFileParser(GetNamingOptions());
return parser.IsAudioFile(path);
}
@@ -2505,34 +2511,42 @@ namespace Emby.Server.Implementations.Library
public NamingOptions GetNamingOptions()
{
- return GetNamingOptions(new LibraryOptions());
+ return GetNamingOptions(true);
}
+ public NamingOptions GetNamingOptions(bool allowOptimisticEpisodeDetection)
+ {
+ if (!allowOptimisticEpisodeDetection)
+ {
+ if (_namingOptionsWithoutOptimisticEpisodeDetection == null)
+ {
+ var namingOptions = new ExtendedNamingOptions();
+
+ InitNamingOptions(namingOptions);
+ namingOptions.EpisodeExpressions = namingOptions.EpisodeExpressions
+ .Where(i => i.IsNamed && !i.IsOptimistic)
+ .ToList();
+
+ _namingOptionsWithoutOptimisticEpisodeDetection = namingOptions;
+ }
+
+ return _namingOptionsWithoutOptimisticEpisodeDetection;
+ }
+
+ return GetNamingOptionsInternal();
+ }
+
+ private NamingOptions _namingOptionsWithoutOptimisticEpisodeDetection;
private NamingOptions _namingOptions;
private string[] _videoFileExtensions;
- public NamingOptions GetNamingOptions(LibraryOptions libraryOptions)
+ private NamingOptions GetNamingOptionsInternal()
{
if (_namingOptions == null)
{
var options = new ExtendedNamingOptions();
- // These cause apps to have problems
- options.AudioFileExtensions.Remove(".m3u");
- options.AudioFileExtensions.Remove(".wpl");
-
- //if (!libraryOptions.EnableArchiveMediaFiles)
- {
- options.AudioFileExtensions.Remove(".rar");
- options.AudioFileExtensions.Remove(".zip");
- }
+ InitNamingOptions(options);
- //if (!libraryOptions.EnableArchiveMediaFiles)
- {
- options.VideoFileExtensions.Remove(".rar");
- options.VideoFileExtensions.Remove(".zip");
- }
-
- options.VideoFileExtensions.Add(".tp");
_namingOptions = options;
_videoFileExtensions = _namingOptions.VideoFileExtensions.ToArray();
}
@@ -2540,6 +2554,27 @@ namespace Emby.Server.Implementations.Library
return _namingOptions;
}
+ private void InitNamingOptions(NamingOptions options)
+ {
+ // These cause apps to have problems
+ options.AudioFileExtensions.Remove(".m3u");
+ options.AudioFileExtensions.Remove(".wpl");
+
+ //if (!libraryOptions.EnableArchiveMediaFiles)
+ {
+ options.AudioFileExtensions.Remove(".rar");
+ options.AudioFileExtensions.Remove(".zip");
+ }
+
+ //if (!libraryOptions.EnableArchiveMediaFiles)
+ {
+ options.VideoFileExtensions.Remove(".rar");
+ options.VideoFileExtensions.Remove(".zip");
+ }
+
+ options.VideoFileExtensions.Add(".tp");
+ }
+
public ItemLookupInfo ParseName(string name)
{
var resolver = new VideoResolver(GetNamingOptions(), new NullLogger());
@@ -2918,7 +2953,7 @@ namespace Emby.Server.Implementations.Library
// No need to start if scanning the library because it will handle it
if (refreshLibrary)
{
- ValidateMediaLibrary(new Progress<double>(), CancellationToken.None);
+ ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
}
else
{
@@ -3046,7 +3081,7 @@ namespace Emby.Server.Implementations.Library
private void SyncLibraryOptionsToLocations(string virtualFolderPath, LibraryOptions options)
{
var topLibraryFolders = GetUserRootFolder().Children.ToList();
- var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders);
+ var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null);
if (info.Locations.Count > 0 && info.Locations.Count != options.PathInfos.Length)
{
@@ -3096,7 +3131,7 @@ namespace Emby.Server.Implementations.Library
// No need to start if scanning the library because it will handle it
if (refreshLibrary)
{
- ValidateMediaLibrary(new Progress<double>(), CancellationToken.None);
+ ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
}
else
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index 2e3d81474..e2f2946db 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
using MediaBrowser.Controller.Entities;
+using System.IO;
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
@@ -42,6 +43,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
if (_libraryManager.IsAudioFile(args.Path, libraryOptions))
{
+ if (string.Equals(Path.GetExtension(args.Path), ".cue", StringComparison.OrdinalIgnoreCase))
+ {
+ // if audio file exists of same name, return null
+
+ return null;
+ }
+
var collectionType = args.GetCollectionType();
var isMixed = string.IsNullOrWhiteSpace(collectionType);
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 806e20f00..70fe8d9ef 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -163,7 +163,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
private bool IsMultiDiscFolder(string path, LibraryOptions libraryOptions)
{
- var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(libraryOptions);
+ var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
var parser = new AlbumParser(namingOptions, new NullLogger());
var result = parser.ParseMultiPart(path);
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 60260e98a..e1c18c913 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -160,15 +160,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
return true;
}
- var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();
-
- // In mixed folders we need to be conservative and avoid expressions that may result in false positives (e.g. movies with numbers in the title)
- if (!isTvContentType)
- {
- namingOptions.EpisodeExpressions = namingOptions.EpisodeExpressions
- .Where(i => i.IsNamed && !i.IsOptimistic)
- .ToList();
- }
+ var allowOptimisticEpisodeDetection = isTvContentType;
+ var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(allowOptimisticEpisodeDetection);
var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new NullLogger());
var episodeInfo = episodeResolver.Resolve(fullName, false, false);
diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
index d4be2dabe..1a53ad672 100644
--- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
@@ -2,11 +2,14 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Persistence;
namespace Emby.Server.Implementations.Library.Validators
@@ -78,6 +81,35 @@ namespace Emby.Server.Implementations.Library.Validators
progress.Report(percent);
}
+ names = names.Select(i => i.RemoveDiacritics()).DistinctNames().ToList();
+
+ var artistEntities = _libraryManager.GetItemList(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(MusicArtist).Name }
+
+ }).Cast<MusicArtist>().ToList();
+
+ foreach (var artist in artistEntities)
+ {
+ if (!artist.IsAccessedByName)
+ {
+ continue;
+ }
+
+ var name = (artist.Name ?? string.Empty).RemoveDiacritics();
+
+ if (!names.Contains(name, StringComparer.OrdinalIgnoreCase))
+ {
+ _logger.Info("Deleting dead artist {0} {1}.", artist.Id.ToString("N"), artist.Name);
+
+ await _libraryManager.DeleteItem(artist, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+ }
+
progress.Report(100);
}
}
diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
index ef3b86abf..c2eb30ee4 100644
--- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -55,10 +55,6 @@ namespace Emby.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
{
- var innerProgress = new ActionableProgress<double>();
-
- innerProgress.RegisterAction(pct => progress.Report(pct * .15));
-
var people = _libraryManager.GetPeople(new InternalPeopleQuery());
var dict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
diff --git a/Emby.Server.Implementations/Library/Validators/YearsPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/YearsPostScanTask.cs
deleted file mode 100644
index 4afb4c04a..000000000
--- a/Emby.Server.Implementations/Library/Validators/YearsPostScanTask.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Emby.Server.Implementations.Library.Validators
-{
- public class YearsPostScanTask : ILibraryPostScanTask
- {
- private readonly ILibraryManager _libraryManager;
- private readonly ILogger _logger;
-
- public YearsPostScanTask(ILibraryManager libraryManager, ILogger logger)
- {
- _libraryManager = libraryManager;
- _logger = logger;
- }
-
- public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
- {
- var yearNumber = 1900;
- var maxYear = DateTime.UtcNow.Year + 3;
- var count = maxYear - yearNumber + 1;
- var numComplete = 0;
-
- while (yearNumber < maxYear)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- try
- {
- var year = _libraryManager.GetYear(yearNumber);
-
- await year.RefreshMetadata(cancellationToken).ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
- // Don't clutter the log
- throw;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error refreshing year {0}", ex, yearNumber);
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= count;
- percent *= 100;
-
- progress.Report(percent);
- yearNumber++;
- }
- }
- }
-}