Ver Fonte

update image encoding

Luke Pulverenti há 9 anos atrás
pai
commit
9b998a068a
27 ficheiros alterados com 232 adições e 122 exclusões
  1. 3 0
      Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
  2. 2 1
      MediaBrowser.Api/Movies/MoviesService.cs
  3. 23 12
      MediaBrowser.Api/TvShowsService.cs
  4. 1 1
      MediaBrowser.Common.Implementations/Logging/NlogManager.cs
  5. 9 0
      MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
  6. 1 0
      MediaBrowser.Common/MediaBrowser.Common.csproj
  7. 8 0
      MediaBrowser.Common/Security/PaymentRequiredException.cs
  8. 9 1
      MediaBrowser.Controller/Entities/BaseItem.cs
  9. 11 0
      MediaBrowser.Controller/Entities/InternalItemsQuery.cs
  10. 8 0
      MediaBrowser.Controller/Library/ILibraryManager.cs
  11. 0 1
      MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
  12. 12 23
      MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
  13. 0 1
      MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
  14. 1 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  15. 15 0
      MediaBrowser.Controller/Net/PaymentRequiredException.cs
  16. 0 14
      MediaBrowser.Controller/Providers/MetadataStatus.cs
  17. 14 8
      MediaBrowser.Providers/Manager/MetadataService.cs
  18. 6 2
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  19. 3 1
      MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
  20. 4 1
      MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs
  21. 1 9
      MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
  22. 6 6
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  23. 1 2
      MediaBrowser.Server.Implementations/Library/SearchEngine.cs
  24. 18 22
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  25. 56 4
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  26. 3 10
      MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
  27. 17 3
      MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs

+ 3 - 0
Emby.Drawing/ImageMagick/ImageMagickEncoder.cs

@@ -136,6 +136,9 @@ namespace Emby.Drawing.ImageMagick
 
         public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options)
         {
+            // Even if the caller specified 100, don't use it because it takes forever
+            quality = Math.Min(quality, 99);
+
             if (string.IsNullOrWhiteSpace(options.BackgroundColor) || !HasTransparency(inputPath))
             {
                 using (var originalImage = new MagickWand(inputPath))

+ 2 - 1
MediaBrowser.Api/Movies/MoviesService.cs

@@ -379,9 +379,10 @@ namespace MediaBrowser.Api.Movies
         {
             foreach (var name in names)
             {
-                var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery
+                var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery(user)
                 {
                     Person = name
+
                 });
 
                 var items = allMovies

+ 23 - 12
MediaBrowser.Api/TvShowsService.cs

@@ -159,7 +159,7 @@ namespace MediaBrowser.Api
 
         [ApiMember(Name = "StartItemId", Description = "Optional. Skip through the list until a given item is found.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string StartItemId { get; set; }
-        
+
         /// <summary>
         /// Skips over a given number of items within the results. Use for paging.
         /// </summary>
@@ -273,21 +273,32 @@ namespace MediaBrowser.Api
         {
             var user = _userManager.GetUserById(request.UserId);
 
-            var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode);
+            var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime();
+
+            IEnumerable<BaseItem> items;
+
+            if (string.IsNullOrWhiteSpace(request.ParentId))
+            {
+                items = _libraryManager.GetItems(new InternalItemsQuery(user)
+                {
+                    IncludeItemTypes = new[] { typeof(Episode).Name },
+                    SortBy = new[] { "PremiereDate", "SortName" },
+                    SortOrder = SortOrder.Ascending,
+                    MinPremiereDate = minPremiereDate
+
+                }, user);
+            }
+            else
+            {
+                items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode && (i.PremiereDate ?? DateTime.MinValue) >= minPremiereDate);
+            }
 
             var itemsList = _libraryManager
                 .Sort(items, user, new[] { "PremiereDate", "AirTime", "SortName" }, SortOrder.Ascending)
                 .Cast<Episode>()
                 .ToList();
 
-            var unairedEpisodes = itemsList.Where(i => i.IsUnaired).ToList();
-
-            var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime();
-            var previousEpisodes = itemsList.Where(i => !i.IsUnaired && (i.PremiereDate ?? DateTime.MinValue) >= minPremiereDate).ToList();
-
-            previousEpisodes.AddRange(unairedEpisodes);
-
-            var pagedItems = ApplyPaging(previousEpisodes, request.StartIndex, request.Limit);
+            var pagedItems = ApplyPaging(itemsList, request.StartIndex, request.Limit);
 
             var options = GetDtoOptions(request);
 
@@ -440,7 +451,7 @@ namespace MediaBrowser.Api
                 }
 
                 episodes = season.GetEpisodes(user);
-            } 
+            }
             else if (request.Season.HasValue)
             {
                 var series = _libraryManager.GetItemById(request.Id) as Series;
@@ -495,7 +506,7 @@ namespace MediaBrowser.Api
                 .ToList();
 
             var pagedItems = ApplyPaging(returnList, request.StartIndex, request.Limit);
-            
+
             var dtoOptions = GetDtoOptions(request);
 
             var dtos = _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user)

+ 1 - 1
MediaBrowser.Common.Implementations/Logging/NlogManager.cs

@@ -110,7 +110,7 @@ namespace MediaBrowser.Common.Implementations.Logging
 			var logFile = new FileTarget
             {
                 FileName = path,
-                Layout = "${longdate} ${level} - ${logger}: ${message}"
+                Layout = "${longdate} ${level} ${logger}: ${message}"
             };
 
             logFile.Name = "ApplicationLogFile";

+ 9 - 0
MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs

@@ -219,6 +219,10 @@ namespace MediaBrowser.Common.Implementations.Security
                     {
                         SupporterKey = reg.key;
                     }
+                    else
+                    {
+                        throw new PaymentRequiredException();
+                    }
                 }
 
             }
@@ -227,6 +231,11 @@ namespace MediaBrowser.Common.Implementations.Security
                 SaveAppStoreInfo(parameters);
                 throw;
             }
+            catch (PaymentRequiredException)
+            {
+                SaveAppStoreInfo(parameters);
+                throw;
+            }
             catch (Exception e)
             {
                 _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT");

+ 1 - 0
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -89,6 +89,7 @@
     <Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
     <Compile Include="Security\IRequiresRegistration.cs" />
     <Compile Include="Security\ISecurityManager.cs" />
+    <Compile Include="Security\PaymentRequiredException.cs" />
     <Compile Include="Updates\IInstallationManager.cs" />
     <Compile Include="Updates\InstallationEventArgs.cs" />
     <Compile Include="Updates\InstallationFailedEventArgs.cs" />

+ 8 - 0
MediaBrowser.Common/Security/PaymentRequiredException.cs

@@ -0,0 +1,8 @@
+using System;
+
+namespace MediaBrowser.Common.Security
+{
+    public class PaymentRequiredException : Exception
+    {
+    }
+}

+ 9 - 1
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -24,6 +24,7 @@ using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Model.LiveTv;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -134,6 +135,13 @@ namespace MediaBrowser.Controller.Entities
         [IgnoreDataMember]
         public bool? IsHD { get; set; }
 
+        /// <summary>
+        /// Gets or sets the audio.
+        /// </summary>
+        /// <value>The audio.</value>
+        [IgnoreDataMember]
+        public ProgramAudio? Audio { get; set; }
+
         /// <summary>
         /// Return the id that should be used to key display prefs for this item.
         /// Default is based on the type for everything except actual generic folders.
@@ -178,7 +186,7 @@ namespace MediaBrowser.Controller.Entities
         }
 
         /// <summary>
-        /// Id of the program.
+        /// If this content came from an external service, the id of the content on that service
         /// </summary>
         [IgnoreDataMember]
         public string ExternalId

+ 11 - 0
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -75,6 +75,7 @@ namespace MediaBrowser.Controller.Entities
         public string[] Tags { get; set; }
         public string[] OfficialRatings { get; set; }
 
+        public DateTime? MinPremiereDate { get; set; }
         public DateTime? MinStartDate { get; set; }
         public DateTime? MaxStartDate { get; set; }
         public DateTime? MinEndDate { get; set; }
@@ -121,5 +122,15 @@ namespace MediaBrowser.Controller.Entities
             ChannelIds = new string[] { };
             ItemIds = new string[] { };
         }
+
+        public InternalItemsQuery(User user)
+            : this()
+        {
+            if (user != null)
+            {
+                var policy = user.Policy;
+                MaxParentalRating = policy.MaxParentalRating;
+            }
+        }
     }
 }

+ 8 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -543,5 +543,13 @@ namespace MediaBrowser.Controller.Library
         /// <param name="imageIndex">Index of the image.</param>
         /// <returns>Task.</returns>
         Task<ItemImageInfo> ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex);
+
+        /// <summary>
+        /// Gets the items.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>List&lt;BaseItem&gt;.</returns>
+        IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user);
     }
 }

+ 0 - 1
MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs

@@ -36,7 +36,6 @@ namespace MediaBrowser.Controller.LiveTv
         public bool IsLive { get; set; }
         [IgnoreDataMember]
         public bool IsPremiere { get; set; }
-        public ProgramAudio? Audio { get; set; }
 
         /// <summary>
         /// Gets the user data key.

+ 12 - 23
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs

@@ -32,10 +32,11 @@ namespace MediaBrowser.Controller.LiveTv
         }
 
         /// <summary>
-        /// Gets or sets the type of the channel.
+        /// Gets or sets the name.
         /// </summary>
-        /// <value>The type of the channel.</value>
-        public ChannelType ChannelType { get; set; }
+        /// <value>The name.</value>
+        [IgnoreDataMember]
+        public string ServiceName { get; set; }
 
         /// <summary>
         /// The start date of the program, in UTC.
@@ -43,18 +44,6 @@ namespace MediaBrowser.Controller.LiveTv
         [IgnoreDataMember]
         public DateTime StartDate { get; set; }
 
-        /// <summary>
-        /// Gets or sets the audio.
-        /// </summary>
-        /// <value>The audio.</value>
-        public ProgramAudio? Audio { get; set; }
-
-        /// <summary>
-        /// Gets or sets the name of the service.
-        /// </summary>
-        /// <value>The name of the service.</value>
-        public string ServiceName { get; set; }
-
         /// <summary>
         /// Gets or sets a value indicating whether this instance is repeat.
         /// </summary>
@@ -145,14 +134,14 @@ namespace MediaBrowser.Controller.LiveTv
             }
         }
 
-        [IgnoreDataMember]
-        public override string MediaType
-        {
-            get
-            {
-                return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
-            }
-        }
+        //[IgnoreDataMember]
+        //public override string MediaType
+        //{
+        //    get
+        //    {
+        //        return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
+        //    }
+        //}
 
         [IgnoreDataMember]
         public bool IsAiring

+ 0 - 1
MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs

@@ -36,7 +36,6 @@ namespace MediaBrowser.Controller.LiveTv
         public bool IsLive { get; set; }
         [IgnoreDataMember]
         public bool IsPremiere { get; set; }
-        public ProgramAudio? Audio { get; set; }
 
         /// <summary>
         /// Gets the user data key.

+ 1 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -248,6 +248,7 @@
     <Compile Include="Net\IWebSocketConnection.cs" />
     <Compile Include="Net\IWebSocketListener.cs" />
     <Compile Include="Net\LoggedAttribute.cs" />
+    <Compile Include="Net\PaymentRequiredException.cs" />
     <Compile Include="Net\SecurityException.cs" />
     <Compile Include="Net\ServiceStackServiceRequest.cs" />
     <Compile Include="Net\StaticResultOptions.cs" />

+ 15 - 0
MediaBrowser.Controller/Net/PaymentRequiredException.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Net
+{
+    /// <summary>
+    /// Corresponds to a 402 response code
+    /// </summary>
+    public class PaymentRequiredException : Exception
+    {
+    }
+}

+ 0 - 14
MediaBrowser.Controller/Providers/MetadataStatus.cs

@@ -40,22 +40,8 @@ namespace MediaBrowser.Controller.Providers
         /// <value>The date last images refresh.</value>
         public DateTime? DateLastImagesRefresh { get; set; }
 
-        /// <summary>
-        /// Gets or sets the last result error message.
-        /// </summary>
-        /// <value>The last result error message.</value>
-        public string LastErrorMessage { get; set; }
-
         public DateTime? ItemDateModified { get; set; }
 
-        public void AddStatus(string errorMessage)
-        {
-            if (string.IsNullOrEmpty(LastErrorMessage))
-            {
-                LastErrorMessage = errorMessage;
-            }
-        }
-
         public bool IsDirty { get; private set; }
 
         public void SetDateLastMetadataRefresh(DateTime? date)

+ 14 - 8
MediaBrowser.Providers/Manager/MetadataService.cs

@@ -99,7 +99,6 @@ namespace MediaBrowser.Providers.Manager
 
             var updateType = ItemUpdateType.None;
             var refreshResult = GetLastResult(item);
-            refreshResult.LastErrorMessage = string.Empty;
 
             var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
             var localImagesFailed = false;
@@ -119,7 +118,6 @@ namespace MediaBrowser.Providers.Manager
             {
                 localImagesFailed = true;
                 Logger.ErrorException("Error validating images for {0}", ex, item.Path ?? item.Name ?? "Unknown name");
-                refreshResult.AddStatus(ex.Message);
             }
 
             var metadataResult = new MetadataResult<TItemType>
@@ -150,7 +148,6 @@ namespace MediaBrowser.Providers.Manager
                     var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false);
 
                     updateType = updateType | result.UpdateType;
-                    refreshResult.AddStatus(result.ErrorMessage);
                     if (result.Failures == 0)
                     {
                         refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow);
@@ -172,7 +169,6 @@ namespace MediaBrowser.Providers.Manager
                     var result = await itemImageProvider.RefreshImages(itemOfType, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
 
                     updateType = updateType | result.UpdateType;
-                    refreshResult.AddStatus(result.ErrorMessage);
                     if (result.Failures == 0)
                     {
                         refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow);
@@ -231,22 +227,32 @@ namespace MediaBrowser.Providers.Manager
 
         private DateTime GetLastRefreshDate(IHasMetadata item)
         {
-            if (item.DateLastRefreshed != default(DateTime))
+            if (EnableDateLastRefreshed(item))
             {
                 return item.DateLastRefreshed;
             }
 
+            return item.DateLastSaved;
+        }
+
+        private bool EnableDateLastRefreshed(IHasMetadata item)
+        {
             if (ServerConfigurationManager.Configuration.EnableDateLastRefresh)
             {
-                return item.DateLastRefreshed;
+                return true;
+            }
+
+            if (item.DateLastRefreshed != default(DateTime))
+            {
+                return true;
             }
 
             if (item is BoxSet || (item is IItemByName && !(item is MusicArtist)))
             {
-                return item.DateLastRefreshed;
+                return true;
             }
 
-            return item.DateLastSaved;
+            return false;
         }
 
         protected async Task SaveItem(MetadataResult<TItemType> result, ItemUpdateType reason, CancellationToken cancellationToken)

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

@@ -472,7 +472,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
                 // These are just far too slow. 
                 // TODO: Disable for CollectionFolder
-                if (!(folder is UserRootFolder) && !(folder is UserView))
+                if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem))
                 {
                     SetSpecialCounts(folder, user, dto, fields, syncProgress);
                 }
@@ -1042,7 +1042,11 @@ namespace MediaBrowser.Server.Implementations.Dto
             dto.IsFolder = item.IsFolder;
             dto.MediaType = item.MediaType;
             dto.LocationType = item.LocationType;
-            dto.IsHD = item.IsHD;
+            if (item.IsHD.HasValue && item.IsHD.Value)
+            {
+                dto.IsHD = item.IsHD;
+            }
+            dto.Audio = item.Audio;
 
             dto.PreferredMetadataCountryCode = item.PreferredMetadataCountryCode;
             dto.PreferredMetadataLanguage = item.PreferredMetadataLanguage;

+ 3 - 1
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -92,7 +92,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                 {typeof (FileNotFoundException), 404},
                 {typeof (DirectoryNotFoundException), 404},
                 {typeof (SecurityException), 401},
-                {typeof (UnauthorizedAccessException), 500}
+                {typeof (PaymentRequiredException), 402},
+                {typeof (UnauthorizedAccessException), 500},
+                {typeof (ApplicationException), 500}
             };
 
             HostConfig.Instance.DebugMode = true;

+ 4 - 1
MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs

@@ -16,7 +16,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <param name="duration">The duration.</param>
         public static void LogResponse(ILogger logger, int statusCode, string url, string endPoint, TimeSpan duration)
         {
-            logger.Info("HTTP Response {0} to {1}. Time: {2}ms. {3}", statusCode, endPoint, Convert.ToInt32(duration.TotalMilliseconds).ToString(CultureInfo.InvariantCulture), url);
+            var durationMs = duration.TotalMilliseconds;
+            var logSuffix = durationMs >= 1000 ? "ms (slow)" : "ms";
+
+            logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url);
         }
     }
 }

+ 1 - 9
MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs

@@ -183,15 +183,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
         /// <param name="request">The request.</param>
         private static void LogRequest(ILogger logger, HttpListenerRequest request)
         {
-            var log = new StringBuilder();
-
-            var headers = string.Join(",", request.Headers.AllKeys.Where(i => !string.Equals(i, "cookie", StringComparison.OrdinalIgnoreCase) && !string.Equals(i, "Referer", StringComparison.OrdinalIgnoreCase)).Select(k => k + "=" + request.Headers[k]));
-
-            log.AppendLine("Ip: " + request.RemoteEndPoint + ". Headers: " + headers);
-
-            var type = request.IsWebSocketRequest ? "Web Socket" : "HTTP " + request.HttpMethod;
-
-            logger.LogMultiline(type + " " + request.Url, LogSeverity.Info, log);
+            logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), request.Url, request.UserAgent ?? string.Empty);
         }
 
         private void HandleError(Exception ex, HttpListenerContext context)

+ 6 - 6
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1280,6 +1280,11 @@ namespace MediaBrowser.Server.Implementations.Library
             return ItemRepository.GetItemIdsList(query);
         }
 
+        public IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user)
+        {
+            return GetItemIds(query).Select(GetItemById).Where(i => i.IsVisibleStandalone(user));
+        }
+
         /// <summary>
         /// Gets the intros.
         /// </summary>
@@ -1811,14 +1816,9 @@ namespace MediaBrowser.Server.Implementations.Library
                 isNew = true;
             }
 
-            if (!item.UserId.HasValue)
+            if (!item.UserId.HasValue || !string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
             {
                 item.UserId = user.Id;
-                await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
-            }
-
-            if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
-            {
                 item.ViewType = viewType;
                 await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
             }

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

@@ -157,12 +157,11 @@ namespace MediaBrowser.Server.Implementations.Library
 
             AddIfMissing(excludeItemTypes, typeof(CollectionFolder).Name);
             
-            var mediaItems = _libraryManager.GetItems(new InternalItemsQuery
+            var mediaItems = _libraryManager.GetItems(new InternalItemsQuery(user)
             {
                 NameContains = searchTerm,
                 ExcludeItemTypes = excludeItemTypes.ToArray(),
                 IncludeItemTypes = includeItemTypes.ToArray(),
-                MaxParentalRating = user == null ? null : user.Policy.MaxParentalRating,
                 Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 3) : null),
 
             }).Items;

+ 18 - 22
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -607,6 +607,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var item = _libraryManager.GetItemById(id) as LiveTvProgram;
             var isNew = false;
+            var forceUpdate = false;
 
             if (item == null)
             {
@@ -621,7 +622,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 };
             }
 
-            item.ChannelType = channelType;
+            //item.ChannelType = channelType;
+            if (!string.Equals(item.ServiceName, serviceName, StringComparison.Ordinal))
+            {
+                forceUpdate = true;
+            }
             item.ServiceName = serviceName;
 
             item.Audio = info.Audio;
@@ -666,7 +671,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             {
                 await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
             }
-            else if (string.IsNullOrWhiteSpace(info.Etag))
+            else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
             {
                 await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
             }
@@ -814,7 +819,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
         {
-            var internalQuery = new InternalItemsQuery
+            var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+            
+            var internalQuery = new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
                 MinEndDate = query.MinEndDate,
@@ -832,11 +839,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 SortOrder = query.SortOrder ?? SortOrder.Ascending
             };
 
-            var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
             if (user != null)
             {
-                internalQuery.MaxParentalRating = user.Policy.MaxParentalRating;
-
                 if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
                 {
                     internalQuery.HasParentalRating = true;
@@ -874,7 +878,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
         public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
         {
-            var internalQuery = new InternalItemsQuery
+            var user = _userManager.GetUserById(query.UserId);
+            
+            var internalQuery = new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
                 IsAiring = query.IsAiring,
@@ -895,11 +901,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 }
             }
 
-            var user = _userManager.GetUserById(query.UserId);
             if (user != null)
             {
-                internalQuery.MaxParentalRating = user.Policy.MaxParentalRating;
-
                 if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
                 {
                     internalQuery.HasParentalRating = true;
@@ -1037,6 +1040,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             {
                 var internalProgram = GetInternalProgram(program.Id);
 
+                if (string.IsNullOrWhiteSpace(internalProgram.ServiceName))
+                {
+                    continue;
+                }
+
                 List<TimerInfo> timerList;
                 if (!timers.TryGetValue(internalProgram.ServiceName, out timerList))
                 {
@@ -1052,7 +1060,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                     }
                 }
 
-
                 var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, internalProgram.ExternalId, StringComparison.OrdinalIgnoreCase));
 
                 if (timer != null)
@@ -1429,18 +1436,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
         public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, bool addChannelInfo, User user = null)
         {
             var program = (LiveTvProgram)item;
-            var service = GetService(program);
-
-            dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N");
 
             dto.StartDate = program.StartDate;
             dto.EpisodeTitle = program.EpisodeTitle;
-            dto.Audio = program.Audio;
 
-            if (program.IsHD.HasValue && program.IsHD.Value)
-            {
-                dto.IsHD = program.IsHD;
-            }
             if (program.IsRepeat)
             {
                 dto.IsRepeat = program.IsRepeat;
@@ -1499,7 +1498,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var info = recording;
 
-            dto.Id = item.Id.ToString("N");
             dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
                 ? null
                 : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
@@ -1508,8 +1506,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             dto.RecordingStatus = info.Status;
             dto.IsRepeat = info.IsRepeat;
             dto.EpisodeTitle = info.EpisodeTitle;
-            dto.Audio = info.Audio;
-            dto.IsHD = info.IsHD;
             dto.IsMovie = info.IsMovie;
             dto.IsSeries = info.IsSeries;
             dto.IsSports = info.IsSports;

+ 56 - 4
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -19,6 +19,7 @@ using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Channels;
+using MediaBrowser.Model.LiveTv;
 
 namespace MediaBrowser.Server.Implementations.Persistence
 {
@@ -76,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deleteStreamsCommand;
         private IDbCommand _saveStreamCommand;
 
-        private const int LatestSchemaVersion = 16;
+        private const int LatestSchemaVersion = 17;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -202,7 +203,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _connection.AddColumn(_logger, "TypedBaseItems", "IsInMixedFolder", "BIT");
             _connection.AddColumn(_logger, "TypedBaseItems", "LockedFields", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "Studios", "Text");
-  
+            _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text");
+            _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text");
+
             PrepareStatements();
 
             new MediaStreamColumns(_connection, _logger).AddColumns();
@@ -311,7 +314,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
             "DateCreated",
             "DateModified",
             "guid",
-            "Genres"
+            "Genres",
+            "ParentId",
+            "Audio",
+            "ExternalServiceId"
         };
 
         private readonly string[] _mediaStreamSaveColumns =
@@ -403,7 +409,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "DateLastSaved",
                 "IsInMixedFolder",
                 "LockedFields",
-                "Studios"
+                "Studios",
+                "Audio",
+                "ExternalServiceId"
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -637,6 +645,25 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray());
                     _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Studios.ToArray());
 
+                    if (item.Audio.HasValue)
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = item.Audio.Value.ToString();
+                    }
+                    else
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = null;
+                    }
+
+                    var tvItem = item as ILiveTvItem;
+                    if (tvItem != null)
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = tvItem.ServiceName;
+                    }
+                    else
+                    {
+                        _saveItemCommand.GetParameter(index++).Value = null;
+                    }
+
                     _saveItemCommand.Transaction = transaction;
 
                     _saveItemCommand.ExecuteNonQuery();
@@ -940,6 +967,25 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 item.Genres = reader.GetString(40).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
             }
 
+            if (!reader.IsDBNull(41))
+            {
+                item.ParentId = reader.GetGuid(41);
+            }
+
+            if (!reader.IsDBNull(42))
+            {
+                item.Audio = (ProgramAudio)Enum.Parse(typeof(ProgramAudio), reader.GetString(42), true);
+            }
+
+            if (!reader.IsDBNull(43))
+            {
+                var tvItem = item as ILiveTvItem;
+                if (tvItem != null)
+                {
+                    item.ForcedSortName = reader.GetString(43);
+                }
+            }
+
             return item;
         }
 
@@ -1668,6 +1714,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 cmd.Parameters.Add(cmd, "@MinStartDate", DbType.Date).Value = query.MinStartDate.Value;
             }
 
+            if (query.MinPremiereDate.HasValue)
+            {
+                whereClauses.Add("PremiereDate>=@MinPremiereDate");
+                cmd.Parameters.Add(cmd, "@MinPremiereDate", DbType.Date).Value = query.MinPremiereDate.Value;
+            }
+
             if (query.MaxStartDate.HasValue)
             {
                 whereClauses.Add("StartDate<=@MaxStartDate");

+ 3 - 10
MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs

@@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             string[] queries = {
 
-                                "create table if not exists MetadataStatus (ItemId GUID PRIMARY KEY, ItemName TEXT, ItemType TEXT, SeriesName TEXT, DateLastMetadataRefresh datetime, DateLastImagesRefresh datetime, LastErrorMessage TEXT, ItemDateModified DateTimeNull)",
+                                "create table if not exists MetadataStatus (ItemId GUID PRIMARY KEY, ItemName TEXT, ItemType TEXT, SeriesName TEXT, DateLastMetadataRefresh datetime, DateLastImagesRefresh datetime, ItemDateModified DateTimeNull)",
                                 "create index if not exists idx_MetadataStatus on MetadataStatus(ItemId)",
 
                                 //pragmas
@@ -71,7 +71,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
             "SeriesName",
             "DateLastMetadataRefresh",
             "DateLastImagesRefresh",
-            "LastErrorMessage",
             "ItemDateModified"
         };
 
@@ -185,12 +184,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             if (!reader.IsDBNull(6))
             {
-                result.LastErrorMessage = reader.GetString(6);
-            }
-
-            if (!reader.IsDBNull(7))
-            {
-                result.ItemDateModified = reader.GetDateTime(7).ToUniversalTime();
+                result.ItemDateModified = reader.GetDateTime(6).ToUniversalTime();
             }
 
             return result;
@@ -219,8 +213,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 _saveStatusCommand.GetParameter(3).Value = status.SeriesName;
                 _saveStatusCommand.GetParameter(4).Value = status.DateLastMetadataRefresh;
                 _saveStatusCommand.GetParameter(5).Value = status.DateLastImagesRefresh;
-                _saveStatusCommand.GetParameter(6).Value = status.LastErrorMessage;
-                _saveStatusCommand.GetParameter(7).Value = status.ItemDateModified;
+                _saveStatusCommand.GetParameter(6).Value = status.ItemDateModified;
 
                 _saveStatusCommand.Transaction = transaction;
 

+ 17 - 3
MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs

@@ -36,8 +36,22 @@ namespace MediaBrowser.Server.Implementations.TV
                 ? new string[] { }
                 : new[] { request.ParentId };
 
-            var items = GetAllLibraryItems(user, parentIds, i => i is Series)
-                .Cast<Series>();
+            IEnumerable<Series> items;
+
+            if (parentIds.Length == 0)
+            {
+                items = _libraryManager.GetItems(new InternalItemsQuery(user)
+               {
+                   IncludeItemTypes = new[] { typeof(Series).Name },
+                   SortOrder = SortOrder.Ascending
+
+               }, user).Cast<Series>();
+            }
+            else
+            {
+                items = GetAllLibraryItems(user, parentIds, i => i is Series)
+                   .Cast<Series>();
+            }
 
             // Avoid implicitly captured closure
             var episodes = GetNextUpEpisodes(request, user, items);
@@ -64,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.TV
             return GetResult(episodes, null, request);
         }
 
-        private IEnumerable<BaseItem> GetAllLibraryItems(User user, string[] parentIds, Func<BaseItem,bool> filter)
+        private IEnumerable<BaseItem> GetAllLibraryItems(User user, string[] parentIds, Func<BaseItem, bool> filter)
         {
             if (parentIds.Length > 0)
             {