mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Cache feeds
This commit is contained in:
@@ -27,11 +27,13 @@ namespace Podsync.Controllers
|
||||
|
||||
private readonly ILinkService _linkService;
|
||||
private readonly IFeedService _feedService;
|
||||
private readonly IStorageService _storageService;
|
||||
|
||||
public FeedController(IRssBuilder rssBuilder, ILinkService linkService, IStorageService storageService, IFeedService feedService)
|
||||
public FeedController(IRssBuilder rssBuilder, ILinkService linkService, IStorageService storageService, IFeedService feedService, IStorageService storageService1)
|
||||
{
|
||||
_linkService = linkService;
|
||||
_feedService = feedService;
|
||||
_storageService = storageService1;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
@@ -73,32 +75,41 @@ namespace Podsync.Controllers
|
||||
[ValidateModelState]
|
||||
public async Task<IActionResult> Feed([Required] string feedId)
|
||||
{
|
||||
Feed feed;
|
||||
var serializedFeed = await _storageService.GetCached(Constants.Cache.FeedsPrefix, feedId);
|
||||
|
||||
try
|
||||
if (string.IsNullOrEmpty(serializedFeed))
|
||||
{
|
||||
feed = await _feedService.Get(feedId);
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return NotFound($"ERROR: No feed with id {feedId}");
|
||||
Feed feed;
|
||||
|
||||
try
|
||||
{
|
||||
feed = await _feedService.Get(feedId);
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return NotFound($"ERROR: No feed with id {feedId}");
|
||||
}
|
||||
|
||||
var selfHost = Request.GetBaseUrl();
|
||||
|
||||
// Set atom link to this feed
|
||||
// See https://validator.w3.org/feed/docs/warning/MissingAtomSelfLink.html
|
||||
var selfLink = new Uri(selfHost, Request.Path);
|
||||
feed.Channels.ForEach(x => x.AtomLink = selfLink);
|
||||
|
||||
// No magic here, just make download links to DownloadController.Download
|
||||
feed.Channels.SelectMany(x => x.Items).ForEach(item =>
|
||||
{
|
||||
var ext = Extensions[item.ContentType];
|
||||
item.DownloadLink = new Uri(selfHost, $"download/{feedId}/{item.Id}.{ext}");
|
||||
});
|
||||
|
||||
serializedFeed = feed.ToString();
|
||||
|
||||
await _storageService.Cache(Constants.Cache.FeedsPrefix, feedId, serializedFeed, TimeSpan.FromMinutes(3));
|
||||
}
|
||||
|
||||
var selfHost = Request.GetBaseUrl();
|
||||
|
||||
// Set atom link to this feed
|
||||
// See https://validator.w3.org/feed/docs/warning/MissingAtomSelfLink.html
|
||||
var selfLink = new Uri(selfHost, Request.Path);
|
||||
feed.Channels.ForEach(x => x.AtomLink = selfLink);
|
||||
|
||||
// No magic here, just make download links to DownloadController.Download
|
||||
feed.Channels.SelectMany(x => x.Items).ForEach(item =>
|
||||
{
|
||||
var ext = Extensions[item.ContentType];
|
||||
item.DownloadLink = new Uri(selfHost, $"download/{feedId}/{item.Id}.{ext}");
|
||||
});
|
||||
|
||||
return Content(feed.ToString(), "application/rss+xml; charset=UTF-8");
|
||||
return Content(serializedFeed, "application/rss+xml; charset=UTF-8");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,5 +27,12 @@ namespace Podsync.Services
|
||||
|
||||
public const int UnhandledError = 3;
|
||||
}
|
||||
|
||||
public static class Cache
|
||||
{
|
||||
public const string VideosPrefix = "video_urls";
|
||||
|
||||
public const string FeedsPrefix = "feeds";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ namespace Podsync.Services.Resolver
|
||||
{
|
||||
public abstract class CachedResolver : IResolverService
|
||||
{
|
||||
private const string CachePrefix = "video_urls";
|
||||
|
||||
private readonly TimeSpan UrlExpiration = TimeSpan.FromHours(3);
|
||||
private readonly IStorageService _storageService;
|
||||
|
||||
@@ -23,7 +21,7 @@ namespace Podsync.Services.Resolver
|
||||
var id = videoUrl.GetHashCode().ToString();
|
||||
|
||||
// Check if this video URL was resolved within last 3 hours
|
||||
var value = await _storageService.GetCached(CachePrefix, id);
|
||||
var value = await _storageService.GetCached(Constants.Cache.VideosPrefix, id);
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return new Uri(value);
|
||||
@@ -31,7 +29,7 @@ namespace Podsync.Services.Resolver
|
||||
|
||||
// Resolve and save to cache
|
||||
var uri = await ResolveInternal(videoUrl, format);
|
||||
await _storageService.Cache(CachePrefix, id, uri.ToString(), UrlExpiration);
|
||||
await _storageService.Cache(Constants.Cache.VideosPrefix, id, uri.ToString(), UrlExpiration);
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Podsync.Services;
|
||||
using Podsync.Services.Resolver;
|
||||
using Podsync.Services.Storage;
|
||||
using Xunit;
|
||||
@@ -30,8 +31,8 @@ namespace Podsync.Tests.Services.Resolver
|
||||
var videoUrl = new Uri(url);
|
||||
var downloadUrl = await _resolver.Resolve(videoUrl);
|
||||
|
||||
_storage.Verify(x => x.GetCached("video_urls", videoUrl.GetHashCode().ToString()), Times.Once);
|
||||
_storage.Verify(x => x.Cache("video_urls", videoUrl.GetHashCode().ToString(), It.IsAny<string>(), It.IsAny<TimeSpan>()), Times.Once);
|
||||
_storage.Verify(x => x.GetCached(Constants.Cache.VideosPrefix, videoUrl.GetHashCode().ToString()), Times.Once);
|
||||
_storage.Verify(x => x.Cache(Constants.Cache.VideosPrefix, videoUrl.GetHashCode().ToString(), It.IsAny<string>(), It.IsAny<TimeSpan>()), Times.Once);
|
||||
|
||||
Assert.NotEqual(downloadUrl, videoUrl);
|
||||
Assert.True(downloadUrl.IsAbsoluteUri);
|
||||
|
||||
Reference in New Issue
Block a user