Explorar el Código

support sending channel paging direct to the provider

Luke Pulverenti hace 11 años
padre
commit
ad3c30c145

+ 2 - 1
MediaBrowser.Controller/Channels/ChannelAudioItem.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using System.Collections.Generic;
@@ -11,7 +12,7 @@ namespace MediaBrowser.Controller.Channels
         public string ExternalId { get; set; }
 
         public string ChannelId { get; set; }
-        
+
         public ChannelItemType ChannelItemType { get; set; }
 
         public bool IsInfiniteStream { get; set; }

+ 1 - 0
MediaBrowser.Controller/Channels/ChannelItemInfo.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;

+ 2 - 0
MediaBrowser.Controller/Channels/ChannelItemResult.cs

@@ -8,5 +8,7 @@ namespace MediaBrowser.Controller.Channels
         public List<ChannelItemInfo> Items { get; set; }
 
         public TimeSpan CacheLength { get; set; }
+
+        public int? TotalRecordCount { get; set; }
     }
 }

+ 2 - 1
MediaBrowser.Controller/Channels/ChannelVideoItem.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using System.Collections.Generic;
@@ -12,7 +13,7 @@ namespace MediaBrowser.Controller.Channels
         public string ExternalId { get; set; }
 
         public string ChannelId { get; set; }
-        
+
         public ChannelItemType ChannelItemType { get; set; }
 
         public bool IsInfiniteStream { get; set; }

+ 1 - 0
MediaBrowser.Controller/Channels/IChannel.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Entities;
 using System.Collections.Generic;
 using System.Threading;

+ 7 - 0
MediaBrowser.Controller/Channels/IChannelManager.cs

@@ -16,6 +16,13 @@ namespace MediaBrowser.Controller.Channels
         /// <param name="factories">The factories.</param>
         void AddParts(IEnumerable<IChannel> channels, IEnumerable<IChannelFactory> factories);
 
+        /// <summary>
+        /// Gets the channel.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <returns>Channel.</returns>
+        Channel GetChannel(string id);
+
         /// <summary>
         /// Gets the channels.
         /// </summary>

+ 1 - 0
MediaBrowser.Controller/Channels/IChannelMediaItem.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using MediaBrowser.Model.Channels;
 
 namespace MediaBrowser.Controller.Channels
 {

+ 4 - 0
MediaBrowser.Controller/Channels/InternalChannelItemQuery.cs

@@ -7,5 +7,9 @@ namespace MediaBrowser.Controller.Channels
         public string CategoryId { get; set; }
 
         public User User { get; set; }
+
+        public int? StartIndex { get; set; }
+
+        public int? Limit { get; set; }
     }
 }

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

@@ -69,13 +69,10 @@
       <Link>Properties\SharedVersion.cs</Link>
     </Compile>
     <Compile Include="Channels\ChannelCategoryItem.cs" />
-    <Compile Include="Channels\ChannelInfo.cs" />
     <Compile Include="Channels\ChannelItemInfo.cs" />
     <Compile Include="Channels\ChannelItemResult.cs" />
     <Compile Include="Channels\ChannelItemType.cs" />
-    <Compile Include="Channels\ChannelMediaContentType.cs" />
     <Compile Include="Channels\ChannelMediaInfo.cs" />
-    <Compile Include="Channels\ChannelMediaType.cs" />
     <Compile Include="Channels\ChannelSearchInfo.cs" />
     <Compile Include="Channels\IChannel.cs" />
     <Compile Include="Channels\IChannelFactory.cs" />

+ 9 - 0
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -77,9 +77,18 @@
     <Compile Include="..\MediaBrowser.Model\ApiClient\SessionUpdatesEventArgs.cs">
       <Link>ApiClient\SessionUpdatesEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelInfo.cs">
+      <Link>Channels\ChannelInfo.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Channels\ChannelItemQuery.cs">
       <Link>Channels\ChannelItemQuery.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelMediaContentType.cs">
+      <Link>Channels\ChannelMediaContentType.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelMediaType.cs">
+      <Link>Channels\ChannelMediaType.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Channels\ChannelQuery.cs">
       <Link>Channels\ChannelQuery.cs</Link>
     </Compile>

+ 9 - 0
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -64,9 +64,18 @@
     <Compile Include="..\MediaBrowser.Model\ApiClient\SessionUpdatesEventArgs.cs">
       <Link>ApiClient\SessionUpdatesEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelInfo.cs">
+      <Link>Channels\ChannelInfo.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Channels\ChannelItemQuery.cs">
       <Link>Channels\ChannelItemQuery.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelMediaContentType.cs">
+      <Link>Channels\ChannelMediaContentType.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Channels\ChannelMediaType.cs">
+      <Link>Channels\ChannelMediaType.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Channels\ChannelQuery.cs">
       <Link>Channels\ChannelQuery.cs</Link>
     </Compile>

+ 6 - 1
MediaBrowser.Controller/Channels/ChannelInfo.cs → MediaBrowser.Model/Channels/ChannelInfo.cs

@@ -1,6 +1,6 @@
 using System.Collections.Generic;
 
-namespace MediaBrowser.Controller.Channels
+namespace MediaBrowser.Model.Channels
 {
     public class ChannelInfo
     {
@@ -20,6 +20,11 @@ namespace MediaBrowser.Controller.Channels
 
         public List<ChannelMediaContentType> ContentTypes { get; set; }
 
+        /// <summary>
+        /// Represents the maximum number of records the channel allows retrieving at a time
+        /// </summary>
+        public int? MaxPageSize { get; set; }
+
         public ChannelInfo()
         {
             MediaTypes = new List<ChannelMediaType>();

+ 1 - 1
MediaBrowser.Controller/Channels/ChannelMediaContentType.cs → MediaBrowser.Model/Channels/ChannelMediaContentType.cs

@@ -1,4 +1,4 @@
-namespace MediaBrowser.Controller.Channels
+namespace MediaBrowser.Model.Channels
 {
     public enum ChannelMediaContentType
     {

+ 1 - 1
MediaBrowser.Controller/Channels/ChannelMediaType.cs → MediaBrowser.Model/Channels/ChannelMediaType.cs

@@ -1,4 +1,4 @@
-namespace MediaBrowser.Controller.Channels
+namespace MediaBrowser.Model.Channels
 {
     public enum ChannelMediaType
     {

+ 2 - 1
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -138,7 +138,8 @@ namespace MediaBrowser.Model.Dto
         /// </summary>
         /// <value>The channel identifier.</value>
         public string ChannelId { get; set; }
-        
+        public string ChannelName { get; set; }
+
         /// <summary>
         /// Gets or sets the overview.
         /// </summary>

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

@@ -59,7 +59,10 @@
     <Compile Include="ApiClient\IServerEvents.cs" />
     <Compile Include="ApiClient\GeneralCommandEventArgs.cs" />
     <Compile Include="ApiClient\SessionUpdatesEventArgs.cs" />
+    <Compile Include="Channels\ChannelInfo.cs" />
     <Compile Include="Channels\ChannelItemQuery.cs" />
+    <Compile Include="Channels\ChannelMediaContentType.cs" />
+    <Compile Include="Channels\ChannelMediaType.cs" />
     <Compile Include="Channels\ChannelQuery.cs" />
     <Compile Include="Chapters\RemoteChapterInfo.cs" />
     <Compile Include="Chapters\RemoteChapterResult.cs" />

+ 80 - 46
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -234,6 +234,11 @@ namespace MediaBrowser.Server.Implementations.Channels
             return item;
         }
 
+        public Channel GetChannel(string id)
+        {
+            return (Channel)_libraryManager.GetItemById(new Guid(id));
+        }
+
         private Guid GetInternalChannelId(string name)
         {
             if (string.IsNullOrWhiteSpace(name))
@@ -246,48 +251,70 @@ namespace MediaBrowser.Server.Implementations.Channels
 
         public async Task<QueryResult<BaseItemDto>> GetChannelItems(ChannelItemQuery query, CancellationToken cancellationToken)
         {
-            var user = string.IsNullOrWhiteSpace(query.UserId)
-                ? null
-                : _userManager.GetUserById(new Guid(query.UserId));
-
             var queryChannelId = query.ChannelId;
-            var channels = string.IsNullOrWhiteSpace(queryChannelId)
-                ? _channelEntities
-                : _channelEntities.Where(i => i.Id == new Guid(queryChannelId));
+            // Get the internal channel entity
+            var channel = _channelEntities.First(i => i.Id == new Guid(queryChannelId));
 
-            var itemTasks = channels.Select(async channel =>
+            // Find the corresponding channel provider plugin
+            var channelProvider = GetChannelProvider(channel);
+
+            var channelInfo = channelProvider.GetChannelInfo();
+
+            int? providerStartIndex = null;
+            int? providerLimit = null;
+
+            if (channelInfo.MaxPageSize.HasValue)
             {
-                var channelProvider = GetChannelProvider(channel);
+                providerStartIndex = query.StartIndex;
+
+                if (!query.Limit.HasValue || query.Limit.Value > channelInfo.MaxPageSize.Value)
+                {
+                    throw new ArgumentException(string.Format("Channel {0} only supports a maximum of {1} records at a time.", channel.Name, channelInfo.MaxPageSize.Value));
+                }
+                providerLimit = query.Limit;
+            }
 
-                var items = await GetChannelItems(channelProvider, user, query.CategoryId, cancellationToken)
-                            .ConfigureAwait(false);
+            var user = string.IsNullOrWhiteSpace(query.UserId)
+                ? null
+                : _userManager.GetUserById(new Guid(query.UserId));
 
-                var channelId = channel.Id.ToString("N");
+            var itemsResult = await GetChannelItems(channelProvider, user, query.CategoryId, providerStartIndex, providerLimit, cancellationToken)
+                        .ConfigureAwait(false);
 
-                var channelPlugin = GetChannelProvider(channel);
+            var providerTotalRecordCount = providerLimit.HasValue ? itemsResult.TotalRecordCount : null;
 
-                var tasks = items.Select(i => GetChannelItemEntity(i, channelPlugin, channelId, cancellationToken));
+            var tasks = itemsResult.Items.Select(i => GetChannelItemEntity(i, channelProvider, channel, cancellationToken));
 
-                return await Task.WhenAll(tasks).ConfigureAwait(false);
-            });
+            var internalItems = await Task.WhenAll(tasks).ConfigureAwait(false);
 
-            var results = await Task.WhenAll(itemTasks).ConfigureAwait(false);
+            if (user != null)
+            {
+                internalItems = internalItems.Where(i => i.IsVisible(user)).ToArray();
 
-            return await GetReturnItems(results.SelectMany(i => i), user, query, cancellationToken).ConfigureAwait(false);
+                if (providerTotalRecordCount.HasValue)
+                {
+                    providerTotalRecordCount = providerTotalRecordCount.Value;
+                }
+            }
+
+            return await GetReturnItems(internalItems, providerTotalRecordCount, user, query, cancellationToken).ConfigureAwait(false);
         }
 
         private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
-        private async Task<IEnumerable<ChannelItemInfo>> GetChannelItems(IChannel channel, User user, string categoryId, CancellationToken cancellationToken)
+        private async Task<ChannelItemResult> GetChannelItems(IChannel channel, User user, string categoryId, int? startIndex, int? limit, CancellationToken cancellationToken)
         {
             var cachePath = GetChannelDataCachePath(channel, user, categoryId);
 
             try
             {
-                var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
-
-                if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+                if (!startIndex.HasValue && !limit.HasValue)
                 {
-                    return channelItemResult.Items;
+                    var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+
+                    if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+                    {
+                        return channelItemResult;
+                    }
                 }
             }
             catch (FileNotFoundException)
@@ -305,11 +332,14 @@ namespace MediaBrowser.Server.Implementations.Channels
             {
                 try
                 {
-                    var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
-
-                    if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+                    if (!startIndex.HasValue && !limit.HasValue)
                     {
-                        return channelItemResult.Items;
+                        var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+
+                        if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+                        {
+                            return channelItemResult;
+                        }
                     }
                 }
                 catch (FileNotFoundException)
@@ -323,7 +353,9 @@ namespace MediaBrowser.Server.Implementations.Channels
 
                 var query = new InternalChannelItemQuery
                 {
-                    User = user
+                    User = user,
+                    StartIndex = startIndex,
+                    Limit = limit
                 };
 
                 if (!string.IsNullOrWhiteSpace(categoryId))
@@ -335,9 +367,12 @@ namespace MediaBrowser.Server.Implementations.Channels
 
                 var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
 
-                CacheResponse(result, cachePath);
+                if (!startIndex.HasValue && !limit.HasValue)
+                {
+                    CacheResponse(result, cachePath);
+                }
 
-                return result.Items;
+                return result;
             }
             finally
             {
@@ -370,22 +405,26 @@ namespace MediaBrowser.Server.Implementations.Channels
             return Path.Combine(_config.ApplicationPaths.CachePath, "channels", channelId, version, categoryKey, user.Id.ToString("N") + ".json");
         }
 
-        private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<BaseItem> items, User user, ChannelItemQuery query, CancellationToken cancellationToken)
+        private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<BaseItem> items, int? totalCountFromProvider, User user, ChannelItemQuery query, CancellationToken cancellationToken)
         {
             items = ApplyFilters(items, query.Filters, user);
 
-            items = _libraryManager.Sort(items, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending);
+            var sortBy = query.SortBy.Length == 0 ? new[] { ItemSortBy.SortName } : query.SortBy;
+            items = _libraryManager.Sort(items, user, sortBy, query.SortOrder ?? SortOrder.Ascending);
 
             var all = items.ToList();
-            var totalCount = all.Count;
+            var totalCount = totalCountFromProvider ?? all.Count;
 
-            if (query.StartIndex.HasValue)
+            if (!totalCountFromProvider.HasValue)
             {
-                all = all.Skip(query.StartIndex.Value).ToList();
-            }
-            if (query.Limit.HasValue)
-            {
-                all = all.Take(query.Limit.Value).ToList();
+                if (query.StartIndex.HasValue)
+                {
+                    all = all.Skip(query.StartIndex.Value).ToList();
+                }
+                if (query.Limit.HasValue)
+                {
+                    all = all.Take(query.Limit.Value).ToList();
+                }
             }
 
             await RefreshIfNeeded(all, cancellationToken).ConfigureAwait(false);
@@ -412,13 +451,8 @@ namespace MediaBrowser.Server.Implementations.Channels
             return externalId + (channelProvider.DataVersion ?? string.Empty) + (channelProvider.Name ?? string.Empty) + "11";
         }
 
-        private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info, IChannel channelProvider, string internalChannnelId, CancellationToken cancellationToken)
+        private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info, IChannel channelProvider, Channel internalChannel, CancellationToken cancellationToken)
         {
-            if (string.IsNullOrEmpty(internalChannnelId))
-            {
-                throw new ArgumentNullException("internalChannnelId");
-            }
-
             BaseItem item;
             Guid id;
             var isNew = false;
@@ -488,7 +522,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             channelItem.OriginalImageUrl = info.ImageUrl;
             channelItem.ExternalId = info.Id;
-            channelItem.ChannelId = internalChannnelId;
+            channelItem.ChannelId = internalChannel.Id.ToString("N");
             channelItem.ChannelItemType = info.Type;
 
             if (isNew)

+ 5 - 4
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -12,14 +12,11 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Session;
 using MoreLinq;
 using System;
 using System.Collections.Generic;
@@ -41,7 +38,9 @@ namespace MediaBrowser.Server.Implementations.Dto
         private readonly IFileSystem _fileSystem;
         private readonly IProviderManager _providerManager;
 
-        public DtoService(ILogger logger, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager)
+        private readonly Func<IChannelManager> _channelManagerFactory;
+
+        public DtoService(ILogger logger, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func<IChannelManager> channelManagerFactory)
         {
             _logger = logger;
             _libraryManager = libraryManager;
@@ -52,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             _config = config;
             _fileSystem = fileSystem;
             _providerManager = providerManager;
+            _channelManagerFactory = channelManagerFactory;
         }
 
         /// <summary>
@@ -1147,6 +1147,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             if (channelItem != null)
             {
                 dto.ChannelId = channelItem.ChannelId;
+                dto.ChannelName = _channelManagerFactory().GetChannel(channelItem.ChannelId).Name;
             }
         }
 

+ 1 - 1
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -493,7 +493,7 @@ namespace MediaBrowser.ServerApplication
             ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder);
             RegisterSingleInstance(ImageProcessor);
 
-            DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager);
+            DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager);
             RegisterSingleInstance(DtoService);
 
             SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, ItemRepository, JsonSerializer, this, HttpClient);

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.371</version>
+        <version>3.0.372</version>
         <title>MediaBrowser.Common.Internal</title>
         <authors>Luke</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.371" />
+            <dependency id="MediaBrowser.Common" version="3.0.372" />
             <dependency id="NLog" version="2.1.0" />
             <dependency id="SimpleInjector" version="2.5.0" />
             <dependency id="sharpcompress" version="0.10.2" />

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common</id>
-        <version>3.0.371</version>
+        <version>3.0.372</version>
         <title>MediaBrowser.Common</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.371</version>
+        <version>3.0.372</version>
         <title>Media Browser.Server.Core</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Media Browser Server.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.371" />
+            <dependency id="MediaBrowser.Common" version="3.0.372" />
         </dependencies>
     </metadata>
     <files>