mirror of
https://github.com/BlossomiShymae/Needlework.Net.git
synced 2025-12-06 10:10:48 +01:00
feat: use file kv-store for posts
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -1,41 +1,49 @@
|
|||||||
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());
|
||||||
|
|
||||||
|
private readonly IBlobCache _blobCache;
|
||||||
|
|
||||||
|
public HextechDocsPostService(IBlobCache blobCache)
|
||||||
|
{
|
||||||
|
_blobCache = blobCache;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<HextechDocsPost>> GetPostsAsync()
|
public async Task<List<HextechDocsPost>> GetPostsAsync()
|
||||||
{
|
{
|
||||||
if (Cached<List<HextechDocsPost>>.TryGet(nameof(GetPostsAsync), out var cached))
|
return await _blobCache.GetOrFetchObject("HextechDocsPosts", async () =>
|
||||||
{
|
{
|
||||||
return cached;
|
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>();
|
foreach (var element in elements)
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
Path = path,
|
var path = element.QuerySelector("a.post-card-content-link")!.GetAttribute("href")!;
|
||||||
Title = title,
|
var title = element.QuerySelector(".post-card-title")!.TextContent;
|
||||||
Excerpt = excerpt,
|
var excerpt = element.QuerySelector(".post-card-excerpt > p")!.TextContent;
|
||||||
};
|
var post = new HextechDocsPost()
|
||||||
posts.Add(post);
|
{
|
||||||
}
|
Path = path,
|
||||||
|
Title = title,
|
||||||
return cached.Save(posts, TimeSpan.FromMinutes(60));
|
Excerpt = excerpt,
|
||||||
|
};
|
||||||
|
posts.Add(post);
|
||||||
|
}
|
||||||
|
return posts;
|
||||||
|
}, DateTimeOffset.Now + TimeSpan.FromHours(12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user