@ -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 items = await GetChannelItems ( channelProvider , user , query . CategoryId , cancellationToken )
var channelInfo = channelProvider . GetChannelInfo ( ) ;
int? providerStartIndex = null ;
int? providerLimit = null ;
if ( channelInfo . MaxPageSize . HasValue )
{
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 user = string . IsNullOrWhiteSpace ( query . UserId )
? null
: _userManager . GetUserById ( new Guid ( query . UserId ) ) ;
var itemsResult = await GetChannelItems ( channelProvider , user , query . CategoryId , providerStartIndex , providerLimit , cancellationToken )
. ConfigureAwait ( false ) ;
var channelId = channel . Id . ToString ( "N" ) ;
var providerTotalRecordCount = providerLimit . HasValue ? itemsResult . TotalRecordCount : null ;
var channelPlugin = GetChannelProvider ( channel ) ;
var tasks = itemsResult . Items . Select ( i = > GetChannelItemEntity ( i , channelProvider , channel , cancellationToken ) ) ;
var tasks = items . Select ( i = > GetChannelItemEntity ( i , channelPlugin , channelId , cancellationToken ) ) ;
var internalItems = await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
return await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
} ) ;
if ( user ! = null )
{
internalItems = internalItems . Where ( i = > i . IsVisible ( user ) ) . ToArray ( ) ;
var results = await Task . WhenAll ( itemTasks ) . ConfigureAwait ( false ) ;
if ( providerTotalRecordCount . HasValue )
{
providerTotalRecordCount = providerTotalRecordCount . Value ;
}
}
return await GetReturnItems ( results . SelectMany ( i = > i ) , user , query , cancellationToken ) . ConfigureAwait ( false ) ;
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
{
if ( ! startIndex . HasValue & & ! limit . HasValue )
{
var channelItemResult = _jsonSerializer . DeserializeFromFile < ChannelItemResult > ( cachePath ) ;
if ( _fileSystem . GetLastWriteTimeUtc ( cachePath ) . Add ( channelItemResult . CacheLength ) > DateTime . UtcNow )
{
return channelItemResult . Items ;
return channelItemResult ;
}
}
}
catch ( FileNotFoundException )
@ -304,12 +331,15 @@ namespace MediaBrowser.Server.Implementations.Channels
try
{
try
{
if ( ! startIndex . HasValue & & ! limit . HasValue )
{
var channelItemResult = _jsonSerializer . DeserializeFromFile < ChannelItemResult > ( cachePath ) ;
if ( _fileSystem . GetLastWriteTimeUtc ( cachePath ) . Add ( channelItemResult . CacheLength ) > DateTime . UtcNow )
{
return channelItemResult . Items ;
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 ) ;
if ( ! startIndex . HasValue & & ! limit . HasValue )
{
CacheResponse ( result , cachePath ) ;
}
return result .Items ;
return result ;
}
finally
{
@ -370,15 +405,18 @@ 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 ( ! totalCountFromProvider . HasValue )
{
if ( query . StartIndex . HasValue )
{
all = all . Skip ( query . StartIndex . Value ) . ToList ( ) ;
@ -387,6 +425,7 @@ namespace MediaBrowser.Server.Implementations.Channels
{
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 )
{
if ( string . IsNullOrEmpty ( internalChannnelId ) )
private async Task < BaseItem > GetChannelItemEntity ( ChannelItemInfo info , IChannel channelProvider , Channel internalChannel , CancellationToken cancellationToken )
{
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 = internalChann n elId;
channelItem . ChannelId = internalChann el. Id. ToString ( "N" ) ;
channelItem . ChannelItemType = info . Type ;
if ( isNew )