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)); }
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")); }
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(); } }
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(); } }
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)); }