Beispiel #1
0
        public async Task <QueryResult <BaseItem> > GetChannelItemsInternal(InternalItemsQuery query, IProgress <double> progress, CancellationToken cancellationToken)
        {
            // Get the internal channel entity
            var channel = GetChannel(query.ChannelIds[0]);

            // Find the corresponding channel provider plugin
            var channelProvider = GetChannelProvider(channel);

            var user = query.User;

            ChannelItemSortField?sortField = null;
            var sortDescending             = false;

            var parentItem = query.ParentId.HasValue ? _libraryManager.GetItemById(query.ParentId.Value) : channel;

            var itemsResult = await GetChannelItems(channelProvider,
                                                    user,
                                                    parentItem is Channel?null : parentItem.ExternalId,
                                                    sortField,
                                                    sortDescending,
                                                    cancellationToken)
                              .ConfigureAwait(false);

            // Not needed since there is a parentId
            query.ChannelIds = new string[] { };

            // Not yet sure why this is causing a problem
            query.GroupByPresentationUniqueKey = false;

            //_logger.Debug("GetChannelItemsInternal");

            // null if came from cache
            if (itemsResult != null)
            {
                var internalItems = itemsResult.Items
                                    .Select(i => GetChannelItemEntity(i, channelProvider, channel.Id, parentItem.Id, cancellationToken))
                                    .ToArray();

                var existingIds = _libraryManager.GetItemIds(query);
                var deadIds     = existingIds.Except(internalItems.Select(i => i.Id))
                                  .ToArray();

                foreach (var deadId in deadIds)
                {
                    var deadItem = _libraryManager.GetItemById(deadId);
                    if (deadItem != null)
                    {
                        _libraryManager.DeleteItem(deadItem, new DeleteOptions
                        {
                            DeleteFileLocation         = false,
                            DeleteFromExternalProvider = false
                        }, parentItem, false);
                    }
                }
            }

            return(_libraryManager.GetItemsResult(query));
        }
Beispiel #2
0
        private string GetChannelDataCachePath(IChannel channel,
                                               string userId,
                                               string externalFolderId,
                                               ChannelItemSortField?sortField,
                                               bool sortDescending)
        {
            var channelId = GetInternalChannelId(channel.Name).ToString("N", CultureInfo.InvariantCulture);

            var userCacheKey = string.Empty;

            var hasCacheKey = channel as IHasCacheKey;

            if (hasCacheKey != null)
            {
                userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty;
            }

            var filename = string.IsNullOrEmpty(externalFolderId) ? "root" : externalFolderId.GetMD5().ToString("N", CultureInfo.InvariantCulture);

            filename += userCacheKey;

            var version = ((channel.DataVersion ?? string.Empty) + "2").GetMD5().ToString("N", CultureInfo.InvariantCulture);

            if (sortField.HasValue)
            {
                filename += "-sortField-" + sortField.Value;
            }
            if (sortDescending)
            {
                filename += "-sortDescending";
            }

            filename = filename.GetMD5().ToString("N", CultureInfo.InvariantCulture);

            return(Path.Combine(_config.ApplicationPaths.CachePath,
                                "channels",
                                channelId,
                                version,
                                filename + ".json"));
        }
Beispiel #3
0
        private async Task <ChannelItemResult> GetChannelItems(IChannel channel,
                                                               User user,
                                                               string externalFolderId,
                                                               ChannelItemSortField?sortField,
                                                               bool sortDescending,
                                                               CancellationToken cancellationToken)
        {
            var userId = user == null ? null : user.Id.ToString("N", CultureInfo.InvariantCulture);

            var cacheLength = CacheLength;
            var cachePath   = GetChannelDataCachePath(channel, userId, externalFolderId, sortField, sortDescending);

            try
            {
                if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                {
                    var cachedResult = _jsonSerializer.DeserializeFromFile <ChannelItemResult>(cachePath);
                    if (cachedResult != null)
                    {
                        return(null);
                    }
                }
            }
            catch (FileNotFoundException)
            {
            }
            catch (IOException)
            {
            }

            await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                try
                {
                    if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                    {
                        var cachedResult = _jsonSerializer.DeserializeFromFile <ChannelItemResult>(cachePath);
                        if (cachedResult != null)
                        {
                            return(null);
                        }
                    }
                }
                catch (FileNotFoundException)
                {
                }
                catch (IOException)
                {
                }

                var query = new InternalChannelItemQuery
                {
                    UserId         = user == null ? Guid.Empty : user.Id,
                    SortBy         = sortField,
                    SortDescending = sortDescending,
                    FolderId       = externalFolderId
                };

                query.FolderId = externalFolderId;

                var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);

                if (result == null)
                {
                    throw new InvalidOperationException("Channel returned a null result from GetChannelItems");
                }

                CacheResponse(result, cachePath);

                return(result);
            }
            finally
            {
                _resourcePool.Release();
            }
        }
Beispiel #4
0
        private async Task <ChannelItemResult> GetChannelItems(IChannel channel,
                                                               User user,
                                                               string folderId,
                                                               int?startIndex,
                                                               int?limit,
                                                               ChannelItemSortField?sortField,
                                                               bool sortDescending,
                                                               CancellationToken cancellationToken)
        {
            var userId = user.Id.ToString("N");

            var cacheLength = CacheLength;
            var cachePath   = GetChannelDataCachePath(channel, userId, folderId, sortField, sortDescending);

            try
            {
                if (!startIndex.HasValue && !limit.HasValue)
                {
                    if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                    {
                        return(_jsonSerializer.DeserializeFromFile <ChannelItemResult>(cachePath));
                    }
                }
            }
            catch (FileNotFoundException)
            {
            }
            catch (DirectoryNotFoundException)
            {
            }

            await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                try
                {
                    if (!startIndex.HasValue && !limit.HasValue)
                    {
                        if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow)
                        {
                            return(_jsonSerializer.DeserializeFromFile <ChannelItemResult>(cachePath));
                        }
                    }
                }
                catch (FileNotFoundException)
                {
                }
                catch (DirectoryNotFoundException)
                {
                }

                var query = new InternalChannelItemQuery
                {
                    UserId         = userId,
                    StartIndex     = startIndex,
                    Limit          = limit,
                    SortBy         = sortField,
                    SortDescending = sortDescending
                };

                if (!string.IsNullOrWhiteSpace(folderId))
                {
                    var categoryItem = (IChannelItem)_libraryManager.GetItemById(new Guid(folderId));

                    query.FolderId = categoryItem.ExternalId;
                }

                var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);

                if (!startIndex.HasValue && !limit.HasValue)
                {
                    CacheResponse(result, cachePath);
                }

                return(result);
            }
            finally
            {
                _resourcePool.Release();
            }
        }
Beispiel #5
0
        public async Task <QueryResult <BaseItem> > GetChannelItemsInternal(ChannelItemQuery query, CancellationToken cancellationToken)
        {
            // Get the internal channel entity
            var channel = GetChannel(query.ChannelId);

            // Find the corresponding channel provider plugin
            var channelProvider = GetChannelProvider(channel);

            var channelInfo = channelProvider.GetChannelFeatures();

            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("{0} channel only supports a maximum of {1} records at a time.", channel.Name, channelInfo.MaxPageSize.Value));
                }
                providerLimit = query.Limit;

                // This will cause some providers to fail
                if (providerLimit == 0)
                {
                    providerLimit = 1;
                }
            }

            var user = string.IsNullOrWhiteSpace(query.UserId)
                ? null
                : _userManager.GetUserById(new Guid(query.UserId));

            ChannelItemSortField?sortField = null;
            ChannelItemSortField parsedField;

            if (query.SortBy.Length == 1 &&
                Enum.TryParse(query.SortBy[0], true, out parsedField))
            {
                sortField = parsedField;
            }

            var sortDescending = query.SortOrder.HasValue && query.SortOrder.Value == SortOrder.Descending;

            var itemsResult = await GetChannelItems(channelProvider,
                                                    user,
                                                    query.FolderId,
                                                    providerStartIndex,
                                                    providerLimit,
                                                    sortField,
                                                    sortDescending,
                                                    cancellationToken)
                              .ConfigureAwait(false);

            var providerTotalRecordCount = providerLimit.HasValue ? itemsResult.TotalRecordCount : null;

            var tasks = itemsResult.Items.Select(i => GetChannelItemEntity(i, channelProvider, channel.Id, cancellationToken));

            var internalItems = await Task.WhenAll(tasks).ConfigureAwait(false);

            if (user != null)
            {
                internalItems = internalItems.Where(i => i.IsVisible(user)).ToArray();

                if (providerTotalRecordCount.HasValue)
                {
                    providerTotalRecordCount = providerTotalRecordCount.Value;
                }
            }

            return(await GetReturnItems(internalItems, providerTotalRecordCount, user, query, cancellationToken).ConfigureAwait(false));
        }