From 65a1ef020b205b1676bd7dd70e7261a1fa29b7a2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 19 Nov 2016 00:52:49 -0500 Subject: move sync repository to portable project --- MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 3fb118a9cf..94baacf133 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -123,7 +123,6 @@ namespace MediaBrowser.Controller.Entities public int? MinParentalRating { get; set; } public int? MaxParentalRating { get; set; } - public bool? IsCurrentSchema { get; set; } public bool? HasDeadParentId { get; set; } public bool? IsOffline { get; set; } public bool? IsVirtualItem { get; set; } -- cgit v1.2.3 From f275d7f3d2f40f5e4cbe2f97df6dbd9be8ec37fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 21 Nov 2016 03:54:53 -0500 Subject: reduce library queries --- .../EnvironmentInfo/EnvironmentInfo.cs | 5 ++ Emby.Server.Core/ApplicationHost.cs | 2 +- .../Activity/ActivityRepository.cs | 5 +- .../Data/BaseSqliteRepository.cs | 37 +++++++-- .../Data/SqliteDisplayPreferencesRepository.cs | 5 +- .../Data/SqliteFileOrganizationRepository.cs | 5 +- .../Data/SqliteItemRepository.cs | 96 +++++++++++----------- .../Data/SqliteUserDataRepository.cs | 5 +- .../Data/SqliteUserRepository.cs | 5 +- Emby.Server.Implementations/Dto/DtoService.cs | 16 +++- .../Library/LibraryManager.cs | 31 +++---- .../Library/UserViewManager.cs | 30 ++++--- .../LiveTv/LiveTvManager.cs | 2 +- .../Notifications/SqliteNotificationsRepository.cs | 11 ++- .../Security/AuthenticationRepository.cs | 5 +- .../Social/SharingRepository.cs | 5 +- Emby.Server.Implementations/Sync/SyncRepository.cs | 5 +- Emby.Server.Implementations/TV/TVSeriesManager.cs | 4 +- MediaBrowser.Api/Library/LibraryService.cs | 2 +- MediaBrowser.Api/Movies/MoviesService.cs | 17 +--- MediaBrowser.Controller/Entities/Audio/Audio.cs | 6 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 22 ++++- MediaBrowser.Controller/Entities/Folder.cs | 39 +++++---- .../Entities/InternalItemsQuery.cs | 1 - MediaBrowser.Controller/Entities/TV/Episode.cs | 6 ++ MediaBrowser.Controller/Entities/TV/Season.cs | 6 ++ MediaBrowser.Controller/Entities/TV/Series.cs | 1 - .../Entities/UserViewBuilder.cs | 10 +-- MediaBrowser.Controller/Library/ILibraryManager.cs | 5 +- MediaBrowser.Controller/TV/ITVSeriesManager.cs | 2 +- MediaBrowser.Model/System/IEnvironmentInfo.cs | 1 + MediaBrowser.Providers/Manager/MetadataService.cs | 14 ++-- 32 files changed, 230 insertions(+), 176 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs index c040e39313..ebd596dc41 100644 --- a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs +++ b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs @@ -105,5 +105,10 @@ namespace Emby.Common.Implementations.EnvironmentInfo { return null; } + + public string StackTrace + { + get { return Environment.StackTrace; } + } } } diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs index 55a8510337..d481380805 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Core/ApplicationHost.cs @@ -551,7 +551,7 @@ namespace Emby.Server.Core DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo); ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 8a7573d666..eef9792de4 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -29,10 +29,9 @@ namespace Emby.Server.Implementations.Activity { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs index 382c7f2457..d4226ec256 100644 --- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs +++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs @@ -40,6 +40,8 @@ namespace Emby.Server.Implementations.Data private static bool _versionLogged; + private string _defaultWal; + protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false, Action onConnect = null) { if (!_versionLogged) @@ -51,6 +53,15 @@ namespace Emby.Server.Implementations.Data ConnectionFlags connectionFlags; + if (isReadOnly) + { + //Logger.Info("Opening read connection"); + } + else + { + //Logger.Info("Opening write connection"); + } + isReadOnly = false; if (isReadOnly) @@ -70,12 +81,16 @@ namespace Emby.Server.Implementations.Data var db = SQLite3.Open(DbFilePath, connectionFlags, null); + if (string.IsNullOrWhiteSpace(_defaultWal)) + { + _defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First(); + } + var queries = new List { + "PRAGMA default_temp_store=memory", "pragma temp_store = memory", - "PRAGMA page_size=4096", - "PRAGMA journal_mode=WAL", - "pragma synchronous=Normal", + "PRAGMA journal_mode=WAL" //"PRAGMA cache size=-10000" }; @@ -90,13 +105,19 @@ namespace Emby.Server.Implementations.Data //// db.Execute(query); ////} - using (WriteLock.Write()) - { - db.ExecuteAll(string.Join(";", queries.ToArray())); + //Logger.Info("synchronous: " + db.Query("PRAGMA synchronous").SelectScalarString().First()); + //Logger.Info("temp_store: " + db.Query("PRAGMA temp_store").SelectScalarString().First()); - if (onConnect != null) + //if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase) || onConnect != null) + { + using (WriteLock.Write()) { - onConnect(db); + db.ExecuteAll(string.Join(";", queries.ToArray())); + + if (onConnect != null) + { + onConnect(db); + } } } diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index ab927ce867..17afbcfa91 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -56,10 +56,9 @@ namespace Emby.Server.Implementations.Data { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Data/SqliteFileOrganizationRepository.cs b/Emby.Server.Implementations/Data/SqliteFileOrganizationRepository.cs index a716823299..efc0ee2ed0 100644 --- a/Emby.Server.Implementations/Data/SqliteFileOrganizationRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteFileOrganizationRepository.cs @@ -33,10 +33,9 @@ namespace Emby.Server.Implementations.Data { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 754af96407..bc1eca06a9 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -29,6 +29,7 @@ using MediaBrowser.Server.Implementations.Devices; using MediaBrowser.Server.Implementations.Playlists; using MediaBrowser.Model.Reflection; using SQLitePCL.pretty; +using MediaBrowser.Model.System; namespace Emby.Server.Implementations.Data { @@ -66,14 +67,14 @@ namespace Emby.Server.Implementations.Data private readonly string _criticReviewsPath; - public const int LatestSchemaVersion = 109; private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IFileSystem _fileSystem; + private readonly IEnvironmentInfo _environmentInfo; /// /// Initializes a new instance of the class. /// - public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem) + public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo) : base(logger) { if (config == null) @@ -89,6 +90,7 @@ namespace Emby.Server.Implementations.Data _jsonSerializer = jsonSerializer; _memoryStreamProvider = memoryStreamProvider; _fileSystem = fileSystem; + _environmentInfo = environmentInfo; _typeMapper = new TypeMapper(assemblyInfo); _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews"); @@ -129,10 +131,9 @@ namespace Emby.Server.Implementations.Data _connection.ExecuteAll(string.Join(";", new[] { - "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "PRAGMA page_size=4096", + "PRAGMA default_temp_store=memory", + "PRAGMA temp_store=memory" })); var createMediaStreamsTableCommand @@ -193,7 +194,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "ProductionYear", "INT", existingColumnNames); AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames); AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "SchemaVersion", "INT", existingColumnNames); AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames); @@ -205,7 +205,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "IsOffline", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "LocationType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames); @@ -381,7 +380,6 @@ namespace Emby.Server.Implementations.Data "data", "StartDate", "EndDate", - "IsOffline", "ChannelId", "IsMovie", "IsSports", @@ -529,7 +527,6 @@ namespace Emby.Server.Implementations.Data "ParentId", "Genres", "InheritedParentalRatingValue", - "SchemaVersion", "SortName", "RunTimeTicks", "OfficialRatingDescription", @@ -539,7 +536,6 @@ namespace Emby.Server.Implementations.Data "DateCreated", "DateModified", "ForcedSortName", - "IsOffline", "LocationType", "PreferredMetadataLanguage", "PreferredMetadataCountryCode", @@ -790,7 +786,6 @@ namespace Emby.Server.Implementations.Data } saveItemStatement.TryBind("@InheritedParentalRatingValue", item.GetInheritedParentalRatingValue() ?? 0); - saveItemStatement.TryBind("@SchemaVersion", LatestSchemaVersion); saveItemStatement.TryBind("@SortName", item.SortName); saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks); @@ -803,7 +798,6 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@DateModified", item.DateModified); saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName); - saveItemStatement.TryBind("@IsOffline", item.IsOffline); saveItemStatement.TryBind("@LocationType", item.LocationType.ToString()); saveItemStatement.TryBind("@PreferredMetadataLanguage", item.PreferredMetadataLanguage); @@ -1182,7 +1176,7 @@ namespace Emby.Server.Implementations.Data } CheckDisposed(); - + //Logger.Info("Retrieving item {0}", id.ToString("N")); using (var connection = CreateConnection(true)) { using (WriteLock.Read()) @@ -1369,64 +1363,72 @@ namespace Emby.Server.Implementations.Data if (!reader.IsDBNull(4)) { - item.IsOffline = reader.GetBoolean(4); + item.ChannelId = reader.GetString(4); } - if (!reader.IsDBNull(5)) - { - item.ChannelId = reader.GetString(5); - } + var index = 5; var hasProgramAttributes = item as IHasProgramAttributes; if (hasProgramAttributes != null) { - if (!reader.IsDBNull(6)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsMovie = reader.GetBoolean(6); + hasProgramAttributes.IsMovie = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(7)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsSports = reader.GetBoolean(7); + hasProgramAttributes.IsSports = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(8)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsKids = reader.GetBoolean(8); + hasProgramAttributes.IsKids = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(9)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsSeries = reader.GetBoolean(9); + hasProgramAttributes.IsSeries = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(10)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsLive = reader.GetBoolean(10); + hasProgramAttributes.IsLive = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(11)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsNews = reader.GetBoolean(11); + hasProgramAttributes.IsNews = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(12)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsPremiere = reader.GetBoolean(12); + hasProgramAttributes.IsPremiere = reader.GetBoolean(index); } + index++; - if (!reader.IsDBNull(13)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.EpisodeTitle = reader.GetString(13); + hasProgramAttributes.EpisodeTitle = reader.GetString(index); } + index++; - if (!reader.IsDBNull(14)) + if (!reader.IsDBNull(index)) { - hasProgramAttributes.IsRepeat = reader.GetBoolean(14); + hasProgramAttributes.IsRepeat = reader.GetBoolean(index); } + index++; + } + else + { + index += 9; } - - var index = 15; if (!reader.IsDBNull(index)) { @@ -2368,6 +2370,8 @@ namespace Emby.Server.Implementations.Data CheckDisposed(); + //Logger.Info("GetItemList: " + _environmentInfo.StackTrace); + var now = DateTime.UtcNow; var list = new List(); @@ -2533,6 +2537,7 @@ namespace Emby.Server.Implementations.Data TotalRecordCount = returnList.Count }; } + //Logger.Info("GetItems: " + _environmentInfo.StackTrace); var now = DateTime.UtcNow; @@ -2770,6 +2775,7 @@ namespace Emby.Server.Implementations.Data } CheckDisposed(); + //Logger.Info("GetItemIdsList: " + _environmentInfo.StackTrace); var now = DateTime.UtcNow; @@ -2928,6 +2934,7 @@ namespace Emby.Server.Implementations.Data TotalRecordCount = returnList.Count }; } + //Logger.Info("GetItemIds: " + _environmentInfo.StackTrace); var now = DateTime.UtcNow; @@ -3053,14 +3060,6 @@ namespace Emby.Server.Implementations.Data statement.TryBind("@IsLocked", query.IsLocked); } } - if (query.IsOffline.HasValue) - { - whereClauses.Add("IsOffline=@IsOffline"); - if (statement != null) - { - statement.TryBind("@IsOffline", query.IsOffline); - } - } var exclusiveProgramAttribtues = !(query.IsMovie ?? true) || !(query.IsSports ?? true) || @@ -4721,7 +4720,7 @@ namespace Emby.Server.Implementations.Data using (var connection = CreateConnection(true)) { - using (WriteLock.Write()) + using (WriteLock.Read()) { foreach (var row in connection.Query(commandText)) { @@ -4750,6 +4749,7 @@ namespace Emby.Server.Implementations.Data } CheckDisposed(); + //Logger.Info("GetItemValues: " + _environmentInfo.StackTrace); var now = DateTime.UtcNow; diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index 0b4768c141..9f7cce13b5 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -45,10 +45,9 @@ namespace Emby.Server.Implementations.Data { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index 0a2f9e7cde..f902d981fe 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -52,10 +52,9 @@ namespace Emby.Server.Implementations.Data { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 85549439b7..438fc55d77 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -482,7 +482,7 @@ namespace Emby.Server.Implementations.Dto { if (dtoOptions.EnableUserData) { - dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result; + dto.UserData = await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false); } } @@ -1450,11 +1450,19 @@ namespace Emby.Server.Implementations.Dto private void AddInheritedImages(BaseItemDto dto, BaseItem item, DtoOptions options, BaseItem owner) { + if (!item.SupportsInheritedParentImages) + { + return; + } + var logoLimit = options.GetImageLimit(ImageType.Logo); var artLimit = options.GetImageLimit(ImageType.Art); var thumbLimit = options.GetImageLimit(ImageType.Thumb); var backdropLimit = options.GetImageLimit(ImageType.Backdrop); + // For now. Emby apps are not using this + artLimit = 0; + if (logoLimit == 0 && artLimit == 0 && thumbLimit == 0 && backdropLimit == 0) { return; @@ -1515,6 +1523,12 @@ namespace Emby.Server.Implementations.Dto } isFirst = false; + + if (!parent.SupportsInheritedParentImages) + { + break; + } + parent = parent.GetParent(); } } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 13c6485e5b..283d193dd6 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -339,11 +339,6 @@ namespace Emby.Server.Implementations.Library { throw new ArgumentNullException("item"); } - RegisterItem(item.Id, item); - } - - private void RegisterItem(Guid id, BaseItem item) - { if (item is IItemByName) { if (!(item is MusicArtist)) @@ -354,13 +349,13 @@ namespace Emby.Server.Implementations.Library if (item.IsFolder) { - if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder)) - { - if (item.SourceType != SourceType.Library) - { - return; - } - } + //if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder)) + //{ + // if (item.SourceType != SourceType.Library) + // { + // return; + // } + //} } else { @@ -370,7 +365,7 @@ namespace Emby.Server.Implementations.Library } } - LibraryItemsCache.AddOrUpdate(id, item, delegate { return item; }); + LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; }); } public async Task DeleteItem(BaseItem item, DeleteOptions options) @@ -822,7 +817,7 @@ namespace Emby.Server.Implementations.Library return _userRootFolder; } - + public BaseItem FindByPath(string path, bool? isFolder) { // If this returns multiple items it could be tricky figuring out which one is correct. @@ -836,7 +831,7 @@ namespace Emby.Server.Implementations.Library SortOrder = SortOrder.Descending, Limit = 1 }; - + return GetItemList(query) .FirstOrDefault(); } @@ -1273,10 +1268,8 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetItemList(query); } - public IEnumerable GetItemList(InternalItemsQuery query, IEnumerable parentIds) + public IEnumerable GetItemList(InternalItemsQuery query, List parents) { - var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList(); - SetTopParentIdsOrAncestors(query, parents); if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0) @@ -1536,7 +1529,7 @@ namespace Emby.Server.Implementations.Library } // Handle grouping - if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType)) + if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) && user.Configuration.GroupedFolders.Length > 0) { return user.RootFolder .GetChildren(user, true) diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index b93f565a32..f7cc8bb73f 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -245,20 +245,26 @@ namespace Emby.Server.Implementations.Library var includeItemTypes = request.IncludeItemTypes; var limit = request.Limit ?? 10; - var parentIds = string.IsNullOrEmpty(parentId) - ? new string[] { } - : new[] { parentId }; + var parents = new List(); - if (parentIds.Length == 0) + if (!string.IsNullOrWhiteSpace(parentId)) { - parentIds = user.RootFolder.GetChildren(user, true) - .OfType() - .Select(i => i.Id.ToString("N")) - .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i)) - .ToArray(); + var parent = _libraryManager.GetItemById(parentId) as Folder; + if (parent != null) + { + parents.Add(parent); + } + } + + if (parents.Count == 0) + { + parents = user.RootFolder.GetChildren(user, true) + .Where(i => i is Folder) + .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N"))) + .ToList(); } - if (parentIds.Length == 0) + if (parents.Count == 0) { return new List(); } @@ -283,10 +289,10 @@ namespace Emby.Server.Implementations.Library ExcludeItemTypes = excludeItemTypes, ExcludeLocationTypes = new[] { LocationType.Virtual }, Limit = limit * 5, - SourceTypes = parentIds.Length == 0 ? new[] { SourceType.Library } : new SourceType[] { }, + SourceTypes = parents.Count == 0 ? new[] { SourceType.Library } : new SourceType[] { }, IsPlayed = request.IsPlayed - }, parentIds); + }, parents); } } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 3a6f23fe95..faf9687f40 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.LiveTv var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id); - var item = _itemRepo.RetrieveItem(id) as LiveTvChannel; + var item = _libraryManager.GetItemById(id) as LiveTvChannel; if (item == null) { diff --git a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 5fc691527e..66ef5d5d18 100644 --- a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -31,10 +31,9 @@ namespace Emby.Server.Implementations.Notifications { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { @@ -57,9 +56,9 @@ namespace Emby.Server.Implementations.Notifications { var result = new NotificationResult(); - using (WriteLock.Read()) + using (var connection = CreateConnection(true)) { - using (var connection = CreateConnection(true)) + //using (WriteLock.Read()) { var clauses = new List(); var paramList = new List(); @@ -114,7 +113,7 @@ namespace Emby.Server.Implementations.Notifications using (var connection = CreateConnection(true)) { - using (WriteLock.Read()) + //using (WriteLock.Read()) { using (var statement = connection.PrepareStatement("select Level from Notifications where UserId=@UserId and IsRead=@IsRead")) { diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 0a598e9a71..dad05718c9 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -32,10 +32,9 @@ namespace Emby.Server.Implementations.Security { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Social/SharingRepository.cs b/Emby.Server.Implementations/Social/SharingRepository.cs index e0ee62780e..6dab54bc6b 100644 --- a/Emby.Server.Implementations/Social/SharingRepository.cs +++ b/Emby.Server.Implementations/Social/SharingRepository.cs @@ -29,10 +29,9 @@ namespace Emby.Server.Implementations.Social { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/Sync/SyncRepository.cs b/Emby.Server.Implementations/Sync/SyncRepository.cs index 36558142b9..308c3bd00d 100644 --- a/Emby.Server.Implementations/Sync/SyncRepository.cs +++ b/Emby.Server.Implementations/Sync/SyncRepository.cs @@ -45,10 +45,9 @@ namespace Emby.Server.Implementations.Sync { connection.ExecuteAll(string.Join(";", new[] { + "PRAGMA page_size=4096", "pragma default_temp_store = memory", - "pragma default_synchronous=Normal", - "pragma temp_store = memory", - "pragma synchronous=Normal", + "pragma temp_store = memory" })); string[] queries = { diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index a47aaa3055..fd576e081f 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.TV return GetResult(episodes, null, request); } - public QueryResult GetNextUp(NextUpQuery request, IEnumerable parentsFolders) + public QueryResult GetNextUp(NextUpQuery request, List parentsFolders) { var user = _userManager.GetUserById(request.UserId); @@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.TV PresentationUniqueKey = presentationUniqueKey, Limit = limit - }, parentsFolders.Select(i => i.Id.ToString("N"))).Cast(); + }, parentsFolders.Cast().ToList()).Cast(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 36a58cc208..695718a255 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -369,7 +369,7 @@ namespace MediaBrowser.Api.Library if (item is Movie || (program != null && program.IsMovie) || item is Trailer) { - return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _config, _authContext) + return new MoviesService(_userManager, _libraryManager, _dtoService, _config, _authContext) { Request = Request, diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 1b2fa4fff9..b5c6f52fc0 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -78,16 +78,8 @@ namespace MediaBrowser.Api.Movies /// private readonly IUserManager _userManager; - /// - /// The _user data repository - /// - private readonly IUserDataManager _userDataRepository; - /// - /// The _library manager - /// private readonly ILibraryManager _libraryManager; - private readonly IItemRepository _itemRepo; private readonly IDtoService _dtoService; private readonly IServerConfigurationManager _config; private readonly IAuthorizationContext _authContext; @@ -95,17 +87,10 @@ namespace MediaBrowser.Api.Movies /// /// Initializes a new instance of the class. /// - /// The user manager. - /// The user data repository. - /// The library manager. - /// The item repo. - /// The dto service. - public MoviesService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IServerConfigurationManager config, IAuthorizationContext authContext) + public MoviesService(IUserManager userManager, ILibraryManager libraryManager, IDtoService dtoService, IServerConfigurationManager config, IAuthorizationContext authContext) { _userManager = userManager; - _userDataRepository = userDataRepository; _libraryManager = libraryManager; - _itemRepo = itemRepo; _dtoService = dtoService; _config = config; _authContext = authContext; diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 539cc5f221..e4f638cb6f 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -61,6 +61,12 @@ namespace MediaBrowser.Controller.Entities.Audio get { return true; } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } + } + [IgnoreDataMember] protected override bool SupportsOwnedItems { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cd61d2cce4..b7ea7a92d8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1569,6 +1569,12 @@ namespace MediaBrowser.Controller.Entities return IsVisibleStandaloneInternal(user, true); } + [IgnoreDataMember] + public virtual bool SupportsInheritedParentImages + { + get { return false; } + } + protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) { if (!IsVisible(user)) @@ -2329,17 +2335,25 @@ namespace MediaBrowser.Controller.Entities { get { - if (GetParent() is AggregateFolder || this is BasePluginFolder || this is Channel) + if (this is BasePluginFolder || this is Channel) { return true; } var view = this as UserView; - if (view != null && string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + if (view != null) { - return true; + if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + if (string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) + { + return true; + } } - if (view != null && string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) + + if (GetParent() is AggregateFolder) { return true; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 3df77673f7..d4ddab7b28 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1383,6 +1383,15 @@ namespace MediaBrowser.Controller.Entities { return false; } + var iItemByName = this as IItemByName; + if (iItemByName != null) + { + var hasDualAccess = this as IHasDualAccess; + if (hasDualAccess == null || hasDualAccess.IsAccessedByName) + { + return false; + } + } return true; } @@ -1395,17 +1404,6 @@ namespace MediaBrowser.Controller.Entities return; } - var unplayedQueryResult = await GetItems(new InternalItemsQuery(user) - { - Recursive = true, - IsFolder = false, - IsVirtualItem = false, - EnableTotalRecordCount = true, - Limit = 0, - IsPlayed = false - - }).ConfigureAwait(false); - var allItemsQueryResult = await GetItems(new InternalItemsQuery(user) { Recursive = true, @@ -1415,17 +1413,28 @@ namespace MediaBrowser.Controller.Entities Limit = 0 }).ConfigureAwait(false); + var recursiveItemCount = allItemsQueryResult.TotalRecordCount; if (itemDto != null) { itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount; } - var recursiveItemCount = allItemsQueryResult.TotalRecordCount; - double unplayedCount = unplayedQueryResult.TotalRecordCount; - - if (recursiveItemCount > 0) + if (recursiveItemCount > 0 && SupportsPlayedStatus) { + var unplayedQueryResult = recursiveItemCount > 0 ? await GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false, + IsVirtualItem = false, + EnableTotalRecordCount = true, + Limit = 0, + IsPlayed = false + + }).ConfigureAwait(false) : new QueryResult(); + + double unplayedCount = unplayedQueryResult.TotalRecordCount; + var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100; dto.PlayedPercentage = 100 - unplayedPercentage; dto.Played = dto.PlayedPercentage.Value >= 100; diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 94baacf133..be6e95ddd6 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -124,7 +124,6 @@ namespace MediaBrowser.Controller.Entities public int? MaxParentalRating { get; set; } public bool? HasDeadParentId { get; set; } - public bool? IsOffline { get; set; } public bool? IsVirtualItem { get; set; } public Guid? ParentId { get; set; } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 99abf56119..29a63f3175 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -71,6 +71,12 @@ namespace MediaBrowser.Controller.Entities.TV { return IsStacked || MediaSourceCount > 1; } + } + + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index d8a9a16c17..2663a9dd50 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -39,6 +39,12 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } + } + [IgnoreDataMember] public override Guid? DisplayParentId { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index a997d34766..69a3a67c81 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -135,7 +135,6 @@ namespace MediaBrowser.Controller.Entities.TV { AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), IncludeItemTypes = new[] { typeof(Season).Name }, - SortBy = new[] { ItemSortBy.SortName }, IsVirtualItem = false, Limit = 0 }); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 3820de83d1..d5781d21e2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1812,7 +1812,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i)); } - private IEnumerable GetMediaFolders(User user, IEnumerable viewTypes) + private List GetMediaFolders(User user, IEnumerable viewTypes) { if (user == null) { @@ -1822,7 +1822,7 @@ namespace MediaBrowser.Controller.Entities var folder = i as ICollectionFolder; return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - }); + }).ToList(); } return GetMediaFolders(user) .Where(i => @@ -1830,17 +1830,17 @@ namespace MediaBrowser.Controller.Entities var folder = i as ICollectionFolder; return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - }); + }).ToList(); } - private IEnumerable GetMediaFolders(Folder parent, User user, IEnumerable viewTypes) + private List GetMediaFolders(Folder parent, User user, IEnumerable viewTypes) { if (parent == null || parent is UserView) { return GetMediaFolders(user, viewTypes); } - return new[] { parent }; + return new List { parent }; } private IEnumerable GetRecursiveChildren(Folder parent, User user, IEnumerable viewTypes) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index acdd9a0423..955230b8ab 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -538,10 +538,7 @@ namespace MediaBrowser.Controller.Library /// /// Gets the items. /// - /// The query. - /// The parent ids. - /// List<BaseItem>. - IEnumerable GetItemList(InternalItemsQuery query, IEnumerable parentIds); + IEnumerable GetItemList(InternalItemsQuery query, List parents); /// /// Gets the items result. diff --git a/MediaBrowser.Controller/TV/ITVSeriesManager.cs b/MediaBrowser.Controller/TV/ITVSeriesManager.cs index 3d6e87474c..771fa602a0 100644 --- a/MediaBrowser.Controller/TV/ITVSeriesManager.cs +++ b/MediaBrowser.Controller/TV/ITVSeriesManager.cs @@ -19,6 +19,6 @@ namespace MediaBrowser.Controller.TV /// The request. /// The parents folders. /// QueryResult<BaseItem>. - QueryResult GetNextUp(NextUpQuery request, IEnumerable parentsFolders); + QueryResult GetNextUp(NextUpQuery request, List parentsFolders); } } diff --git a/MediaBrowser.Model/System/IEnvironmentInfo.cs b/MediaBrowser.Model/System/IEnvironmentInfo.cs index 7e7d81e30b..f9795a5684 100644 --- a/MediaBrowser.Model/System/IEnvironmentInfo.cs +++ b/MediaBrowser.Model/System/IEnvironmentInfo.cs @@ -14,6 +14,7 @@ namespace MediaBrowser.Model.System Architecture SystemArchitecture { get; } string GetEnvironmentVariable(string name); string GetUserId(); + string StackTrace { get; } } public enum OperatingSystem diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 3046fc395c..0491e800f6 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -536,7 +536,7 @@ namespace MediaBrowser.Providers.Manager refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; // Only one local provider allowed per item - if (item.IsLocked || IsFullLocalMetadata(localItem.Item)) + if (item.IsLocked || localItem.Item.IsLocked || IsFullLocalMetadata(localItem.Item)) { hasLocalMetadata = true; } @@ -573,14 +573,16 @@ namespace MediaBrowser.Providers.Manager { if (refreshResult.UpdateType > ItemUpdateType.None) { - // If no local metadata, take data from item itself - if (!hasLocalMetadata) + if (hasLocalMetadata) + { + MergeData(temp, metadata, item.LockedFields, true, true); + } + else { // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields - MergeData(metadata, temp, new List(), false, true); + MergeData(metadata, temp, new List(), false, false); + MergeData(temp, metadata, item.LockedFields, true, false); } - - MergeData(temp, metadata, item.LockedFields, true, true); } } -- cgit v1.2.3 From 921ec9cd11b71171cb69fa538e9d1ec1f2ffbbd5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 26 Nov 2016 19:40:15 -0500 Subject: save additional info to recording nfo's --- .../Data/SqliteItemRepository.cs | 13 +- .../HttpServer/HttpListenerHost.cs | 6 +- .../LiveTv/EmbyTV/EmbyTV.cs | 201 ++++++++++++++++++--- Emby.Server.Implementations/Sync/SyncRepository.cs | 20 +- MediaBrowser.Api/Library/LibraryService.cs | 17 +- .../Entities/InternalItemsQuery.cs | 1 + 6 files changed, 219 insertions(+), 39 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 727a9c4bb2..c6e5a6dcf9 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -170,7 +170,9 @@ namespace Emby.Server.Implementations.Data createMediaStreamsTableCommand, - "create index if not exists idx_mediastreams1 on mediastreams(ItemId)" + "create index if not exists idx_mediastreams1 on mediastreams(ItemId)", + + "pragma shrink_memory" }; @@ -3591,6 +3593,15 @@ namespace Emby.Server.Implementations.Data } } + if (!string.IsNullOrWhiteSpace(query.ExternalId)) + { + whereClauses.Add("ExternalId=@ExternalId"); + if (statement != null) + { + statement.TryBind("@ExternalId", query.ExternalId); + } + } + if (!string.IsNullOrWhiteSpace(query.Name)) { whereClauses.Add("CleanName=@Name"); diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index c1758127a5..8a5ae2c3a5 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -414,9 +414,9 @@ namespace Emby.Server.Implementations.HttpServer httpRes.StatusCode = 200; httpRes.AddHeader("Access-Control-Allow-Origin", "*"); httpRes.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - httpRes.AddHeader("Access-Control-Allow-Headers", - "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); - httpRes.ContentType = "text/html"; + httpRes.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); + httpRes.ContentType = "text/plain"; + Write(httpRes, string.Empty); return; } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1fe5d87cef..36a4dc6084 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1601,6 +1601,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { try { + var program = string.IsNullOrWhiteSpace(timer.ProgramId) ? null : _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + Limit = 1, + ExternalId = timer.ProgramId + + }).FirstOrDefault(); + if (timer.IsSports) { AddGenre(timer.Genres, "Sports"); @@ -1615,14 +1623,37 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV AddGenre(timer.Genres, "News"); } + // dummy this up + if (program == null) + { + program = new LiveTvProgram + { + Name = timer.Name, + HomePageUrl = timer.HomePageUrl, + ShortOverview = timer.ShortOverview, + Overview = timer.Overview, + Genres = timer.Genres, + CommunityRating = timer.CommunityRating, + OfficialRating = timer.OfficialRating, + ProductionYear = timer.ProductionYear, + PremiereDate = timer.OriginalAirDate, + IndexNumber = timer.EpisodeNumber, + ParentIndexNumber = timer.SeasonNumber + }; + } + if (timer.IsProgramSeries) { - SaveSeriesNfo(timer, recordingPath, seriesPath); - SaveVideoNfo(timer, recordingPath, false); + SaveSeriesNfo(timer, seriesPath); + SaveVideoNfo(timer, recordingPath, program, false); } else if (!timer.IsMovie || timer.IsSports || timer.IsNews) { - SaveVideoNfo(timer, recordingPath, true); + SaveVideoNfo(timer, recordingPath, program, true); + } + else + { + SaveVideoNfo(timer, recordingPath, program, false); } } catch (Exception ex) @@ -1631,7 +1662,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } - private void SaveSeriesNfo(TimerInfo timer, string recordingPath, string seriesPath) + private void SaveSeriesNfo(TimerInfo timer, string seriesPath) { var nfoPath = Path.Combine(seriesPath, "tvshow.nfo"); @@ -1676,7 +1707,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss"; - private void SaveVideoNfo(TimerInfo timer, string recordingPath, bool lockData) + private void SaveVideoNfo(TimerInfo timer, string recordingPath, BaseItem item, bool lockData) { var nfoPath = Path.ChangeExtension(recordingPath, ".nfo"); @@ -1694,6 +1725,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV CloseOutput = false }; + var options = _config.GetNfoConfiguration(); + using (XmlWriter writer = XmlWriter.Create(stream, settings)) { writer.WriteStartDocument(true); @@ -1707,45 +1740,64 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV writer.WriteElementString("title", timer.EpisodeTitle); } - if (timer.OriginalAirDate.HasValue) + if (item.PremiereDate.HasValue) { - var formatString = _config.GetNfoConfiguration().ReleaseDateFormat; + var formatString = options.ReleaseDateFormat; - writer.WriteElementString("aired", timer.OriginalAirDate.Value.ToLocalTime().ToString(formatString)); + writer.WriteElementString("aired", item.PremiereDate.Value.ToLocalTime().ToString(formatString)); } - if (timer.EpisodeNumber.HasValue) + if (item.IndexNumber.HasValue) { - writer.WriteElementString("episode", timer.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture)); + writer.WriteElementString("episode", item.IndexNumber.Value.ToString(CultureInfo.InvariantCulture)); } - if (timer.SeasonNumber.HasValue) + if (item.ParentIndexNumber.HasValue) { - writer.WriteElementString("season", timer.SeasonNumber.Value.ToString(CultureInfo.InvariantCulture)); + writer.WriteElementString("season", item.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture)); } } else { writer.WriteStartElement("movie"); - if (!string.IsNullOrWhiteSpace(timer.Name)) + if (!string.IsNullOrWhiteSpace(item.Name)) + { + writer.WriteElementString("title", item.Name); + } + + if (!string.IsNullOrWhiteSpace(item.OriginalTitle)) + { + writer.WriteElementString("originaltitle", item.OriginalTitle); + } + + if (item.PremiereDate.HasValue) { - writer.WriteElementString("title", timer.Name); + var formatString = options.ReleaseDateFormat; + + writer.WriteElementString("premiered", item.PremiereDate.Value.ToLocalTime().ToString(formatString)); + writer.WriteElementString("releasedate", item.PremiereDate.Value.ToLocalTime().ToString(formatString)); } } writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat)); - if (timer.ProductionYear.HasValue) + if (item.ProductionYear.HasValue) { - writer.WriteElementString("year", timer.ProductionYear.Value.ToString(CultureInfo.InvariantCulture)); + writer.WriteElementString("year", item.ProductionYear.Value.ToString(CultureInfo.InvariantCulture)); } - if (!string.IsNullOrEmpty(timer.OfficialRating)) + + if (!string.IsNullOrEmpty(item.OfficialRating)) { - writer.WriteElementString("mpaa", timer.OfficialRating); + writer.WriteElementString("mpaa", item.OfficialRating); } - var overview = (timer.Overview ?? string.Empty) + if (!string.IsNullOrEmpty(item.OfficialRatingDescription)) + { + writer.WriteElementString("mpaadescription", item.OfficialRatingDescription); + } + + var overview = (item.Overview ?? string.Empty) .StripHtml() .Replace(""", "'"); @@ -1756,24 +1808,116 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV writer.WriteElementString("lockdata", true.ToString().ToLower()); } - if (timer.CommunityRating.HasValue) + if (item.CommunityRating.HasValue) { - writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture)); + writer.WriteElementString("rating", item.CommunityRating.Value.ToString(CultureInfo.InvariantCulture)); } - foreach (var genre in timer.Genres) + foreach (var genre in item.Genres) { writer.WriteElementString("genre", genre); } - if (!string.IsNullOrWhiteSpace(timer.ShortOverview)) + if (!string.IsNullOrWhiteSpace(item.ShortOverview)) { - writer.WriteElementString("outline", timer.ShortOverview); + writer.WriteElementString("outline", item.ShortOverview); } - if (!string.IsNullOrWhiteSpace(timer.HomePageUrl)) + if (!string.IsNullOrWhiteSpace(item.HomePageUrl)) + { + writer.WriteElementString("website", item.HomePageUrl); + } + + var people = item.Id == Guid.Empty ? new List() : _libraryManager.GetPeople(item); + + var directors = people + .Where(i => IsPersonType(i, PersonType.Director)) + .Select(i => i.Name) + .ToList(); + + foreach (var person in directors) { - writer.WriteElementString("website", timer.HomePageUrl); + writer.WriteElementString("director", person); + } + + var writers = people + .Where(i => IsPersonType(i, PersonType.Writer)) + .Select(i => i.Name) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + foreach (var person in writers) + { + writer.WriteElementString("writer", person); + } + + foreach (var person in writers) + { + writer.WriteElementString("credits", person); + } + + var rt = item.GetProviderId(MetadataProviders.RottenTomatoes); + + if (!string.IsNullOrEmpty(rt)) + { + writer.WriteElementString("rottentomatoesid", rt); + } + + var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection); + + if (!string.IsNullOrEmpty(tmdbCollection)) + { + writer.WriteElementString("collectionnumber", tmdbCollection); + } + + var imdb = item.GetProviderId(MetadataProviders.Imdb); + if (!string.IsNullOrEmpty(imdb)) + { + if (item is Series) + { + writer.WriteElementString("imdb_id", imdb); + } + else + { + writer.WriteElementString("imdbid", imdb); + } + } + + var tvdb = item.GetProviderId(MetadataProviders.Tvdb); + if (!string.IsNullOrEmpty(tvdb)) + { + writer.WriteElementString("tvdbid", tvdb); + } + + var tmdb = item.GetProviderId(MetadataProviders.Tmdb); + if (!string.IsNullOrEmpty(tmdb)) + { + writer.WriteElementString("tmdbid", tmdb); + } + + if (item.CriticRating.HasValue) + { + writer.WriteElementString("criticrating", item.CriticRating.Value.ToString(CultureInfo.InvariantCulture)); + } + + if (!string.IsNullOrEmpty(item.CriticRatingSummary)) + { + writer.WriteElementString("criticratingsummary", item.CriticRatingSummary); + } + + if (!string.IsNullOrWhiteSpace(item.Tagline)) + { + writer.WriteElementString("tagline", item.Tagline); + } + + foreach (var studio in item.Studios) + { + writer.WriteElementString("studio", studio); + } + + if (item.VoteCount.HasValue) + { + writer.WriteElementString("votes", item.VoteCount.Value.ToString(CultureInfo.InvariantCulture)); } writer.WriteEndElement(); @@ -1782,6 +1926,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } + private static bool IsPersonType(PersonInfo person, string type) + { + return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase); + } + private void AddGenre(List genres, string genre) { if (!genres.Contains(genre, StringComparer.OrdinalIgnoreCase)) diff --git a/Emby.Server.Implementations/Sync/SyncRepository.cs b/Emby.Server.Implementations/Sync/SyncRepository.cs index d8bec1ce36..8cce7a8bfa 100644 --- a/Emby.Server.Implementations/Sync/SyncRepository.cs +++ b/Emby.Server.Implementations/Sync/SyncRepository.cs @@ -229,7 +229,6 @@ namespace Emby.Server.Implementations.Sync commandText = "update SyncJobs set TargetId=?,Name=?,Profile=?,Quality=?,Bitrate=?,Status=?,Progress=?,UserId=?,ItemIds=?,Category=?,ParentId=?,UnwatchedOnly=?,ItemLimit=?,SyncNewContent=?,DateCreated=?,DateLastModified=?,ItemCount=? where Id=?"; } - paramList.Add(job.Id.ToGuidParamValue()); paramList.Add(job.TargetId); paramList.Add(job.Name); paramList.Add(job.Profile); @@ -249,6 +248,15 @@ namespace Emby.Server.Implementations.Sync paramList.Add(job.DateLastModified.ToDateTimeParamValue()); paramList.Add(job.ItemCount); + if (insert) + { + paramList.Insert(0, job.Id.ToGuidParamValue()); + } + else + { + paramList.Add(job.Id.ToGuidParamValue()); + } + connection.RunInTransaction(conn => { conn.Execute(commandText, paramList.ToArray()); @@ -698,7 +706,6 @@ namespace Emby.Server.Implementations.Sync } var paramList = new List(); - paramList.Add(jobItem.Id.ToGuidParamValue()); paramList.Add(jobItem.ItemId); paramList.Add(jobItem.ItemName); paramList.Add(jobItem.MediaSourceId); @@ -716,6 +723,15 @@ namespace Emby.Server.Implementations.Sync paramList.Add(jobItem.JobItemIndex); paramList.Add(jobItem.ItemDateModifiedTicks); + if (insert) + { + paramList.Insert(0, jobItem.Id.ToGuidParamValue()); + } + else + { + paramList.Add(jobItem.Id.ToGuidParamValue()); + } + connection.RunInTransaction(conn => { conn.Execute(commandText, paramList.ToArray()); diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 695718a255..15c1cbe827 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -680,14 +680,17 @@ namespace MediaBrowser.Api.Library /// The request. public void Post(RefreshLibrary request) { - try - { - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); - } - catch (Exception ex) + Task.Run(() => { - Logger.ErrorException("Error refreshing library", ex); - } + try + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } + catch (Exception ex) + { + Logger.ErrorException("Error refreshing library", ex); + } + }); } /// diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index be6e95ddd6..17ef81db9b 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -141,6 +141,7 @@ namespace MediaBrowser.Controller.Entities public SeriesStatus[] SeriesStatuses { get; set; } public string AlbumArtistStartsWithOrGreater { get; set; } public string ExternalSeriesId { get; set; } + public string ExternalId { get; set; } public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } -- cgit v1.2.3 From 016d8301f5060d899cccbfad67823fa9e628d260 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 6 Dec 2016 03:24:29 -0500 Subject: update series queries --- .../Data/SqliteItemRepository.cs | 32 +++++++++++++- .../Library/LibraryManager.cs | 11 ++++- Emby.Server.Implementations/TV/TVSeriesManager.cs | 9 +++- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Controller/Entities/Book.cs | 6 +++ MediaBrowser.Controller/Entities/IHasSeries.cs | 2 + .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Entities/TV/Episode.cs | 13 +++++- MediaBrowser.Controller/Entities/TV/Season.cs | 9 ++++ MediaBrowser.Controller/Entities/TV/Series.cs | 51 +++++++++++++++++----- MediaBrowser.Model/Configuration/LibraryOptions.cs | 2 + .../Configuration/ServerConfiguration.cs | 1 + .../TV/EpisodeMetadataService.cs | 7 +++ MediaBrowser.Providers/TV/SeasonMetadataService.cs | 7 +++ .../MediaBrowser.WebDashboard.csproj | 6 --- 15 files changed, 132 insertions(+), 26 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 9c096916f7..14723c0a7b 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -291,6 +291,7 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "Artists", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "AlbumArtists", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ExternalId", "Text", existingColumnNames); + AddColumn(db, "TypedBaseItems", "SeriesPresentationUniqueKey", "Text", existingColumnNames); existingColumnNames = GetColumnNames(db, "ItemValues"); AddColumn(db, "ItemValues", "CleanValue", "Text", existingColumnNames); @@ -341,6 +342,7 @@ namespace Emby.Server.Implementations.Data "drop index if exists Idx_ProviderIds1", "drop table if exists Images", "drop index if exists idx_Images", + "drop index if exists idx_TypeSeriesPresentationUniqueKey", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", @@ -353,6 +355,9 @@ namespace Emby.Server.Implementations.Data // covering index "create index if not exists idx_TopParentIdGuid on TypedBaseItems(TopParentId,Guid)", + // series + "create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)", + // live tv programs "create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)", @@ -488,7 +493,8 @@ namespace Emby.Server.Implementations.Data "ExtraType", "Artists", "AlbumArtists", - "ExternalId" + "ExternalId", + "SeriesPresentationUniqueKey" }; private readonly string[] _mediaStreamSaveColumns = @@ -619,7 +625,8 @@ namespace Emby.Server.Implementations.Data "ExtraType", "Artists", "AlbumArtists", - "ExternalId" + "ExternalId", + "SeriesPresentationUniqueKey" }; var saveItemCommandCommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -1024,11 +1031,13 @@ namespace Emby.Server.Implementations.Data { saveItemStatement.TryBind("@SeriesId", hasSeries.SeriesId); saveItemStatement.TryBind("@SeriesSortName", hasSeries.SeriesSortName); + saveItemStatement.TryBind("@SeriesPresentationUniqueKey", hasSeries.SeriesPresentationUniqueKey); } else { saveItemStatement.TryBindNull("@SeriesId"); saveItemStatement.TryBindNull("@SeriesSortName"); + saveItemStatement.TryBindNull("@SeriesPresentationUniqueKey"); } saveItemStatement.TryBind("@ExternalSeriesId", item.ExternalSeriesId); @@ -1983,6 +1992,15 @@ namespace Emby.Server.Implementations.Data } index++; + if (hasSeries != null) + { + if (!reader.IsDBNull(index)) + { + hasSeries.SeriesPresentationUniqueKey = reader.GetString(index); + } + } + index++; + if (string.IsNullOrWhiteSpace(item.Tagline)) { var movie = item as Movie; @@ -4292,6 +4310,16 @@ namespace Emby.Server.Implementations.Data } } + if (!string.IsNullOrWhiteSpace(query.SeriesPresentationUniqueKey)) + { + whereClauses.Add("SeriesPresentationUniqueKey=@SeriesPresentationUniqueKey"); + + if (statement != null) + { + statement.TryBind("@SeriesPresentationUniqueKey", query.SeriesPresentationUniqueKey); + } + } + if (query.BlockUnratedItems.Length == 1) { whereClauses.Add("(InheritedParentalRatingValue > 0 or UnratedType <> @UnratedType)"); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 8fb28fb591..d96756ce1b 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1057,6 +1057,12 @@ namespace Emby.Server.Implementations.Library try { await PerformLibraryValidation(progress, cancellationToken).ConfigureAwait(false); + + if (!ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey) + { + ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey = true; + ConfigurationManager.SaveConfiguration(); + } } finally { @@ -1478,8 +1484,9 @@ namespace Emby.Server.Implementations.Library !query.ParentId.HasValue && query.ChannelIds.Length == 0 && query.TopParentIds.Length == 0 && - string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey) - && query.ItemIds.Length == 0) + string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey) && + string.IsNullOrWhiteSpace(query.SeriesPresentationUniqueKey) && + query.ItemIds.Length == 0) { var userViews = _userviewManager().GetUserViews(new UserViewQuery { diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 56e7299951..4f876f6a39 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -158,9 +158,13 @@ namespace Emby.Server.Implementations.TV /// Task{Episode}. private Tuple> GetNextUp(Series series, User user) { + var enableSeriesPresentationKey = _config.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(series); + var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName }, SortOrder = SortOrder.Descending, @@ -174,7 +178,8 @@ namespace Emby.Server.Implementations.TV { return _libraryManager.GetItemList(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName }, SortOrder = SortOrder.Ascending, diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 4e5047f78b..25a4609351 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -119,6 +119,7 @@ namespace MediaBrowser.Api config.SkipDeserializationForBasicTypes = true; config.SkipDeserializationForPrograms = true; config.SkipDeserializationForAudio = true; + config.EnableSeriesPresentationUniqueKey = true; } public void Post(UpdateStartupConfiguration request) diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 9ccc7125a6..a6da389f05 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -18,6 +18,8 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } [IgnoreDataMember] public string SeriesName { get; set; } [IgnoreDataMember] @@ -33,6 +35,10 @@ namespace MediaBrowser.Controller.Entities { return SeriesName; } + public string FindSeriesPresentationUniqueKey() + { + return SeriesPresentationUniqueKey; + } [IgnoreDataMember] public override bool EnableRefreshOnDateModifiedChange diff --git a/MediaBrowser.Controller/Entities/IHasSeries.cs b/MediaBrowser.Controller/Entities/IHasSeries.cs index 531f587881..203be93e88 100644 --- a/MediaBrowser.Controller/Entities/IHasSeries.cs +++ b/MediaBrowser.Controller/Entities/IHasSeries.cs @@ -15,5 +15,7 @@ namespace MediaBrowser.Controller.Entities string FindSeriesSortName(); Guid? SeriesId { get; set; } Guid? FindSeriesId(); + string SeriesPresentationUniqueKey { get; set; } + string FindSeriesPresentationUniqueKey(); } } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 17ef81db9b..a2d278a71c 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -147,6 +147,7 @@ namespace MediaBrowser.Controller.Entities public string[] ArtistNames { get; set; } public string[] ExcludeArtistIds { get; set; } public string AncestorWithPresentationUniqueKey { get; set; } + public string SeriesPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } public bool EnableTotalRecordCount { get; set; } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 29a63f3175..2bcccf5e8b 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -165,13 +165,22 @@ namespace MediaBrowser.Controller.Entities.TV { return FindParent() != null; } - } + } + + [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } [IgnoreDataMember] public string SeriesName { get; set; } [IgnoreDataMember] - public string SeasonName { get; set; } + public string SeasonName { get; set; } + + public string FindSeriesPresentationUniqueKey() + { + var series = Series; + return series == null ? null : series.PresentationUniqueKey; + } public string FindSeasonName() { diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 2663a9dd50..e0cc496a10 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -207,12 +207,21 @@ namespace MediaBrowser.Controller.Entities.TV return UnratedItem.Series; } + [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } + [IgnoreDataMember] public string SeriesName { get; set; } [IgnoreDataMember] public Guid? SeriesId { get; set; } + public string FindSeriesPresentationUniqueKey() + { + var series = Series; + return series == null ? null : series.PresentationUniqueKey; + } + public string FindSeriesName() { var series = Series; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index ef25faf91d..92cd20769b 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -95,12 +95,16 @@ namespace MediaBrowser.Controller.Entities.TV public override string CreatePresentationUniqueKey() { - var userdatakeys = GetUserDataKeys(); - - if (userdatakeys.Count > 1) + if (LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping) { - return AddLibrariesToPresentationUniqueKey(userdatakeys[0]); + var userdatakeys = GetUserDataKeys(); + + if (userdatakeys.Count > 1) + { + return AddLibrariesToPresentationUniqueKey(userdatakeys[0]); + } } + return base.CreatePresentationUniqueKey(); } @@ -131,9 +135,13 @@ namespace MediaBrowser.Controller.Entities.TV public override int GetChildCount(User user) { + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Season).Name }, IsVirtualItem = false, Limit = 0 @@ -144,9 +152,15 @@ namespace MediaBrowser.Controller.Entities.TV public override int GetRecursiveChildCount(User user) { - var query = new InternalItemsQuery(user); + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + + var query = new InternalItemsQuery(user) + { + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, + }; - query.AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this); if (query.SortBy.Length == 0) { query.SortBy = new[] { ItemSortBy.SortName }; @@ -223,11 +237,13 @@ namespace MediaBrowser.Controller.Entities.TV { var config = user.Configuration; + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; var seriesKey = GetUniqueSeriesKey(this); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Season).Name }, SortBy = new[] { ItemSortBy.SortName } }; @@ -259,7 +275,11 @@ namespace MediaBrowser.Controller.Entities.TV if (query.Recursive) { - query.AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this); + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + + query.AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey; + query.SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null; if (query.SortBy.Length == 0) { query.SortBy = new[] { ItemSortBy.SortName }; @@ -281,11 +301,13 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(User user) { + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; var seriesKey = GetUniqueSeriesKey(this); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }, SortBy = new[] { ItemSortBy.SortName } }; @@ -387,14 +409,19 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetSeasonEpisodes(Season parentSeason, User user) { + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + + var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons; + // add optimization when this setting is not enabled - var seriesKey = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons ? + var seriesKey = queryFromSeries ? GetUniqueSeriesKey(this) : GetUniqueSeriesKey(parentSeason); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, + AncestorWithPresentationUniqueKey = queryFromSeries && enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = queryFromSeries && enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName } }; diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index ffcb79cfb4..e79253d190 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -14,6 +14,7 @@ public bool SaveLocalMetadata { get; set; } public bool EnableInternetProviders { get; set; } public bool ImportMissingEpisodes { get; set; } + public bool EnableAutomaticSeriesGrouping { get; set; } public LibraryOptions() { @@ -21,6 +22,7 @@ EnableRealtimeMonitor = true; PathInfos = new MediaPathInfo[] { }; EnableInternetProviders = true; + EnableAutomaticSeriesGrouping = true; } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 520cc97018..35677813d8 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -46,6 +46,7 @@ namespace MediaBrowser.Model.Configuration /// /// true if [use HTTPS]; otherwise, false. public bool EnableHttps { get; set; } + public bool EnableSeriesPresentationUniqueKey { get; set; } /// /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs index 2e4271c0f4..538d96c176 100644 --- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs +++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs @@ -55,6 +55,13 @@ namespace MediaBrowser.Providers.TV updateType |= ItemUpdateType.MetadataImport; } + var seriesPresentationUniqueKey = item.FindSeriesPresentationUniqueKey(); + if (!string.Equals(item.SeriesPresentationUniqueKey, seriesPresentationUniqueKey, StringComparison.Ordinal)) + { + item.SeriesPresentationUniqueKey = seriesPresentationUniqueKey; + updateType |= ItemUpdateType.MetadataImport; + } + return updateType; } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index 81a0c0b4a2..af7dea59ee 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -51,6 +51,13 @@ namespace MediaBrowser.Providers.TV updateType |= ItemUpdateType.MetadataImport; } + var seriesPresentationUniqueKey = item.FindSeriesPresentationUniqueKey(); + if (!string.Equals(item.SeriesPresentationUniqueKey, seriesPresentationUniqueKey, StringComparison.Ordinal)) + { + item.SeriesPresentationUniqueKey = seriesPresentationUniqueKey; + updateType |= ItemUpdateType.MetadataImport; + } + var seriesId = item.FindSeriesId(); if (item.SeriesId != seriesId) { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 3564cffa11..3cf7e54c05 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -693,9 +693,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -876,9 +873,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3