Browse Source

update channel db

Luke Pulverenti 9 years ago
parent
commit
fbf8d27637
32 changed files with 224 additions and 644 deletions
  1. 2 3
      MediaBrowser.Api/UserLibrary/UserViewsService.cs
  2. 17 0
      MediaBrowser.Controller/Entities/BaseItem.cs
  3. 17 24
      MediaBrowser.Controller/Entities/Folder.cs
  4. 11 1
      MediaBrowser.Controller/Entities/UserView.cs
  5. 2 6
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  6. 7 0
      MediaBrowser.Controller/Persistence/IItemRepository.cs
  7. 0 3
      MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
  8. 0 20
      MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs
  9. 0 166
      MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs
  10. 0 14
      MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs
  11. 0 147
      MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs
  12. 0 154
      MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs
  13. 1 1
      MediaBrowser.Model/Configuration/UserConfiguration.cs
  14. 9 0
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  15. 0 6
      MediaBrowser.Model/Dto/BaseItemDto.cs
  16. 0 6
      MediaBrowser.Model/Dto/IItemDto.cs
  17. 0 6
      MediaBrowser.Model/Dto/UserDto.cs
  18. 0 2
      MediaBrowser.Model/Entities/MetadataProviders.cs
  19. 0 6
      MediaBrowser.Model/LiveTv/ChannelInfoDto.cs
  20. 0 5
      MediaBrowser.Model/Querying/ItemFields.cs
  21. 16 1
      MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
  22. 8 13
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  23. 12 4
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  24. 1 1
      MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
  25. 1 1
      MediaBrowser.Server.Implementations/Library/SearchEngine.cs
  26. 20 24
      MediaBrowser.Server.Implementations/Library/UserViewManager.cs
  27. 3 1
      MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
  28. 78 15
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  29. 0 1
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs
  30. 11 3
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  31. 6 8
      MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
  32. 2 2
      SharedVersion.cs

+ 2 - 3
MediaBrowser.Api/UserLibrary/UserViewsService.cs

@@ -78,6 +78,7 @@ namespace MediaBrowser.Api.UserLibrary
             var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
 
             var dtoOptions = GetDtoOptions(request);
+            dtoOptions.Fields = new List<ItemFields>();
 
             var user = _userManager.GetUserById(request.UserId);
 
@@ -141,9 +142,7 @@ namespace MediaBrowser.Api.UserLibrary
 
         private bool IsEligibleForSpecialView(ICollectionFolder view)
         {
-            var types = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Games, CollectionType.Music, CollectionType.Photos };
-
-            return types.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
+            return UserView.IsEligibleForEnhancedView(view.CollectionType);
         }
     }
 

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

@@ -1153,6 +1153,23 @@ namespace MediaBrowser.Controller.Entities
         }
 
         public int? GetParentalRatingValue()
+        {
+            var rating = CustomRating;
+
+            if (string.IsNullOrWhiteSpace(rating))
+            {
+                rating = OfficialRating;
+            }
+
+            if (string.IsNullOrWhiteSpace(rating))
+            {
+                return null;
+            }
+
+            return LocalizationManager.GetRatingLevel(rating);
+        }
+
+        public int? GetInheritedParentalRatingValue()
         {
             var rating = CustomRatingForComparison;
 

+ 17 - 24
MediaBrowser.Controller/Entities/Folder.cs

@@ -468,34 +468,25 @@ namespace MediaBrowser.Controller.Entities
                 {
                     BaseItem currentChild;
 
-                    if (currentChildren.TryGetValue(child.Id, out currentChild))
+                    if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child))
                     {
-                        if (IsValidFromResolver(currentChild, child))
+                        var currentChildLocationType = currentChild.LocationType;
+                        if (currentChildLocationType != LocationType.Remote &&
+                            currentChildLocationType != LocationType.Virtual)
                         {
-                            var currentChildLocationType = currentChild.LocationType;
-                            if (currentChildLocationType != LocationType.Remote &&
-                                currentChildLocationType != LocationType.Virtual)
-                            {
-                                currentChild.DateModified = child.DateModified;
-                            }
-
-                            await UpdateIsOffline(currentChild, false).ConfigureAwait(false);
-                            validChildren.Add(currentChild);
-                        }
-                        else
-                        {
-                            child.SetParent(this);
-                            newItems.Add(child);
-                            validChildren.Add(child);
+                            currentChild.DateModified = child.DateModified;
                         }
+
+                        await UpdateIsOffline(currentChild, false).ConfigureAwait(false);
+                        validChildren.Add(currentChild);
+
+                        continue;
                     }
-                    else
-                    {
-                        // Brand new item - needs to be added
-                        child.SetParent(this);
-                        newItems.Add(child);
-                        validChildren.Add(child);
-                    }
+
+                    // Brand new item - needs to be added
+                    child.SetParent(this);
+                    newItems.Add(child);
+                    validChildren.Add(child);
                 }
 
                 // If any items were added or removed....
@@ -531,6 +522,8 @@ namespace MediaBrowser.Controller.Entities
 
                         foreach (var item in actualRemovals)
                         {
+                            Logger.Debug("Removed item: " + item.Path);
+
                             item.SetParent(null);
                             item.IsOffline = false;
                             await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false);

+ 11 - 1
MediaBrowser.Controller/Entities/UserView.cs

@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.Runtime.Serialization;
 using System.Threading.Tasks;
+using System.Linq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -105,7 +106,9 @@ namespace MediaBrowser.Controller.Entities
                 CollectionType.Photos,
                 CollectionType.Playlists,
                 CollectionType.BoxSets,
-                CollectionType.MusicVideos
+                CollectionType.MusicVideos,
+                CollectionType.Games,
+                CollectionType.Music
             };
 
             var collectionFolder = folder as ICollectionFolder;
@@ -136,6 +139,13 @@ namespace MediaBrowser.Controller.Entities
             return standaloneTypes.Contains(collectionFolder.CollectionType ?? string.Empty);
         }
 
+        public static bool IsEligibleForEnhancedView(string viewType)
+        {
+            var types = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music };
+
+            return types.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
+        }
+
         [IgnoreDataMember]
         public override bool SupportsPeople
         {

+ 2 - 6
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -120,26 +120,22 @@ namespace MediaBrowser.Controller.Entities
                         return await GetLiveTvView(queryParent, user, query).ConfigureAwait(false);
                     }
 
+                case CollectionType.Photos:
                 case CollectionType.Books:
                 case CollectionType.HomeVideos:
+                case CollectionType.Games:
                 case CollectionType.MusicVideos:
                     return GetResult(queryParent.GetChildren(user, true), queryParent, query);
 
                 case CollectionType.Folders:
                     return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query);
 
-                case CollectionType.Games:
-                    return await GetGameView(user, queryParent, query).ConfigureAwait(false);
-
                 case CollectionType.Playlists:
                     return await GetPlaylistsView(queryParent, user, query).ConfigureAwait(false);
 
                 case CollectionType.BoxSets:
                     return await GetBoxsetView(queryParent, user, query).ConfigureAwait(false);
 
-                case CollectionType.Photos:
-                    return await GetPhotosView(queryParent, user, query).ConfigureAwait(false);
-
                 case CollectionType.TvShows:
                     return await GetTvView(queryParent, user, query).ConfigureAwait(false);
 

+ 7 - 0
MediaBrowser.Controller/Persistence/IItemRepository.cs

@@ -183,6 +183,13 @@ namespace MediaBrowser.Controller.Persistence
         /// <param name="query">The query.</param>
         /// <returns>List&lt;BaseItem&gt;.</returns>
         IEnumerable<BaseItem> GetItemList(InternalItemsQuery query);
+
+        /// <summary>
+        /// Updates the inherited values.
+        /// </summary>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task UpdateInheritedValues(CancellationToken cancellationToken);
     }
 }
 

+ 0 - 3
MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj

@@ -79,14 +79,11 @@
     <Compile Include="Providers\SeriesXmlProvider.cs" />
     <Compile Include="Providers\VideoXmlProvider.cs" />
     <Compile Include="Savers\BoxSetXmlSaver.cs" />
-    <Compile Include="Savers\EpisodeXmlSaver.cs" />
     <Compile Include="Savers\FolderXmlSaver.cs" />
     <Compile Include="Savers\GameSystemXmlSaver.cs" />
     <Compile Include="Savers\GameXmlSaver.cs" />
-    <Compile Include="Savers\MovieXmlSaver.cs" />
     <Compile Include="Savers\PersonXmlSaver.cs" />
     <Compile Include="Savers\PlaylistXmlSaver.cs" />
-    <Compile Include="Savers\SeriesXmlSaver.cs" />
     <Compile Include="Savers\XmlSaverHelpers.cs" />
   </ItemGroup>
   <ItemGroup>

+ 0 - 20
MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs

@@ -62,26 +62,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
                         break;
                     }
 
-                case "NesBox":
-                    {
-                        var val = reader.ReadElementContentAsString();
-                        if (!string.IsNullOrWhiteSpace(val))
-                        {
-                            item.SetProviderId(MetadataProviders.NesBox, val);
-                        }
-                        break;
-                    }
-
-                case "NesBoxRom":
-                    {
-                        var val = reader.ReadElementContentAsString();
-                        if (!string.IsNullOrWhiteSpace(val))
-                        {
-                            item.SetProviderId(MetadataProviders.NesBoxRom, val);
-                        }
-                        break;
-                    }
-
                 case "Players":
                     {
                         var val = reader.ReadElementContentAsString();

+ 0 - 166
MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs

@@ -1,166 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-using CommonIO;
-using MediaBrowser.Common.IO;
-
-namespace MediaBrowser.LocalMetadata.Savers
-{
-    public class EpisodeXmlProvider : IMetadataFileSaver, IConfigurableProvider
-    {
-        private readonly IItemRepository _itemRepository;
-
-        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-        private readonly IServerConfigurationManager _config;
-        private readonly ILibraryManager _libraryManager;
-        private IFileSystem _fileSystem;
-
-        public EpisodeXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem)
-        {
-            _itemRepository = itemRepository;
-            _config = config;
-            _libraryManager = libraryManager;
-            _fileSystem = fileSystem;
-        }
-
-        /// <summary>
-        /// Determines whether [is enabled for] [the specified item].
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="updateType">Type of the update.</param>
-        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
-        public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
-        {
-            if (!item.SupportsLocalMetadata)
-            {
-                return false;
-            }
-
-            return item is Episode && updateType >= ItemUpdateType.MetadataDownload;
-        }
-
-        public string Name
-        {
-            get
-            {
-                return XmlProviderUtils.Name;
-            }
-        }
-
-        public bool IsEnabled
-        {
-            get { return !_config.Configuration.DisableXmlSavers; }
-        }
-
-        /// <summary>
-        /// Saves the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        public void Save(IHasMetadata item, CancellationToken cancellationToken)
-        {
-            var episode = (Episode)item;
-
-            var builder = new StringBuilder();
-
-            builder.Append("<Item>");
-
-            if (!string.IsNullOrEmpty(item.Name))
-            {
-                builder.Append("<EpisodeName>" + SecurityElement.Escape(episode.Name) + "</EpisodeName>");
-            }
-
-            if (episode.IndexNumber.HasValue)
-            {
-                builder.Append("<EpisodeNumber>" + SecurityElement.Escape(episode.IndexNumber.Value.ToString(_usCulture)) + "</EpisodeNumber>");
-            }
-
-            if (episode.IndexNumberEnd.HasValue)
-            {
-                builder.Append("<EpisodeNumberEnd>" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + "</EpisodeNumberEnd>");
-            }
-
-            if (episode.AirsAfterSeasonNumber.HasValue)
-            {
-                builder.Append("<airsafter_season>" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + "</airsafter_season>");
-            }
-            if (episode.AirsBeforeEpisodeNumber.HasValue)
-            {
-                builder.Append("<airsbefore_episode>" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + "</airsbefore_episode>");
-            }
-            if (episode.AirsBeforeSeasonNumber.HasValue)
-            {
-                builder.Append("<airsbefore_season>" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + "</airsbefore_season>");
-            }
-   
-            if (episode.ParentIndexNumber.HasValue)
-            {
-                builder.Append("<SeasonNumber>" + SecurityElement.Escape(episode.ParentIndexNumber.Value.ToString(_usCulture)) + "</SeasonNumber>");
-            }
-
-            if (episode.AbsoluteEpisodeNumber.HasValue)
-            {
-                builder.Append("<absolute_number>" + SecurityElement.Escape(episode.AbsoluteEpisodeNumber.Value.ToString(_usCulture)) + "</absolute_number>");
-            }
-            
-            if (episode.DvdEpisodeNumber.HasValue)
-            {
-                builder.Append("<DVD_episodenumber>" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + "</DVD_episodenumber>");
-            }
-
-            if (episode.DvdSeasonNumber.HasValue)
-            {
-                builder.Append("<DVD_season>" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + "</DVD_season>");
-            } 
-            
-            if (episode.PremiereDate.HasValue)
-            {
-                builder.Append("<FirstAired>" + SecurityElement.Escape(episode.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + "</FirstAired>");
-            }
-
-            XmlSaverHelpers.AddCommonNodes(episode, _libraryManager, builder);
-            XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository);
-
-            builder.Append("</Item>");
-
-            var xmlFilePath = GetSavePath(item);
-
-            XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
-                {
-                    "FirstAired",
-                    "SeasonNumber",
-                    "EpisodeNumber",
-                    "EpisodeName",
-                    "EpisodeNumberEnd",
-                    "airsafter_season",
-                    "airsbefore_episode",
-                    "airsbefore_season",
-                    "DVD_episodenumber",
-                    "DVD_season",
-                    "absolute_number"
-
-                }, _config, _fileSystem);
-        }
-
-        /// <summary>
-        /// Gets the save path.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>System.String.</returns>
-        public string GetSavePath(IHasMetadata item)
-        {
-            var filename = Path.ChangeExtension(Path.GetFileName(item.Path), ".xml");
-
-            return Path.Combine(Path.GetDirectoryName(item.Path), "metadata", filename);
-        }
-    }
-}

+ 0 - 14
MediaBrowser.LocalMetadata/Savers/GameXmlSaver.cs

@@ -79,20 +79,6 @@ namespace MediaBrowser.LocalMetadata.Savers
                 builder.Append("<GameSystem>" + SecurityElement.Escape(game.GameSystem) + "</GameSystem>");
             }
 
-            var val = game.GetProviderId(MetadataProviders.NesBox);
-
-            if (!string.IsNullOrEmpty(val))
-            {
-                builder.Append("<NesBox>" + SecurityElement.Escape(val) + "</NesBox>");
-            }
-
-            val = game.GetProviderId(MetadataProviders.NesBoxRom);
-
-            if (!string.IsNullOrEmpty(val))
-            {
-                builder.Append("<NesBoxRom>" + SecurityElement.Escape(val) + "</NesBoxRom>");
-            }
-
             XmlSaverHelpers.AddCommonNodes(game, _libraryManager, builder);
 
             builder.Append("</Item>");

+ 0 - 147
MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs

@@ -1,147 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using System.Collections.Generic;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-using CommonIO;
-using MediaBrowser.Common.IO;
-
-namespace MediaBrowser.LocalMetadata.Savers
-{
-    /// <summary>
-    /// Saves movie.xml for movies, trailers and music videos
-    /// </summary>
-    public class MovieXmlProvider : IMetadataFileSaver, IConfigurableProvider
-    {
-        private readonly IItemRepository _itemRepository;
-        private readonly IServerConfigurationManager _config;
-        private readonly ILibraryManager _libraryManager;
-        private IFileSystem _fileSystem;
-
-        public MovieXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem)
-        {
-            _itemRepository = itemRepository;
-            _config = config;
-            _libraryManager = libraryManager;
-            _fileSystem = fileSystem;
-        }
-
-        public string Name
-        {
-            get
-            {
-                return XmlProviderUtils.Name;
-            }
-        }
-
-        public bool IsEnabled
-        {
-            get { return !_config.Configuration.DisableXmlSavers; }
-        }
-
-        /// <summary>
-        /// Determines whether [is enabled for] [the specified item].
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="updateType">Type of the update.</param>
-        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
-        public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
-        {
-            if (!item.SupportsLocalMetadata)
-            {
-                return false;
-            }
-
-            var video = item as Video;
-
-            // Check parent for null to avoid running this against things like video backdrops
-            if (video != null && !(item is Episode) && !video.IsOwnedItem)
-            {
-                return updateType >= ItemUpdateType.MetadataDownload;
-            }
-
-            return false;
-        }
-
-        /// <summary>
-        /// Saves the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        public void Save(IHasMetadata item, CancellationToken cancellationToken)
-        {
-            var video = (Video)item;
-
-            var builder = new StringBuilder();
-
-            builder.Append("<Title>");
-
-            XmlSaverHelpers.AddCommonNodes(video, _libraryManager, builder);
-
-            var musicVideo = item as MusicVideo;
-
-            if (musicVideo != null)
-            {
-                if (musicVideo.Artists.Count > 0)
-                {
-                    builder.Append("<Artist>" + SecurityElement.Escape(string.Join(";", musicVideo.Artists.ToArray())) + "</Artist>");
-                }
-                if (!string.IsNullOrEmpty(musicVideo.Album))
-                {
-                    builder.Append("<Album>" + SecurityElement.Escape(musicVideo.Album) + "</Album>");
-                }
-            }
-
-            var movie = item as Movie;
-
-            if (movie != null)
-            {
-                if (!string.IsNullOrEmpty(movie.TmdbCollectionName))
-                {
-                    builder.Append("<TmdbCollectionName>" + SecurityElement.Escape(movie.TmdbCollectionName) + "</TmdbCollectionName>");
-                }
-            }
-            
-            XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository);
-
-            builder.Append("</Title>");
-
-            var xmlFilePath = GetSavePath(item);
-
-            XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
-                {
-                    // Deprecated. No longer saving in this field.
-                    "IMDBrating",
-                    
-                    // Deprecated. No longer saving in this field.
-                    "Description",
-
-                    "Artist",
-                    "Album",
-                    "TmdbCollectionName"
-                }, _config, _fileSystem);
-        }
-
-        public string GetSavePath(IHasMetadata item)
-        {
-            return GetMovieSavePath((Video)item);
-        }
-
-        public static string GetMovieSavePath(Video item)
-        {
-            if (item.IsInMixedFolder)
-            {
-                return Path.ChangeExtension(item.Path, ".xml");
-            }
-
-            return Path.Combine(item.ContainingFolderPath, "movie.xml");
-        }
-    }
-}

+ 0 - 154
MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs

@@ -1,154 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-using CommonIO;
-using MediaBrowser.Common.IO;
-
-namespace MediaBrowser.LocalMetadata.Savers
-{
-    public class SeriesXmlProvider : IMetadataFileSaver, IConfigurableProvider
-    {
-        private readonly IServerConfigurationManager _config;
-        private readonly ILibraryManager _libraryManager;
-        private IFileSystem _fileSystem;
-
-        public SeriesXmlProvider(IServerConfigurationManager config, ILibraryManager libraryManager, IFileSystem fileSystem)
-        {
-            _config = config;
-            _libraryManager = libraryManager;
-            _fileSystem = fileSystem;
-        }
-
-        public string Name
-        {
-            get
-            {
-                return XmlProviderUtils.Name;
-            }
-        }
-
-        /// <summary>
-        /// Determines whether [is enabled for] [the specified item].
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="updateType">Type of the update.</param>
-        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
-        public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
-        {
-            if (!item.SupportsLocalMetadata)
-            {
-                return false;
-            }
-
-            return item is Series && updateType >= ItemUpdateType.MetadataDownload;
-        }
-
-        public bool IsEnabled
-        {
-            get { return !_config.Configuration.DisableXmlSavers; }
-        }
-
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
-        /// <summary>
-        /// Saves the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        public void Save(IHasMetadata item, CancellationToken cancellationToken)
-        {
-            var series = (Series)item;
-
-            var builder = new StringBuilder();
-
-            builder.Append("<Series>");
-
-            var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
-
-            if (!string.IsNullOrEmpty(tvdb))
-            {
-                builder.Append("<id>" + SecurityElement.Escape(tvdb) + "</id>");
-            }
-
-            if (series.Status.HasValue)
-            {
-                builder.Append("<Status>" + SecurityElement.Escape(series.Status.Value.ToString()) + "</Status>");
-            }
-
-            if (series.Studios.Count > 0)
-            {
-                builder.Append("<Network>" + SecurityElement.Escape(series.Studios[0]) + "</Network>");
-            }
-
-            if (!string.IsNullOrEmpty(series.AirTime))
-            {
-                builder.Append("<Airs_Time>" + SecurityElement.Escape(series.AirTime) + "</Airs_Time>");
-            }
-
-            if (series.AirDays != null)
-            {
-                if (series.AirDays.Count == 7)
-                {
-                    builder.Append("<Airs_DayOfWeek>" + SecurityElement.Escape("Daily") + "</Airs_DayOfWeek>");
-                }
-                else if (series.AirDays.Count > 0)
-                {
-                    builder.Append("<Airs_DayOfWeek>" + SecurityElement.Escape(series.AirDays[0].ToString()) + "</Airs_DayOfWeek>");
-                }
-            }
-
-            if (series.PremiereDate.HasValue)
-            {
-                builder.Append("<FirstAired>" + SecurityElement.Escape(series.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + "</FirstAired>");
-            }
-
-            if (series.AnimeSeriesIndex.HasValue)
-            {
-                builder.Append("<AnimeSeriesIndex>" + SecurityElement.Escape(series.AnimeSeriesIndex.Value.ToString(UsCulture)) + "</AnimeSeriesIndex>");
-            }
-
-            XmlSaverHelpers.AddCommonNodes(series, _libraryManager, builder);
-
-            builder.Append("</Series>");
-
-            var xmlFilePath = GetSavePath(item);
-
-            XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
-                {
-                    "id", 
-                    "Status",
-                    "Network",
-                    "Airs_Time",
-                    "Airs_DayOfWeek",
-                    "FirstAired",
-
-                    // Don't preserve old series node
-                    "Series",
-
-                    "SeriesName",
-
-                    // Deprecated. No longer saving in this field.
-                    "AnimeSeriesIndex"
-                }, _config, _fileSystem);
-        }
-
-        /// <summary>
-        /// Gets the save path.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>System.String.</returns>
-        public string GetSavePath(IHasMetadata item)
-        {
-            return Path.Combine(item.Path, "series.xml");
-        }
-    }
-}

+ 1 - 1
MediaBrowser.Model/Configuration/UserConfiguration.cs

@@ -63,9 +63,9 @@ namespace MediaBrowser.Model.Configuration
             LatestItemsExcludes = new string[] { };
             OrderedViews = new string[] { };
             DisplayChannelsWithinViews = new string[] { };
+            DisplayChannelsInline = true;
 
             PlainFolderViews = new string[] { };
-            DisplayCollectionsView = true;
 
             IncludeTrailersInSuggestions = true;
             EnableCinemaMode = true;

+ 9 - 0
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -525,6 +525,15 @@ namespace MediaBrowser.Model.Dlna
             bool isEligibleForDirectPlay,
             bool isEligibleForDirectStream)
         {
+            if (videoStream == null)
+            {
+                _logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}",
+                    profile.Name ?? "Unknown Profile",
+                    mediaSource.Path ?? "Unknown path");
+
+                return null;
+            }
+
             // See if it can be direct played
             DirectPlayProfile directPlay = null;
             foreach (DirectPlayProfile i in profile.DirectPlayProfiles)

+ 0 - 6
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -530,12 +530,6 @@ namespace MediaBrowser.Model.Dto
         /// <value>The primary image aspect ratio.</value>
         public double? PrimaryImageAspectRatio { get; set; }
 
-        /// <summary>
-        /// Gets or sets the primary image aspect ratio, before image enhancements.
-        /// </summary>
-        /// <value>The original primary image aspect ratio.</value>
-        public double? OriginalPrimaryImageAspectRatio { get; set; }
-
         /// <summary>
         /// Gets or sets the artists.
         /// </summary>

+ 0 - 6
MediaBrowser.Model/Dto/IItemDto.cs

@@ -11,11 +11,5 @@ namespace MediaBrowser.Model.Dto
         /// </summary>
         /// <value>The primary image aspect ratio.</value>
         double? PrimaryImageAspectRatio { get; set; }
-
-        /// <summary>
-        /// Gets or sets the original primary image aspect ratio.
-        /// </summary>
-        /// <value>The original primary image aspect ratio.</value>
-        double? OriginalPrimaryImageAspectRatio { get; set; }
     }
 }

+ 0 - 6
MediaBrowser.Model/Dto/UserDto.cs

@@ -122,12 +122,6 @@ namespace MediaBrowser.Model.Dto
         /// <value>The primary image aspect ratio.</value>
         public double? PrimaryImageAspectRatio { get; set; }
 
-        /// <summary>
-        /// Gets or sets the original primary image aspect ratio.
-        /// </summary>
-        /// <value>The original primary image aspect ratio.</value>
-        public double? OriginalPrimaryImageAspectRatio { get; set; }
-
         /// <summary>
         /// Gets a value indicating whether this instance has primary image.
         /// </summary>

+ 0 - 2
MediaBrowser.Model/Entities/MetadataProviders.cs

@@ -36,8 +36,6 @@ namespace MediaBrowser.Model.Entities
         MusicBrainzArtist = 10,
         MusicBrainzReleaseGroup = 11,
         Zap2It = 12,
-        NesBox = 13,
-        NesBoxRom = 14,
         TvRage = 15,
         AudioDbArtist = 16,
         AudioDbAlbum = 17,

+ 0 - 6
MediaBrowser.Model/LiveTv/ChannelInfoDto.cs

@@ -105,12 +105,6 @@ namespace MediaBrowser.Model.LiveTv
         /// <value>The primary image aspect ratio.</value>
         public double? PrimaryImageAspectRatio { get; set; }
 
-        /// <summary>
-        /// Gets or sets the primary image aspect ratio, before image enhancements.
-        /// </summary>
-        /// <value>The original primary image aspect ratio.</value>
-        public double? OriginalPrimaryImageAspectRatio { get; set; }
-
         /// <summary>
         /// Gets a value indicating whether this instance has primary image.
         /// </summary>

+ 0 - 5
MediaBrowser.Model/Querying/ItemFields.cs

@@ -165,11 +165,6 @@
         /// </summary>
         PrimaryImageAspectRatio,
 
-        /// <summary>
-        /// The original primary image aspect ratio
-        /// </summary>
-        OriginalPrimaryImageAspectRatio,
-        
         /// <summary>
         /// The revenue
         /// </summary>

+ 16 - 1
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -408,6 +408,9 @@ namespace MediaBrowser.Server.Implementations.Channels
 
         private async Task<Channel> GetChannel(IChannel channelInfo, CancellationToken cancellationToken)
         {
+            var parentFolder = await GetInternalChannelFolder(cancellationToken).ConfigureAwait(false);
+            var parentFolderId = parentFolder.Id;
+
             var id = GetInternalChannelId(channelInfo.Name);
 
             var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id);
@@ -450,6 +453,13 @@ namespace MediaBrowser.Server.Implementations.Channels
             {
                 isNew = true;
             }
+            item.ChannelId = channelId;
+
+            if (item.ParentId != parentFolderId)
+            {
+                isNew = true;
+            }
+            item.ParentId = parentFolderId;
 
             item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating);
             item.Overview = channelInfo.Description;
@@ -1254,7 +1264,6 @@ namespace MediaBrowser.Server.Implementations.Channels
                 item.ProductionYear = info.ProductionYear;
                 item.ProviderIds = info.ProviderIds;
                 item.OfficialRating = info.OfficialRating;
-
                 item.DateCreated = info.DateCreated ?? DateTime.UtcNow;
             }
 
@@ -1262,6 +1271,12 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             channelItem.ChannelId = internalChannelId.ToString("N");
 
+            if (item.ParentId != internalChannelId)
+            {
+                isNew = true;
+            }
+            item.ParentId = internalChannelId;
+
             if (!string.Equals(channelItem.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
             {
                 isNew = true;

+ 8 - 13
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -463,12 +463,15 @@ namespace MediaBrowser.Server.Implementations.Dto
 
                 var folder = (Folder)item;
 
-                dto.ChildCount = GetChildCount(folder, user);
-
-                // These are just far too slow. 
-                if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem) && !(folder is ICollectionFolder))
+                if (!(folder is IChannelItem) && !(folder is Channel))
                 {
-                    SetSpecialCounts(folder, user, dto, fields, syncProgress);
+                    dto.ChildCount = GetChildCount(folder, user);
+
+                    // These are just far too slow. 
+                    if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is ICollectionFolder))
+                    {
+                        SetSpecialCounts(folder, user, dto, fields, syncProgress);
+                    }
                 }
 
                 dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100;
@@ -1763,14 +1766,6 @@ namespace MediaBrowser.Server.Implementations.Dto
                 return;
             }
 
-            if (fields.Contains(ItemFields.OriginalPrimaryImageAspectRatio))
-            {
-                if (size.Width > 0 && size.Height > 0)
-                {
-                    dto.OriginalPrimaryImageAspectRatio = size.Width / size.Height;
-                }
-            }
-
             var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList();
 
             foreach (var enhancer in supportedEnhancers)

+ 12 - 4
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1293,14 +1293,13 @@ namespace MediaBrowser.Server.Implementations.Library
 
             query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
 
-            var items = GetItemIds(query).Select(GetItemById);
-
             if (user != null)
             {
                 AddUserToQuery(query, user);
-                items = items.Where(i => i.IsVisibleStandalone(user));
             }
 
+            var items = GetItemIds(query).Select(GetItemById);
+
             return items;
         }
 
@@ -1320,7 +1319,16 @@ namespace MediaBrowser.Server.Implementations.Library
 
         private void AddUserToQuery(InternalItemsQuery query, User user)
         {
-            
+            if (query.AncestorIds.Length == 0)
+            {
+                // Need to filter on user folders
+            }
+
+            query.MaxParentalRating = user.Policy.MaxParentalRating;
+
+            // handle blocking by tags
+
+            // handle unrated filter
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs

@@ -114,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 return 10000000;
             }
 
-            return 2000000;
+            return 4000000;
         }
 
         private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams)

+ 1 - 1
MediaBrowser.Server.Implementations/Library/SearchEngine.cs

@@ -162,7 +162,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 NameContains = searchTerm,
                 ExcludeItemTypes = excludeItemTypes.ToArray(),
                 IncludeItemTypes = includeItemTypes.ToArray(),
-                Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 2) : null),
+                Limit = query.Limit,
 
             }, user, new string[] { });
 

+ 20 - 24
MediaBrowser.Server.Implementations/Library/UserViewManager.cs

@@ -16,6 +16,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities.Audio;
 
 namespace MediaBrowser.Server.Implementations.Library
 {
@@ -74,7 +75,7 @@ namespace MediaBrowser.Server.Implementations.Library
                     {
                         list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, true, string.Empty, user, cancellationToken).ConfigureAwait(false));
                     }
-                    else if (plainFolderIds.Contains(folder.Id))
+                    else if (plainFolderIds.Contains(folder.Id) && UserView.IsEligibleForEnhancedView(folderViewType))
                     {
                         list.Add(await GetUserView(folder, folderViewType, false, string.Empty, cancellationToken).ConfigureAwait(false));
                     }
@@ -100,7 +101,7 @@ namespace MediaBrowser.Server.Implementations.Library
                     {
                         list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, true, string.Empty, user, cancellationToken).ConfigureAwait(false));
                     }
-                    else if (plainFolderIds.Contains(folder.Id))
+                    else if (plainFolderIds.Contains(folder.Id) && UserView.IsEligibleForEnhancedView(folderViewType))
                     {
                         list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, false, string.Empty, user, cancellationToken).ConfigureAwait(false));
                     }
@@ -123,14 +124,6 @@ namespace MediaBrowser.Server.Implementations.Library
                 list.Add(await GetUserView(parents, list, CollectionType.TvShows, string.Empty, user, enableUserViews, cancellationToken).ConfigureAwait(false));
             }
 
-            parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user)))
-                .ToList();
-
-            if (parents.Count > 0)
-            {
-                list.Add(await GetUserView(parents, list, CollectionType.Music, string.Empty, user, enableUserViews, cancellationToken).ConfigureAwait(false));
-            }
-
             parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user)))
                .ToList();
 
@@ -139,14 +132,6 @@ namespace MediaBrowser.Server.Implementations.Library
                 list.Add(await GetUserView(parents, list, CollectionType.Movies, string.Empty, user, enableUserViews, cancellationToken).ConfigureAwait(false));
             }
 
-            parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Games, StringComparison.OrdinalIgnoreCase))
-               .ToList();
-
-            if (parents.Count > 0)
-            {
-                list.Add(await GetUserView(parents, list, CollectionType.Games, string.Empty, user, enableUserViews, cancellationToken).ConfigureAwait(false));
-            }
-
             if (user.Configuration.DisplayFoldersView)
             {
                 var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders);
@@ -245,7 +230,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             var currentUser = user;
 
-            var libraryItems = GetItemsForLatestItems(user, request.ParentId, includeTypes).Where(i =>
+            var libraryItems = GetItemsForLatestItems(user, request.ParentId, includeTypes, request.Limit ?? 10).Where(i =>
             {
                 if (request.IsPlayed.HasValue)
                 {
@@ -293,23 +278,34 @@ namespace MediaBrowser.Server.Implementations.Library
             return list;
         }
 
-        private IEnumerable<BaseItem> GetItemsForLatestItems(User user, string parentId, string[] includeItemTypes)
+        private IEnumerable<BaseItem> GetItemsForLatestItems(User user, string parentId, string[] includeItemTypes, int limit)
         {
             var parentIds = string.IsNullOrEmpty(parentId)
               ? new string[] { }
               : new[] { parentId };
 
+            if (parentIds.Length == 0)
+            {
+                parentIds = user.RootFolder.GetChildren(user, true)
+                    .OfType<Folder>()
+                    .Select(i => i.Id.ToString("N"))
+                    .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i))
+                    .ToArray();
+            }
+
+            var excludeItemTypes = includeItemTypes.Length == 0 ? new[] { "ChannelItem", "LiveTvItem", typeof(Person).Name, typeof(Studio).Name, typeof(Year).Name, typeof(GameGenre).Name, typeof(MusicGenre).Name, typeof(Genre).Name } : new string[] { };
+
             return _libraryManager.GetItems(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = includeItemTypes,
                 SortOrder = SortOrder.Descending,
                 SortBy = new[] { ItemSortBy.DateCreated },
-                IsFolder = false,
-                ExcludeItemTypes = new[] { "ChannelItem", "Recording" },
-                ExcludeLocationTypes = new[] { LocationType.Virtual }
+                IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
+                ExcludeItemTypes = excludeItemTypes,
+                ExcludeLocationTypes = new[] { LocationType.Virtual },
+                Limit = limit * 20
 
             }, user, parentIds);
-
         }
     }
 }

+ 3 - 1
MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private readonly IServerConfigurationManager _config;
         private readonly IFileSystem _fileSystem;
 
-        public const int MigrationVersion = 2;
+        public const int MigrationVersion = 4;
 
         public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem)
         {
@@ -66,6 +66,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
             innerProgress.RegisterAction(p => progress.Report(45 + (.55 * p)));
             await CleanDeletedItems(cancellationToken, innerProgress).ConfigureAwait(false);
             progress.Report(100);
+
+            await _itemRepo.UpdateInheritedValues(cancellationToken).ConfigureAwait(false);
         }
 
         private async Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress<double> progress)

+ 78 - 15
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deleteAncestorsCommand;
         private IDbCommand _saveAncestorCommand;
 
-        private const int LatestSchemaVersion = 19;
+        private const int LatestSchemaVersion = 25;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -133,13 +133,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
                                 "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)",
                                 "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
 
-                                "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, PRIMARY KEY (ItemId, AncestorId))",
+                                "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
                                 "create index if not exists idx_AncestorIds on AncestorIds(ItemId,AncestorId)",
                                 
                                 "create table if not exists ChildrenIds (ParentId GUID, ItemId GUID, PRIMARY KEY (ParentId, ItemId))",
                                 "create index if not exists idx_ChildrenIds on ChildrenIds(ParentId,ItemId)",
 
                                 "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
+                                "create index if not exists idxPeopleItemId on People(ItemId)",
+                                "create index if not exists idxPeopleName on People(Name)",
 
                                 "create table if not exists "+ChaptersTableName+" (ItemId GUID, ChapterIndex INT, StartPositionTicks BIGINT, Name TEXT, ImagePath TEXT, PRIMARY KEY (ItemId, ChapterIndex))",
                                 "create index if not exists idx_"+ChaptersTableName+" on "+ChaptersTableName+"(ItemId, ChapterIndex)",
@@ -155,6 +157,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             _connection.RunQueries(queries, _logger);
 
+            _connection.AddColumn(_logger, "AncestorIds", "AncestorIdText", "Text");
+            
             _connection.AddColumn(_logger, "TypedBaseItems", "Path", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "StartDate", "DATETIME");
             _connection.AddColumn(_logger, "TypedBaseItems", "EndDate", "DATETIME");
@@ -214,6 +218,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "IsFolder", "BIT");
+            _connection.AddColumn(_logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT");
 
             PrepareStatements();
 
@@ -416,6 +421,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "ParentId",
                 "Genres",
                 "ParentalRatingValue",
+                "InheritedParentalRatingValue",
                 "SchemaVersion",
                 "SortName",
                 "RunTimeTicks",
@@ -483,16 +489,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _savePersonCommand.Parameters.Add(_savePersonCommand, "@PersonType");
             _savePersonCommand.Parameters.Add(_savePersonCommand, "@SortOrder");
             _savePersonCommand.Parameters.Add(_savePersonCommand, "@ListOrder");
-            
+
             // Ancestors
             _deleteAncestorsCommand = _connection.CreateCommand();
             _deleteAncestorsCommand.CommandText = "delete from AncestorIds where ItemId=@Id";
             _deleteAncestorsCommand.Parameters.Add(_deleteAncestorsCommand, "@Id");
 
             _saveAncestorCommand = _connection.CreateCommand();
-            _saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId) values (@ItemId, @AncestorId)";
+            _saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId, AncestorIdText) values (@ItemId, @AncestorId, @AncestorIdText)";
             _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@ItemId");
             _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorId");
+            _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorIdText");
 
             // Chapters
             _deleteChaptersCommand = _connection.CreateCommand();
@@ -648,7 +655,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     }
 
                     _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray());
-                    _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue();
+                    _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0;
+                    _saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0;
 
                     _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion;
                     _saveItemCommand.GetParameter(index++).Value = item.SortName;
@@ -705,7 +713,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
                     _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
                     _saveItemCommand.GetParameter(index++).Value = item.IsFolder;
-           
+
                     _saveItemCommand.Transaction = transaction;
 
                     _saveItemCommand.ExecuteNonQuery();
@@ -1368,7 +1376,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = parentId;
 
                 //_logger.Debug(cmd.CommandText);
-                
+
                 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
                 {
                     while (reader.Read())
@@ -1885,7 +1893,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             if (query.MaxParentalRating.HasValue)
             {
-                whereClauses.Add("(ParentalRatingValue is NULL OR ParentalRatingValue<=@MaxParentalRating)");
+                whereClauses.Add("InheritedParentalRatingValue<=@MaxParentalRating");
                 cmd.Parameters.Add(cmd, "@MaxParentalRating", DbType.Int32).Value = query.MaxParentalRating.Value;
             }
 
@@ -1893,11 +1901,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
             {
                 if (query.HasParentalRating.Value)
                 {
-                    whereClauses.Add("ParentalRatingValue NOT NULL");
+                    whereClauses.Add("InheritedParentalRatingValue > 0");
                 }
                 else
                 {
-                    whereClauses.Add("ParentalRatingValue IS NULL");
+                    whereClauses.Add("InheritedParentalRatingValue = 0");
                 }
             }
 
@@ -1916,8 +1924,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             if (query.AncestorIds.Length > 1)
             {
-                var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i + "'").ToArray());
-                whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
+                var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + new Guid(i).ToString("N") + "'").ToArray());
+                whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
             }
             if (query.ExcludeLocationTypes.Length == 1)
             {
@@ -1986,6 +1994,59 @@ namespace MediaBrowser.Server.Implementations.Persistence
             typeof(Channel)
         };
 
+        public async Task UpdateInheritedValues(CancellationToken cancellationToken)
+        {
+            await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+            IDbTransaction transaction = null;
+
+            try
+            {
+                transaction = _connection.BeginTransaction();
+
+                using (var cmd = _connection.CreateCommand())
+                {
+                    cmd.CommandText = "update TypedBaseItems set InheritedParentalRatingValue = (select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems as T where guid in (Select AncestorId from AncestorIds where ItemId=T.guid))))";
+
+                    cmd.Transaction = transaction;
+                    cmd.ExecuteNonQuery();
+
+                    cmd.ExecuteNonQuery();
+                }
+
+                transaction.Commit();
+            }
+            catch (OperationCanceledException)
+            {
+                if (transaction != null)
+                {
+                    transaction.Rollback();
+                }
+
+                throw;
+            }
+            catch (Exception e)
+            {
+                _logger.ErrorException("Error running query:", e);
+
+                if (transaction != null)
+                {
+                    transaction.Rollback();
+                }
+
+                throw;
+            }
+            finally
+            {
+                if (transaction != null)
+                {
+                    transaction.Dispose();
+                }
+
+                _writeLock.Release();
+            }
+        }
+
         private static Dictionary<string, string[]> GetTypeMapDictionary()
         {
             var dict = new Dictionary<string, string[]>();
@@ -1996,6 +2057,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
 
             dict["ChannelItem"] = new[] { typeof(ChannelVideoItem).FullName, typeof(ChannelAudioItem).FullName, typeof(ChannelFolderItem).FullName };
+            dict["LiveTvItem"] = new[] { typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName, typeof(LiveTvChannel).FullName, typeof(LiveTvProgram).FullName };
             dict["Recording"] = new[] { typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName };
             dict["Program"] = new[] { typeof(LiveTvProgram).FullName };
             dict["TvChannel"] = new[] { typeof(LiveTvChannel).FullName };
@@ -2053,7 +2115,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 _deleteStreamsCommand.GetParameter(0).Value = id;
                 _deleteStreamsCommand.Transaction = transaction;
                 _deleteStreamsCommand.ExecuteNonQuery();
-                
+
                 // Delete ancestors
                 _deleteAncestorsCommand.GetParameter(0).Value = id;
                 _deleteAncestorsCommand.Transaction = transaction;
@@ -2063,7 +2125,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 _deleteItemCommand.GetParameter(0).Value = id;
                 _deleteItemCommand.Transaction = transaction;
                 _deleteItemCommand.ExecuteNonQuery();
-                
+
                 transaction.Commit();
             }
             catch (OperationCanceledException)
@@ -2316,6 +2378,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             {
                 _saveAncestorCommand.GetParameter(0).Value = itemId;
                 _saveAncestorCommand.GetParameter(1).Value = ancestorId;
+                _saveAncestorCommand.GetParameter(2).Value = ancestorId.ToString("N");
 
                 _saveAncestorCommand.Transaction = transaction;
 
@@ -2550,7 +2613,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     }
 
                     _saveStreamCommand.GetParameter(index++).Value = stream.CodecTag;
-                    
+
                     _saveStreamCommand.Transaction = transaction;
                     _saveStreamCommand.ExecuteNonQuery();
                 }

+ 0 - 1
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -640,7 +640,6 @@ namespace MediaBrowser.Server.Implementations.Sync
             dtoOptions.Fields.Remove(ItemFields.MediaStreams);
             dtoOptions.Fields.Remove(ItemFields.IndexOptions);
             dtoOptions.Fields.Remove(ItemFields.MediaSourceCount);
-            dtoOptions.Fields.Remove(ItemFields.OriginalPrimaryImageAspectRatio);
             dtoOptions.Fields.Remove(ItemFields.Path);
             dtoOptions.Fields.Remove(ItemFields.SeriesGenres);
             dtoOptions.Fields.Remove(ItemFields.Settings);

+ 11 - 3
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -640,11 +640,19 @@ namespace MediaBrowser.Server.Startup.Common
         /// <returns>Task{IUserRepository}.</returns>
         private async Task<IUserRepository> GetUserRepository()
         {
-            var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer);
+            try
+            {
+                var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer);
 
-            await repo.Initialize().ConfigureAwait(false);
+                await repo.Initialize().ConfigureAwait(false);
 
-            return repo;
+                return repo;
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error opening user db", ex);
+                throw;
+            }
         }
 
         /// <summary>

+ 6 - 8
MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs

@@ -20,15 +20,13 @@ namespace MediaBrowser.Server.Startup.Common.Migrations
         {
             if (_config.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion)
             {
-                return;
-            }
-
-            Task.Run(async () =>
-            {
-                await Task.Delay(2000).ConfigureAwait(false);
+                Task.Run(async () =>
+                {
+                    await Task.Delay(2000).ConfigureAwait(false);
 
-                _taskManager.QueueScheduledTask<CleanDatabaseScheduledTask>();
-            });
+                    _taskManager.QueueScheduledTask<CleanDatabaseScheduledTask>();
+                });
+            }
         }
     }
 }

+ 2 - 2
SharedVersion.cs

@@ -1,4 +1,4 @@
 using System.Reflection;
 
-//[assembly: AssemblyVersion("3.0.*")]
-[assembly: AssemblyVersion("3.0.5781.0")]
+[assembly: AssemblyVersion("3.0.*")]
+//[assembly: AssemblyVersion("3.0.5781.0")]