diff options
Diffstat (limited to 'Emby.Server.Implementations/Library')
16 files changed, 243 insertions, 201 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 4846a5768..8c5ecf782 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -136,14 +136,6 @@ namespace Emby.Server.Implementations.Library /// <value>The configuration manager.</value> private IServerConfigurationManager ConfigurationManager { get; set; } - /// <summary> - /// A collection of items that may be referenced from multiple physical places in the library - /// (typically, multiple user roots). We store them here and be sure they all reference a - /// single instance. - /// </summary> - /// <value>The by reference items.</value> - private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; } - private readonly Func<ILibraryMonitor> _libraryMonitorFactory; private readonly Func<IProviderManager> _providerManagerFactory; private readonly Func<IUserViewManager> _userviewManager; @@ -186,7 +178,6 @@ namespace Emby.Server.Implementations.Library _fileSystem = fileSystem; _providerManagerFactory = providerManagerFactory; _userviewManager = userviewManager; - ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>(); _libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>(); ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -362,7 +353,7 @@ namespace Emby.Server.Implementations.Library } else { - if (item is Photo) + if (!(item is Video)) { return; } @@ -470,10 +461,10 @@ namespace Emby.Server.Implementations.Library parent.RemoveChild(item); } - await ItemRepository.DeleteItem(item.Id, CancellationToken.None).ConfigureAwait(false); + ItemRepository.DeleteItem(item.Id, CancellationToken.None); foreach (var child in children) { - await ItemRepository.DeleteItem(child.Id, CancellationToken.None).ConfigureAwait(false); + ItemRepository.DeleteItem(child.Id, CancellationToken.None); } BaseItem removed; @@ -560,22 +551,6 @@ namespace Emby.Server.Implementations.Library return key.GetMD5(); } - /// <summary> - /// Ensure supplied item has only one instance throughout - /// </summary> - /// <param name="item">The item.</param> - /// <returns>The proper instance to the item</returns> - public BaseItem GetOrAddByReferenceItem(BaseItem item) - { - // Add this item to our list if not there already - if (!ByReferenceItems.TryAdd(item.Id, item)) - { - // Already there - return the existing reference - item = ByReferenceItems[item.Id]; - } - return item; - } - public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null) { @@ -624,18 +599,16 @@ namespace Emby.Server.Implementations.Library // When resolving the root, we need it's grandchildren (children of user views) var flattenFolderDepth = isPhysicalRoot ? 2 : 0; - var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); + var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); // Need to remove subpaths that may have been resolved from shortcuts // Example: if \\server\movies exists, then strip out \\server\movies\action if (isPhysicalRoot) { - var paths = NormalizeRootPathList(fileSystemDictionary.Values); - - fileSystemDictionary = paths.ToDictionary(i => i.FullName); + files = NormalizeRootPathList(files).ToArray(); } - args.FileSystemDictionary = fileSystemDictionary; + args.FileSystemChildren = files; } // Check to see if we should resolve based on our contents @@ -681,7 +654,7 @@ namespace Emby.Server.Implementations.Library return false; } - public IEnumerable<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths) + public List<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths) { var originalList = paths.ToList(); @@ -873,8 +846,7 @@ namespace Emby.Server.Implementations.Library { Path = path, IsFolder = isFolder, - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(), Limit = 1, DtoOptions = new DtoOptions(true) }; @@ -1024,8 +996,7 @@ namespace Emby.Server.Implementations.Library Path = path }; - var task = CreateItem(item, CancellationToken.None); - Task.WaitAll(task); + CreateItem(item, CancellationToken.None); } return item; @@ -1197,6 +1168,8 @@ namespace Emby.Server.Implementations.Library progress.Report(percent * 100); } + ItemRepository.UpdateInheritedValues(cancellationToken); + progress.Report(100); } @@ -1231,7 +1204,7 @@ namespace Emby.Server.Implementations.Library .Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Select(_fileSystem.ResolveShortcut) .OrderBy(i => i) - .ToList(), + .ToArray(), CollectionType = GetCollectionType(dir) }; @@ -1298,7 +1271,7 @@ namespace Emby.Server.Implementations.Library return item; } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) + public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) { if (query.Recursive && query.ParentId.HasValue) { @@ -1317,7 +1290,7 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetItemList(query); } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query) + public List<BaseItem> GetItemList(InternalItemsQuery query) { return GetItemList(query, true); } @@ -1341,7 +1314,7 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetCount(query); } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) + public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) { SetTopParentIdsOrAncestors(query, parents); @@ -1515,9 +1488,11 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetItems(query); } + var list = ItemRepository.GetItemList(query); + return new QueryResult<BaseItem> { - Items = ItemRepository.GetItemList(query).ToArray() + Items = list.ToArray(list.Count) }; } @@ -1575,7 +1550,7 @@ namespace Emby.Server.Implementations.Library IncludeHidden = true, IncludeExternalContent = allowExternalContent - }, CancellationToken.None).Result.ToList(); + }, CancellationToken.None).Result; query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray(); } @@ -1801,6 +1776,37 @@ namespace Emby.Server.Implementations.Library return orderedItems ?? items; } + public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<Tuple<string, SortOrder>> orderByList) + { + var isFirst = true; + + IOrderedEnumerable<BaseItem> orderedItems = null; + + foreach (var orderBy in orderByList) + { + var comparer = GetComparer(orderBy.Item1, user); + if (comparer == null) + { + continue; + } + + var sortOrder = orderBy.Item2; + + if (isFirst) + { + orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer); + } + else + { + orderedItems = sortOrder == SortOrder.Descending ? orderedItems.ThenByDescending(i => i, comparer) : orderedItems.ThenBy(i => i, comparer); + } + + isFirst = false; + } + + return orderedItems ?? items; + } + /// <summary> /// Gets the comparer. /// </summary> @@ -1835,9 +1841,9 @@ namespace Emby.Server.Implementations.Library /// <param name="item">The item.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public Task CreateItem(BaseItem item, CancellationToken cancellationToken) + public void CreateItem(BaseItem item, CancellationToken cancellationToken) { - return CreateItems(new[] { item }, cancellationToken); + CreateItems(new[] { item }, cancellationToken); } /// <summary> @@ -1846,11 +1852,11 @@ namespace Emby.Server.Implementations.Library /// <param name="items">The items.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public async Task CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken) + public void CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken) { var list = items.ToList(); - await ItemRepository.SaveItems(list, cancellationToken).ConfigureAwait(false); + ItemRepository.SaveItems(list, cancellationToken); foreach (var item in list) { @@ -1893,7 +1899,7 @@ namespace Emby.Server.Implementations.Library var logName = item.LocationType == LocationType.Remote ? item.Name ?? item.Path : item.Path ?? item.Name; _logger.Debug("Saving {0} to database.", logName); - await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); + ItemRepository.SaveItem(item, cancellationToken); RegisterItem(item); @@ -2090,7 +2096,7 @@ namespace Emby.Server.Implementations.Library private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); //private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromMinutes(1); - public Task<UserView> GetNamedView(User user, + public UserView GetNamedView(User user, string name, string viewType, string sortName, @@ -2128,7 +2134,7 @@ namespace Emby.Server.Implementations.Library ForcedSortName = sortName }; - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); refresh = true; } @@ -2159,7 +2165,7 @@ namespace Emby.Server.Implementations.Library return item; } - public async Task<UserView> GetNamedView(User user, + public UserView GetNamedView(User user, string name, string parentId, string viewType, @@ -2196,7 +2202,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = new Guid(parentId); } - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2222,7 +2228,7 @@ namespace Emby.Server.Implementations.Library return item; } - public async Task<UserView> GetShadowView(BaseItem parent, + public UserView GetShadowView(BaseItem parent, string viewType, string sortName, CancellationToken cancellationToken) @@ -2261,7 +2267,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = parentId; - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2332,7 +2338,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = new Guid(parentId); } - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2395,8 +2401,7 @@ namespace Emby.Server.Implementations.Library var resolver = new EpisodeResolver(GetNamingOptions(), new NullLogger()); - var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || - episode.VideoType == VideoType.HdDvd; + var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd; var locationType = episode.LocationType; @@ -2593,7 +2598,7 @@ namespace Emby.Server.Implementations.Library { var namingOptions = GetNamingOptions(); - var files = owner.DetectIsInMixedFolder() ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory) + var files = owner.IsInMixedFolder ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false)) .ToList(); @@ -2611,7 +2616,7 @@ namespace Emby.Server.Implementations.Library var resolvers = new IItemResolver[] { - new GenericVideoResolver<Trailer>(this) + new GenericVideoResolver<Trailer>(this, _fileSystem) }; return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers) @@ -2632,7 +2637,7 @@ namespace Emby.Server.Implementations.Library return video; // Sort them so that the list can be easily compared for changes - }).OrderBy(i => i.Path).ToList(); + }).OrderBy(i => i.Path); } private static readonly string[] ExtrasSubfolderNames = new[] { "extras", "specials", "shorts", "scenes", "featurettes", "behind the scenes", "deleted scenes", "interviews" }; @@ -2674,7 +2679,7 @@ namespace Emby.Server.Implementations.Library return video; // Sort them so that the list can be easily compared for changes - }).OrderBy(i => i.Path).ToList(); + }).OrderBy(i => i.Path); } public string GetPathAfterNetworkSubstitution(string path, BaseItem ownerItem) @@ -2847,17 +2852,17 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetPeopleNames(query); } - public Task UpdatePeople(BaseItem item, List<PersonInfo> people) + public void UpdatePeople(BaseItem item, List<PersonInfo> people) { if (!item.SupportsPeople) { - return Task.FromResult(true); + return; } - return ItemRepository.UpdatePeople(item.Id, people); + ItemRepository.UpdatePeople(item.Id, people); } - public async Task<ItemImageInfo> ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex) + public async Task<ItemImageInfo> ConvertImageToLocal(IHasMetadata item, ItemImageInfo image, int imageIndex) { foreach (var url in image.Path.Split('|')) { @@ -3083,7 +3088,7 @@ namespace Emby.Server.Implementations.Library var topLibraryFolders = GetUserRootFolder().Children.ToList(); var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null); - if (info.Locations.Count > 0 && info.Locations.Count != options.PathInfos.Length) + if (info.Locations.Length > 0 && info.Locations.Length != options.PathInfos.Length) { var list = options.PathInfos.ToList(); diff --git a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs index e64980dff..757e67eb4 100644 --- a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -45,7 +46,7 @@ namespace Emby.Server.Implementations.Library Recursive = true, DtoOptions = new DtoOptions(false) - }).ToArray(); + }); var numComplete = 0; @@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.Library progress.Report(100); } - private async Task AssignTrailers(IHasTrailers item, BaseItem[] channelTrailers) + private async Task AssignTrailers(IHasTrailers item, IEnumerable<BaseItem> channelTrailers) { if (item is Game) { @@ -90,7 +91,7 @@ namespace Emby.Server.Implementations.Library }); var trailerIds = trailers.Select(i => i.Id) - .ToList(); + .ToArray(); if (!trailerIds.SequenceEqual(item.RemoteTrailerIds)) { diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c1360c887..d60a04353 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -49,10 +49,9 @@ namespace Emby.Server.Implementations.Library _providers = providers.ToArray(); } - public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query) + public List<MediaStream> GetMediaStreams(MediaStreamQuery query) { - var list = _itemRepo.GetMediaStreams(query) - .ToList(); + var list = _itemRepo.GetMediaStreams(query); foreach (var stream in list) { @@ -77,7 +76,7 @@ namespace Emby.Server.Implementations.Library return false; } - public IEnumerable<MediaStream> GetMediaStreams(string mediaSourceId) + public List<MediaStream> GetMediaStreams(string mediaSourceId) { var list = GetMediaStreams(new MediaStreamQuery { @@ -87,7 +86,7 @@ namespace Emby.Server.Implementations.Library return GetMediaStreamsForItem(list); } - public IEnumerable<MediaStream> GetMediaStreams(Guid itemId) + public List<MediaStream> GetMediaStreams(Guid itemId) { var list = GetMediaStreams(new MediaStreamQuery { @@ -97,7 +96,7 @@ namespace Emby.Server.Implementations.Library return GetMediaStreamsForItem(list); } - private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams) + private List<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams) { var list = streams.ToList(); @@ -253,7 +252,7 @@ namespace Emby.Server.Implementations.Library return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); } - public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null) + public List<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null) { if (item == null) { @@ -265,7 +264,7 @@ namespace Emby.Server.Implementations.Library return item.GetMediaSources(enablePathSubstitution); } - var sources = item.GetMediaSources(enablePathSubstitution).ToList(); + var sources = item.GetMediaSources(enablePathSubstitution); if (user != null) { @@ -525,6 +524,7 @@ namespace Emby.Server.Implementations.Library public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } private readonly object _disposeLock = new object(); diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs index f0d07cc3c..1cbf4235a 100644 --- a/Emby.Server.Implementations/Library/MusicManager.cs +++ b/Emby.Server.Implementations/Library/MusicManager.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Controller.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Library @@ -19,27 +20,27 @@ namespace Emby.Server.Implementations.Library _libraryManager = libraryManager; } - public IEnumerable<Audio> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions) { var list = new List<Audio> { item }; - return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)); + return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)).ToList(); } - public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions) { var genres = item .GetRecursiveChildren(user, new InternalItemsQuery(user) @@ -55,12 +56,12 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenres(genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions) { var genreIds = genres.DistinctNames().Select(i => { @@ -78,7 +79,7 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenreIds(genreIds, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions) { return _libraryManager.GetItemList(new InternalItemsQuery(user) { @@ -88,14 +89,14 @@ namespace Emby.Server.Implementations.Library Limit = 200, - SortBy = new[] { ItemSortBy.Random }, + OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, DtoOptions = dtoOptions - }).Cast<Audio>(); + }); } - public IEnumerable<Audio> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions) { var genre = item as MusicGenre; if (genre != null) @@ -133,7 +134,7 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromFolder(folder, user, dtoOptions); } - return new Audio[] { }; + return new List<BaseItem>(); } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 9a5d6b105..fa4f026f4 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -6,6 +6,7 @@ using System; using System.IO; using System.Linq; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; namespace Emby.Server.Implementations.Library.Resolvers @@ -18,9 +19,11 @@ namespace Emby.Server.Implementations.Library.Resolvers where T : Video, new() { protected readonly ILibraryManager LibraryManager; + protected readonly IFileSystem FileSystem; - protected BaseVideoResolver(ILibraryManager libraryManager) + protected BaseVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) { + FileSystem = fileSystem; LibraryManager = libraryManager; } @@ -178,11 +181,6 @@ namespace Emby.Server.Implementations.Library.Resolvers { video.VideoType = VideoType.Dvd; } - else if (string.Equals(videoInfo.StubType, "hddvd", StringComparison.OrdinalIgnoreCase)) - { - video.VideoType = VideoType.HdDvd; - video.IsHD = true; - } else if (string.Equals(videoInfo.StubType, "bluray", StringComparison.OrdinalIgnoreCase)) { video.VideoType = VideoType.BluRay; @@ -276,7 +274,7 @@ namespace Emby.Server.Implementations.Library.Resolvers return false; } - return directoryService.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase)); + return FileSystem.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase)); } /// <summary> diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 69563e5a0..1e5c0beed 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -23,11 +23,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies /// </summary> public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver { - public MovieResolver(ILibraryManager libraryManager) - : base(libraryManager) - { - } - /// <summary> /// Gets the priority. /// </summary> @@ -74,7 +69,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) { - return ResolveVideos<MusicVideo>(parent, files, directoryService, false, collectionType); + return ResolveVideos<MusicVideo>(parent, files, directoryService, true, collectionType); } if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || @@ -164,8 +159,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies IsInMixedFolder = isInMixedFolder, ProductionYear = video.Year, Name = video.Name, - AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToList(), - LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToList() + AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToArray(), + LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToArray() }; SetVideoType(videoItem, firstVideo); @@ -452,8 +447,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies var folderPaths = multiDiscFolders.Select(i => i.FullName).Where(i => { - var subFileEntries = directoryService.GetFileSystemEntries(i) - .ToList(); + var subFileEntries = directoryService.GetFileSystemEntries(i); var subfolders = subFileEntries .Where(e => e.IsDirectory) @@ -509,7 +503,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies { Path = folderPaths[0], - AdditionalParts = folderPaths.Skip(1).ToList(), + AdditionalParts = folderPaths.Skip(1).ToArray(), VideoType = videoTypes[0], @@ -547,5 +541,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return !validCollectionTypes.Contains(collectionType, StringComparer.OrdinalIgnoreCase); } + + public MovieResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 8bbda3b62..04312f277 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.Library.Resolvers var filename = Path.GetFileNameWithoutExtension(args.Path); // Make sure the image doesn't belong to a video file - if (args.DirectoryService.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename))) + if (_fileSystem.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename))) { return null; } diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index 6c7c1f052..6a1f8ec6f 100644 --- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Library.Resolvers return new CollectionFolder { CollectionType = GetCollectionType(args), - PhysicalLocationsList = args.PhysicalLocations.ToList() + PhysicalLocationsList = args.PhysicalLocations }; } } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index bdab8552a..7d1c4d65a 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using System.Linq; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers.TV { @@ -11,10 +12,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// </summary> public class EpisodeResolver : BaseVideoResolver<Episode> { - public EpisodeResolver(ILibraryManager libraryManager) : base(libraryManager) - { - } - /// <summary> /// Resolves the specified args. /// </summary> @@ -76,5 +73,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV return null; } + + public EpisodeResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index 84ceac65e..830bd9d85 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -1,6 +1,8 @@ -using MediaBrowser.Controller.Configuration; +using System.Globalization; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Globalization; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.TV; @@ -17,15 +19,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + private readonly ILocalizationManager _localization; /// <summary> /// Initializes a new instance of the <see cref="SeasonResolver"/> class. /// </summary> /// <param name="config">The config.</param> - public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager) + public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization) { _config = config; _libraryManager = libraryManager; + _localization = localization; } /// <summary> @@ -47,9 +52,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV SeriesName = series.Name }; - if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0) + if (season.IndexNumber.HasValue) { - season.Name = _config.Configuration.SeasonZeroDisplayName; + var seasonNumber = season.IndexNumber.Value; + + season.Name = seasonNumber == 0 ? + _config.Configuration.SeasonZeroDisplayName : + string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture)); } return season; diff --git a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs index b5e1bf5f7..5c7a528f5 100644 --- a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers { @@ -9,11 +10,6 @@ namespace Emby.Server.Implementations.Library.Resolvers /// </summary> public class VideoResolver : BaseVideoResolver<Video> { - public VideoResolver(ILibraryManager libraryManager) - : base(libraryManager) - { - } - protected override Video Resolve(ItemResolveArgs args) { if (args.Parent != null) @@ -33,12 +29,16 @@ namespace Emby.Server.Implementations.Library.Resolvers { get { return ResolverPriority.Last; } } + + public VideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } public class GenericVideoResolver<T> : BaseVideoResolver<T> where T : Video, new () { - public GenericVideoResolver(ILibraryManager libraryManager) : base(libraryManager) + public GenericVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) { } } diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index 6f63322c8..b1ed034ca 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -10,6 +10,8 @@ using System.Linq; using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Library { @@ -163,12 +165,12 @@ namespace Emby.Server.Implementations.Library var mediaItems = _libraryManager.GetItemList(new InternalItemsQuery(user) { NameContains = searchTerm, - ExcludeItemTypes = excludeItemTypes.ToArray(), - IncludeItemTypes = includeItemTypes.ToArray(), + ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count), + IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count), Limit = query.Limit, IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId), ParentId = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId), - SortBy = new[] { ItemSortBy.SortName }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }, Recursive = true, IsKids = query.IsKids, @@ -180,7 +182,7 @@ namespace Emby.Server.Implementations.Library DtoOptions = new DtoOptions { - Fields = new List<ItemFields> + Fields = new ItemFields[] { ItemFields.AirTime, ItemFields.DateCreated, diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index e066ab61b..7ef5ca35e 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.Library /// <value>The repository.</value> public IUserDataRepository Repository { get; set; } - public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) + public void SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) { if (userData == null) { @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.Library foreach (var key in keys) { - await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false); + Repository.SaveUserData(userId, key, userData, cancellationToken); } var cacheKey = GetCacheKey(userId, item.Id); @@ -86,7 +86,7 @@ namespace Emby.Server.Implementations.Library /// <param name="userData"></param> /// <param name="cancellationToken"></param> /// <returns></returns> - public async Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) + public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken) { if (userData == null) { @@ -99,7 +99,7 @@ namespace Emby.Server.Implementations.Library cancellationToken.ThrowIfCancellationRequested(); - await Repository.SaveAllUserData(userId, userData, cancellationToken).ConfigureAwait(false); + Repository.SaveAllUserData(userId, userData, cancellationToken); } /// <summary> @@ -107,7 +107,7 @@ namespace Emby.Server.Implementations.Library /// </summary> /// <param name="userId"></param> /// <returns></returns> - public IEnumerable<UserItemData> GetAllUserData(Guid userId) + public List<UserItemData> GetAllUserData(Guid userId) { if (userId == Guid.Empty) { @@ -187,11 +187,11 @@ namespace Emby.Server.Implementations.Library var userData = GetUserData(user.Id, item); var dto = GetUserItemDataDto(userData); - item.FillUserDataDtoValues(dto, userData, null, user, new List<ItemFields>()); + item.FillUserDataDtoValues(dto, userData, null, user, new ItemFields[] { }); return dto; } - public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields) + public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, ItemFields[] fields) { var userData = GetUserData(user.Id, item); var dto = GetUserItemDataDto(userData); diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 8e8f8c4dc..e5fe2969f 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -71,9 +71,8 @@ namespace Emby.Server.Implementations.Library private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; private readonly ICryptoProvider _cryptographyProvider; - private readonly string _defaultUserName; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string defaultUserName) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) { _logger = logger; UserRepository = userRepository; @@ -86,7 +85,6 @@ namespace Emby.Server.Implementations.Library _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _cryptographyProvider = cryptographyProvider; - _defaultUserName = defaultUserName; ConfigurationManager = configurationManager; Users = new List<User>(); @@ -122,7 +120,7 @@ namespace Emby.Server.Implementations.Library /// <param name="user">The user.</param> private void OnUserDeleted(User user) { - EventHelper.QueueEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger); + EventHelper.FireEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger); } #endregion @@ -162,9 +160,9 @@ namespace Emby.Server.Implementations.Library return Users.FirstOrDefault(u => string.Equals(u.Name, name, StringComparison.OrdinalIgnoreCase)); } - public async Task Initialize() + public void Initialize() { - Users = await LoadUsers().ConfigureAwait(false); + Users = LoadUsers(); var users = Users.ToList(); @@ -176,7 +174,7 @@ namespace Emby.Server.Implementations.Library if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value == UserLinkType.LinkedUser) { user.Policy.IsAdministrator = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); } } } @@ -296,12 +294,12 @@ namespace Emby.Server.Implementations.Library if (success) { user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; - await UpdateUser(user).ConfigureAwait(false); - await UpdateInvalidLoginAttemptCount(user, 0).ConfigureAwait(false); + UpdateUser(user); + UpdateInvalidLoginAttemptCount(user, 0); } else { - await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false); + UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1); } _logger.Info("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied"); @@ -309,7 +307,7 @@ namespace Emby.Server.Implementations.Library return success ? user : null; } - private async Task UpdateInvalidLoginAttemptCount(User user, int newValue) + private void UpdateInvalidLoginAttemptCount(User user, int newValue) { if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0) { @@ -329,7 +327,7 @@ namespace Emby.Server.Implementations.Library //fireLockout = true; } - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); if (fireLockout) { @@ -374,27 +372,27 @@ namespace Emby.Server.Implementations.Library /// Loads the users from the repository /// </summary> /// <returns>IEnumerable{User}.</returns> - private async Task<IEnumerable<User>> LoadUsers() + private List<User> LoadUsers() { var users = UserRepository.RetrieveAllUsers().ToList(); // There always has to be at least one user. if (users.Count == 0) { - var name = MakeValidUsername(_defaultUserName); + var name = MakeValidUsername(Environment.UserName); var user = InstantiateNewUser(name); user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); users.Add(user); user.Policy.IsAdministrator = true; user.Policy.EnableContentDeletion = true; user.Policy.EnableRemoteControlOfOtherUsers = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); } return users; @@ -541,7 +539,7 @@ namespace Emby.Server.Implementations.Library /// <param name="user">The user.</param> /// <exception cref="System.ArgumentNullException">user</exception> /// <exception cref="System.ArgumentException"></exception> - public async Task UpdateUser(User user) + public void UpdateUser(User user) { if (user == null) { @@ -556,7 +554,7 @@ namespace Emby.Server.Implementations.Library user.DateModified = DateTime.UtcNow; user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); OnUserUpdated(user); } @@ -601,7 +599,7 @@ namespace Emby.Server.Implementations.Library user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger); @@ -655,7 +653,7 @@ namespace Emby.Server.Implementations.Library { var configPath = GetConfigurationFilePath(user); - await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.DeleteUser(user, CancellationToken.None); try { @@ -669,7 +667,7 @@ namespace Emby.Server.Implementations.Library DeleteUserPolicy(user); // Force this to be lazy loaded again - Users = await LoadUsers().ConfigureAwait(false); + Users = LoadUsers(); OnUserDeleted(user); } @@ -683,17 +681,17 @@ namespace Emby.Server.Implementations.Library /// Resets the password by clearing it. /// </summary> /// <returns>Task.</returns> - public Task ResetPassword(User user) + public void ResetPassword(User user) { - return ChangePassword(user, GetSha1String(string.Empty)); + ChangePassword(user, GetSha1String(string.Empty)); } - public Task ResetEasyPassword(User user) + public void ResetEasyPassword(User user) { - return ChangeEasyPassword(user, GetSha1String(string.Empty)); + ChangeEasyPassword(user, GetSha1String(string.Empty)); } - public async Task ChangePassword(User user, string newPasswordSha1) + public void ChangePassword(User user, string newPasswordSha1) { if (user == null) { @@ -711,12 +709,12 @@ namespace Emby.Server.Implementations.Library user.Password = newPasswordSha1; - await UpdateUser(user).ConfigureAwait(false); + UpdateUser(user); EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); } - public async Task ChangeEasyPassword(User user, string newPasswordSha1) + public void ChangeEasyPassword(User user, string newPasswordSha1) { if (user == null) { @@ -729,7 +727,7 @@ namespace Emby.Server.Implementations.Library user.EasyPassword = newPasswordSha1; - await UpdateUser(user).ConfigureAwait(false); + UpdateUser(user); EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); } @@ -844,7 +842,7 @@ namespace Emby.Server.Implementations.Library }; } - public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin) + public PinRedeemResult RedeemPasswordResetPin(string pin) { DeletePinFile(); @@ -865,12 +863,12 @@ namespace Emby.Server.Implementations.Library foreach (var user in users) { - await ResetPassword(user).ConfigureAwait(false); + ResetPassword(user); if (user.Policy.IsDisabled) { user.Policy.IsDisabled = false; - await UpdateUserPolicy(user, user.Policy, true).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, true); } usersReset.Add(user.Name); } @@ -947,13 +945,13 @@ namespace Emby.Server.Implementations.Library } private readonly object _policySyncLock = new object(); - public Task UpdateUserPolicy(string userId, UserPolicy userPolicy) + public void UpdateUserPolicy(string userId, UserPolicy userPolicy) { var user = GetUserById(userId); - return UpdateUserPolicy(user, userPolicy, true); + UpdateUserPolicy(user, userPolicy, true); } - private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) + private void UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) { // The xml serializer will output differently if the type is not exact if (userPolicy.GetType() != typeof(UserPolicy)) @@ -972,7 +970,7 @@ namespace Emby.Server.Implementations.Library user.Policy = userPolicy; } - await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false); + UpdateConfiguration(user, user.Configuration, true); } private void DeleteUserPolicy(User user) @@ -1034,13 +1032,13 @@ namespace Emby.Server.Implementations.Library } private readonly object _configSyncLock = new object(); - public Task UpdateConfiguration(string userId, UserConfiguration config) + public void UpdateConfiguration(string userId, UserConfiguration config) { var user = GetUserById(userId); - return UpdateConfiguration(user, config, true); + UpdateConfiguration(user, config, true); } - private async Task UpdateConfiguration(User user, UserConfiguration config, bool fireEvent) + private void UpdateConfiguration(User user, UserConfiguration config, bool fireEvent) { var path = GetConfigurationFilePath(user); diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index a6ed84f29..8c9377291 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Library { @@ -38,7 +39,7 @@ namespace Emby.Server.Implementations.Library _config = config; } - public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken) + public async Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken) { var user = _userManager.GetUserById(query.UserId); @@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.Library if (UserView.IsUserSpecific(folder)) { - list.Add(await _libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken).ConfigureAwait(false)); + list.Add(_libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken)); continue; } @@ -79,7 +80,7 @@ namespace Emby.Server.Implementations.Library if (query.PresetViews.Contains(folderViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - list.Add(await GetUserView(folder, folderViewType, string.Empty, cancellationToken).ConfigureAwait(false)); + list.Add(GetUserView(folder, folderViewType, string.Empty, cancellationToken)); } else { @@ -94,7 +95,7 @@ namespace Emby.Server.Implementations.Library if (parents.Count > 0) { - list.Add(await GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken).ConfigureAwait(false)); + list.Add(GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken)); } } @@ -113,7 +114,7 @@ namespace Emby.Server.Implementations.Library }, cancellationToken).ConfigureAwait(false); var channels = channelResult.Items; - + if (_config.Configuration.EnableChannelView && channels.Length > 0) { list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false)); @@ -153,7 +154,8 @@ namespace Emby.Server.Implementations.Library return index == -1 ? int.MaxValue : index; }) .ThenBy(sorted.IndexOf) - .ThenBy(i => i.SortName); + .ThenBy(i => i.SortName) + .ToArray(); } public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken) @@ -170,7 +172,7 @@ namespace Emby.Server.Implementations.Library return GetUserSubView(name, parentId, type, sortName, cancellationToken); } - private async Task<Folder> GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken) + private Folder GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken) { if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase))) { @@ -179,14 +181,14 @@ namespace Emby.Server.Implementations.Library return (Folder)parents[0]; } - return await GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken).ConfigureAwait(false); + return GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken); } var name = _localizationManager.GetLocalizedString("ViewType" + viewType); - return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); + return _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken); } - public Task<UserView> GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken) + public UserView GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken) { return _libraryManager.GetShadowView(parent, viewType, sortName, cancellationToken); } @@ -231,7 +233,7 @@ namespace Emby.Server.Implementations.Library return list; } - private IEnumerable<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options) + private List<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options) { var parentId = request.ParentId; @@ -269,7 +271,41 @@ namespace Emby.Server.Implementations.Library return new List<BaseItem>(); } - var excludeItemTypes = includeItemTypes.Length == 0 ? new[] + var mediaTypes = new List<string>(); + + if (includeItemTypes.Length == 0) + { + foreach (var parent in parents.OfType<ICollectionFolder>()) + { + switch (parent.CollectionType) + { + case CollectionType.Books: + mediaTypes.Add(MediaType.Book); + break; + case CollectionType.Games: + mediaTypes.Add(MediaType.Game); + break; + case CollectionType.Music: + mediaTypes.Add(MediaType.Audio); + break; + case CollectionType.Photos: + mediaTypes.Add(MediaType.Photo); + mediaTypes.Add(MediaType.Video); + break; + case CollectionType.HomeVideos: + mediaTypes.Add(MediaType.Photo); + mediaTypes.Add(MediaType.Video); + break; + default: + mediaTypes.Add(MediaType.Video); + break; + } + } + + mediaTypes = mediaTypes.Distinct().ToList(); + } + + var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0 ? new[] { typeof(Person).Name, typeof(Studio).Name, @@ -283,14 +319,14 @@ namespace Emby.Server.Implementations.Library var query = new InternalItemsQuery(user) { IncludeItemTypes = includeItemTypes, - SortOrder = SortOrder.Descending, - SortBy = new[] { ItemSortBy.DateCreated }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) }, IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null, ExcludeItemTypes = excludeItemTypes, IsVirtualItem = false, Limit = limit * 5, IsPlayed = isPlayed, - DtoOptions = options + DtoOptions = options, + MediaTypes = mediaTypes.ToArray(mediaTypes.Count) }; if (parents.Count == 0) diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs index c2eb30ee4..39630cf96 100644 --- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -55,28 +55,21 @@ namespace Emby.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress) { - var people = _libraryManager.GetPeople(new InternalPeopleQuery()); - - var dict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase); - - foreach (var person in people) - { - dict[person.Name] = true; - } + var people = _libraryManager.GetPeopleNames(new InternalPeopleQuery()); var numComplete = 0; - _logger.Debug("Will refresh {0} people", dict.Count); + var numPeople = people.Count; - var numPeople = dict.Count; + _logger.Debug("Will refresh {0} people", numPeople); - foreach (var person in dict) + foreach (var person in people) { cancellationToken.ThrowIfCancellationRequested(); try { - var item = _libraryManager.GetPerson(person.Key); + var item = _libraryManager.GetPerson(person); var options = new MetadataRefreshOptions(_fileSystem) { |
