feat: use file kv-store for posts

This commit is contained in:
estrogen elf
2025-06-18 16:56:51 -05:00
parent 116c798db3
commit 4dc2d74ccf
5 changed files with 55 additions and 25 deletions

5
.gitignore vendored
View File

@@ -34,6 +34,7 @@ bld/
[Oo]bj/ [Oo]bj/
[Ll]og/ [Ll]og/
[Ll]ogs/ [Ll]ogs/
[Dd]ata/
# Visual Studio 2015/2017 cache/options directory # Visual Studio 2015/2017 cache/options directory
.vs/ .vs/
@@ -482,3 +483,7 @@ $RECYCLE.BIN/
# Vim temporary swap files # Vim temporary swap files
*.swp *.swp
*.sqlite
*.sqlite-shm
*.sqlite-wal

View File

@@ -1,3 +1,4 @@
using Akavache;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
@@ -9,6 +10,7 @@ using Needlework.Net.ViewModels.MainWindow;
using Needlework.Net.ViewModels.Pages; using Needlework.Net.ViewModels.Pages;
using Needlework.Net.Views.MainWindow; using Needlework.Net.Views.MainWindow;
using System; using System;
using System.Reactive.Linq;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -59,6 +61,13 @@ public partial class App : Application, IEnableLogger
DataContext = _serviceProvider.GetRequiredService<MainWindowViewModel>() DataContext = _serviceProvider.GetRequiredService<MainWindowViewModel>()
}; };
MainWindow = desktop.MainWindow; MainWindow = desktop.MainWindow;
desktop.ShutdownRequested += (_, _) =>
{
var blobCache = _serviceProvider.GetRequiredService<IBlobCache>();
blobCache.Flush().Wait();
blobCache.Dispose();
};
} }
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();

View File

@@ -17,6 +17,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="akavache" Version="10.2.41" />
<PackageReference Include="AngleSharp" Version="1.3.0" /> <PackageReference Include="AngleSharp" Version="1.3.0" />
<PackageReference Include="Avalonia" Version="11.2.8" /> <PackageReference Include="Avalonia" Version="11.2.8" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.3.0" /> <PackageReference Include="Avalonia.AvaloniaEdit" Version="11.3.0" />

View File

@@ -1,4 +1,6 @@
using Avalonia; using Akavache;
using Akavache.Sqlite3;
using Avalonia;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Flurl.Http.Configuration; using Flurl.Http.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -105,6 +107,11 @@ class Program
builder.AddSingleton<NotificationService>(); builder.AddSingleton<NotificationService>();
builder.AddSingleton<SchemaPaneService>(); builder.AddSingleton<SchemaPaneService>();
builder.AddSingleton<HextechDocsPostService>(); builder.AddSingleton<HextechDocsPostService>();
builder.AddSingleton<IBlobCache>((_) =>
{
Directory.CreateDirectory("Data");
return new SqlRawPersistentBlobCache("Data/data.sqlite");
});
builder.AddSingleton<IFlurlClientCache>(new FlurlClientCache() builder.AddSingleton<IFlurlClientCache>(new FlurlClientCache()
.Add("GithubClient", "https://api.github.com") .Add("GithubClient", "https://api.github.com")
.Add("GithubUserContentClient", "https://raw.githubusercontent.com") .Add("GithubUserContentClient", "https://raw.githubusercontent.com")

View File

@@ -1,23 +1,31 @@
using AngleSharp; using Akavache;
using FastCache; using AngleSharp;
using Needlework.Net.Extensions;
using Needlework.Net.Models; using Needlework.Net.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Needlework.Net.Services namespace Needlework.Net.Services
{ {
public class HextechDocsPostService public class HextechDocsPostService : IEnableLogger
{ {
private readonly IBrowsingContext _context = BrowsingContext.New(Configuration.Default.WithDefaultLoader()); private readonly IBrowsingContext _context = BrowsingContext.New(Configuration.Default.WithDefaultLoader());
public async Task<List<HextechDocsPost>> GetPostsAsync() private readonly IBlobCache _blobCache;
public HextechDocsPostService(IBlobCache blobCache)
{ {
if (Cached<List<HextechDocsPost>>.TryGet(nameof(GetPostsAsync), out var cached)) _blobCache = blobCache;
{
return cached;
} }
public async Task<List<HextechDocsPost>> GetPostsAsync()
{
return await _blobCache.GetOrFetchObject("HextechDocsPosts", async () =>
{
this.Log()
.Debug("Downloading HextechDocs posts...");
var document = await _context.OpenAsync("https://hextechdocs.dev/tag/lcu/"); var document = await _context.OpenAsync("https://hextechdocs.dev/tag/lcu/");
var elements = document.QuerySelectorAll("article.post-card"); var elements = document.QuerySelectorAll("article.post-card");
var posts = new List<HextechDocsPost>(); var posts = new List<HextechDocsPost>();
@@ -34,8 +42,8 @@ namespace Needlework.Net.Services
}; };
posts.Add(post); posts.Add(post);
} }
return posts;
return cached.Save(posts, TimeSpan.FromMinutes(60)); }, DateTimeOffset.Now + TimeSpan.FromHours(12));
} }
} }
} }