diff options
17 files changed, 129 insertions, 56 deletions
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 2cca63217..2637e729c 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -40,6 +40,20 @@ namespace MediaBrowser.Controller.Entities.Audio return !IsAccessedByName; } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + var itemByNameFilter = GetItemFilter(); + + if (query.User != null) + { + return query.User.RootFolder + .GetRecursiveChildren(query.User, i => !i.IsFolder && itemByNameFilter(i)); + } + + return LibraryManager.RootFolder + .GetRecursiveChildren(i => !i.IsFolder && itemByNameFilter(i)); + } + protected override IEnumerable<BaseItem> ActualChildren { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 4d041264c..05870176e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -79,5 +79,13 @@ namespace MediaBrowser.Controller.Entities.Audio return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } } } diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 71028d4cf..7c1e88cb1 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -62,6 +62,14 @@ namespace MediaBrowser.Controller.Entities return i => i is Game && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.IncludeItemTypes = new[] { typeof(Game).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index fa890ad9e..c87d4daaf 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -66,6 +66,14 @@ namespace MediaBrowser.Controller.Entities return i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(Game).Name, typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index e6667290c..7747e738c 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -20,6 +20,8 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <returns>Func<BaseItem, System.Boolean>.</returns> Func<BaseItem, bool> GetItemFilter(); + + IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query); } public interface IHasDualAccess : IItemByName diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 2615f351a..385ee81e9 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -134,6 +134,7 @@ namespace MediaBrowser.Controller.Entities public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } + public string AncestorWithPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 89581e967..2b099e3d5 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -31,6 +31,13 @@ namespace MediaBrowser.Controller.Entities return GetItemLookupInfo<PersonLookupInfo>(); } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + query.Person = Name; + + return LibraryManager.GetItemList(query); + } + /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index c8ab67a69..b0ddcfb8c 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -8,15 +8,6 @@ namespace MediaBrowser.Controller.Entities public class PhotoAlbum : Folder { [IgnoreDataMember] - public override bool SupportsLocalMetadata - { - get - { - return false; - } - } - - [IgnoreDataMember] public override bool AlwaysScanInternalMetadataPath { get diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 7ceefbc6e..48ca7bbcc 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -65,6 +65,13 @@ namespace MediaBrowser.Controller.Entities return i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + query.Studios = new[] { Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index abca6a643..a70bac6db 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MoreLinq; namespace MediaBrowser.Controller.Entities.TV { @@ -180,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.TV else { items = query.Recursive - ? GetRecursiveChildren(user, filter) + ? GetSeasons(user).Cast<BaseItem>().Concat(GetEpisodes(user)).Where(filter) : GetSeasons(user).Where(filter); } @@ -211,7 +212,7 @@ namespace MediaBrowser.Controller.Entities.TV } else { - seasons = base.GetChildren(user, true).OfType<Season>(); + seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>(); } if (!includeMissingSeasons && !includeVirtualUnaired) @@ -250,17 +251,8 @@ namespace MediaBrowser.Controller.Entities.TV // Specials could appear twice based on above - once in season 0, once in the aired season // This depends on settings for that series // When this happens, remove the duplicate from season 0 - var returnList = new List<Episode>(); - foreach (var episode in allEpisodes) - { - if (!returnList.Contains(episode)) - { - returnList.Insert(0, episode); - } - } - - return returnList; + return allEpisodes.DistinctBy(i => i.Id).Reverse(); } public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index f27ce79dd..db896f1fc 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -70,6 +70,22 @@ namespace MediaBrowser.Controller.Entities return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year); } + public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) + { + int year; + + var usCulture = new CultureInfo("en-US"); + + if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year)) + { + return new List<BaseItem>(); + } + + query.Years = new[] { year }; + + return LibraryManager.GetItemList(query); + } + public int? GetYearValue() { int i; diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 750dea361..cd0c5dc1c 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -99,11 +99,12 @@ namespace MediaBrowser.Controller.Playlists var musicGenre = item as MusicGenre; if (musicGenre != null) { - Func<BaseItem, bool> filter = i => i is Audio && i.Genres.Contains(musicGenre.Name, StringComparer.OrdinalIgnoreCase); - - var items = user == null - ? LibraryManager.RootFolder.GetRecursiveChildren(filter) - : user.RootFolder.GetRecursiveChildren(user, filter); + var items = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + Recursive = true, + IncludeItemTypes = new[] { typeof(Audio).Name }, + Genres = new[] { musicGenre.Name } + }); return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); } diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index aad7c112b..c82c4cdf7 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user) { var genres = item - .GetRecursiveChildren(user, i => i is Audio) + .GetRecursiveChildren(user, i => i is Audio) .Cast<Audio>() .SelectMany(i => i.Genres) .Concat(item.Genres) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 2de458d6e..14acd64e6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2334,6 +2334,12 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + new Guid(i).ToString("N") + "'").ToArray()); whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause)); } + if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey)) + { + var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey"; + whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause)); + cmd.Parameters.Add(cmd, "@AncestorWithPresentationUniqueKey", DbType.String).Value = query.AncestorWithPresentationUniqueKey; + } if (query.BlockUnratedItems.Length == 1) { diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index acb1227e4..ea2460719 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -109,6 +109,21 @@ namespace MediaBrowser.Server.Implementations.Photos protected async Task<ItemUpdateType> FetchAsync(IHasImages item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken) { + var image = item.GetImageInfo(imageType, 0); + + if (image != null) + { + if (!image.IsLocalFile) + { + return ItemUpdateType.None; + } + + if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path)) + { + return ItemUpdateType.None; + } + } + var items = await GetItemsWithImages(item).ConfigureAwait(false); return await FetchToFileInternal(item, items, imageType, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 014e8babf..77843ef6b 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -848,7 +848,7 @@ namespace MediaBrowser.Server.Implementations.Session if (!playbackFailed) { var data = _userDataRepository.GetUserData(userId, item); - + if (positionTicks.HasValue) { playedToCompletion = _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); @@ -1026,11 +1026,11 @@ namespace MediaBrowser.Server.Implementations.Session if (byName != null) { - var itemFilter = byName.GetItemFilter(); - - var items = user == null ? - _libraryManager.RootFolder.GetRecursiveChildren(i => !i.IsFolder && itemFilter(i)) : - user.RootFolder.GetRecursiveChildren(user, i => !i.IsFolder && itemFilter(i)); + var items = byName.GetTaggedItems(new InternalItemsQuery(user) + { + IsFolder = false, + Recursive = true + }); return FilterToSingleMediaType(items) .OrderBy(i => i.SortName); @@ -1040,9 +1040,12 @@ namespace MediaBrowser.Server.Implementations.Session { var folder = (Folder)item; - var items = user == null ? - folder.GetRecursiveChildren(i => !i.IsFolder) : - folder.GetRecursiveChildren(user, i => !i.IsFolder); + var items = folder.GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false + + }).Result.Items; return FilterToSingleMediaType(items) .OrderBy(i => i.SortName); @@ -1367,8 +1370,8 @@ namespace MediaBrowser.Server.Implementations.Session ServerId = _appHost.SystemId }; } - - + + private async Task<string> GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName) { var existing = _authRepo.Get(new AuthenticationInfoQuery diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index d95a4fefb..379e2f056 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -326,32 +326,26 @@ namespace MediaBrowser.Server.Implementations.Sync var itemByName = item as IItemByName; if (itemByName != null) { - var itemByNameFilter = itemByName.GetItemFilter(); - - return user.RootFolder - .GetRecursiveChildren(user, i => !i.IsFolder && itemByNameFilter(i)); - } - - var series = item as Series; - if (series != null) - { - return series.GetEpisodes(user, false, false); - } - - var season = item as Season; - if (season != null) - { - return season.GetEpisodes(user, false, false); + return itemByName.GetTaggedItems(new InternalItemsQuery(user) + { + IsFolder = false, + Recursive = true + }); } if (item.IsFolder) { var folder = (Folder)item; - var items = folder.GetRecursiveChildren(user, i => !i.IsFolder); + var items = folder.GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false + + }).Result.Items; if (!folder.IsPreSorted) { - items = items.OrderBy(i => i.SortName); + items = items.OrderBy(i => i.SortName).ToArray(); } return items; |
