Browse Source

update user data queries

Luke Pulverenti 9 years ago
parent
commit
3118196ac6

+ 1 - 1
MediaBrowser.Api/TvShowsService.cs

@@ -429,7 +429,7 @@ namespace MediaBrowser.Api
             if (request.IsMissing.HasValue)
             {
                 var val = request.IsMissing.Value;
-                items = items.Where(i => i.IsMissingSeason == val);
+                items = items.Where(i => (i.IsMissingSeason ?? false) == val);
             }
 
             if (request.IsVirtualUnaired.HasValue)

+ 6 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -149,6 +149,12 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
+        [IgnoreDataMember]
+        public bool IsUnaired
+        {
+            get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
+        }
+
         public string OriginalTitle { get; set; }
 
         /// <summary>

+ 2 - 1
MediaBrowser.Controller/Entities/Folder.cs

@@ -1316,7 +1316,8 @@ namespace MediaBrowser.Controller.Entities
                 {
                     var folder = (Folder)child;
 
-                    folder.AddChildrenToList(result, includeLinkedChildren, true, filter);
+                    // We can only support includeLinkedChildren for the first folder, or we might end up stuck in a loop of linked items
+                    folder.AddChildrenToList(result, false, true, filter);
                 }
             }
 

+ 0 - 6
MediaBrowser.Controller/Entities/TV/Episode.cs

@@ -210,12 +210,6 @@ namespace MediaBrowser.Controller.Entities.TV
             }
         }
 
-        [IgnoreDataMember]
-        public bool IsUnaired
-        {
-            get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
-        }
-
         [IgnoreDataMember]
         public bool IsVirtualUnaired
         {

+ 17 - 16
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -54,8 +54,8 @@ namespace MediaBrowser.Controller.Entities.TV
         // Genre, Rating and Stuido will all be the same
         protected override IEnumerable<string> GetIndexByOptions()
         {
-            return new List<string> {            
-                {"None"}, 
+            return new List<string> {
+                {"None"},
                 {"Performer"},
                 {"Director"},
                 {"Year"},
@@ -128,22 +128,23 @@ namespace MediaBrowser.Controller.Entities.TV
             return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
         }
 
-        [IgnoreDataMember]
-        public bool IsMissingSeason
+        public override bool RequiresRefresh()
         {
-            get { return LocationType == LocationType.Virtual && GetEpisodes().All(i => i.IsMissingEpisode); }
-        }
+            var result = base.RequiresRefresh();
 
-        private bool GetIsUnaired()
-        {
-            return GetEpisodes().All(i => i.IsUnaired);
+            if (!result)
+            {
+                if (!IsMissingSeason.HasValue)
+                {
+                    return true;
+                }
+            }
+
+            return result;
         }
 
         [IgnoreDataMember]
-        public bool IsUnaired
-        {
-            get { return GetIsUnaired(); }
-        }
+        public bool? IsMissingSeason { get; set; }
 
         [IgnoreDataMember]
         public bool IsVirtualUnaired
@@ -154,7 +155,7 @@ namespace MediaBrowser.Controller.Entities.TV
         [IgnoreDataMember]
         public bool IsMissingOrVirtualUnaired
         {
-            get { return LocationType == LocationType.Virtual && GetEpisodes().All(i => i.IsVirtualUnaired || i.IsMissingEpisode); }
+            get { return (IsMissingSeason ?? false) || (LocationType == LocationType.Virtual && IsUnaired); }
         }
 
         [IgnoreDataMember]
@@ -223,7 +224,7 @@ namespace MediaBrowser.Controller.Entities.TV
 
                 episodes = list.DistinctBy(i => i.Id);
             }
-            
+
             if (!includeMissingEpisodes)
             {
                 episodes = episodes.Where(i => !i.IsMissingEpisode);
@@ -238,7 +239,7 @@ namespace MediaBrowser.Controller.Entities.TV
                 .Cast<Episode>();
         }
 
-        private IEnumerable<Episode> GetEpisodes()
+        public IEnumerable<Episode> GetEpisodes()
         {
             var episodes = GetRecursiveChildren().OfType<Episode>();
             var series = Series;

+ 45 - 25
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -201,23 +201,30 @@ namespace MediaBrowser.Controller.Entities.TV
 
         public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
         {
-            var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
-            {
-                PresentationUniqueKey = PresentationUniqueKey,
-                IncludeItemTypes = new[] { typeof(Series).Name }
-            });
-
             IEnumerable<Season> seasons;
 
-            if (seriesIds.Count > 1)
+            if (EnablePooling())
             {
-                seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
+                {
+                    PresentationUniqueKey = PresentationUniqueKey,
+                    IncludeItemTypes = new[] { typeof(Series).Name }
+                });
+
+                if (seriesIds.Count > 1)
                 {
-                    AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
-                    IncludeItemTypes = new[] { typeof(Season).Name },
-                    SortBy = new[] { ItemSortBy.SortName }
+                    seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                    {
+                        AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
+                        IncludeItemTypes = new[] { typeof(Season).Name },
+                        SortBy = new[] { ItemSortBy.SortName }
 
-                }).Cast<Season>();
+                    }).Cast<Season>();
+                }
+                else
+                {
+                    seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>();
+                }
             }
             else
             {
@@ -232,7 +239,7 @@ namespace MediaBrowser.Controller.Entities.TV
             {
                 if (!includeMissingSeasons)
                 {
-                    seasons = seasons.Where(i => !i.IsMissingSeason);
+                    seasons = seasons.Where(i => !(i.IsMissingSeason ?? false));
                 }
                 if (!includeVirtualUnaired)
                 {
@@ -338,25 +345,38 @@ namespace MediaBrowser.Controller.Entities.TV
             return GetEpisodes(user, seasonNumber, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
         }
 
-        public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
+        private bool EnablePooling()
         {
-            var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
-            {
-                PresentationUniqueKey = PresentationUniqueKey,
-                IncludeItemTypes = new[] { typeof(Series).Name }
-            });
+            return false;
+        }
 
+        public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
+        {
             IEnumerable<Episode> episodes;
 
-            if (seriesIds.Count > 1)
+            if (EnablePooling())
             {
-                episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
                 {
-                    AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
-                    IncludeItemTypes = new[] { typeof(Episode).Name },
-                    SortBy = new[] { ItemSortBy.SortName }
+                    PresentationUniqueKey = PresentationUniqueKey,
+                    IncludeItemTypes = new[] { typeof(Series).Name }
+                });
 
-                }).Cast<Episode>();
+                if (seriesIds.Count > 1)
+                {
+                    episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
+                    {
+                        AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
+                        IncludeItemTypes = new[] { typeof(Episode).Name },
+                        SortBy = new[] { ItemSortBy.SortName }
+
+                    }).Cast<Episode>();
+                }
+                else
+                {
+                    episodes = GetRecursiveChildren(user, i => i is Episode)
+                        .Cast<Episode>();
+                }
             }
             else
             {

+ 1 - 1
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -1077,7 +1077,7 @@ namespace MediaBrowser.Controller.Entities
                     var e = i as Season;
                     if (e != null)
                     {
-                        return e.IsMissingSeason == val;
+                        return (e.IsMissingSeason ?? false) == val;
                     }
                     return true;
                 });

+ 0 - 16
MediaBrowser.Controller/Library/IUserDataManager.cs

@@ -29,22 +29,6 @@ namespace MediaBrowser.Controller.Library
         /// <returns>Task.</returns>
         Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken);
 
-        /// <summary>
-        /// Gets the user data.
-        /// </summary>
-        /// <param name="userId">The user id.</param>
-        /// <param name="key">The key.</param>
-        /// <returns>Task{UserItemData}.</returns>
-        UserItemData GetUserData(string userId, string key);
-
-        /// <summary>
-        /// Gets the user data.
-        /// </summary>
-        /// <param name="userId">The user id.</param>
-        /// <param name="key">The key.</param>
-        /// <returns>Task{UserItemData}.</returns>
-        UserItemData GetUserData(Guid userId, string key);
-
         UserItemData GetUserData(IHasUserData user, IHasUserData item);
 
         UserItemData GetUserData(string userId, IHasUserData item);

+ 41 - 0
MediaBrowser.Providers/TV/SeasonMetadataService.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Model.Logging;
 using MediaBrowser.Providers.Manager;
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using CommonIO;
 
@@ -31,6 +32,13 @@ namespace MediaBrowser.Providers.TV
                 }
             }
 
+            if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
+            {
+                var episodes = item.GetEpisodes().ToList();
+                updateType |= SavePremiereDate(item, episodes);
+                updateType |= SaveIsMissing(item, episodes);
+            }
+
             return updateType;
         }
 
@@ -38,5 +46,38 @@ namespace MediaBrowser.Providers.TV
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }
+
+        private ItemUpdateType SavePremiereDate(Season item, List<Episode> episodes)
+        {
+            var dates = episodes.Where(i => i.PremiereDate.HasValue).Select(i => i.PremiereDate.Value).ToList();
+
+            DateTime? premiereDate = null;
+
+            if (dates.Count > 0)
+            {
+                premiereDate = dates.Min();
+            }
+
+            if (item.PremiereDate != premiereDate)
+            {
+                item.PremiereDate = premiereDate;
+                return ItemUpdateType.MetadataEdit;
+            }
+
+            return ItemUpdateType.None;
+        }
+
+        private ItemUpdateType SaveIsMissing(Season item, List<Episode> episodes)
+        {
+            var isMissing = item.LocationType == LocationType.Virtual && episodes.All(i => i.IsMissingEpisode);
+
+            if (item.IsMissingSeason != isMissing)
+            {
+                item.IsMissingSeason = isMissing;
+                return ItemUpdateType.MetadataEdit;
+            }
+
+            return ItemUpdateType.None;
+        }
     }
 }

+ 6 - 3
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -617,9 +617,12 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             if (!string.IsNullOrEmpty(item.Album))
             {
-                var parentAlbum = _libraryManager.RootFolder
-                    .GetRecursiveChildren(i => i is MusicAlbum && string.Equals(i.Name, item.Album, StringComparison.OrdinalIgnoreCase))
-                    .FirstOrDefault();
+                var parentAlbum = _libraryManager.GetItemList(new InternalItemsQuery
+                {
+                    IncludeItemTypes = new[] { typeof(MusicAlbum).Name },
+                    Name = item.Album
+
+                }).FirstOrDefault();
 
                 if (parentAlbum != null)
                 {

+ 63 - 25
MediaBrowser.Server.Implementations/Library/UserDataManager.cs

@@ -140,6 +140,54 @@ namespace MediaBrowser.Server.Implementations.Library
             return Repository.GetAllUserData(userId);
         }
 
+        public UserItemData GetUserData(Guid userId, List<string> keys)
+        {
+            if (userId == Guid.Empty)
+            {
+                throw new ArgumentNullException("userId");
+            }
+            if (keys == null)
+            {
+                throw new ArgumentNullException("keys");
+            }
+
+            lock (_userData)
+            {
+                foreach (var key in keys)
+                {
+                    var cacheKey = GetCacheKey(userId, key);
+                    UserItemData value;
+                    if (_userData.TryGetValue(cacheKey, out value))
+                    {
+                        return value;
+                    }
+
+                    value = Repository.GetUserData(userId, key);
+
+                    if (value != null)
+                    {
+                        _userData[cacheKey] = value;
+                        return value;
+                    }
+                }
+
+                if (keys.Count > 0)
+                {
+                    var key = keys[0];
+                    var cacheKey = GetCacheKey(userId, key);
+                    var userdata = new UserItemData
+                    {
+                        UserId = userId,
+                        Key = key
+                    };
+                    _userData[cacheKey] = userdata;
+                    return userdata;
+                }
+
+                return null;
+            }
+        }
+
         /// <summary>
         /// Gets the user data.
         /// </summary>
@@ -166,25 +214,20 @@ namespace MediaBrowser.Server.Implementations.Library
                     return value;
                 }
 
-                value = GetUserDataFromRepository(userId, key);
-                _userData[cacheKey] = value;
-                return value;
-            }
-        }
-
-        private UserItemData GetUserDataFromRepository(Guid userId, string key)
-        {
-            var data = Repository.GetUserData(userId, key);
+                value = Repository.GetUserData(userId, key);
 
-            if (data == null)
-            {
-                data = new UserItemData
+                if (value == null)
                 {
-                    UserId = userId,
-                    Key = key
-                };
+                    value = new UserItemData
+                    {
+                        UserId = userId,
+                        Key = key
+                    };
+                }
+
+                _userData[cacheKey] = value;
+                return value;
             }
-            return data;
         }
 
         /// <summary>
@@ -200,22 +243,22 @@ namespace MediaBrowser.Server.Implementations.Library
 
         public UserItemData GetUserData(IHasUserData user, IHasUserData item)
         {
-            return GetUserData(user.Id, item.GetUserDataKeys().First());
+            return GetUserData(user.Id, item);
         }
 
         public UserItemData GetUserData(string userId, IHasUserData item)
         {
-            return GetUserData(userId, item.GetUserDataKeys().First());
+            return GetUserData(new Guid(userId), item);
         }
 
         public UserItemData GetUserData(Guid userId, IHasUserData item)
         {
-            return GetUserData(userId, item.GetUserDataKeys().First());
+            return GetUserData(userId, item.GetUserDataKeys());
         }
 
         public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
         {
-            var userData = GetUserData(user.Id, item.GetUserDataKeys().First());
+            var userData = GetUserData(user.Id, item);
             var dto = GetUserItemDataDto(userData);
 
             item.FillUserDataDtoValues(dto, userData, user);
@@ -302,10 +345,5 @@ namespace MediaBrowser.Server.Implementations.Library
 
             return playedToCompletion;
         }
-
-        public UserItemData GetUserData(string userId, string key)
-        {
-            return GetUserData(new Guid(userId), key);
-        }
     }
 }

+ 14 - 8
MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -34,20 +35,25 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var items = _libraryManager.GetItemList(new InternalItemsQuery
-            {
-                IncludeItemTypes = new[] { typeof(Studio).Name }
-
-            }).ToList();
+            var items = _libraryManager.RootFolder.GetRecursiveChildren(i => true)
+                .SelectMany(i => i.Studios)
+                .DistinctNames()
+                .ToList();
 
             var numComplete = 0;
             var count = items.Count;
 
-            foreach (var item in items)
+            var validIds = new List<Guid>();
+
+            foreach (var name in items)
             {
                 try
                 {
-                    await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetStudio(name);
+
+                    validIds.Add(itemByName.Id);
+
+                    await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {
@@ -56,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error refreshing {0}", ex, item.Name);
+                    _logger.ErrorException("Error refreshing {0}", ex, name);
                 }
 
                 numComplete++;

+ 3 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -1870,9 +1870,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
                 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
                 {
-                    Logger.Debug("GetItemIdsList query time: {0}ms. Query: {1}",
-                        Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
-                        cmd.CommandText);
+                    //Logger.Debug("GetItemIdsList query time: {0}ms. Query: {1}",
+                    //    Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
+                    //    cmd.CommandText);
 
                     while (reader.Read())
                     {