aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Library
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library')
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs277
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs27
-rw-r--r--MediaBrowser.Server.Implementations/Library/MusicManager.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs18
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs19
-rw-r--r--MediaBrowser.Server.Implementations/Library/SearchEngine.cs266
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs42
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs29
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs29
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs30
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs42
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs30
13 files changed, 524 insertions, 319 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index bdc94b88b..cc9d9551c 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -3,12 +3,14 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
@@ -244,10 +246,6 @@ namespace MediaBrowser.Server.Implementations.Library
}
/// <summary>
- /// The _items by name path
- /// </summary>
- private string _itemsByNamePath;
- /// <summary>
/// The _season zero display name
/// </summary>
private string _seasonZeroDisplayName;
@@ -260,7 +258,6 @@ namespace MediaBrowser.Server.Implementations.Library
private void RecordConfigurationValues(ServerConfiguration configuration)
{
_seasonZeroDisplayName = configuration.SeasonZeroDisplayName;
- _itemsByNamePath = ConfigurationManager.ApplicationPaths.ItemsByNamePath;
_wizardCompleted = configuration.IsStartupWizardCompleted;
}
@@ -273,56 +270,24 @@ namespace MediaBrowser.Server.Implementations.Library
{
var config = ConfigurationManager.Configuration;
- var ibnPathChanged = !string.Equals(_itemsByNamePath, ConfigurationManager.ApplicationPaths.ItemsByNamePath, StringComparison.Ordinal);
-
- if (ibnPathChanged)
- {
- RemoveItemsByNameFromCache();
- }
-
var newSeasonZeroName = ConfigurationManager.Configuration.SeasonZeroDisplayName;
var seasonZeroNameChanged = !string.Equals(_seasonZeroDisplayName, newSeasonZeroName, StringComparison.Ordinal);
var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted;
RecordConfigurationValues(config);
- Task.Run(async () =>
+ if (seasonZeroNameChanged || wizardChanged)
{
- if (seasonZeroNameChanged)
- {
- await UpdateSeasonZeroNames(newSeasonZeroName, CancellationToken.None).ConfigureAwait(false);
- }
-
- if (seasonZeroNameChanged || ibnPathChanged || wizardChanged)
- {
- _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
- }
- });
- }
+ _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
+ }
- private void RemoveItemsByNameFromCache()
- {
- RemoveItemsFromCache(i => i is Person);
- RemoveItemsFromCache(i => i is Year);
- RemoveItemsFromCache(i => i is Genre);
- RemoveItemsFromCache(i => i is MusicGenre);
- RemoveItemsFromCache(i => i is GameGenre);
- RemoveItemsFromCache(i => i is Studio);
- RemoveItemsFromCache(i =>
+ if (seasonZeroNameChanged)
{
- var artist = i as MusicArtist;
- return artist != null && artist.IsAccessedByName;
- });
- }
-
- private void RemoveItemsFromCache(Func<BaseItem, bool> remove)
- {
- var items = _libraryItemsCache.ToList().Where(i => remove(i.Value)).ToList();
+ Task.Run(async () =>
+ {
+ await UpdateSeasonZeroNames(newSeasonZeroName, CancellationToken.None).ConfigureAwait(false);
- foreach (var item in items)
- {
- BaseItem value;
- _libraryItemsCache.TryRemove(item.Key, out value);
+ });
}
}
@@ -374,6 +339,21 @@ namespace MediaBrowser.Server.Implementations.Library
private void RegisterItem(Guid id, BaseItem item)
{
+ if (item is LiveTvProgram)
+ {
+ return;
+ }
+ if (item is IChannelItem)
+ {
+ return;
+ }
+ if (item is IItemByName)
+ {
+ if (!(item is MusicArtist))
+ {
+ return;
+ }
+ }
LibraryItemsCache.AddOrUpdate(id, item, delegate { return item; });
}
@@ -939,26 +919,7 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
- var fileInfo = new DirectoryInfo(path);
-
- var isNew = false;
-
- if (!fileInfo.Exists)
- {
- try
- {
- fileInfo = Directory.CreateDirectory(path);
- }
- catch (UnauthorizedAccessException ex)
- {
- _logger.Error("Error creating directory {0}", ex, path);
- throw new Exception(string.Format("Error creating directory {0}", path), ex);
- }
-
- isNew = true;
- }
-
- var item = isNew ? null : GetItemById(id) as T;
+ var item = GetItemById(id) as T;
if (item == null)
{
@@ -966,20 +927,76 @@ namespace MediaBrowser.Server.Implementations.Library
{
Name = name,
Id = id,
- DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo),
- DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo),
+ DateCreated = DateTime.UtcNow,
+ DateModified = DateTime.UtcNow,
Path = path
};
- }
- if (isArtist)
- {
- (item as MusicArtist).IsAccessedByName = true;
+ if (isArtist)
+ {
+ (item as MusicArtist).IsAccessedByName = true;
+ }
+
+ var task = CreateItem(item, CancellationToken.None);
+ Task.WaitAll(task);
}
return item;
}
+ public IEnumerable<MusicArtist> GetAlbumArtists(IEnumerable<IHasAlbumArtist> items)
+ {
+ var names = items
+ .SelectMany(i => i.AlbumArtists)
+ .DistinctNames()
+ .Select(i =>
+ {
+ try
+ {
+ var artist = GetArtist(i);
+
+ return artist;
+ }
+ catch
+ {
+ // Already logged at lower levels
+ return null;
+ }
+ })
+ .Where(i => i != null);
+
+ return names;
+ }
+
+ public IEnumerable<MusicArtist> GetArtists(IEnumerable<IHasArtist> items)
+ {
+ var names = items
+ .SelectMany(i => i.AllArtists)
+ .DistinctNames()
+ .Select(i =>
+ {
+ try
+ {
+ var artist = GetArtist(i);
+
+ return artist;
+ }
+ catch
+ {
+ // Already logged at lower levels
+ return null;
+ }
+ })
+ .Where(i => i != null);
+
+ return names;
+ }
+
+ private void SetPropertiesFromSongs(MusicArtist artist, IEnumerable<IHasMetadata> items)
+ {
+
+ }
+
/// <summary>
/// Validate and refresh the People sub-set of the IBN.
/// The items are stored in the db but not loaded into memory until actually requested by an operation.
@@ -1217,7 +1234,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
var result = ItemRepository.GetItemIdsList(query);
- var items = result.Select(GetItemById).ToArray();
+ var items = result.Select(GetItemById).Where(i => i != null).ToArray();
return new QueryResult<BaseItem>
{
@@ -1225,6 +1242,11 @@ namespace MediaBrowser.Server.Implementations.Library
};
}
+ public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
+ {
+ return ItemRepository.GetItems(query);
+ }
+
public List<Guid> GetItemIds(InternalItemsQuery query)
{
return ItemRepository.GetItemIdsList(query);
@@ -1617,7 +1639,7 @@ namespace MediaBrowser.Server.Implementations.Library
private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24);
- public async Task<UserView> GetNamedView(User user,
+ public Task<UserView> GetNamedView(User user,
string name,
string viewType,
string sortName,
@@ -1625,12 +1647,18 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (ConfigurationManager.Configuration.EnableUserSpecificUserViews)
{
- return await GetNamedViewInternal(user, name, null, viewType, sortName, null, cancellationToken)
- .ConfigureAwait(false);
+ return GetNamedViewInternal(user, name, null, viewType, sortName, null, cancellationToken);
}
- var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath,
- "views");
+ return GetNamedView(name, viewType, sortName, cancellationToken);
+ }
+
+ public async Task<UserView> GetNamedView(string name,
+ string viewType,
+ string sortName,
+ CancellationToken cancellationToken)
+ {
+ var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "views");
path = Path.Combine(path, _fileSystem.GetValidFilename(viewType));
@@ -1666,7 +1694,7 @@ namespace MediaBrowser.Server.Implementations.Library
await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
}
- if (!refresh && item != null)
+ if (!refresh)
{
refresh = (DateTime.UtcNow - item.DateLastSaved) >= _viewRefreshInterval;
}
@@ -1739,8 +1767,77 @@ namespace MediaBrowser.Server.Implementations.Library
DateCreated = DateTime.UtcNow,
Name = name,
ViewType = viewType,
- ForcedSortName = sortName,
- UserId = user.Id
+ ForcedSortName = sortName
+ };
+
+ if (!string.IsNullOrWhiteSpace(parentId))
+ {
+ item.ParentId = new Guid(parentId);
+ }
+
+ await CreateItem(item, cancellationToken).ConfigureAwait(false);
+
+ isNew = true;
+ }
+
+ if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
+ {
+ item.ViewType = viewType;
+ await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
+ }
+
+ var refresh = isNew || (DateTime.UtcNow - item.DateLastSaved) >= _viewRefreshInterval;
+
+ if (refresh)
+ {
+ _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions
+ {
+ // Need to force save to increment DateLastSaved
+ ForceSave = true
+ });
+ }
+
+ return item;
+ }
+
+ public async Task<UserView> GetNamedView(string name,
+ string parentId,
+ string viewType,
+ string sortName,
+ string uniqueId,
+ CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ var idValues = "37_namedview_" + name + (parentId ?? string.Empty) + (viewType ?? string.Empty);
+ if (!string.IsNullOrWhiteSpace(uniqueId))
+ {
+ idValues += uniqueId;
+ }
+
+ var id = GetNewItemId(idValues, typeof(UserView));
+
+ var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
+
+ var item = GetItemById(id) as UserView;
+
+ var isNew = false;
+
+ if (item == null)
+ {
+ Directory.CreateDirectory(path);
+
+ item = new UserView
+ {
+ Path = path,
+ Id = id,
+ DateCreated = DateTime.UtcNow,
+ Name = name,
+ ViewType = viewType,
+ ForcedSortName = sortName
};
if (!string.IsNullOrWhiteSpace(parentId))
@@ -2071,14 +2168,17 @@ namespace MediaBrowser.Server.Implementations.Library
public List<PersonInfo> GetPeople(BaseItem item)
{
- var people = GetPeople(new InternalPeopleQuery
+ if (item.SupportsPeople)
{
- ItemId = item.Id
- });
+ var people = GetPeople(new InternalPeopleQuery
+ {
+ ItemId = item.Id
+ });
- if (people.Count > 0)
- {
- return people;
+ if (people.Count > 0)
+ {
+ return people;
+ }
}
return item.People ?? new List<PersonInfo>();
@@ -2115,6 +2215,11 @@ namespace MediaBrowser.Server.Implementations.Library
public Task UpdatePeople(BaseItem item, List<PersonInfo> people)
{
+ if (!item.SupportsPeople)
+ {
+ return Task.FromResult(true);
+ }
+
return ItemRepository.UpdatePeople(item.Id, people);
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index b6441053d..e3ec99392 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -72,6 +72,16 @@ namespace MediaBrowser.Server.Implementations.Library
private bool InternalTextStreamSupportsExternalStream(MediaStream stream)
{
+ // These usually have styles and fonts that won't convert to text very well
+ if (string.Equals(stream.Codec, "ass", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(stream.Codec, "ssa", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
return true;
}
@@ -230,7 +240,7 @@ namespace MediaBrowser.Server.Implementations.Library
private void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo mediaSource)
{
- var prefix = provider.GetType().FullName.GetMD5().ToString("N") + "|";
+ var prefix = provider.GetType().FullName.GetMD5().ToString("N") + LiveStreamIdDelimeter;
if (!string.IsNullOrWhiteSpace(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
@@ -464,13 +474,24 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
+ // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
+ private const char LiveStreamIdDelimeter = '_';
+
private Tuple<IMediaSourceProvider, string> GetProvider(string key)
{
- var keys = key.Split(new[] { '|' }, 2);
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ throw new ArgumentException("key");
+ }
+
+ var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2);
var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), keys[0], StringComparison.OrdinalIgnoreCase));
- return new Tuple<IMediaSourceProvider, string>(provider, keys[1]);
+ var splitIndex = key.IndexOf(LiveStreamIdDelimeter);
+ var keyId = key.Substring(splitIndex + 1);
+
+ return new Tuple<IMediaSourceProvider, string>(provider, keyId);
}
private Timer _closeTimer;
diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
index 1a9e98268..683e6c5cc 100644
--- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
@@ -27,10 +27,8 @@ namespace MediaBrowser.Server.Implementations.Library
return list.Concat(GetInstantMixFromGenres(item.Genres, user));
}
- public IEnumerable<Audio> GetInstantMixFromArtist(string name, User user)
+ public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user)
{
- var artist = _libraryManager.GetArtist(name);
-
var genres = user.RootFolder
.GetRecursiveChildren(user, i => i is Audio)
.Cast<Audio>()
@@ -54,6 +52,18 @@ namespace MediaBrowser.Server.Implementations.Library
return GetInstantMixFromGenres(genres, user);
}
+ public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user)
+ {
+ var genres = item
+ .GetRecursiveChildren(user, i => i is Audio)
+ .Cast<Audio>()
+ .SelectMany(i => i.Genres)
+ .Concat(item.Genres)
+ .DistinctNames();
+
+ return GetInstantMixFromGenres(genres, user);
+ }
+
public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user)
{
var genres = item
@@ -107,7 +117,7 @@ namespace MediaBrowser.Server.Implementations.Library
var artist = item as MusicArtist;
if (artist != null)
{
- return GetInstantMixFromArtist(artist.Name, user);
+ return GetInstantMixFromArtist(artist, user);
}
var song = item as Audio;
@@ -115,6 +125,12 @@ namespace MediaBrowser.Server.Implementations.Library
{
return GetInstantMixFromSong(song, user);
}
+
+ var folder = item as Folder;
+ if (folder != null)
+ {
+ return GetInstantMixFromFolder(folder, user);
+ }
return new Audio[] { };
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index a6b8c44b6..0d1e4202c 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -47,6 +47,24 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
string collectionType,
IDirectoryService directoryService)
{
+ var result = ResolveMultipleInternal(parent, files, collectionType, directoryService);
+
+ if (result != null)
+ {
+ foreach (var item in result.Items)
+ {
+ SetInitialItemValues((Video)item, null);
+ }
+ }
+
+ return result;
+ }
+
+ private MultiItemResolverResult ResolveMultipleInternal(Folder parent,
+ List<FileSystemInfo> files,
+ string collectionType,
+ IDirectoryService directoryService)
+ {
if (IsInvalid(parent, collectionType, files))
{
return null;
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 70ab105b2..c5565eb53 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -110,11 +110,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
var attributes = child.Attributes;
- if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
- {
- //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName);
- continue;
- }
+ //if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ //{
+ // //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName);
+ // continue;
+ //}
// Can't enforce this because files saved by Bitcasa are always marked System
//if ((attributes & FileAttributes.System) == FileAttributes.System)
@@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
{
- if (IsSeasonFolder(child.FullName, isTvContentType))
+ if (IsSeasonFolder(child.FullName, isTvContentType, libraryManager))
{
//logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
return true;
@@ -188,10 +188,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
/// </summary>
/// <param name="path">The path.</param>
/// <param name="isTvContentType">if set to <c>true</c> [is tv content type].</param>
+ /// <param name="libraryManager">The library manager.</param>
/// <returns><c>true</c> if [is season folder] [the specified path]; otherwise, <c>false</c>.</returns>
- private static bool IsSeasonFolder(string path, bool isTvContentType)
+ private static bool IsSeasonFolder(string path, bool isTvContentType, ILibraryManager libraryManager)
{
- var seasonNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, isTvContentType, isTvContentType).SeasonNumber;
+ var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();
+
+ var seasonNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(path, isTvContentType, isTvContentType).SeasonNumber;
return seasonNumber.HasValue;
}
diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
index 05dde5b3e..d4ff89b4f 100644
--- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
+++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
@@ -33,30 +33,17 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task<QueryResult<SearchHintInfo>> GetSearchHints(SearchQuery query)
{
- IEnumerable<BaseItem> inputItems;
-
- Func<BaseItem, bool> filter = i => !(i is ICollectionFolder);
+ User user = null;
if (string.IsNullOrWhiteSpace(query.UserId))
{
- inputItems = _libraryManager.RootFolder.GetRecursiveChildren(filter);
}
else
{
- var user = _userManager.GetUserById(query.UserId);
-
- inputItems = user.RootFolder.GetRecursiveChildren(user, filter);
+ user = _userManager.GetUserById(query.UserId);
}
- inputItems = _libraryManager.ReplaceVideosWithPrimaryVersions(inputItems);
-
- var results = await GetSearchHints(inputItems, query).ConfigureAwait(false);
-
- // Include item types
- if (query.IncludeItemTypes.Length > 0)
- {
- results = results.Where(f => query.IncludeItemTypes.Contains(f.Item.GetType().Name, StringComparer.OrdinalIgnoreCase));
- }
+ var results = await GetSearchHints(query, user).ConfigureAwait(false);
var searchResultArray = results.ToArray();
results = searchResultArray;
@@ -81,14 +68,22 @@ namespace MediaBrowser.Server.Implementations.Library
};
}
+ private void AddIfMissing(List<string> list, string value)
+ {
+ if (!list.Contains(value, StringComparer.OrdinalIgnoreCase))
+ {
+ list.Add(value);
+ }
+ }
+
/// <summary>
/// Gets the search hints.
/// </summary>
- /// <param name="inputItems">The input items.</param>
/// <param name="query">The query.</param>
+ /// <param name="user">The user.</param>
/// <returns>IEnumerable{SearchHintResult}.</returns>
/// <exception cref="System.ArgumentNullException">searchTerm</exception>
- private Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, SearchQuery query)
+ private Task<IEnumerable<SearchHintInfo>> GetSearchHints(SearchQuery query, User user)
{
var searchTerm = query.SearchTerm;
@@ -98,195 +93,85 @@ namespace MediaBrowser.Server.Implementations.Library
}
searchTerm = searchTerm.RemoveDiacritics();
-
+
var terms = GetWords(searchTerm);
var hints = new List<Tuple<BaseItem, string, int>>();
- var items = inputItems.Where(i => !(i is MusicArtist)).ToList();
+ var excludeItemTypes = new List<string>();
+ var includeItemTypes = (query.IncludeItemTypes ?? new string[] { }).ToList();
- if (query.IncludeMedia)
- {
- // Add search hints based on item name
- hints.AddRange(items.Where(i => !string.IsNullOrWhiteSpace(i.Name) && IncludeInSearch(i)).Select(item =>
- {
- var index = GetIndex(item.Name, searchTerm, terms);
+ excludeItemTypes.Add(typeof(Year).Name);
- return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2);
- }));
- }
-
- if (query.IncludeArtists)
+ if (query.IncludeGenres && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Genre", StringComparer.OrdinalIgnoreCase)))
{
- // Find artists
- var artists = items.OfType<Audio>()
- .SelectMany(i => i.AllArtists)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .DistinctNames()
- .ToList();
-
- foreach (var item in artists)
+ if (!query.IncludeMedia)
{
- var index = GetIndex(item, searchTerm, terms);
-
- if (index.Item2 != -1)
- {
- try
- {
- var artist = _libraryManager.GetArtist(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(artist, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
+ AddIfMissing(includeItemTypes, typeof(Genre).Name);
+ AddIfMissing(includeItemTypes, typeof(GameGenre).Name);
+ AddIfMissing(includeItemTypes, typeof(MusicGenre).Name);
}
}
-
- if (query.IncludeGenres)
+ else
{
- // Find genres, from non-audio items
- var genres = items.Where(i => !(i is IHasMusicGenres) && !(i is Game))
- .SelectMany(i => i.Genres)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- foreach (var item in genres)
- {
- var index = GetIndex(item, searchTerm, terms);
-
- if (index.Item2 != -1)
- {
- try
- {
- var genre = _libraryManager.GetGenre(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
- }
-
- // Find music genres
- var musicGenres = items.Where(i => i is IHasMusicGenres)
- .SelectMany(i => i.Genres)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
+ AddIfMissing(excludeItemTypes, typeof(Genre).Name);
+ AddIfMissing(excludeItemTypes, typeof(GameGenre).Name);
+ AddIfMissing(excludeItemTypes, typeof(MusicGenre).Name);
+ }
- foreach (var item in musicGenres)
+ if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase)))
+ {
+ if (!query.IncludeMedia)
{
- var index = GetIndex(item, searchTerm, terms);
-
- if (index.Item2 != -1)
- {
- try
- {
- var genre = _libraryManager.GetMusicGenre(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
+ AddIfMissing(includeItemTypes, typeof(Person).Name);
}
+ }
+ else
+ {
+ AddIfMissing(excludeItemTypes, typeof(Person).Name);
+ }
- // Find music genres
- var gameGenres = items.OfType<Game>()
- .SelectMany(i => i.Genres)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- foreach (var item in gameGenres)
+ if (query.IncludeStudios && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Studio", StringComparer.OrdinalIgnoreCase)))
+ {
+ if (!query.IncludeMedia)
{
- var index = GetIndex(item, searchTerm, terms);
-
- if (index.Item2 != -1)
- {
- try
- {
- var genre = _libraryManager.GetGameGenre(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
+ AddIfMissing(includeItemTypes, typeof(Studio).Name);
}
}
-
- if (query.IncludeStudios)
+ else
{
- // Find studios
- var studios = items.SelectMany(i => i.Studios)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
+ AddIfMissing(excludeItemTypes, typeof(Studio).Name);
+ }
- foreach (var item in studios)
+ if (query.IncludeArtists && (includeItemTypes.Count == 0 || includeItemTypes.Contains("MusicArtist", StringComparer.OrdinalIgnoreCase)))
+ {
+ if (!query.IncludeMedia)
{
- var index = GetIndex(item, searchTerm, terms);
-
- if (index.Item2 != -1)
- {
- try
- {
- var studio = _libraryManager.GetStudio(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(studio, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
+ AddIfMissing(includeItemTypes, typeof(MusicArtist).Name);
}
}
+ else
+ {
+ AddIfMissing(excludeItemTypes, typeof(MusicArtist).Name);
+ }
- if (query.IncludePeople)
+ var mediaItems = _libraryManager.GetItems(new InternalItemsQuery
{
- var itemIds = items.Select(i => i.Id).ToList();
+ NameContains = searchTerm,
+ ExcludeItemTypes = excludeItemTypes.ToArray(),
+ IncludeItemTypes = includeItemTypes.ToArray(),
+ MaxParentalRating = user == null ? null : user.Policy.MaxParentalRating,
+ Limit = query.Limit.HasValue ? query.Limit * 3 : null
- // Find persons
- var persons = _libraryManager.GetPeople(new InternalPeopleQuery
- {
- NameContains = searchTerm
- })
- .Where(i => itemIds.Contains(i.ItemId))
- .Select(i => i.Name)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- foreach (var item in persons)
- {
- var index = GetIndex(item, searchTerm, terms);
+ }).Items;
- if (index.Item2 != -1)
- {
- try
- {
- var person = _libraryManager.GetPerson(item);
-
- hints.Add(new Tuple<BaseItem, string, int>(person, index.Item1, index.Item2));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting {0}", ex, item);
- }
- }
- }
- }
+ // Add search hints based on item name
+ hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && IsVisible(i, user) && !(i is CollectionFolder)).Select(item =>
+ {
+ var index = GetIndex(item.Name, searchTerm, terms);
+
+ return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2);
+ }));
var returnValue = hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).Select(i => new SearchHintInfo
{
@@ -297,13 +182,32 @@ namespace MediaBrowser.Server.Implementations.Library
return Task.FromResult(returnValue);
}
+ private bool IsVisible(BaseItem item, User user)
+ {
+ if (user == null)
+ {
+ return true;
+ }
+
+ if (item is IItemByName)
+ {
+ var dual = item as IHasDualAccess;
+ if (dual == null || dual.IsAccessedByName)
+ {
+ return true;
+ }
+ }
+
+ return item.IsVisibleStandalone(user);
+ }
+
private bool IncludeInSearch(BaseItem item)
{
var episode = item as Episode;
if (episode != null)
{
- if (episode.IsVirtualUnaired || episode.IsMissingEpisode)
+ if (episode.IsMissingEpisode)
{
return false;
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index 69600f0fe..43f77ec49 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.AddRange(standaloneFolders);
}
- var parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
+ var parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user)))
.ToList();
if (parents.Count > 0)
@@ -99,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(parents, list, CollectionType.TvShows, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.Equals(i.CollectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
+ parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user)))
.ToList();
if (parents.Count > 0)
@@ -107,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(parents, list, CollectionType.Music, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
+ parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user)))
.ToList();
if (parents.Count > 0)
@@ -115,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(parents, list, CollectionType.Movies, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
+ parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Games, StringComparison.OrdinalIgnoreCase))
.ToList();
if (parents.Count > 0)
@@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(parents, list, CollectionType.Games, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
+ parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
.ToList();
if (parents.Count > 0)
@@ -131,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(await GetUserView(parents, list, CollectionType.BoxSets, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
+ parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
.ToList();
if (parents.Count > 0)
@@ -141,12 +141,13 @@ namespace MediaBrowser.Server.Implementations.Library
if (user.Configuration.DisplayFoldersView)
{
- list.Add(await GetUserView(new List<ICollectionFolder>(), list, CollectionType.Folders, "zz_" + CollectionType.Folders, user, cancellationToken).ConfigureAwait(false));
+ var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders);
+ list.Add(await _libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty, cancellationToken).ConfigureAwait(false));
}
if (query.IncludeExternalContent)
{
- var channelResult = await _channelManager.GetChannels(new ChannelQuery
+ var channelResult = await _channelManager.GetChannelsInternal(new ChannelQuery
{
UserId = query.UserId
@@ -155,20 +156,19 @@ namespace MediaBrowser.Server.Implementations.Library
var channels = channelResult.Items;
var embeddedChannels = channels
- .Where(i => user.Configuration.DisplayChannelsWithinViews.Contains(i.Id))
+ .Where(i => user.Configuration.DisplayChannelsInline || user.Configuration.DisplayChannelsWithinViews.Contains(i.Id.ToString("N")))
.ToList();
- list.AddRange(embeddedChannels.Select(i => _channelManager.GetChannel(i.Id)));
+ list.AddRange(embeddedChannels);
if (channels.Length > embeddedChannels.Count)
{
- list.Add(await _channelManager.GetInternalChannelFolder(query.UserId, cancellationToken).ConfigureAwait(false));
+ list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false));
}
if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId))
{
- //list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
- list.Add(await GetUserView(new List<ICollectionFolder>(), list, CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false));
+ list.Add(await _liveTvManager.GetInternalLiveTvFolder(CancellationToken.None).ConfigureAwait(false));
}
}
@@ -187,25 +187,26 @@ namespace MediaBrowser.Server.Implementations.Library
.ThenBy(i => i.SortName);
}
- public Task<UserView> GetUserSubView(string name, string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
+ public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken)
{
var uniqueId = parentId + "subview" + type;
- return _libraryManager.GetNamedView(user, name, parentId, type, sortName, uniqueId, cancellationToken);
+ return _libraryManager.GetNamedView(name, parentId, type, sortName, uniqueId, cancellationToken);
}
- public Task<UserView> GetUserSubView(string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
+ public Task<UserView> GetUserSubView(string parentId, string type, string sortName, CancellationToken cancellationToken)
{
var name = _localizationManager.GetLocalizedString("ViewType" + type);
- return GetUserSubView(name, parentId, type, user, sortName, cancellationToken);
+ return GetUserSubView(name, parentId, type, sortName, cancellationToken);
}
public async Task<UserView> GetUserView(List<ICollectionFolder> parents, List<Folder> currentViews, string viewType, string sortName, User user, CancellationToken cancellationToken)
{
var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
+ var enableUserSpecificViews = _config.Configuration.EnableUserSpecificUserViews;
- if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
+ if (parents.Count == 1 && parents.All(i => string.Equals((enableUserSpecificViews ? i.CollectionType : i.GetViewType(user)), viewType, StringComparison.OrdinalIgnoreCase)))
{
if (!string.IsNullOrWhiteSpace(parents[0].Name))
{
@@ -221,9 +222,8 @@ namespace MediaBrowser.Server.Implementations.Library
return await GetUserView(parentId, name, viewType, enableRichView, sortName, user, cancellationToken).ConfigureAwait(false);
}
- if (_config.Configuration.EnableUserSpecificUserViews)
+ if (enableUserSpecificViews)
{
- viewType = enableRichView ? viewType : null;
var view = await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
if (view.ParentId != parentId)
@@ -233,8 +233,6 @@ namespace MediaBrowser.Server.Implementations.Library
}
return view;
}
-
- return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
}
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
index c9440bb27..68d351b44 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
@@ -48,26 +48,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
.Cast<IHasArtist>()
.ToList();
- var allArtists = allSongs.SelectMany(i => i.AllArtists)
- .DistinctNames()
- .ToList();
+ var allArtists = _libraryManager.GetArtists(allSongs).ToList();
var numComplete = 0;
var numArtists = allArtists.Count;
- foreach (var artist in allArtists)
+ foreach (var artistItem in allArtists)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
- var artistItem = _libraryManager.GetArtist(artist);
-
await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
catch (IOException ex)
{
- _logger.ErrorException("Error validating Artist {0}", ex, artist);
+ _logger.ErrorException("Error validating Artist {0}", ex, artistItem.Name);
}
// Update progress
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs
index fe2e6a114..b57e128d3 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities;
+using System.Collections.Generic;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System;
@@ -42,12 +43,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
var numComplete = 0;
var count = items.Count;
+ var validIds = new List<Guid>();
+
foreach (var name in items)
{
try
{
var itemByName = _libraryManager.GetGameGenre(name);
+ validIds.Add(itemByName.Id);
+
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -68,6 +73,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
progress.Report(percent);
}
+ var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(GameGenre).Name }
+ });
+
+ var invalidIds = allIds
+ .Except(validIds)
+ .ToList();
+
+ foreach (var id in invalidIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var item = _libraryManager.GetItemById(id);
+
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+
progress.Report(100);
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
index fac5cfc35..11d4c9f16 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities;
+using System.Collections.Generic;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
@@ -43,12 +44,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
var numComplete = 0;
var count = items.Count;
+ var validIds = new List<Guid>();
+
foreach (var name in items)
{
try
{
var itemByName = _libraryManager.GetGenre(name);
+ validIds.Add(itemByName.Id);
+
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -69,6 +74,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
progress.Report(percent);
}
+ var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(Genre).Name }
+ });
+
+ var invalidIds = allIds
+ .Except(validIds)
+ .ToList();
+
+ foreach (var id in invalidIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var item = _libraryManager.GetItemById(id);
+
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+
progress.Report(100);
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
index e3be75e9b..0a66b4b41 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
@@ -1,4 +1,6 @@
-using MediaBrowser.Controller.Entities.Audio;
+using System.Collections.Generic;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System;
@@ -42,12 +44,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
var numComplete = 0;
var count = items.Count;
+ var validIds = new List<Guid>();
+
foreach (var name in items)
{
try
{
var itemByName = _libraryManager.GetMusicGenre(name);
+ validIds.Add(itemByName.Id);
+
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -68,6 +74,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
progress.Report(percent);
}
+ var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(MusicGenre).Name }
+ });
+
+ var invalidIds = allIds
+ .Except(validIds)
+ .ToList();
+
+ foreach (var id in invalidIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var item = _libraryManager.GetItemById(id);
+
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+
progress.Report(100);
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
index ef9dee8b5..a4c43af5d 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -92,15 +92,25 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
foreach (var person in people)
{
- bool current;
- if (!dict.TryGetValue(person.Name, out current) || !current)
+ var isMetadataEnabled = DownloadMetadata(person, peopleOptions);
+
+ bool currentValue;
+ if (dict.TryGetValue(person.Name, out currentValue))
+ {
+ if (!currentValue && isMetadataEnabled)
+ {
+ dict[person.Name] = true;
+ }
+ }
+ else
{
- dict[person.Name] = DownloadMetadata(person, peopleOptions);
+ dict[person.Name] = isMetadataEnabled;
}
}
var numComplete = 0;
-
+ var validIds = new List<Guid>();
+
foreach (var person in dict)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -109,6 +119,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
{
var item = _libraryManager.GetPerson(person.Key);
+ validIds.Add(item.Id);
+
var options = new MetadataRefreshOptions
{
MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly,
@@ -130,6 +142,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
progress.Report(100 * percent);
}
+ var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(Person).Name }
+ });
+
+ var invalidIds = allIds
+ .Except(validIds)
+ .ToList();
+
+ foreach (var id in invalidIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var item = _libraryManager.GetItemById(id);
+
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+
progress.Report(100);
_logger.Info("People validation complete");
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs
index 066b96853..c122d64d3 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs
@@ -1,6 +1,8 @@
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -41,12 +43,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
var numComplete = 0;
var count = items.Count;
+ var validIds = new List<Guid>();
+
foreach (var name in items)
{
try
{
var itemByName = _libraryManager.GetStudio(name);
+ validIds.Add(itemByName.Id);
+
await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -67,6 +73,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
progress.Report(percent);
}
+ var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(Studio).Name }
+ });
+
+ var invalidIds = allIds
+ .Except(validIds)
+ .ToList();
+
+ foreach (var id in invalidIds)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var item = _libraryManager.GetItemById(id);
+
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
+ }
+
progress.Report(100);
}
}