[optimize] code optimize

This commit is contained in:
acite
2025-09-09 12:11:30 +08:00
parent 99a5e42d99
commit 3e03b13d11
11 changed files with 166 additions and 43 deletions

View File

@@ -10,24 +10,21 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment=""> <list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Abyss/Toolkits/image-creator.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Abyss/Toolkits/image-sum.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Components/Tools/TemporaryDB.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Abyss/Toolkits/update-tags.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Model/Chip.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Abyss/Toolkits/update-video.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Model/Comment.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Model/Task.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Model/TaskCreation.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Abyss/Model/Video.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss.sln.DotSettings.user" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss.sln.DotSettings.user" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss.sln.DotSettings.user" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss.sln.DotSettings.user" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/ImageController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/ImageController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Tools/NaturalStringComparer.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Tools/NaturalStringComparer.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Program.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Model/Bookmark.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Bookmark.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Model/Comic.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Comic.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Properties/launchSettings.json" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Properties/launchSettings.json" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Properties/launchSettings.json" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Properties/launchSettings.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/appsettings.Development.json" beforeDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -43,6 +40,7 @@
<component name="HighlightingSettingsPerFile"> <component name="HighlightingSettingsPerFile">
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/011a191356a243438f987de3ec3d6c6230800/04/8419ff35/ServiceProvider.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/011a191356a243438f987de3ec3d6c6230800/04/8419ff35/ServiceProvider.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/4c/4b962087/Monitor.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/4c/4b962087/Monitor.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/d0/3b166e9e/String.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/5df2accb46d040ccbbbe8331bf4d24b61daa00/df/93debd37/ControllerBase.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/5df2accb46d040ccbbbe8331bf4d24b61daa00/df/93debd37/ControllerBase.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/7598e47d5cdf4107ba88f8220720fdc89000/a6/79d67871/xxHash128.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/7598e47d5cdf4107ba88f8220720fdc89000/a6/79d67871/xxHash128.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" />
@@ -54,9 +52,10 @@
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Tools/TemporaryDB.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/Bookmark.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/Chip.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/Chip.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comic.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comment.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/Comment.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/Task.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/Task.cs" root0="FORCE_HIGHLIGHTING" />
@@ -65,6 +64,7 @@
<setting file="file://$PROJECT_DIR$/Abyss/Model/UserCreating.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/UserCreating.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Model/Video.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Model/Video.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/AbyssCli/Program.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/AbyssCli/Program.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file:///storage/Images/31/summary.json" root0="FORCE_HIGHLIGHTING" />
<setting file="file:///usr/lib/dotnet/sdk/9.0.109/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets" root0="FORCE_HIGHLIGHTING" /> <setting file="file:///usr/lib/dotnet/sdk/9.0.109/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets" root0="FORCE_HIGHLIGHTING" />
</component> </component>
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" /> <component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
@@ -93,17 +93,17 @@
"RunOnceActivity.git.unshallow": "true", "RunOnceActivity.git.unshallow": "true",
"XThreadsFramesViewSplitterKey": "0.30266345", "XThreadsFramesViewSplitterKey": "0.30266345",
"git-widget-placeholder": "dev-task", "git-widget-placeholder": "dev-task",
"last_opened_file_path": "/home/acite/embd/WebProjects/Abyss/.gitignore", "last_opened_file_path": "/storage/Images/31/summary.json",
"node.js.detected.package.eslint": "true", "node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true", "node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)", "node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)", "node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm", "nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.pluginManager", "settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
"vue.rearranger.settings.migration": "true" "vue.rearranger.settings.migration": "true"
} }
}]]></component> }]]></component>
<component name="RunManager" selected=".NET Launch Settings Profile.Abyss: https"> <component name="RunManager" selected="Publish to folder.Publish Abyss to folder">
<configuration name="Publish Abyss to folder x86" type="DotNetFolderPublish" factoryName="Publish to folder"> <configuration name="Publish Abyss to folder x86" type="DotNetFolderPublish" factoryName="Publish to folder">
<riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" ready_to_run="true" self_contained="true" target_folder="/opt/security/https/server" target_framework="net9.0" uuid_high="3690631506471504162" uuid_low="-4858628519588143325"> <riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" ready_to_run="true" self_contained="true" target_folder="/opt/security/https/server" target_framework="net9.0" uuid_high="3690631506471504162" uuid_low="-4858628519588143325">
<runtimes> <runtimes>
@@ -198,7 +198,19 @@
<workItem from="1756145197559" duration="780000" /> <workItem from="1756145197559" duration="780000" />
<workItem from="1756205686118" duration="5398000" /> <workItem from="1756205686118" duration="5398000" />
<workItem from="1756277940361" duration="1097000" /> <workItem from="1756277940361" duration="1097000" />
<workItem from="1756293105406" duration="17059000" /> <workItem from="1756293105406" duration="18336000" />
<workItem from="1756364194123" duration="748000" />
<workItem from="1756553959939" duration="2071000" />
<workItem from="1756611257955" duration="11070000" />
<workItem from="1756693065091" duration="645000" />
<workItem from="1756879449291" duration="630000" />
<workItem from="1756905732385" duration="955000" />
<workItem from="1756953389550" duration="29000" />
<workItem from="1756995048032" duration="3919000" />
<workItem from="1757064153985" duration="1107000" />
<workItem from="1757076719875" duration="601000" />
<workItem from="1757219779961" duration="112000" />
<workItem from="1757386288260" duration="3634000" />
</task> </task>
<servers /> <servers />
</component> </component>
@@ -218,7 +230,7 @@
<entry key="branch"> <entry key="branch">
<value> <value>
<list> <list>
<option value="main" /> <option value="dev-task" />
</list> </list>
</value> </value>
</entry> </entry>
@@ -248,19 +260,6 @@
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" /> <properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
<option name="timeStamp" value="3" /> <option name="timeStamp" value="3" />
</breakpoint> </breakpoint>
<line-breakpoint enabled="true" type="DotNet Breakpoints">
<url>file://$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs</url>
<line>60</line>
<properties documentPath="$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" containingFunctionPresentation="Method 'CreateVideoTask'">
<startOffsets>
<option value="2099" />
</startOffsets>
<endOffsets>
<option value="2163" />
</endOffsets>
</properties>
<option name="timeStamp" value="13" />
</line-breakpoint>
</breakpoints> </breakpoints>
</breakpoint-manager> </breakpoint-manager>
</component> </component>

View File

@@ -3,4 +3,5 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKey_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff09ccaeb94c34c2299acd3efee0facee1a400_003F81_003F137b58b4_003FKey_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKey_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff09ccaeb94c34c2299acd3efee0facee1a400_003F81_003F137b58b4_003FKey_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003F4c_003F4b962087_003FMonitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003F4c_003F4b962087_003FMonitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceProvider_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F011a191356a243438f987de3ec3d6c6230800_003F04_003F8419ff35_003FServiceProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceProvider_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F011a191356a243438f987de3ec3d6c6230800_003F04_003F8419ff35_003FServiceProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003Fd0_003F3b166e9e_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AxxHash128_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7598e47d5cdf4107ba88f8220720fdc89000_003Fa6_003F79d67871_003FxxHash128_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AxxHash128_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7598e47d5cdf4107ba88f8220720fdc89000_003Fa6_003F79d67871_003FxxHash128_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@@ -1,6 +1,9 @@
using Abyss.Components.Services; using Abyss.Components.Services;
using Abyss.Components.Static; using Abyss.Components.Static;
using Abyss.Components.Tools;
using Abyss.Model;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace Abyss.Components.Controllers.Media; namespace Abyss.Components.Controllers.Media;
@@ -28,7 +31,7 @@ public class ImageController(ILogger<ImageController> logger, ResourceService rs
if(r == null) if(r == null)
return StatusCode(401, new { message = "Unauthorized" }); return StatusCode(401, new { message = "Unauthorized" });
return Ok(r); return Ok(r.NaturalSort(x => x));
} }
[HttpGet("{id}")] [HttpGet("{id}")]
@@ -42,6 +45,27 @@ public class ImageController(ILogger<ImageController> logger, ResourceService rs
return Ok(await System.IO.File.ReadAllTextAsync(d)); return Ok(await System.IO.File.ReadAllTextAsync(d));
} }
[HttpPost("{id}/bookmark")]
public async Task<IActionResult> Bookmark(string id, string token, [FromBody] Bookmark bookmark)
{
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
if (d == null) return StatusCode(403, new { message = "403 Denied" });
var r = await rs.Update(d, token, Ip);
if (!r) return StatusCode(403, new { message = "403 Denied" });
Comic c = JsonConvert.DeserializeObject<Comic>(await System.IO.File.ReadAllTextAsync(d))!;
var bookmarkPage = Helpers.SafePathCombine(ImageFolder, [id, bookmark.Page]);
if(!System.IO.File.Exists(bookmarkPage))
return BadRequest();
c.Bookmarks.Add(bookmark);
var o = JsonConvert.SerializeObject(c);
await System.IO.File.WriteAllTextAsync(d, o);
return Ok();
}
[HttpGet("{id}/{file}")] [HttpGet("{id}/{file}")]
public async Task<IActionResult> Get(string id, string file, string token) public async Task<IActionResult> Get(string id, string file, string token)

View File

@@ -1,7 +1,10 @@
using System.Diagnostics; using System.Diagnostics;
using Abyss.Components.Services; using Abyss.Components.Services;
using Abyss.Components.Static; using Abyss.Components.Static;
using Abyss.Components.Tools;
using Abyss.Model;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace Abyss.Components.Controllers.Media; namespace Abyss.Components.Controllers.Media;
@@ -38,10 +41,24 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
var d = Helpers.SafePathCombine(VideoFolder, klass); var d = Helpers.SafePathCombine(VideoFolder, klass);
if (d == null) return StatusCode(403, new { message = "403 Denied" }); if (d == null) return StatusCode(403, new { message = "403 Denied" });
var r = await rs.Query(d, token, Ip); var r = await rs.Query(d, token, Ip);
if (r == null) return StatusCode(401, new { message = "Unauthorized" }); if (r == null) return StatusCode(401, new { message = "Unauthorized" });
var rv = r.Select(x =>
{
return Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"]);
}).ToArray();
for (int i = 0; i < rv.Length; i++)
{
if(rv[i] == null) continue;
rv[i] = await System.IO.File.ReadAllTextAsync(rv[i] ?? "");
}
var sv = rv.Where(x => x!=null).Select(x => x ?? "")
.Select(x => JsonConvert.DeserializeObject<Video>(x)).ToArray();
return Ok(r); return Ok(sv.Zip(r, (x, y) => (x, y)).NaturalSort(x => x.x.name).Select(x => x.y).ToArray());
} }
[HttpGet("{klass}/{id}")] [HttpGet("{klass}/{id}")]

View File

@@ -3,6 +3,7 @@ namespace Abyss.Components.Services;
public class ConfigureService public class ConfigureService
{ {
public string MediaRoot { get; set; } = Environment.GetEnvironmentVariable("MEDIA_ROOT") ?? "/opt"; public string MediaRoot { get; set; } = Environment.GetEnvironmentVariable("MEDIA_ROOT") ?? "/opt";
public string DebugMode { get; set; } = Environment.GetEnvironmentVariable("DEBUG_MODE") ?? "Production";
public string Version { get; } = "Alpha v0.1"; public string Version { get; } = "Alpha v0.1";
public string UserDatabase { get; set; } = "user.db"; public string UserDatabase { get; set; } = "user.db";
public string RaDatabase { get; set; } = "ra.db"; public string RaDatabase { get; set; } = "ra.db";

View File

@@ -27,7 +27,7 @@ public class ResourceService
private readonly SQLiteAsyncConnection _database; private readonly SQLiteAsyncConnection _database;
private static readonly Regex PermissionRegex = private static readonly Regex PermissionRegex =
new Regex(@"^([r-][w-]),([r-][w-]),([r-][w-])$", RegexOptions.Compiled); new(@"^([r-][w-]),([r-][w-]),([r-][w-])$", RegexOptions.Compiled);
public ResourceService(ILogger<ResourceService> logger, ConfigureService config, IMemoryCache cache, public ResourceService(ILogger<ResourceService> logger, ConfigureService config, IMemoryCache cache,
UserService user) UserService user)
@@ -47,7 +47,7 @@ public class ResourceService
} }
// Create UID only for resources, without considering advanced hash security such as adding salt // Create UID only for resources, without considering advanced hash security such as adding salt
private string Uid(string path) private static string Uid(string path)
{ {
var b = Encoding.UTF8.GetBytes(path); var b = Encoding.UTF8.GetBytes(path);
var r = XxHash128.Hash(b, 0x11451419); var r = XxHash128.Hash(b, 0x11451419);
@@ -169,8 +169,16 @@ public class ResourceService
return await Valid(path, token, OperationType.Read, ip); return await Valid(path, token, OperationType.Read, ip);
} }
public async Task<bool> Update(string path, string token, string ip)
{
return await Valid(path, token, OperationType.Write, ip);
}
public async Task<bool> Initialize(string path, string token, string username, string ip) public async Task<bool> Initialize(string path, string token, string username, string ip)
{ {
// TODO: Use a more elegant Debug mode
if (_config.DebugMode == "Debug")
goto debug;
// 1. Authorization: Verify the operation is performed by 'root' // 1. Authorization: Verify the operation is performed by 'root'
var requester = _user.Validate(token, ip); var requester = _user.Validate(token, ip);
if (requester != "root") if (requester != "root")
@@ -178,7 +186,7 @@ public class ResourceService
_logger.LogWarning($"Permission denied: Non-root user '{requester ?? "unknown"}' attempted to initialize resources."); _logger.LogWarning($"Permission denied: Non-root user '{requester ?? "unknown"}' attempted to initialize resources.");
return false; return false;
} }
debug:
// 2. Validation: Ensure the target path and owner are valid // 2. Validation: Ensure the target path and owner are valid
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {

View File

@@ -28,7 +28,9 @@ public class UserService
_database.CreateTableAsync<User>().Wait(); _database.CreateTableAsync<User>().Wait();
var rootUser = _database.Table<User>().Where(x => x.Name == "root").FirstOrDefaultAsync().Result; var rootUser = _database.Table<User>().Where(x => x.Name == "root").FirstOrDefaultAsync().Result;
_cache.Set("acite", $"acite@127.0.0.1", DateTimeOffset.Now.AddDays(1)); if (_config.DebugMode == "Debug")
_cache.Set("root", $"root@127.0.0.1", DateTimeOffset.Now.AddHours(1));
// Test token, can only be used locally. Will be destroyed in one hour.
if (rootUser == null) if (rootUser == null)
{ {

View File

@@ -1,6 +1,60 @@
namespace Abyss.Components.Tools; namespace Abyss.Components.Tools;
public class TemporaryDB public static class NaturalSortExtensions
{ {
public static IOrderedEnumerable<T> NaturalSort<T>(this IEnumerable<T> source, Func<T, string> keySelector)
{
return source.OrderBy(keySelector, new NaturalStringComparer());
}
}
public class NaturalStringComparer : IComparer<string>
{
public int Compare(string? a, string? b)
{
if (a == null && b == null) return 0;
if (a == null) return -1;
if (b == null) return 1;
int aIndex = 0;
int bIndex = 0;
while (aIndex < a.Length && bIndex < b.Length)
{
if (char.IsDigit(a[aIndex]) && char.IsDigit(b[bIndex]))
{
long aNum = 0;
long bNum = 0;
while (aIndex < a.Length && char.IsDigit(a[aIndex]))
{
aNum = aNum * 10 + (a[aIndex] - '0');
aIndex++;
}
while (bIndex < b.Length && char.IsDigit(b[bIndex]))
{
bNum = bNum * 10 + (b[bIndex] - '0');
bIndex++;
}
if (aNum != bNum)
{
return aNum.CompareTo(bNum);
}
}
else
{
int charCompare = a[aIndex].CompareTo(b[bIndex]);
if (charCompare != 0)
{
return charCompare;
}
aIndex++;
bIndex++;
}
}
return a.Length.CompareTo(b.Length);
}
} }

View File

@@ -1,6 +1,11 @@
using Newtonsoft.Json;
namespace Abyss.Model; namespace Abyss.Model;
public class Bookmark public class Bookmark
{ {
[JsonProperty("page")]
public string Page { get; set; } = "";
[JsonProperty("name")]
public string Name { get; set; } = "";
} }

View File

@@ -1,6 +1,17 @@
using Newtonsoft.Json;
namespace Abyss.Model; namespace Abyss.Model;
public class Comic public class Comic
{ {
[JsonProperty("comic_name")]
public string ComicName { get; set; } = "";
[JsonProperty("page_count")]
public int PageCount { get; set; }
[JsonProperty("bookmarks")]
public List<Bookmark> Bookmarks { get; set; } = new();
[JsonProperty("author")]
public string Author { get; set; } = "";
[JsonProperty("list")]
public List<string> List { get; set; } = new();
} }

View File

@@ -18,7 +18,8 @@
"applicationUrl": "https://localhost:7013;http://localhost:5198", "applicationUrl": "https://localhost:7013;http://localhost:5198",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"MEDIA_ROOT" : "/storage" "MEDIA_ROOT" : "/storage",
"DEBUG_MODE" : "Debug"
} }
} }
} }