refact: move projects into src directory.
Signed-off-by: jackfiled <xcrenchangjun@outlook.com>
This commit is contained in:
@@ -12,7 +12,7 @@ indent_style = space
|
|||||||
indent_size = 4
|
indent_size = 4
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[project.json]
|
[{project.json,appsettings.json,appsettings.*.json}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.{yaml,yml}]
|
[*.{yaml,yml}]
|
||||||
|
|||||||
12
YaeBlog.slnx
12
YaeBlog.slnx
@@ -7,9 +7,17 @@
|
|||||||
<File Path=".editorconfig" />
|
<File Path=".editorconfig" />
|
||||||
<File Path=".gitattributes" />
|
<File Path=".gitattributes" />
|
||||||
<File Path=".gitignore" />
|
<File Path=".gitignore" />
|
||||||
|
<File Path="build.ps1" />
|
||||||
<File Path="LICENSE" />
|
<File Path="LICENSE" />
|
||||||
<File Path="README.md" />
|
<File Path="README.md" />
|
||||||
</Folder>
|
</Folder>
|
||||||
<Project Path="YaeBlog.Tests/YaeBlog.Tests.csproj" />
|
<Folder Name="/src/">
|
||||||
<Project Path="YaeBlog/YaeBlog.csproj" />
|
<Project Path="src/YaeBlog.Tests/YaeBlog.Tests.csproj" />
|
||||||
|
<Project Path="src/YaeBlog/YaeBlog.csproj" />
|
||||||
|
</Folder>
|
||||||
|
<Folder Name="/third-party/" />
|
||||||
|
<Folder Name="/third-party/BlazorSvgComponents/" />
|
||||||
|
<Folder Name="/third-party/BlazorSvgComponents/src/">
|
||||||
|
<Project Path="third-party/BlazorSvgComponents/src/BlazorSvgComponents/BlazorSvgComponents.csproj" />
|
||||||
|
</Folder>
|
||||||
</Solution>
|
</Solution>
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
using Markdig;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
using YamlDotNet.Serialization.NamingConventions;
|
|
||||||
|
|
||||||
namespace YaeBlog.Extensions;
|
|
||||||
|
|
||||||
public static class ServiceCollectionExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection AddMarkdig(this IServiceCollection collection)
|
|
||||||
{
|
|
||||||
MarkdownPipelineBuilder builder = new();
|
|
||||||
|
|
||||||
builder.UseAdvancedExtensions();
|
|
||||||
|
|
||||||
collection.AddSingleton<MarkdownPipeline>(_ => builder.Build());
|
|
||||||
|
|
||||||
return collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddYamlParser(this IServiceCollection collection)
|
|
||||||
{
|
|
||||||
DeserializerBuilder deserializerBuilder = new();
|
|
||||||
deserializerBuilder.WithNamingConvention(CamelCaseNamingConvention.Instance);
|
|
||||||
deserializerBuilder.IgnoreUnmatchedProperties();
|
|
||||||
collection.AddSingleton(deserializerBuilder.Build());
|
|
||||||
|
|
||||||
SerializerBuilder serializerBuilder = new();
|
|
||||||
serializerBuilder.WithNamingConvention(CamelCaseNamingConvention.Instance);
|
|
||||||
collection.AddSingleton(serializerBuilder.Build());
|
|
||||||
|
|
||||||
return collection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
using AngleSharp;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using YaeBlog.Abstraction;
|
|
||||||
using YaeBlog.Services;
|
|
||||||
using YaeBlog.Models;
|
|
||||||
using YaeBlog.Processors;
|
|
||||||
|
|
||||||
namespace YaeBlog.Extensions;
|
|
||||||
|
|
||||||
public static class WebApplicationBuilderExtensions
|
|
||||||
{
|
|
||||||
public static WebApplicationBuilder AddYaeBlog(this WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.Configure<BlogOptions>(builder.Configuration.GetSection(BlogOptions.OptionName));
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient();
|
|
||||||
|
|
||||||
builder.Services.AddMarkdig();
|
|
||||||
builder.Services.AddYamlParser();
|
|
||||||
builder.Services.AddSingleton<AngleSharp.IConfiguration>(_ => Configuration.Default);
|
|
||||||
builder.Services.AddSingleton<IEssayScanService, EssayScanService>();
|
|
||||||
builder.Services.AddSingleton<RendererService>();
|
|
||||||
builder.Services.AddSingleton<IEssayContentService, EssayContentService>();
|
|
||||||
builder.Services.AddTransient<ImagePostRenderProcessor>();
|
|
||||||
builder.Services.AddTransient<HeadlinePostRenderProcessor>();
|
|
||||||
builder.Services.AddTransient<EssayStylesPostRenderProcessor>();
|
|
||||||
builder.Services.AddTransient<BlogOptions>(provider =>
|
|
||||||
provider.GetRequiredService<IOptions<BlogOptions>>().Value);
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WebApplicationBuilder AddServer(this WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.AddHostedService<BlogHostedService>();
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WebApplicationBuilder AddWatcher(this WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.AddTransient<BlogChangeWatcher>();
|
|
||||||
builder.Services.AddHostedService<BlogHotReloadService>();
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
namespace YaeBlog.Models;
|
|
||||||
|
|
||||||
public class BlogEssay : IComparable<BlogEssay>
|
|
||||||
{
|
|
||||||
public required string Title { get; init; }
|
|
||||||
|
|
||||||
public required string FileName { get; init; }
|
|
||||||
|
|
||||||
public required bool IsDraft { get; init; }
|
|
||||||
|
|
||||||
public required DateTimeOffset PublishTime { get; init; }
|
|
||||||
|
|
||||||
public required DateTimeOffset UpdateTime { get; init; }
|
|
||||||
|
|
||||||
public required string Description { get; init; }
|
|
||||||
|
|
||||||
public required uint WordCount { get; init; }
|
|
||||||
|
|
||||||
public required string ReadTime { get; init; }
|
|
||||||
|
|
||||||
public List<string> Tags { get; } = [];
|
|
||||||
|
|
||||||
public required string HtmlContent { get; init; }
|
|
||||||
|
|
||||||
public string EssayLink => $"/blog/essays/{FileName}";
|
|
||||||
|
|
||||||
public BlogEssay WithNewHtmlContent(string newHtmlContent)
|
|
||||||
{
|
|
||||||
var essay = new BlogEssay
|
|
||||||
{
|
|
||||||
Title = Title,
|
|
||||||
FileName = FileName,
|
|
||||||
IsDraft = IsDraft,
|
|
||||||
PublishTime = PublishTime,
|
|
||||||
UpdateTime = UpdateTime,
|
|
||||||
Description = Description,
|
|
||||||
WordCount = WordCount,
|
|
||||||
ReadTime = ReadTime,
|
|
||||||
HtmlContent = newHtmlContent
|
|
||||||
};
|
|
||||||
essay.Tags.AddRange(Tags);
|
|
||||||
|
|
||||||
return essay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CompareTo(BlogEssay? other)
|
|
||||||
{
|
|
||||||
if (other is null)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 草稿文章应当排在前面
|
|
||||||
if (IsDraft != other.IsDraft)
|
|
||||||
{
|
|
||||||
return IsDraft ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return other.PublishTime.CompareTo(PublishTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{Title}-{PublishTime}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
namespace YaeBlog.Models;
|
|
||||||
|
|
||||||
public class BlogOptions
|
|
||||||
{
|
|
||||||
public const string OptionName = "Blog";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 博客markdown文件的根目录
|
|
||||||
/// </summary>
|
|
||||||
public required string Root { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 博客正文的广而告之
|
|
||||||
/// </summary>
|
|
||||||
public required string Announcement { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 博客的起始年份
|
|
||||||
/// </summary>
|
|
||||||
public required int StartYear { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 博客的友链
|
|
||||||
/// </summary>
|
|
||||||
public required List<FriendLink> Links { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
namespace YaeBlog.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 友链模型类
|
|
||||||
/// </summary>
|
|
||||||
public class FriendLink
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 友链名称
|
|
||||||
/// </summary>
|
|
||||||
public required string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 友链的简单介绍
|
|
||||||
/// </summary>
|
|
||||||
public required string Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 友链地址
|
|
||||||
/// </summary>
|
|
||||||
public required string Link { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 头像地址
|
|
||||||
/// </summary>
|
|
||||||
public required string AvatarImage { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowedHosts": "*",
|
|
||||||
"Tailwind": {
|
|
||||||
"InputFile": "wwwroot/input.css",
|
|
||||||
"OutputFile": "wwwroot/output.css"
|
|
||||||
},
|
|
||||||
"Blog": {
|
|
||||||
"Root": "source",
|
|
||||||
"Announcement": "博客锐意装修中,敬请期待!测试阶段如有问题还请海涵。",
|
|
||||||
"StartYear": 2021,
|
|
||||||
"Links": [
|
|
||||||
{
|
|
||||||
"Name": "Ichirinko",
|
|
||||||
"Description": "这是个大哥",
|
|
||||||
"Link": "https://ichirinko.top",
|
|
||||||
"AvatarImage": "https://ichirinko-blog-img-1.oss-cn-shenzhen.aliyuncs.com/Pic_res/img/202209122110798.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "不会写程序的晨旭",
|
|
||||||
"Description": "一个普通大学生",
|
|
||||||
"Link": "https://chenxutalk.top",
|
|
||||||
"AvatarImage": "https://www.chenxutalk.top/img/photo.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "万木长风",
|
|
||||||
"Description": "世界渲染中...",
|
|
||||||
"Link": "https://ryohai.fun",
|
|
||||||
"AvatarImage": "https://ryohai.fun/static/favicons/favicon-32x32.png"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,14 +3,32 @@
|
|||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true, Position = 0, HelpMessage = "Specify the build target")]
|
[Parameter(Mandatory = $true, Position = 0, HelpMessage = "Specify the build target")]
|
||||||
[ValidateSet("tailwind", "publish", "compress", "build", "dev", "new")]
|
[ValidateSet("tailwind", "publish", "compress", "build", "dev", "new", "watch", "serve", "list")]
|
||||||
[string]$Target,
|
[string]$Target,
|
||||||
[string]$Output = "wwwroot",
|
[string]$Output = "wwwroot",
|
||||||
[string]$Essay,
|
[string]$Essay,
|
||||||
[switch]$Compress
|
[switch]$Compress,
|
||||||
|
[string]$Root = "source"
|
||||||
)
|
)
|
||||||
|
|
||||||
begin {
|
begin {
|
||||||
|
if ($Target -eq "tailwind")
|
||||||
|
{
|
||||||
|
# Handle tailwind specially.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set the content root.
|
||||||
|
$fullRootPath = Join-Path $(Get-Location) $Root
|
||||||
|
if (-not (Test-Path $fullRootPath))
|
||||||
|
{
|
||||||
|
Write-Error "Content root $fullRootPath not existed."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Use content from" $fullRootPath
|
||||||
|
$env:BLOG__ROOT=$fullRootPath
|
||||||
|
|
||||||
Write-Host "Building $Target..."
|
Write-Host "Building $Target..."
|
||||||
|
|
||||||
if ($Target -eq "publish")
|
if ($Target -eq "publish")
|
||||||
@@ -30,6 +48,9 @@ begin {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set to the current location.
|
||||||
|
Push-Location src/YaeBlog
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
@@ -87,6 +108,7 @@ process {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch ($Target)
|
switch ($Target)
|
||||||
{
|
{
|
||||||
"tailwind" {
|
"tailwind" {
|
||||||
@@ -119,6 +141,21 @@ process {
|
|||||||
"new" {
|
"new" {
|
||||||
dotnet run -- new $Essay
|
dotnet run -- new $Essay
|
||||||
}
|
}
|
||||||
|
"watch" {
|
||||||
|
dotnet run -- watch
|
||||||
|
break
|
||||||
|
}
|
||||||
|
"serve" {
|
||||||
|
dotnet run -- serve
|
||||||
|
break
|
||||||
|
}
|
||||||
|
"list" {
|
||||||
|
dotnet run -- list
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user