diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index fbd97b6a2..7812cfb3c 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1347,6 +1347,11 @@ namespace Emby.Server.Implementations.Data } private BaseItem GetItem(IReadOnlyList reader, InternalItemsQuery query) + { + return GetItem(reader, query, HasProgramAttributes(query), HasEpisodeAttributes(query), HasStartDate(query), HasTrailerTypes(query), HasArtistFields(query), HasSeriesFields(query)); + } + + private BaseItem GetItem(IReadOnlyList reader, InternalItemsQuery query, bool enableProgramAttributes, bool hasEpisodeAttributes, bool queryHasStartDate, bool hasTrailerTypes, bool hasArtistFields, bool hasSeriesFields) { var typeString = reader.GetString(0); @@ -1394,28 +1399,34 @@ namespace Emby.Server.Implementations.Data return null; } - if (!reader.IsDBNull(2)) + var index = 2; + + if (queryHasStartDate) { - var hasStartDate = item as IHasStartDate; - if (hasStartDate != null) + if (!reader.IsDBNull(index)) { - hasStartDate.StartDate = reader[2].ReadDateTime(); + var hasStartDate = item as IHasStartDate; + if (hasStartDate != null) + { + hasStartDate.StartDate = reader[index].ReadDateTime(); + } } + index++; } - if (!reader.IsDBNull(3)) + if (!reader.IsDBNull(index)) { - item.EndDate = reader[3].ReadDateTime(); + item.EndDate = reader[index].ReadDateTime(); } + index++; - if (!reader.IsDBNull(4)) + if (!reader.IsDBNull(index)) { - item.ChannelId = reader.GetString(4); + item.ChannelId = reader.GetString(index); } + index++; - var index = 5; - - if (HasProgramAttributes(query)) + if (enableProgramAttributes) { var hasProgramAttributes = item as IHasProgramAttributes; if (hasProgramAttributes != null) @@ -1728,15 +1739,18 @@ namespace Emby.Server.Implementations.Data } index++; - var trailer = item as Trailer; - if (trailer != null) + if (hasTrailerTypes) { - if (!reader.IsDBNull(index)) + var trailer = item as Trailer; + if (trailer != null) { - trailer.TrailerTypes = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)).ToList(); + if (!reader.IsDBNull(index)) + { + trailer.TrailerTypes = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)).ToList(); + } } + index++; } - index++; if (HasField(query, ItemFields.OriginalTitle)) { @@ -1786,42 +1800,51 @@ namespace Emby.Server.Implementations.Data index++; var hasSeries = item as IHasSeries; - if (hasSeries != null) + if (hasSeriesFields) { - if (!reader.IsDBNull(index)) + if (hasSeries != null) { - hasSeries.SeriesName = reader.GetString(index); - } - } - index++; - - var episode = item as Episode; - if (episode != null) - { - if (!reader.IsDBNull(index)) - { - episode.SeasonName = reader.GetString(index); + if (!reader.IsDBNull(index)) + { + hasSeries.SeriesName = reader.GetString(index); + } } index++; - if (!reader.IsDBNull(index)) - { - episode.SeasonId = reader.GetGuid(index); - } } - else + + if (hasEpisodeAttributes) { + var episode = item as Episode; + if (episode != null) + { + if (!reader.IsDBNull(index)) + { + episode.SeasonName = reader.GetString(index); + } + index++; + if (!reader.IsDBNull(index)) + { + episode.SeasonId = reader.GetGuid(index); + } + } + else + { + index++; + } index++; } - index++; - if (hasSeries != null) + if (hasSeriesFields) { - if (!reader.IsDBNull(index)) + if (hasSeries != null) { - hasSeries.SeriesId = reader.GetGuid(index); + if (!reader.IsDBNull(index)) + { + hasSeries.SeriesId = reader.GetGuid(index); + } } + index++; } - index++; if (HasField(query, ItemFields.PresentationUniqueKey)) { @@ -1931,19 +1954,22 @@ namespace Emby.Server.Implementations.Data } index++; - var hasArtists = item as IHasArtist; - if (hasArtists != null && !reader.IsDBNull(index)) + if (hasArtistFields) { - hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); - } - index++; + var hasArtists = item as IHasArtist; + if (hasArtists != null && !reader.IsDBNull(index)) + { + hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + index++; - var hasAlbumArtists = item as IHasAlbumArtist; - if (hasAlbumArtists != null && !reader.IsDBNull(index)) - { - hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + var hasAlbumArtists = item as IHasAlbumArtist; + if (hasAlbumArtists != null && !reader.IsDBNull(index)) + { + hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + index++; } - index++; if (!reader.IsDBNull(index)) { @@ -2312,6 +2338,20 @@ namespace Emby.Server.Implementations.Data private bool HasProgramAttributes(InternalItemsQuery query) { + var excludeParentTypes = new string[] + { + "Series", + "Season", + "MusicAlbum", + "MusicArtist", + "PhotoAlbum" + }; + + if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + if (query.IncludeItemTypes.Length == 0) { return true; @@ -2331,6 +2371,130 @@ namespace Emby.Server.Implementations.Data return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); } + private bool HasStartDate(InternalItemsQuery query) + { + var excludeParentTypes = new string[] + { + "Series", + "Season", + "MusicAlbum", + "MusicArtist", + "PhotoAlbum" + }; + + if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + if (query.IncludeItemTypes.Length == 0) + { + return true; + } + + var types = new string[] + { + "Program", + "Recording", + "LiveTvAudioRecording", + "LiveTvVideoRecording", + "LiveTvProgram" + }; + + return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); + } + + private bool HasEpisodeAttributes(InternalItemsQuery query) + { + if (query.IncludeItemTypes.Length == 0) + { + return true; + } + + var types = new string[] + { + "Episode" + }; + + return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); + } + + private bool HasTrailerTypes(InternalItemsQuery query) + { + if (query.IncludeItemTypes.Length == 0) + { + return true; + } + + var types = new string[] + { + "Trailer" + }; + + return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); + } + + private bool HasArtistFields(InternalItemsQuery query) + { + var excludeParentTypes = new string[] + { + "Series", + "Season", + "PhotoAlbum" + }; + + if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + if (query.IncludeItemTypes.Length == 0) + { + return true; + } + + var types = new string[] + { + "Audio", + "MusicAlbum", + "MusicVideo", + "AudioBook", + "AudioPodcast", + "LiveTvAudioRecording", + "Recording" + }; + + return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); + } + + private bool HasSeriesFields(InternalItemsQuery query) + { + var excludeParentTypes = new string[] + { + "PhotoAlbum" + }; + + if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + if (query.IncludeItemTypes.Length == 0) + { + return true; + } + + var types = new string[] + { + "Book", + "AudioBook", + "Episode", + "Season" + }; + + return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)); + } + private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns) { var list = startColumns.ToList(); @@ -2359,6 +2523,40 @@ namespace Emby.Server.Implementations.Data list.Remove("IsRepeat"); } + if (!HasEpisodeAttributes(query)) + { + list.Remove("SeasonName"); + list.Remove("SeasonId"); + } + + if (!HasStartDate(query)) + { + list.Remove("StartDate"); + } + + if (!HasTrailerTypes(query)) + { + list.Remove("TrailerTypes"); + } + + if (!HasArtistFields(query)) + { + list.Remove("AlbumArtists"); + list.Remove("Artists"); + } + + if (!HasSeriesFields(query)) + { + list.Remove("SeriesId"); + list.Remove("SeriesName"); + } + + if (!HasEpisodeAttributes(query)) + { + list.Remove("SeasonName"); + list.Remove("SeasonId"); + } + if (!query.DtoOptions.EnableImages) { list.Remove("Images"); @@ -2590,9 +2788,16 @@ namespace Emby.Server.Implementations.Data // Running this again will bind the params GetWhereClauses(query, statement); + var hasEpisodeAttributes = HasEpisodeAttributes(query); + var hasProgramAttributes = HasProgramAttributes(query); + var hasStartDate = HasStartDate(query); + var hasTrailerTypes = HasTrailerTypes(query); + var hasArtistFields = HasArtistFields(query); + var hasSeriesFields = HasSeriesFields(query); + foreach (var row in statement.ExecuteQuery()) { - var item = GetItem(row, query); + var item = GetItem(row, query, hasProgramAttributes, hasEpisodeAttributes, hasStartDate, hasTrailerTypes, hasArtistFields, hasSeriesFields); if (item != null) { list.Add(item); @@ -2792,9 +2997,16 @@ namespace Emby.Server.Implementations.Data // Running this again will bind the params GetWhereClauses(query, statement); + var hasEpisodeAttributes = HasEpisodeAttributes(query); + var hasProgramAttributes = HasProgramAttributes(query); + var hasStartDate = HasStartDate(query); + var hasTrailerTypes = HasTrailerTypes(query); + var hasArtistFields = HasArtistFields(query); + var hasSeriesFields = HasSeriesFields(query); + foreach (var row in statement.ExecuteQuery()) { - var item = GetItem(row, query); + var item = GetItem(row, query, hasProgramAttributes, hasEpisodeAttributes, hasStartDate, hasTrailerTypes, hasArtistFields, hasSeriesFields); if (item != null) { list.Add(item); @@ -3562,6 +3774,15 @@ namespace Emby.Server.Implementations.Data } } + if (query.MinDateLastSavedForUser.HasValue) + { + whereClauses.Add("DateLastSaved>=@MinDateLastSaved"); + if (statement != null) + { + statement.TryBind("@MinDateLastSaved", query.MinDateLastSavedForUser.Value); + } + } + //if (query.MinPlayers.HasValue) //{ // whereClauses.Add("Players>=@MinPlayers"); @@ -3756,7 +3977,6 @@ namespace Emby.Server.Implementations.Data if (!string.IsNullOrWhiteSpace(query.SlugName)) { - Logger.Info("Searching by SlugName for {0}", query.SlugName); whereClauses.Add("CleanName=@SlugName"); if (statement != null) { @@ -5137,9 +5357,16 @@ namespace Emby.Server.Implementations.Data GetWhereClauses(innerQuery, statement); GetWhereClauses(outerQuery, statement); + var hasEpisodeAttributes = HasEpisodeAttributes(query); + var hasProgramAttributes = HasProgramAttributes(query); + var hasStartDate = HasStartDate(query); + var hasTrailerTypes = HasTrailerTypes(query); + var hasArtistFields = HasArtistFields(query); + var hasSeriesFields = HasSeriesFields(query); + foreach (var row in statement.ExecuteQuery()) { - var item = GetItem(row, query); + var item = GetItem(row, query, hasProgramAttributes, hasEpisodeAttributes, hasStartDate, hasTrailerTypes, hasArtistFields, hasSeriesFields); if (item != null) { var countStartColumn = columns.Count - 1; diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 8907c911a..125db7fd6 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1546,7 +1546,7 @@ namespace Emby.Server.Implementations.Library } } - query.ParentId = null; + query.Parent = null; } private void AddUserToQuery(InternalItemsQuery query, User user) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index c1e1bf2b6..50cb68a95 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -422,7 +422,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun SupportsTranscoding = true, IsInfiniteStream = true, IgnoreDts = true, - IgnoreIndex = true + //IgnoreIndex = true, + //ReadAtNativeFramerate = true }; mediaSource.InferTotalBitrate(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs index 03c21b120..477eef7ab 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs @@ -101,9 +101,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun _logger.Info("Beginning multicastStream.CopyUntilCancelled"); FileSystem.CreateDirectory(FileSystem.GetDirectoryName(_tempFilePath)); - using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous | FileOpenOptions.SequentialScan)) + using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous)) { - ResolveAfterDelay(2000, openTaskCompletionSource); + ResolveAfterDelay(3000, openTaskCompletionSource); await response.Content.CopyToAsync(fileStream, 81920, cancellationToken).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index ff6c0fb2c..7c767c141 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -121,11 +121,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun if (!cancellationToken.IsCancellationRequested) { FileSystem.CreateDirectory(FileSystem.GetDirectoryName(_tempFilePath)); - using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous | FileOpenOptions.SequentialScan)) + using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous)) { - ResolveAfterDelay(2000, openTaskCompletionSource); - - await new UdpClientStream(udpClient).CopyToAsync(fileStream, 81920, cancellationToken).ConfigureAwait(false); + await CopyTo(udpClient, fileStream, openTaskCompletionSource, cancellationToken).ConfigureAwait(false); } } } @@ -159,19 +157,36 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun }); } - private void ResolveAfterDelay(int delayMs, TaskCompletionSource openTaskCompletionSource) + private void Resolve(TaskCompletionSource openTaskCompletionSource) { - Task.Run(async () => - { - await Task.Delay(delayMs).ConfigureAwait(false); - openTaskCompletionSource.TrySetResult(true); - }); + Task.Run(() => + { + openTaskCompletionSource.TrySetResult(true); + }); } public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { return CopyFileTo(_tempFilePath, false, stream, cancellationToken); } + + private static int RtpHeaderBytes = 12; + private async Task CopyTo(ISocket udpClient, Stream outputStream, TaskCompletionSource openTaskCompletionSource, CancellationToken cancellationToken) + { + while (true) + { + var data = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false); + var bytesRead = data.ReceivedBytes - RtpHeaderBytes; + + await outputStream.WriteAsync(data.Buffer, RtpHeaderBytes, bytesRead, cancellationToken).ConfigureAwait(false); + + if (openTaskCompletionSource != null) + { + Resolve(openTaskCompletionSource); + openTaskCompletionSource = null; + } + } + } } // This handles the ReadAsync function only of a Stream object diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 4b1687d68..021a84da7 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -68,15 +68,18 @@ namespace MediaBrowser.Api.Playback if (string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { var userAgent = UserAgent ?? string.Empty; - if (userAgent.IndexOf("AppleTV", StringComparison.OrdinalIgnoreCase) != -1) - { - return 10; - } - if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1 || + + if (userAgent.IndexOf("AppleTV", StringComparison.OrdinalIgnoreCase) != -1 || + userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1 || userAgent.IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 || userAgent.IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 || userAgent.IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1) { + if (IsSegmentedLiveStream) + { + return 6; + } + return 10; } diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index 55c23841c..56fd93014 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -85,6 +85,12 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "MinPremiereDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public string MinPremiereDate { get; set; } + [ApiMember(Name = "MinDateLastSaved", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string MinDateLastSaved { get; set; } + + [ApiMember(Name = "MinDateLastSavedForUser", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string MinDateLastSavedForUser { get; set; } + [ApiMember(Name = "MaxPremiereDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public string MaxPremiereDate { get; set; } diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index b7bb758c3..159de46e6 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -294,6 +294,16 @@ namespace MediaBrowser.Api.UserLibrary } } + if (!string.IsNullOrEmpty(request.MinDateLastSaved)) + { + query.MinDateLastSaved = DateTime.Parse(request.MinDateLastSaved, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + } + + if (!string.IsNullOrEmpty(request.MinDateLastSavedForUser)) + { + query.MinDateLastSavedForUser = DateTime.Parse(request.MinDateLastSavedForUser, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + } + if (!string.IsNullOrEmpty(request.MinPremiereDate)) { query.MinPremiereDate = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b18d47a65..f83b2f7bd 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -672,7 +672,7 @@ namespace MediaBrowser.Controller.Entities { return ItemRepository.GetItemList(new InternalItemsQuery { - ParentId = Id, + Parent = this, GroupByPresentationUniqueKey = false, DtoOptions = new DtoOptions(true) }); @@ -692,7 +692,7 @@ namespace MediaBrowser.Controller.Entities { Recursive = false, Limit = 0, - ParentId = Id, + Parent = this, DtoOptions = new DtoOptions(false) { EnableImages = false @@ -743,7 +743,10 @@ namespace MediaBrowser.Controller.Entities if (!(this is UserRootFolder) && !(this is AggregateFolder)) { - query.ParentId = query.ParentId ?? Id; + if (!query.ParentId.HasValue) + { + query.Parent = this; + } } if (RequiresPostFiltering2(query)) diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index d3220f6c1..2186716d7 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -126,9 +126,27 @@ namespace MediaBrowser.Controller.Entities public bool? IsVirtualItem { get; set; } public Guid? ParentId { get; set; } + public string ParentType { get; set; } public string[] AncestorIds { get; set; } public string[] TopParentIds { get; set; } + public BaseItem Parent + { + set + { + if (value == null) + { + ParentId = null; + ParentType = null; + } + else + { + ParentId = value.Id; + ParentType = value.GetType().Name; + } + } + } + public string[] PresetViews { get; set; } public SourceType[] SourceTypes { get; set; } public SourceType[] ExcludeSourceTypes { get; set; } @@ -156,6 +174,7 @@ namespace MediaBrowser.Controller.Entities public DateTime? MinDateCreated { get; set; } public DateTime? MinDateLastSaved { get; set; } + public DateTime? MinDateLastSavedForUser { get; set; } public DtoOptions DtoOptions { get; set; } public int MinSimilarityScore { get; set; } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 801d1d783..b2edb3da8 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -130,7 +130,7 @@ namespace MediaBrowser.Controller.Entities if (query.Recursive) { query.Recursive = true; - query.ParentId = queryParent.Id; + query.Parent = queryParent; query.SetUser(user); return _libraryManager.GetItemsResult(query); @@ -355,7 +355,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetMusicPlaylists(Folder parent, User user, InternalItemsQuery query) { - query.ParentId = null; + query.Parent = null; query.IncludeItemTypes = new[] { typeof(Playlist).Name }; query.SetUser(user); query.Recursive = true; @@ -366,7 +366,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetMusicAlbums(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IncludeItemTypes = new[] { typeof(MusicAlbum).Name }; @@ -377,7 +377,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetMusicSongs(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IncludeItemTypes = new[] { typeof(Audio.Audio).Name }; @@ -405,7 +405,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IsFavorite = true; query.IncludeItemTypes = new[] { typeof(Audio.Audio).Name }; @@ -416,7 +416,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetFavoriteAlbums(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IsFavorite = true; query.IncludeItemTypes = new[] { typeof(MusicAlbum).Name }; @@ -466,7 +466,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetFavoriteMovies(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IsFavorite = true; query.IncludeItemTypes = new[] { typeof(Movie).Name }; @@ -477,7 +477,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetFavoriteSeries(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IsFavorite = true; query.IncludeItemTypes = new[] { typeof(Series).Name }; @@ -488,7 +488,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetFavoriteEpisodes(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IsFavorite = true; query.IncludeItemTypes = new[] { typeof(Episode).Name }; @@ -499,7 +499,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetMovieMovies(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IncludeItemTypes = new[] { typeof(Movie).Name }; @@ -518,7 +518,7 @@ namespace MediaBrowser.Controller.Entities query.SortOrder = SortOrder.Descending; query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Movie).Name }; @@ -532,7 +532,7 @@ namespace MediaBrowser.Controller.Entities query.SortOrder = SortOrder.Descending; query.IsResumable = true; query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Movie).Name }; @@ -586,7 +586,7 @@ namespace MediaBrowser.Controller.Entities private async Task> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = queryParent.Id; + query.Parent = queryParent; query.GenreIds = new[] { displayParent.Id.ToString("N") }; query.SetUser(user); @@ -602,7 +602,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetBoxsetView(Folder parent, User user, InternalItemsQuery query) { - query.ParentId = null; + query.Parent = null; query.IncludeItemTypes = new[] { typeof(BoxSet).Name }; query.SetUser(user); query.Recursive = true; @@ -644,7 +644,7 @@ namespace MediaBrowser.Controller.Entities query.SortOrder = SortOrder.Descending; query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Episode).Name }; @@ -674,7 +674,7 @@ namespace MediaBrowser.Controller.Entities query.SortOrder = SortOrder.Descending; query.IsResumable = true; query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Episode).Name }; @@ -685,7 +685,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetTvSeries(Folder parent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = parent.Id; + query.Parent = parent; query.SetUser(user); query.IncludeItemTypes = new[] { typeof(Series).Name }; @@ -729,7 +729,7 @@ namespace MediaBrowser.Controller.Entities private QueryResult GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query) { query.Recursive = true; - query.ParentId = queryParent.Id; + query.Parent = queryParent; query.GenreIds = new[] { displayParent.Id.ToString("N") }; query.SetUser(user); diff --git a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs index 979a929ca..5dcb81736 100644 --- a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs +++ b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.Server.Implementations.Devices { if (!_hasChildren.HasValue) { - _hasChildren = LibraryManager.GetItemIds(new InternalItemsQuery { ParentId = Id }).Count > 0; + _hasChildren = LibraryManager.GetItemIds(new InternalItemsQuery { Parent = this }).Count > 0; } return _hasChildren.Value; diff --git a/SharedVersion.cs b/SharedVersion.cs index 5a7ec0dba..1564e4a41 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.17.10")] +[assembly: AssemblyVersion("3.2.17.11")]