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/
[Ll]og/
[Ll]ogs/
[Dd]ata/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -482,3 +483,7 @@ $RECYCLE.BIN/
# Vim temporary swap files
*.swp
*.sqlite
*.sqlite-shm
*.sqlite-wal

View File

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

View File

@@ -17,6 +17,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="akavache" Version="10.2.41" />
<PackageReference Include="AngleSharp" Version="1.3.0" />
<PackageReference Include="Avalonia" Version="11.2.8" />
<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 Flurl.Http.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -105,6 +107,11 @@ class Program
builder.AddSingleton<NotificationService>();
builder.AddSingleton<SchemaPaneService>();
builder.AddSingleton<HextechDocsPostService>();
builder.AddSingleton<IBlobCache>((_) =>
{
Directory.CreateDirectory("Data");
return new SqlRawPersistentBlobCache("Data/data.sqlite");
});
builder.AddSingleton<IFlurlClientCache>(new FlurlClientCache()
.Add("GithubClient", "https://api.github.com")
.Add("GithubUserContentClient", "https://raw.githubusercontent.com")

View File

@@ -1,41 +1,49 @@
using AngleSharp;
using FastCache;
using Akavache;
using AngleSharp;
using Needlework.Net.Extensions;
using Needlework.Net.Models;
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading.Tasks;
namespace Needlework.Net.Services
{
public class HextechDocsPostService
public class HextechDocsPostService : IEnableLogger
{
private readonly IBrowsingContext _context = BrowsingContext.New(Configuration.Default.WithDefaultLoader());
private readonly IBlobCache _blobCache;
public HextechDocsPostService(IBlobCache blobCache)
{
_blobCache = blobCache;
}
public async Task<List<HextechDocsPost>> GetPostsAsync()
{
if (Cached<List<HextechDocsPost>>.TryGet(nameof(GetPostsAsync), out var cached))
return await _blobCache.GetOrFetchObject("HextechDocsPosts", async () =>
{
return cached;
}
var document = await _context.OpenAsync("https://hextechdocs.dev/tag/lcu/");
var elements = document.QuerySelectorAll("article.post-card");
var posts = new List<HextechDocsPost>();
foreach (var element in elements)
{
var path = element.QuerySelector("a.post-card-content-link")!.GetAttribute("href")!;
var title = element.QuerySelector(".post-card-title")!.TextContent;
var excerpt = element.QuerySelector(".post-card-excerpt > p")!.TextContent;
var post = new HextechDocsPost()
this.Log()
.Debug("Downloading HextechDocs posts...");
var document = await _context.OpenAsync("https://hextechdocs.dev/tag/lcu/");
var elements = document.QuerySelectorAll("article.post-card");
var posts = new List<HextechDocsPost>();
foreach (var element in elements)
{
Path = path,
Title = title,
Excerpt = excerpt,
};
posts.Add(post);
}
return cached.Save(posts, TimeSpan.FromMinutes(60));
var path = element.QuerySelector("a.post-card-content-link")!.GetAttribute("href")!;
var title = element.QuerySelector(".post-card-title")!.TextContent;
var excerpt = element.QuerySelector(".post-card-excerpt > p")!.TextContent;
var post = new HextechDocsPost()
{
Path = path,
Title = title,
Excerpt = excerpt,
};
posts.Add(post);
}
return posts;
}, DateTimeOffset.Now + TimeSpan.FromHours(12));
}
}
}