From b160f66a3cae52f35d014fa79b0ad295d2b4352c Mon Sep 17 00:00:00 2001 From: dorthl Date: Tue, 1 Aug 2023 15:56:08 +0800 Subject: [PATCH 01/11] sass no-source-map --- src/Blogifier.Admin/assets/package.json | 10 ++++++---- src/Blogifier.Themes.Standard/assets/package.json | 15 ++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Blogifier.Admin/assets/package.json b/src/Blogifier.Admin/assets/package.json index 7ee45c1e1..eb531f8c4 100644 --- a/src/Blogifier.Admin/assets/package.json +++ b/src/Blogifier.Admin/assets/package.json @@ -4,17 +4,19 @@ "version": "1.0.0", "private": true, "scripts": { - "start": "npm run rollup | npm run sass ", + "start": "npm run watch-rollup | npm run watch-sass ", "rtl": "rtlcss dist/admin/css/styles.css css/styles.rtl.css", - "sass": "sass --watch scss:dist/admin/css --style=compressed", - "rollup": "rollup --config -w", + "sass": "sass", + "rollup": "rollup", + "watch-sass": "sass --watch scss:dist/admin/css --style=compressed", + "watch-rollup": "rollup --config -w", "build-sass": "sass scss:dist/admin/css --style=compressed", "build-rollup": "rollup --config", "build": "npm run build-sass && npm run build-rollup", "sass:Debug": "sass scss:dist/admin/css", "rollup:Debug": "rollup --config rollup.config.dev.mjs", "build:Debug": "npm run sass:Debug && npm run rollup:Debug", - "sass:Release": "sass scss:dist/admin/css --style=compressed", + "sass:Release": "sass scss:dist/admin/css --style=compressed --no-source-map", "rollup:Release": "rollup --config rollup.config.mjs", "build:Release": "npm run sass:Release && npm run rollup:Release" }, diff --git a/src/Blogifier.Themes.Standard/assets/package.json b/src/Blogifier.Themes.Standard/assets/package.json index 9b88b298e..03e6f6d3b 100644 --- a/src/Blogifier.Themes.Standard/assets/package.json +++ b/src/Blogifier.Themes.Standard/assets/package.json @@ -5,14 +5,19 @@ "author": "Farzin", "private": true, "scripts": { - "start": "npm run rollup | npm run sass ", - "rtl": "rtlcss dist/css css/styles.rtl.css", - "sass": "sass --watch scss:dist/css --style=compressed", - "rollup": "rollup --config rollup.config.dev.mjs -w", + "start": "npm run watch-rollup | npm run watch-sass ", + "rtl": "rtlcss dist/admin/css/styles.css css/styles.rtl.css", + "sass": "sass", + "rollup": "rollup", + "watch-sass": "sass --watch scss:dist/css --style=compressed", + "watch-rollup": "rollup --config -w", + "build-sass": "sass scss:dist/css --style=compressed", + "build-rollup": "rollup --config", + "build": "npm run build-sass && npm run build-rollup", "sass:Debug": "sass scss:dist/css", "rollup:Debug": "rollup --config rollup.config.dev.mjs", "build:Debug": "npm run sass:Debug && npm run rollup:Debug", - "sass:Release": "sass scss:dist/css --style=compressed", + "sass:Release": "sass scss:dist/css --style=compressed --no-source-map", "rollup:Release": "rollup --config rollup.config.mjs", "build:Release": "npm run sass:Release && npm run rollup:Release" }, From 3436c8f1a1d988e44d93db56e3737448dbb336bd Mon Sep 17 00:00:00 2001 From: dorthl Date: Tue, 1 Aug 2023 16:20:13 +0800 Subject: [PATCH 02/11] _config --- src/Blogifier.Admin/Pages/HomeView.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blogifier.Admin/Pages/HomeView.razor b/src/Blogifier.Admin/Pages/HomeView.razor index d1e9260d4..ae006617e 100644 --- a/src/Blogifier.Admin/Pages/HomeView.razor +++ b/src/Blogifier.Admin/Pages/HomeView.razor @@ -273,7 +273,7 @@ From 8e04bbd0f1a0d96b3a31773e27a9eb8cd36790f2 Mon Sep 17 00:00:00 2001 From: dorthl Date: Tue, 1 Aug 2023 16:32:10 +0800 Subject: [PATCH 03/11] older newer query err --- src/Blogifier/Posts/PostProvider.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Blogifier/Posts/PostProvider.cs b/src/Blogifier/Posts/PostProvider.cs index f82f77259..dbcf32dae 100644 --- a/src/Blogifier/Posts/PostProvider.cs +++ b/src/Blogifier/Posts/PostProvider.cs @@ -57,15 +57,15 @@ public async Task GetAsync(string slug) var olderQuery = _dbContext.Posts .AsNoTracking() - .Where(m => m.State >= PostState.Release && m.PublishedAt < post.PublishedAt) - .OrderByDescending(p => p.PublishedAt); + .Where(m => m.State >= PostState.Release && m.PublishedAt > post.PublishedAt) + .OrderBy(p => p.PublishedAt); var older = await _mapper.ProjectTo(olderQuery).FirstOrDefaultAsync(); var newerQuery = _dbContext.Posts .AsNoTracking() - .Where(m => m.State >= PostState.Release && m.PublishedAt > post.PublishedAt) - .OrderBy(p => p.PublishedAt); + .Where(m => m.State >= PostState.Release && m.PublishedAt < post.PublishedAt) + .OrderByDescending(p => p.PublishedAt); var newer = await _mapper.ProjectTo(newerQuery).FirstOrDefaultAsync(); From 9a2628a849d404c28fdebb532df06ced07248b22 Mon Sep 17 00:00:00 2001 From: dorthl Date: Tue, 1 Aug 2023 17:54:00 +0800 Subject: [PATCH 04/11] file up --- .../Pages/Blogs/EditorView.razor | 19 +++++++++++++++++-- src/Blogifier/Interfaces/PostController.cs | 2 +- src/Blogifier/Posts/PostProvider.cs | 3 ++- src/Blogifier/Program.cs | 2 -- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor index 1764e771e..46818007f 100644 --- a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor @@ -1,4 +1,5 @@ @page "/admin/blogs/editor/{Slug?}" +@using System.Text; @inject HttpClient _httpClient @inject IStringLocalizer _localizer @@ -38,9 +39,23 @@ protected async Task OnSaveAsync(FrontPostEditorDto post) { + var postData = JsonSerializer.Serialize(post); + + var from = new MultipartFormDataContent(); + from.Add(new StringContent(postData, Encoding.UTF8, "application/json"), "post"); + + if (post.Files != null) + { + foreach (var file in post.Files) + { + var fileBytes = await _httpClient.GetByteArrayAsync(file.Url); + from.Add(new ByteArrayContent(fileBytes), file.Url); + } + } + if (post.Id == 0) { - var response = await _httpClient.PostAsJsonAsync($"api/post/add", post); + var response = await _httpClient.PostAsync($"api/post/add", from); if (_toasterService.CheckResponse(response)) { var slug = await response.Content.ReadAsStringAsync(); @@ -49,7 +64,7 @@ } else { - var response = await _httpClient.PutAsJsonAsync($"api/post/update", post); + var response = await _httpClient.PutAsync($"api/post/update", from); _toasterService.CheckResponse(response); } } diff --git a/src/Blogifier/Interfaces/PostController.cs b/src/Blogifier/Interfaces/PostController.cs index b54319f36..0003b75a3 100644 --- a/src/Blogifier/Interfaces/PostController.cs +++ b/src/Blogifier/Interfaces/PostController.cs @@ -46,7 +46,7 @@ public async Task AddPostAsync([FromBody] PostEditorDto post) } [HttpPut("update")] - public async Task UpdateAsync(PostEditorDto post) + public async Task UpdateAsync([FromForm] PostEditorDto post) { var userId = User.FirstUserId(); await _postProvider.UpdateAsync(post, userId); diff --git a/src/Blogifier/Posts/PostProvider.cs b/src/Blogifier/Posts/PostProvider.cs index dbcf32dae..ced037932 100644 --- a/src/Blogifier/Posts/PostProvider.cs +++ b/src/Blogifier/Posts/PostProvider.cs @@ -5,6 +5,7 @@ using Blogifier.Helper; using Blogifier.Shared; using Microsoft.EntityFrameworkCore; +using ReverseMarkdown.Converters; using System; using System.Collections.Generic; using System.Linq; @@ -129,7 +130,7 @@ public async Task> GetAsync(PublishedStatus filter, Pos PublishedStatus.Featured | PublishedStatus.Published => query.Where(p => p.State >= PostState.Release).OrderByDescending(p => p.PublishedAt), PublishedStatus.Drafts => query.Where(p => p.State == PostState.Draft).OrderByDescending(p => p.Id), - _ => query.OrderByDescending(p => p.Id), + _ => query.OrderByDescending(p => p.PublishedAt).ThenByDescending(p => p.CreatedAt), }; return await _mapper.ProjectTo(query).ToListAsync(); diff --git a/src/Blogifier/Program.cs b/src/Blogifier/Program.cs index f035ce239..dc7bc703a 100644 --- a/src/Blogifier/Program.cs +++ b/src/Blogifier/Program.cs @@ -92,8 +92,6 @@ var app = builder.Build(); -app.UseSerilogRequestLogging(); - if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); From bd81b1f6e9e76f76122635e78215de90426a9294 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 15:19:37 +0800 Subject: [PATCH 05/11] fix Post file --- .../Components/EditorComponent.razor | 8 +++--- .../Components/PostEditorComponent.razor | 9 +++---- src/Blogifier.Admin/Dtos/FrontFileDto.cs | 8 ------ .../Dtos/FrontPostEditorDto.cs | 9 ------- .../Pages/Blogs/EditorView.razor | 25 ++++--------------- .../Pages/Pages/EditorView.razor | 4 +-- src/Blogifier.Admin/assets/js/editor.js | 1 - 7 files changed, 14 insertions(+), 50 deletions(-) delete mode 100644 src/Blogifier.Admin/Dtos/FrontFileDto.cs delete mode 100644 src/Blogifier.Admin/Dtos/FrontPostEditorDto.cs diff --git a/src/Blogifier.Admin/Components/EditorComponent.razor b/src/Blogifier.Admin/Components/EditorComponent.razor index 11712c537..0bcc39bd2 100644 --- a/src/Blogifier.Admin/Components/EditorComponent.razor +++ b/src/Blogifier.Admin/Components/EditorComponent.razor @@ -14,7 +14,6 @@ private ValueTask _taskModule; private ElementReference? _textareaReference; private InputFile? _inputFileReference; - private List _frontFiles = new List(); protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -31,8 +30,7 @@ { var module = await _taskModule; var element = _inputFileReference?.Element; - var file = await module.InvokeAsync("writeFrontFile", element); - _frontFiles.Add(file); + await module.InvokeVoidAsync("writeFrontFile", element); } public async ValueTask SetValueAsync(string value) @@ -41,11 +39,11 @@ await module.InvokeVoidAsync("setEditorValue", value); } - public async ValueTask<(string?, List)> GetValueAsync() + public async ValueTask GetValueAsync() { var module = await _taskModule; var content = await module.InvokeAsync("getEditorValue"); - return (content, _frontFiles); + return content; } async ValueTask IAsyncDisposable.DisposeAsync() diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 186123e12..98b7bdcf8 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -78,13 +78,13 @@ @code { - [Parameter] public FrontPostEditorDto Post { get; set; } = default!; - [Parameter] public EventCallback OnSaveCallback { get; set; } + [Parameter] public PostEditorDto Post { get; set; } = default!; + [Parameter] public EventCallback OnSaveCallback { get; set; } [Parameter] public EventCallback OnRemoveCallback { get; set; } private EditorComponent _editorComponent = default!; - public async Task SetPostInfoAsync(FrontPostEditorDto post) + public async Task SetPostInfoAsync(PostEditorDto post) { var headTitle = _localizer["edit"] + " - " + post.Title; await _jsruntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle); @@ -93,7 +93,7 @@ protected async Task SaveCoreAsync(PostState postState) { - var (content, frontFiles) = await _editorComponent.GetValueAsync(); + var content = await _editorComponent.GetValueAsync(); if (string.IsNullOrEmpty(Post.Title) || string.IsNullOrEmpty(content)) { _toaster.Error(_localizer["title-content-required"]); @@ -105,7 +105,6 @@ if (string.IsNullOrEmpty(Post.Cover)) Post.Cover = BlogifierSharedConstant.DefaultCover; if (string.IsNullOrEmpty(Post.Description)) Post.Description = Post.Title; Post.State = postState; - Post.Files = frontFiles; await OnSaveCallback.InvokeAsync(Post); } diff --git a/src/Blogifier.Admin/Dtos/FrontFileDto.cs b/src/Blogifier.Admin/Dtos/FrontFileDto.cs deleted file mode 100644 index 92f815183..000000000 --- a/src/Blogifier.Admin/Dtos/FrontFileDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Blogifier.Admin; - -public class FrontFileDto -{ - public string FileName { get; set; } = default!; - public string Url { get; set; } = default!; - public string Selection { get; set; } = default!; -} diff --git a/src/Blogifier.Admin/Dtos/FrontPostEditorDto.cs b/src/Blogifier.Admin/Dtos/FrontPostEditorDto.cs deleted file mode 100644 index d39264783..000000000 --- a/src/Blogifier.Admin/Dtos/FrontPostEditorDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using Blogifier.Shared; - -namespace Blogifier.Admin; - -public class FrontPostEditorDto : PostEditorDto -{ - public List Files { get; set; } = default!; -} diff --git a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor index 46818007f..b51c328c4 100644 --- a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor @@ -16,7 +16,7 @@ private PostEditorComponent _postEditorComponent = default!; - protected FrontPostEditorDto Post { get; set; } = new FrontPostEditorDto + protected PostEditorDto Post { get; set; } = new PostEditorDto { Title = string.Empty, Description = string.Empty, @@ -26,36 +26,21 @@ Categories = new List(), }; - protected override async Task OnParametersSetAsync() { if (!string.IsNullOrEmpty(Slug)) { - Post = (await _httpClient.GetFromJsonAsync($"api/post/byslug/{Slug}"))!; + Post = (await _httpClient.GetFromJsonAsync($"api/post/byslug/{Slug}"))!; if (Post.Categories == null) Post.Categories = new List(); await _postEditorComponent.SetPostInfoAsync(Post); } } - protected async Task OnSaveAsync(FrontPostEditorDto post) + protected async Task OnSaveAsync(PostEditorDto post) { - var postData = JsonSerializer.Serialize(post); - - var from = new MultipartFormDataContent(); - from.Add(new StringContent(postData, Encoding.UTF8, "application/json"), "post"); - - if (post.Files != null) - { - foreach (var file in post.Files) - { - var fileBytes = await _httpClient.GetByteArrayAsync(file.Url); - from.Add(new ByteArrayContent(fileBytes), file.Url); - } - } - if (post.Id == 0) { - var response = await _httpClient.PostAsync($"api/post/add", from); + var response = await _httpClient.PostAsJsonAsync($"api/post/add", post); if (_toasterService.CheckResponse(response)) { var slug = await response.Content.ReadAsStringAsync(); @@ -64,7 +49,7 @@ } else { - var response = await _httpClient.PutAsync($"api/post/update", from); + var response = await _httpClient.PutAsJsonAsync($"api/post/update", post); _toasterService.CheckResponse(response); } } diff --git a/src/Blogifier.Admin/Pages/Pages/EditorView.razor b/src/Blogifier.Admin/Pages/Pages/EditorView.razor index 38ebc0504..8c68a72fe 100644 --- a/src/Blogifier.Admin/Pages/Pages/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Pages/EditorView.razor @@ -14,7 +14,7 @@ [Parameter] public string? Slug { get; set; } - protected FrontPostEditorDto Post { get; set; } = new FrontPostEditorDto + protected PostEditorDto Post { get; set; } = new PostEditorDto { Title = string.Empty, Description = string.Empty, @@ -28,7 +28,7 @@ { if (!string.IsNullOrEmpty(Slug)) { - Post = (await _httpClient.GetFromJsonAsync($"api/post/byslug/{Slug}"))!; + Post = (await _httpClient.GetFromJsonAsync($"api/post/byslug/{Slug}"))!; if (Post.Categories == null) Post.Categories = new List(); } } diff --git a/src/Blogifier.Admin/assets/js/editor.js b/src/Blogifier.Admin/assets/js/editor.js index f6142e3a9..95dec20a9 100644 --- a/src/Blogifier.Admin/assets/js/editor.js +++ b/src/Blogifier.Admin/assets/js/editor.js @@ -281,5 +281,4 @@ export function writeFrontFile(inputElement) { let codemirror = easymde.codemirror; codemirror.selection; codemirror.replaceSelection(output); - return { fileName, url, selection: output } } From cc76dee8e2224e6010d695035acd5c9c22b8b179 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 16:42:23 +0800 Subject: [PATCH 06/11] GeneratedRegex --- .../Components/EditorComponent.razor | 1 + src/Blogifier.Admin/assets/js/editor.js | 17 ++++++----- src/Blogifier.Admin/assets/package.json | 7 ++--- src/Blogifier.Shared/Helper/StringHelper.cs | 29 ++++++++++++------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/Blogifier.Admin/Components/EditorComponent.razor b/src/Blogifier.Admin/Components/EditorComponent.razor index 0bcc39bd2..e5322afdf 100644 --- a/src/Blogifier.Admin/Components/EditorComponent.razor +++ b/src/Blogifier.Admin/Components/EditorComponent.razor @@ -43,6 +43,7 @@ { var module = await _taskModule; var content = await module.InvokeAsync("getEditorValue"); + Console.WriteLine(content); return content; } diff --git a/src/Blogifier.Admin/assets/js/editor.js b/src/Blogifier.Admin/assets/js/editor.js index 95dec20a9..c71cb2eca 100644 --- a/src/Blogifier.Admin/assets/js/editor.js +++ b/src/Blogifier.Admin/assets/js/editor.js @@ -210,13 +210,6 @@ function editorToolbarTooltip() { let easymde; let _uploadElement; -function toggleSideBySide() { - EasyMDE.toggleSideBySide(easymde); - // Wait for the screen to complete - setTimeout(() => { - hljs.highlightElement(easymde.gui.sideBySide); - }, 1000); -} export function loadEditor(toolbar, textareaElement, uploadElement) { _uploadElement = uploadElement; @@ -240,6 +233,8 @@ export function loadEditor(toolbar, textareaElement, uploadElement) { singleLineBreaks: false, codeSyntaxHighlighting: true }, + // fullScreen: false, + // sideBySideFullscreen: false, toolbar: selectedToolbar, insertTexts: { horizontalRule: ["", "\n---\n"] @@ -254,6 +249,13 @@ export function loadEditor(toolbar, textareaElement, uploadElement) { editorToolbarTooltip(); } + +function toggleSideBySide() { + EasyMDE.toggleSideBySide(easymde); + // Wait for the screen to complete + setTimeout(() => hljs.highlightElement(easymde.gui.sideBySide), 1000); +} + // Image Upload async function insertImage(editor) { _uploadElement.click(); @@ -266,7 +268,6 @@ export function setEditorValue(txt) { .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"')); - } export function getEditorValue() { diff --git a/src/Blogifier.Admin/assets/package.json b/src/Blogifier.Admin/assets/package.json index eb531f8c4..503dee581 100644 --- a/src/Blogifier.Admin/assets/package.json +++ b/src/Blogifier.Admin/assets/package.json @@ -8,11 +8,8 @@ "rtl": "rtlcss dist/admin/css/styles.css css/styles.rtl.css", "sass": "sass", "rollup": "rollup", - "watch-sass": "sass --watch scss:dist/admin/css --style=compressed", - "watch-rollup": "rollup --config -w", - "build-sass": "sass scss:dist/admin/css --style=compressed", - "build-rollup": "rollup --config", - "build": "npm run build-sass && npm run build-rollup", + "watch-sass": "sass --watch scss:dist/admin/css", + "watch-rollup": "rollup -w --config rollup.config.dev.mjs", "sass:Debug": "sass scss:dist/admin/css", "rollup:Debug": "rollup --config rollup.config.dev.mjs", "build:Debug": "npm run sass:Debug && npm run rollup:Debug", diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 3b787815a..345dc1054 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -2,16 +2,23 @@ namespace Blogifier.Helper; -public static class StringHelper +public static partial class StringHelper { - private static Regex _regexScript = new("]*>[\\s\\S]*?", RegexOptions.Compiled); - private static Regex _regexImg = new("]*>[\\s\\S]*?>", RegexOptions.Compiled); - private static Regex _regexImgTags = new("]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.IgnoreCase); - private static Regex _regexImgSrc = new("", RegexOptions.IgnoreCase | RegexOptions.Singleline); - private static Regex _regexFile = new(@"(?i)]*?>(?.*?)", RegexOptions.IgnoreCase | RegexOptions.Singleline); - public static string RemoveScriptTags(string input) => _regexScript.Replace(input, string.Empty); - public static string RemoveImgTags(string input) => _regexImg.Replace(input, string.Empty); - public static MatchCollection MatchesImgTags(string input) => _regexImgTags.Matches(input); - public static Match MatchImgSrc(string input) => _regexImgSrc.Match(input); - public static MatchCollection MatchesFile(string input) => _regexFile.Matches(input); + [GeneratedRegex("]*>[\\s\\S]*?", RegexOptions.Compiled)] + private static partial Regex ScriptGeneratedRegex(); + [GeneratedRegex("]*>[\\s\\S]*?>", RegexOptions.Compiled)] + private static partial Regex ImgGeneratedRegex(); + [GeneratedRegex("]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.IgnoreCase, "zh-CN")] + private static partial Regex ImgTagsGeneratedRegex(); + [GeneratedRegex("", RegexOptions.IgnoreCase | RegexOptions.Singleline, "zh-CN")] + private static partial Regex ImgSrcGeneratedRegex(); + [GeneratedRegex("(?i)]*?>(?.*?)", RegexOptions.IgnoreCase | RegexOptions.Singleline, "zh-CN")] + private static partial Regex FileGeneratedRegex(); + + public static string RemoveScriptTags(string input) => ScriptGeneratedRegex().Replace(input, string.Empty); + public static string RemoveImgTags(string input) => ImgGeneratedRegex().Replace(input, string.Empty); + public static MatchCollection MatchesImgTags(string input) => ImgTagsGeneratedRegex().Matches(input); + public static Match MatchImgSrc(string input) => ImgSrcGeneratedRegex().Match(input); + public static MatchCollection MatchesFile(string input) => FileGeneratedRegex().Matches(input); + } From e1066264842ecf33a557764d0edc0f81e2ac2424 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 16:50:24 +0800 Subject: [PATCH 07/11] rm unnecessary Extensions --- .../Pages/Newsletter/SubscribersView.razor | 4 +- src/Blogifier.Admin/_Imports.razor | 1 - .../Extensions/DateTimeExtensions.cs | 44 ------------------ .../Extensions/StringExtensions.cs | 46 ------------------- 4 files changed, 2 insertions(+), 93 deletions(-) delete mode 100644 src/Blogifier.Shared/Extensions/DateTimeExtensions.cs delete mode 100644 src/Blogifier.Shared/Extensions/StringExtensions.cs diff --git a/src/Blogifier.Admin/Pages/Newsletter/SubscribersView.razor b/src/Blogifier.Admin/Pages/Newsletter/SubscribersView.razor index f6aaf2d99..bad86b5bc 100644 --- a/src/Blogifier.Admin/Pages/Newsletter/SubscribersView.razor +++ b/src/Blogifier.Admin/Pages/Newsletter/SubscribersView.razor @@ -17,8 +17,8 @@ {
  • @{ - string title = $"{item.Email} / {item.Country} / {item.Region} / {item.Ip}"; - string pubDate = item.CreatedAt.ToFriendlyDateTimeString(); + var title = $"{item.Email} / {item.Country} / {item.Region} / {item.Ip}"; + var pubDate = DateTimeHelper.ToFriendlyShortDateString(item.CreatedAt); } @title @pubDate diff --git a/src/Blogifier.Admin/_Imports.razor b/src/Blogifier.Admin/_Imports.razor index f47b8369b..f7552e5f3 100644 --- a/src/Blogifier.Admin/_Imports.razor +++ b/src/Blogifier.Admin/_Imports.razor @@ -20,7 +20,6 @@ @using Blogifier.Admin.Shared @using Blogifier.Admin.Services @using Blogifier.Shared -@using Blogifier.Shared.Extensions @using Blogifier.Shared.Resources @using Blogifier.Helper; @using Blogifier.Identity diff --git a/src/Blogifier.Shared/Extensions/DateTimeExtensions.cs b/src/Blogifier.Shared/Extensions/DateTimeExtensions.cs deleted file mode 100644 index bfaca585c..000000000 --- a/src/Blogifier.Shared/Extensions/DateTimeExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; - -namespace Blogifier.Shared; - -public static class DateTimeExtensions -{ - public static string ToFriendlyDateTimeString(this DateTime Date) - { - return FriendlyDate(Date) + " @ " + Date.ToString("t").ToLower(); - } - - public static string ToFriendlyShortDateString(this DateTime Date) - { - return $"{Date.ToString("MMM dd")}, {Date.Year}"; - } - - public static string ToFriendlyDateString(this DateTime Date) - { - return FriendlyDate(Date); - } - - static string FriendlyDate(DateTime date) - { - string FormattedDate = ""; - if (date.Date == DateTime.Today) - { - FormattedDate = "Today"; - } - else if (date.Date == DateTime.Today.AddDays(-1)) - { - FormattedDate = "Yesterday"; - } - else if (date.Date > DateTime.Today.AddDays(-6)) - { - // *** Show the Day of the week - FormattedDate = date.ToString("dddd").ToString(); - } - else - { - FormattedDate = date.ToString("MMMM dd, yyyy"); - } - return FormattedDate; - } -} diff --git a/src/Blogifier.Shared/Extensions/StringExtensions.cs b/src/Blogifier.Shared/Extensions/StringExtensions.cs deleted file mode 100644 index 2dab69acf..000000000 --- a/src/Blogifier.Shared/Extensions/StringExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Text.RegularExpressions; - -namespace Blogifier.Shared.Extensions; - -public static class StringExtensions -{ - public static string Capitalize(this string str) - { - if (string.IsNullOrEmpty(str)) - return string.Empty; - char[] a = str.ToCharArray(); - a[0] = char.ToUpper(a[0]); - return new string(a); - } - - public static bool Contains(this string source, string toCheck, StringComparison comp) - { - return source.IndexOf(toCheck, comp) >= 0; - } - - public static string SanitizePath(this string str) - { - if (string.IsNullOrWhiteSpace(str)) - return string.Empty; - - str = str.Replace("%2E", ".").Replace("%2F", "/"); - - if (str.Contains("..") || str.Contains("//")) - throw new ApplicationException("Invalid directory path"); - - return str; - } - - public static string RemoveScriptTags(this string str) - { - var scriptRegex = new Regex(@"]*>[\s\S]*?"); - return scriptRegex.Replace(str, ""); - } - - public static string RemoveImgTags(this string str) - { - var scriptRegex = new Regex(@"]*>[\s\S]*?>"); - return scriptRegex.Replace(str, ""); - } -} From 11218bf67446c8f0354710f113de173840459fc1 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 16:55:38 +0800 Subject: [PATCH 08/11] fix StringHelper --- src/Blogifier.Shared/Helper/StringHelper.cs | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 345dc1054..47811d7f7 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -4,21 +4,28 @@ namespace Blogifier.Helper; public static partial class StringHelper { + [GeneratedRegex("]*>[\\s\\S]*?", RegexOptions.Compiled)] private static partial Regex ScriptGeneratedRegex(); + public static string RemoveScriptTags(string input) => ScriptGeneratedRegex().Replace(input, string.Empty); + + [GeneratedRegex("]*>[\\s\\S]*?>", RegexOptions.Compiled)] private static partial Regex ImgGeneratedRegex(); - [GeneratedRegex("]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.IgnoreCase, "zh-CN")] - private static partial Regex ImgTagsGeneratedRegex(); - [GeneratedRegex("", RegexOptions.IgnoreCase | RegexOptions.Singleline, "zh-CN")] + public static string RemoveImgTags(string input) => ImgGeneratedRegex().Replace(input, string.Empty); + + + [GeneratedRegex("", RegexOptions.Compiled)] private static partial Regex ImgSrcGeneratedRegex(); - [GeneratedRegex("(?i)]*?>(?.*?)", RegexOptions.IgnoreCase | RegexOptions.Singleline, "zh-CN")] - private static partial Regex FileGeneratedRegex(); + public static Match MatchImgSrc(string input) => ImgSrcGeneratedRegex().Match(input); - public static string RemoveScriptTags(string input) => ScriptGeneratedRegex().Replace(input, string.Empty); - public static string RemoveImgTags(string input) => ImgGeneratedRegex().Replace(input, string.Empty); + [GeneratedRegex("]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.Compiled)] + private static partial Regex ImgTagsGeneratedRegex(); public static MatchCollection MatchesImgTags(string input) => ImgTagsGeneratedRegex().Matches(input); - public static Match MatchImgSrc(string input) => ImgSrcGeneratedRegex().Match(input); + + + [GeneratedRegex("(?i)]*?>(?.*?)", RegexOptions.Compiled)] + private static partial Regex FileGeneratedRegex(); public static MatchCollection MatchesFile(string input) => FileGeneratedRegex().Matches(input); } From 9057d2c24c65238c3fce292c1c3c72d90f5c0570 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 17:03:23 +0800 Subject: [PATCH 09/11] hard Html --- src/Blogifier.Shared/Helper/StringHelper.cs | 20 ++++++++++---------- src/Blogifier/Posts/PostProvider.cs | 8 ++++---- src/Blogifier/Storages/StorageManager.cs | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 47811d7f7..fc8cb36d7 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -6,26 +6,26 @@ public static partial class StringHelper { [GeneratedRegex("]*>[\\s\\S]*?", RegexOptions.Compiled)] - private static partial Regex ScriptGeneratedRegex(); - public static string RemoveScriptTags(string input) => ScriptGeneratedRegex().Replace(input, string.Empty); + private static partial Regex HtmlScriptGeneratedRegex(); + public static string RemoveHtmlScriptTags(string input) => HtmlScriptGeneratedRegex().Replace(input, string.Empty); [GeneratedRegex("]*>[\\s\\S]*?>", RegexOptions.Compiled)] - private static partial Regex ImgGeneratedRegex(); - public static string RemoveImgTags(string input) => ImgGeneratedRegex().Replace(input, string.Empty); + private static partial Regex HtmlImgGeneratedRegex(); + public static string RemoveHtmlImgTags(string input) => HtmlImgGeneratedRegex().Replace(input, string.Empty); [GeneratedRegex("", RegexOptions.Compiled)] - private static partial Regex ImgSrcGeneratedRegex(); - public static Match MatchImgSrc(string input) => ImgSrcGeneratedRegex().Match(input); + private static partial Regex HtmlImgSrcGeneratedRegex(); + public static Match MatchHtmlImgSrc(string input) => HtmlImgSrcGeneratedRegex().Match(input); [GeneratedRegex("]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.Compiled)] - private static partial Regex ImgTagsGeneratedRegex(); - public static MatchCollection MatchesImgTags(string input) => ImgTagsGeneratedRegex().Matches(input); + private static partial Regex HtmlImgTagsGeneratedRegex(); + public static MatchCollection MatchesHtmlImgTags(string input) => HtmlImgTagsGeneratedRegex().Matches(input); [GeneratedRegex("(?i)]*?>(?.*?)", RegexOptions.Compiled)] - private static partial Regex FileGeneratedRegex(); - public static MatchCollection MatchesFile(string input) => FileGeneratedRegex().Matches(input); + private static partial Regex HtmlFileGeneratedRegex(); + public static MatchCollection MatchesHtmlFile(string input) => HtmlFileGeneratedRegex().Matches(input); } diff --git a/src/Blogifier/Posts/PostProvider.cs b/src/Blogifier/Posts/PostProvider.cs index ced037932..5b5993ac6 100644 --- a/src/Blogifier/Posts/PostProvider.cs +++ b/src/Blogifier/Posts/PostProvider.cs @@ -256,8 +256,8 @@ private async Task AddInternalAsync(PostEditorDto postInput, int userId) { var slug = await GetSlugFromTitle(postInput.Title); var postCategories = await CheckPostCategories(postInput.Categories); - var contentFiltr = StringHelper.RemoveImgTags(StringHelper.RemoveScriptTags(postInput.Content)); - var descriptionFiltr = StringHelper.RemoveImgTags(StringHelper.RemoveScriptTags(postInput.Description)); + var contentFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Content)); + var descriptionFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Description)); var publishedAt = GetPublishedAt(postInput.PublishedAt, postInput.State); var post = new Post { @@ -316,8 +316,8 @@ public async Task UpdateAsync(PostEditorDto postInput, int userId) post.Slug = postInput.Slug!; post.Title = postInput.Title; - var contentFiltr = StringHelper.RemoveImgTags(StringHelper.RemoveScriptTags(postInput.Content)); - var descriptionFiltr = StringHelper.RemoveImgTags(StringHelper.RemoveScriptTags(postInput.Description)); + var contentFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Content)); + var descriptionFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Description)); post.Description = descriptionFiltr; post.Content = contentFiltr; post.Cover = postInput.Cover; diff --git a/src/Blogifier/Storages/StorageManager.cs b/src/Blogifier/Storages/StorageManager.cs index 57a199f28..6ff56c0af 100644 --- a/src/Blogifier/Storages/StorageManager.cs +++ b/src/Blogifier/Storages/StorageManager.cs @@ -103,14 +103,14 @@ public async Task UploadsFoHtmlAsync(DateTime uploadAt, int userid, Uri public async Task UploadImagesFoHtml(DateTime uploadAt, int userid, Uri baseAddress, string content) { - var matches = StringHelper.MatchesImgTags(content); + var matches = StringHelper.MatchesHtmlImgTags(content); if (matches.Any()) { var contentBuilder = new StringBuilder(content); foreach (Match match in matches.Cast()) { var tag = match.Value; - var matchUrl = StringHelper.MatchImgSrc(tag); + var matchUrl = StringHelper.MatchHtmlImgSrc(tag); var urlString = matchUrl.Groups[1].Value; var storage = await UploadAsync(uploadAt, userid, baseAddress, urlString); var uploadTag = $"![{storage.Name}]({storage.Slug})"; @@ -123,7 +123,7 @@ public async Task UploadImagesFoHtml(DateTime uploadAt, int userid, Uri public async Task UploadFilesFoHtml(DateTime uploadAt, int userid, Uri baseAddress, string content) { - var matches = StringHelper.MatchesFile(content); + var matches = StringHelper.MatchesHtmlFile(content); if (matches.Any()) { var contentBuilder = new StringBuilder(content); From dffdce93ebbfca7d6f9956e691d09d474a860b6c Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 18:43:58 +0800 Subject: [PATCH 10/11] file up --- .../Components/EditorComponent.razor | 20 +++++++++++- src/Blogifier.Shared/Helper/StringHelper.cs | 8 +++++ src/Blogifier/Interfaces/PostController.cs | 14 ++++++-- src/Blogifier/Program.cs | 3 ++ src/Blogifier/Storages/IStorageProvider.cs | 1 + .../Storages/StorageLocalProvider.cs | 32 +++++++++++++++++++ src/Blogifier/Storages/StorageManager.cs | 32 ++++++++++++++++++- .../Storages/StorageMinioProvider.cs | 7 ++++ 8 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/Blogifier.Admin/Components/EditorComponent.razor b/src/Blogifier.Admin/Components/EditorComponent.razor index e5322afdf..e9881bf67 100644 --- a/src/Blogifier.Admin/Components/EditorComponent.razor +++ b/src/Blogifier.Admin/Components/EditorComponent.razor @@ -1,6 +1,11 @@ +@using System.Text.RegularExpressions; +@using System.Text; + @implements IAsyncDisposable + @inject IStringLocalizer _localizer @inject IJSRuntime _jsRuntime +@inject HttpClient _httpClient
    @@ -43,7 +48,20 @@ { var module = await _taskModule; var content = await module.InvokeAsync("getEditorValue"); - Console.WriteLine(content); + var imgsMatches = StringHelper.MatchesMarkdownImgBlob(content); + + if (imgsMatches.Count > 0) + { + var contentStringBuilder = new StringBuilder(content); + foreach (Match match in imgsMatches) + { + var imageUrl = match.Groups[1].Value; + var imageBytes = await _httpClient.GetByteArrayAsync(imageUrl); + var base64String = Convert.ToBase64String(imageBytes); + contentStringBuilder.Replace(imageUrl, "data:image/png;base64," + base64String); + } + content = contentStringBuilder.ToString(); + } return content; } diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index fc8cb36d7..57d6bdf39 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -28,4 +28,12 @@ public static partial class StringHelper private static partial Regex HtmlFileGeneratedRegex(); public static MatchCollection MatchesHtmlFile(string input) => HtmlFileGeneratedRegex().Matches(input); + + [GeneratedRegex("!\\[[^\\]]*\\]\\((blob:[^)]+)\\)", RegexOptions.Compiled)] + private static partial Regex MarkdownImgBlobGeneratedRegex(); + public static MatchCollection MatchesMarkdownImgBlob(string input) => MarkdownImgBlobGeneratedRegex().Matches(input); + + + [GeneratedRegex(@"!\[(?[^\]]+)\]\(data:image\/(?.+);base64,(?.+?)\)", RegexOptions.Compiled)] + public static partial Regex MarkdownDataImageBase64BlobGeneratedRegex(); } diff --git a/src/Blogifier/Interfaces/PostController.cs b/src/Blogifier/Interfaces/PostController.cs index 0003b75a3..9478b6da5 100644 --- a/src/Blogifier/Interfaces/PostController.cs +++ b/src/Blogifier/Interfaces/PostController.cs @@ -1,7 +1,9 @@ using Blogifier.Posts; using Blogifier.Shared; +using Blogifier.Storages; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -39,16 +41,24 @@ public async Task GetPostBySlug(string slug) } [HttpPost("add")] - public async Task AddPostAsync([FromBody] PostEditorDto post) + [RequestSizeLimit(128 * 1024 * 1024)] + public async Task AddPostAsync([FromServices] StorageManager storageManager, [FromBody] PostEditorDto post) { var userId = User.FirstUserId(); + var uploadAt = DateTime.UtcNow; + var uploadContent = await storageManager.UploadImagesBase64FoHtml(uploadAt, userId, post.Content); + post.Content = uploadContent; return await _postProvider.AddAsync(post, userId); } [HttpPut("update")] - public async Task UpdateAsync([FromForm] PostEditorDto post) + [RequestSizeLimit(128 * 1024 * 1024)] + public async Task UpdateAsync([FromServices] StorageManager storageManager, [FromBody] PostEditorDto post) { var userId = User.FirstUserId(); + var uploadAt = DateTime.UtcNow; + var uploadContent = await storageManager.UploadImagesBase64FoHtml(uploadAt, userId, post.Content); + post.Content = uploadContent; await _postProvider.UpdateAsync(post, userId); } diff --git a/src/Blogifier/Program.cs b/src/Blogifier/Program.cs index dc7bc703a..4428d7c86 100644 --- a/src/Blogifier/Program.cs +++ b/src/Blogifier/Program.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; @@ -43,6 +44,8 @@ builder.Services.AddStorageStaticFiles(builder.Configuration); +builder.Services.AddSingleton(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/src/Blogifier/Storages/IStorageProvider.cs b/src/Blogifier/Storages/IStorageProvider.cs index 8ef58b909..98053c291 100644 --- a/src/Blogifier/Storages/IStorageProvider.cs +++ b/src/Blogifier/Storages/IStorageProvider.cs @@ -12,4 +12,5 @@ public interface IStorageProvider Task GetCheckStoragAsync(string path); Task GetAsync(string slug, Func callback); Task AddAsync(DateTime uploadAt, int userid, string path, string fileName, Stream stream, string contentType); + Task AddAsync(DateTime uploadAt, int userid, string path, string fileName, byte[] bytes, string contentType); } diff --git a/src/Blogifier/Storages/StorageLocalProvider.cs b/src/Blogifier/Storages/StorageLocalProvider.cs index 9045fb297..abe651309 100644 --- a/src/Blogifier/Storages/StorageLocalProvider.cs +++ b/src/Blogifier/Storages/StorageLocalProvider.cs @@ -79,6 +79,25 @@ public async Task AddAsync(DateTime uploadAt, int userid, string pat return _mapper.Map(storage); } + public async Task AddAsync(DateTime uploadAt, int userid, string path, string fileName, byte[] bytes, string contentType) + { + var storage = new Storage + { + UploadAt = uploadAt, + UserId = userid, + Name = fileName, + Path = path, + Length = bytes.Length, + ContentType = contentType, + Slug = await WriteAsync(path, bytes), + Type = StorageType.Local + }; + await AddAsync(storage); + return _mapper.Map(storage); + } + + + private void Delete(string path) { var storagePath = Path.Combine(_pathLocalRoot, path); @@ -105,4 +124,17 @@ private async Task WriteAsync(string path, Stream stream) return virtualPath; } + + private async Task WriteAsync(string path, byte[] bytes) + { + var storagePath = Path.Combine(_pathLocalRoot, path); + var directoryPath = Path.GetDirectoryName(storagePath)!; + if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); + await File.WriteAllBytesAsync(storagePath, bytes); + var virtualPath = $"{BlogifierConstant.StorageLocalPhysicalRoot}/{path}"; + _logger.LogInformation("file Write: {storagePath} => {virtualPath}", storagePath, virtualPath); + return virtualPath; + } + + } diff --git a/src/Blogifier/Storages/StorageManager.cs b/src/Blogifier/Storages/StorageManager.cs index 6ff56c0af..6487bdc44 100644 --- a/src/Blogifier/Storages/StorageManager.cs +++ b/src/Blogifier/Storages/StorageManager.cs @@ -2,12 +2,14 @@ using Blogifier.Helper; using Blogifier.Shared; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net.Http; using System.Text; @@ -23,16 +25,19 @@ public class StorageManager private readonly IHttpClientFactory _httpClientFactory; private readonly IStorageProvider _storageProvider; private readonly string[]? _fileExtensions; + private readonly IContentTypeProvider _contentTypeProvider; public StorageManager( ILogger logger, IHttpClientFactory httpClientFactory, IStorageProvider storageProvider, - IConfiguration configuration) + IConfiguration configuration, + IContentTypeProvider contentTypeProvider) { _logger = logger; _httpClientFactory = httpClientFactory; _storageProvider = storageProvider; + _contentTypeProvider = contentTypeProvider; var fileExtensionsString = configuration[$"{BlogifierConstant.Key}:FileExtensions"]; if (!string.IsNullOrEmpty(fileExtensionsString)) @@ -144,6 +149,31 @@ public async Task UploadFilesFoHtml(DateTime uploadAt, int userid, Uri b } + public async Task UploadImagesBase64FoHtml(DateTime uploadAt, int userid, string content) + { + var dataImageBase64Matches = StringHelper.MarkdownDataImageBase64BlobGeneratedRegex().Matches(content); + if (dataImageBase64Matches.Count > 0) + { + var contentStringBuilder = new StringBuilder(content); + foreach (Match match in dataImageBase64Matches.Cast()) + { + var fileNameMarkdown = match.Groups["filename"].Value; + var imageType = match.Groups["type"].Value; + var base64Data = match.Groups["data"].Value; + var imageDataBytes = Convert.FromBase64String(base64Data); + var fileName = Guid.NewGuid().ToString() + "." + imageType; + var path = $"{userid}/{uploadAt.Year}{uploadAt.Month}/{fileName}"; + if (!_contentTypeProvider.TryGetContentType(fileName, out var contentType)) + contentType = "text/html"; + var storage = await _storageProvider.AddAsync(uploadAt, userid, path, fileName, imageDataBytes, contentType); + var uploadTag = $"![{fileNameMarkdown}]({storage.Slug})"; + contentStringBuilder.Replace(match.Value, uploadTag); + } + content = contentStringBuilder.ToString(); + } + return content; + } + private bool InvalidFileName(string fileName) { var fileExtensions = _fileExtensions ?? BlogifierConstant.FileExtensions; diff --git a/src/Blogifier/Storages/StorageMinioProvider.cs b/src/Blogifier/Storages/StorageMinioProvider.cs index d975db681..a92dbc9fc 100644 --- a/src/Blogifier/Storages/StorageMinioProvider.cs +++ b/src/Blogifier/Storages/StorageMinioProvider.cs @@ -12,6 +12,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Blogifier.Storages; @@ -89,6 +90,12 @@ public async Task AddAsync(DateTime uploadAt, int userid, string pat return _mapper.Map(storage); } + public Task AddAsync(DateTime uploadAt, int userid, string path, string fileName, byte[] bytes, string contentType) + { + using var stream = new MemoryStream(bytes); + return AddAsync(uploadAt, userid, path, fileName, stream, contentType); + } + private async Task GetObjectAsync(string objectName, Func callback) { var args = new GetObjectArgs().WithBucket(_bucketName).WithObject(objectName).WithCallbackStream(callback); From d5eaeb2e81c37ed2008535c787363b5a880b4753 Mon Sep 17 00:00:00 2001 From: dorthl Date: Wed, 2 Aug 2023 18:46:53 +0800 Subject: [PATCH 11/11] fix err using --- src/Blogifier/Storages/StorageMinioProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Blogifier/Storages/StorageMinioProvider.cs b/src/Blogifier/Storages/StorageMinioProvider.cs index a92dbc9fc..08c5d33a6 100644 --- a/src/Blogifier/Storages/StorageMinioProvider.cs +++ b/src/Blogifier/Storages/StorageMinioProvider.cs @@ -12,7 +12,6 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace Blogifier.Storages;