[optimize] Phase 1 Architecture Review
This commit is contained in:
2
.idea/.idea.Abyss/.idea/sqldialects.xml
generated
2
.idea/.idea.Abyss/.idea/sqldialects.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/Abyss/Components/Services/ResourceDatabaseService.cs" dialect="GenericSQL" />
|
||||
<file url="file://$PROJECT_DIR$/Abyss/Components/Services/Media/ResourceDatabaseService.cs" dialect="GenericSQL" />
|
||||
</component>
|
||||
</project>
|
||||
132
.idea/.idea.Abyss/.idea/workspace.xml
generated
132
.idea/.idea.Abyss/.idea/workspace.xml
generated
@@ -9,7 +9,43 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<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/Services/Media/ComicService.cs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Abyss/Components/Services/Media/VideoService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/sqldialects.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/sqldialects.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/Components/Controllers/AbyssController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/AbyssController.cs" 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/LiveController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.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/Security/RootController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/RootController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Security/AbyssService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Misc/ConfigureService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/IndexService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Media/IndexService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ResourceDatabaseService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Media/ResourceDatabaseService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Media/ResourceService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Media/TaskService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/Security/UserService.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Static/ControllerExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Static/ControllerExtensions.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Components/Tools/AbyssStream.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Tools/AbyssStream.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Misc/StringClusterer.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Misc/StringClusterer.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Bookmark.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Bookmark.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Security/ChallengeResponse.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Chip.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Chip.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Comic.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Comic.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Comment.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Comment.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Index.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Index.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/ResourceAttribute.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Task.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Task.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/TaskCreation.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/TaskCreation.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/User.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Security/User.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/UserCreating.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Security/UserCreating.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Model/Video.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Media/Video.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Abyss/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Program.cs" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
@@ -41,36 +77,32 @@
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Security/RootController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/IndexService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/ResourceDatabaseService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/ResourceService.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/Media/ComicService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Media/IndexService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Media/ResourceDatabaseService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Media/ResourceService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Media/TaskService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Media/VideoService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Misc/ConfigureService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Security/AbyssService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/Security/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/Tools/AbyssStream.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Tools/HttpHelper.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Tools/HttpReader.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Misc/StringClusterer.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/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/Index.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/TaskCreation.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/User.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="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="mock:///home/acite/AciteProjects/Abyss/Abyss/Program.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Bookmark.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Chip.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Comic.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Comment.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Index.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/ResourceAttribute.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Task.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/TaskCreation.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Video.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/User.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/UserCreating.cs" 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 name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
||||
@@ -85,30 +117,30 @@
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
".NET Launch Settings Profile.Abyss: http.executor": "Debug",
|
||||
".NET Launch Settings Profile.Abyss: https.executor": "Debug",
|
||||
".NET Project.AbyssCli.executor": "Run",
|
||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"Publish to folder.Publish Abyss to folder x86.executor": "Run",
|
||||
"Publish to folder.Publish Abyss to folder.executor": "Run",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"XThreadsFramesViewSplitterKey": "0.55813956",
|
||||
"git-widget-placeholder": "main",
|
||||
"last_opened_file_path": "/home/acite/embd/WebProjects/Abyss/README.md",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
".NET Launch Settings Profile.Abyss: http.executor": "Run",
|
||||
".NET Launch Settings Profile.Abyss: https.executor": "Debug",
|
||||
".NET Project.AbyssCli.executor": "Run",
|
||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"Publish to folder.Publish Abyss to folder x86.executor": "Run",
|
||||
"Publish to folder.Publish Abyss to folder.executor": "Run",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"XThreadsFramesViewSplitterKey": "0.55813956",
|
||||
"git-widget-placeholder": "main",
|
||||
"last_opened_file_path": "/home/acite/embd/WebProjects/Abyss/README.md",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
}]]></component>
|
||||
<component name="RunManager" selected="Publish to folder.Publish Abyss 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">
|
||||
@@ -246,6 +278,8 @@
|
||||
<workItem from="1758814543368" duration="642000" />
|
||||
<workItem from="1758815224532" duration="430000" />
|
||||
<workItem from="1758905391249" duration="128000" />
|
||||
<workItem from="1758906781361" duration="252000" />
|
||||
<workItem from="1759036019712" duration="20077000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAsyncTableQuery_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F61fe11e9d86b4d2a9bd2b806929b7d381a400_003Fa1_003F62750ee4_003FAsyncTableQuery_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConfiguredValueTaskAwaitable_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003F25_003F817def70_003FConfiguredValueTaskAwaitable_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControllerBase_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5df2accb46d040ccbbbe8331bf4d24b61daa00_003Fdf_003F93debd37_003FControllerBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControllerBase_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5df2accb46d040ccbbbe8331bf4d24b61daa00_003Fdf_003F93debd37_003FControllerBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003Faf_003Faac0eaa5_003FExceptionDispatchInfo_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>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
|
||||
@@ -1,100 +1,56 @@
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Components.Tools;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Media;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Abyss.Components.Controllers.Media;
|
||||
using System.IO;
|
||||
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ImageController(ResourceService rs, ConfigureService config) : BaseController
|
||||
public class ImageController(ComicService comicService) : BaseController
|
||||
{
|
||||
public readonly string ImageFolder = Path.Combine(config.MediaRoot, "Images");
|
||||
|
||||
[HttpPost("init")]
|
||||
public async Task<IActionResult> InitAsync(string token, string owner)
|
||||
{
|
||||
var r = await rs.Initialize(ImageFolder, token, owner, Ip);
|
||||
if(r) return Ok(r);
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
var r = await comicService.InitAsync(token, owner, Ip);
|
||||
return r ? Ok("Initialize Success") : _403;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> QueryCollections(string token)
|
||||
{
|
||||
var r = await rs.Query(ImageFolder, token, Ip);
|
||||
|
||||
if(r == null)
|
||||
return StatusCode(401, new { message = "Unauthorized" });
|
||||
|
||||
return Ok(r.NaturalSort(x => x));
|
||||
var r = await comicService.QueryCollections(token, Ip);
|
||||
return r != null ? Ok(r.NaturalSort(x => x)) : _403;
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> Query(string id, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Get(d, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
return Ok(await System.IO.File.ReadAllTextAsync(d));
|
||||
var r = await comicService.Query(id, token, Ip);
|
||||
return r != null ? Ok(r) : _403;
|
||||
}
|
||||
|
||||
[HttpPost("bulkquery")]
|
||||
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id)
|
||||
{
|
||||
var db = id.Select(x => Helpers.SafePathCombine(ImageFolder, [x, "summary.json"])).ToArray();
|
||||
if (db.Any(x => x == null))
|
||||
return BadRequest();
|
||||
|
||||
if(!await rs.GetAll(db!, token, Ip))
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var rc = db.Select(x => System.IO.File.ReadAllTextAsync(x!)).ToArray();
|
||||
string[] rcs = await Task.WhenAll(rc);
|
||||
var rjs = rcs.Select(JsonConvert.DeserializeObject<Comic>).Select(x => x!).ToArray();
|
||||
|
||||
return Ok(JsonConvert.SerializeObject(rjs));
|
||||
var r = await comicService.QueryBulk(token, id, Ip);
|
||||
return Ok(JsonConvert.SerializeObject(r));
|
||||
}
|
||||
|
||||
[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();
|
||||
var r = await comicService.Bookmark(id, token, bookmark, Ip);
|
||||
return r ? Ok("Success") : _403;
|
||||
}
|
||||
|
||||
[HttpGet("{id}/{file}")]
|
||||
public async Task<IActionResult> Get(string id, string file, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(ImageFolder, [id, file]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Get(d, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
||||
var r = await comicService.Page(id, file, token, Ip);
|
||||
return r ?? _403;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Static;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@@ -14,11 +16,11 @@ public class LiveController(ResourceService rs, ConfigureService config): BaseCo
|
||||
public async Task<IActionResult> AddLive(string id, string token, int owner)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(LiveFolder, [id]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
if (d == null) return _403;
|
||||
|
||||
bool r = await rs.Include(d, token, Ip, owner, "rw,--,--");
|
||||
|
||||
return r ? Ok("Success") : BadRequest();
|
||||
return r ? Ok("Success") : _400;
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
@@ -26,31 +28,25 @@ public class LiveController(ResourceService rs, ConfigureService config): BaseCo
|
||||
{
|
||||
var d = Helpers.SafePathCombine(LiveFolder, [id]);
|
||||
if (d == null)
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
return _403;
|
||||
|
||||
bool r = await rs.Exclude(d, token, Ip);
|
||||
|
||||
return r ? Ok("Success") : BadRequest();
|
||||
return r ? Ok("Success") : _400;
|
||||
}
|
||||
|
||||
[HttpGet("{id}/{token}/{item}")]
|
||||
public async Task<IActionResult> GetLive(string id, string token, string item)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(LiveFolder, [id, item]);
|
||||
var f = Helpers.SafePathCombine(LiveFolder, [id]);
|
||||
if (d == null || f == null) return BadRequest();
|
||||
if (d == null) return _400;
|
||||
|
||||
// TODO: (History)ffplay does not add the m3u8 query parameter in ts requests, so special treatment is given to ts here
|
||||
// TODO: (History)It should be pointed out that this implementation is not secure and should be modified in subsequent updates
|
||||
|
||||
// TODO: It's still not very elegant, but it's a bit better to some extent
|
||||
|
||||
bool r = await rs.Valid(f, token, OperationType.Read, Ip);
|
||||
if(!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
if(System.IO.File.Exists(d))
|
||||
return PhysicalFile(d, Helpers.GetContentType(d));
|
||||
else
|
||||
return NotFound();
|
||||
var r = await rs.Get(d, token, Ip, Helpers.GetContentType(d));
|
||||
return r ?? _404;
|
||||
}
|
||||
}
|
||||
@@ -1,218 +1,79 @@
|
||||
using Abyss.Components.Services;
|
||||
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Components.Tools;
|
||||
using Abyss.Model;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss.Components.Controllers.Media;
|
||||
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class VideoController(ILogger<VideoController> logger, ResourceService rs, ConfigureService config)
|
||||
public class VideoController(VideoService videoService)
|
||||
: BaseController
|
||||
{
|
||||
private ILogger<VideoController> _logger = logger;
|
||||
public readonly string VideoFolder = Path.Combine(config.MediaRoot, "Videos");
|
||||
|
||||
|
||||
[HttpPost("init")]
|
||||
public async Task<IActionResult> InitAsync(string token, string owner)
|
||||
{
|
||||
var r = await rs.Initialize(VideoFolder, token, owner, Ip);
|
||||
if (r) return Ok(r);
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
if (await videoService.Init(token, owner, Ip))
|
||||
return Ok("Initialized Successfully");
|
||||
return _403;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetClass(string token)
|
||||
{
|
||||
var r = (await rs.Query(VideoFolder, token, Ip))?.SortLikeWindows();
|
||||
|
||||
if (r == null)
|
||||
return StatusCode(401, new { message = "Unauthorized" });
|
||||
|
||||
return Ok(r);
|
||||
var r = await videoService.GetClasses(token, Ip);
|
||||
return r != null ? Ok(r) : _403;
|
||||
}
|
||||
|
||||
[HttpGet("{klass}")]
|
||||
public async Task<IActionResult> QueryClass(string klass, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, klass);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Query(d, token, Ip);
|
||||
if (r == null) return StatusCode(401, new { message = "Unauthorized" });
|
||||
|
||||
return Ok(r);
|
||||
var r = await videoService.QueryClass(klass, token, Ip);
|
||||
return r != null ? Ok(r) : _403;
|
||||
}
|
||||
|
||||
[HttpGet("{klass}/{id}")]
|
||||
public async Task<IActionResult> QueryVideo(string klass, string id, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "summary.json"]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Get(d, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
return Ok(await System.IO.File.ReadAllTextAsync(d));
|
||||
var r = await videoService.QueryVideo(klass, id, token, Ip);
|
||||
return r != null ? Ok(r) : _403;
|
||||
}
|
||||
|
||||
[HttpPost("{klass}/bulkquery")]
|
||||
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id,
|
||||
[FromRoute] string klass)
|
||||
{
|
||||
var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray();
|
||||
if (db.Any(x => x == null))
|
||||
return BadRequest();
|
||||
|
||||
if (!await rs.GetAll(db!, token, Ip))
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var rc = db.Select(x => System.IO.File.ReadAllTextAsync(x!)).ToArray();
|
||||
string[] rcs = await Task.WhenAll(rc);
|
||||
var rjs = rcs.Select(JsonConvert.DeserializeObject<Video>).Select(x => x!).ToList();
|
||||
|
||||
return Ok(JsonConvert.SerializeObject(rjs));
|
||||
var r = await videoService.QueryBulk(klass, id, token, Ip);
|
||||
return Ok(JsonConvert.SerializeObject(r));
|
||||
}
|
||||
|
||||
[HttpGet("{klass}/{id}/cover")]
|
||||
public async Task<IActionResult> Cover(string klass, string id, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "cover.jpg"]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Get(d, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
||||
var r = await videoService.Cover(klass, id, token, Ip);
|
||||
return r ?? _403;
|
||||
}
|
||||
|
||||
[HttpGet("{klass}/{id}/gallery/{pic}")]
|
||||
public async Task<IActionResult> Gallery(string klass, string id, string pic, string token)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "gallery", pic]);
|
||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var r = await rs.Get(d, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
||||
var r = await videoService.Gallery(klass, id, pic, token, Ip);
|
||||
return r ?? _403;
|
||||
}
|
||||
|
||||
[HttpGet("{klass}/{id}/subtitle")]
|
||||
public async Task<IActionResult> Subtitle(string klass, string id, string token)
|
||||
{
|
||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
||||
if (folder == null)
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
string? subtitlePath = null;
|
||||
|
||||
try
|
||||
{
|
||||
var preferredVtt = Path.Combine(folder, "subtitle.vtt");
|
||||
if (System.IO.File.Exists(preferredVtt))
|
||||
{
|
||||
subtitlePath = preferredVtt;
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitlePath = Directory.EnumerateFiles(folder, "*.vtt").FirstOrDefault();
|
||||
|
||||
if (subtitlePath == null)
|
||||
{
|
||||
var preferredAss = Path.Combine(folder, "subtitle.ass");
|
||||
if (System.IO.File.Exists(preferredAss))
|
||||
{
|
||||
subtitlePath = preferredAss;
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitlePath = Directory.EnumerateFiles(folder, "*.ass").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return NotFound(new { message = "video folder not found" });
|
||||
}
|
||||
|
||||
if (subtitlePath == null)
|
||||
return NotFound(new { message = "subtitle not found" });
|
||||
|
||||
var r = await rs.Get(subtitlePath, token, Ip);
|
||||
if (!r)
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var ext = Path.GetExtension(subtitlePath).ToLowerInvariant();
|
||||
var contentType = ext switch
|
||||
{
|
||||
".vtt" => "text/vtt",
|
||||
".ass" => "text/x-ssa",
|
||||
_ => "text/plain"
|
||||
};
|
||||
|
||||
return PhysicalFile(subtitlePath, contentType, enableRangeProcessing: false);
|
||||
var r = await videoService.Subtitle(klass, id, token, Ip);
|
||||
return r ?? _404;
|
||||
}
|
||||
|
||||
[HttpGet("{klass}/{id}/av")]
|
||||
public async Task<IActionResult> Av(string klass, string id, string token)
|
||||
{
|
||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
||||
if (folder == null) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var allowedExt = new[] { ".mp4", ".mkv", ".webm", ".mov", ".ogg" };
|
||||
|
||||
string? videoPath = null;
|
||||
|
||||
foreach (var ext in allowedExt)
|
||||
{
|
||||
var p = Path.Combine(folder, "video" + ext);
|
||||
if (System.IO.File.Exists(p))
|
||||
{
|
||||
videoPath = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (videoPath == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
videoPath = Directory.EnumerateFiles(folder)
|
||||
.FirstOrDefault(f => allowedExt.Contains(Path.GetExtension(f).ToLowerInvariant()));
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return NotFound(new { message = "video folder not found" });
|
||||
}
|
||||
}
|
||||
|
||||
if (videoPath == null) return NotFound(new { message = "video not found" });
|
||||
|
||||
var r = await rs.Get(videoPath, token, Ip);
|
||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
||||
|
||||
var provider = new FileExtensionContentTypeProvider();
|
||||
if (!provider.TryGetContentType(videoPath, out var contentType))
|
||||
{
|
||||
var ext = Path.GetExtension(videoPath).ToLowerInvariant();
|
||||
contentType = ext switch
|
||||
{
|
||||
".mkv" => "video/x-matroska",
|
||||
".mp4" => "video/mp4",
|
||||
".webm" => "video/webm",
|
||||
".mov" => "video/quicktime",
|
||||
".ogg" => "video/ogg",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
}
|
||||
|
||||
return PhysicalFile(videoPath, contentType, enableRangeProcessing: true);
|
||||
var r = await videoService.Av(klass, id, token, Ip);
|
||||
return r ?? _403;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Text;
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Services.Security;
|
||||
using Abyss.Components.Static;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@@ -18,12 +20,12 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
if (userService.Validate(token, Ip) != 1)
|
||||
{
|
||||
logger.LogInformation("Chmod authorization failed for token: {Token}", token);
|
||||
return StatusCode(401, "Unauthorized");
|
||||
return _401;
|
||||
}
|
||||
|
||||
bool r = await resourceService.Chmod(path, token, permission, Ip, recursive == "true");
|
||||
logger.LogInformation("Chmod operation completed with result: {Result}", r);
|
||||
return r ? Ok() : StatusCode(502);
|
||||
return r ? Ok() : StatusCode(500);
|
||||
}
|
||||
|
||||
[HttpPost("chown")]
|
||||
@@ -34,7 +36,7 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
if (userService.Validate(token, Ip) != 1)
|
||||
{
|
||||
logger.LogInformation("Chown authorization failed for token: {Token}", token);
|
||||
return StatusCode(401, "Unauthorized");
|
||||
return _401;
|
||||
}
|
||||
|
||||
bool r = await resourceService.Chown(path, token, owner, Ip, recursive == "true");
|
||||
@@ -50,13 +52,13 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
if (userService.Validate(token, Ip) != 1)
|
||||
{
|
||||
logger.LogInformation("Ls authorization failed for token: {Token}", token);
|
||||
return StatusCode(401, "Unauthorized");
|
||||
return _401;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
logger.LogInformation("Ls method received empty path parameter");
|
||||
return BadRequest("path is required");
|
||||
return _400;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -67,10 +69,10 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
if (!Directory.Exists(fullPath))
|
||||
{
|
||||
logger.LogInformation("Directory does not exist: {FullPath}", fullPath);
|
||||
return BadRequest("Path does not exist or is not a directory");
|
||||
return _400;
|
||||
}
|
||||
|
||||
var entries = Directory.EnumerateFileSystemEntries(fullPath, "*", SearchOption.TopDirectoryOnly);
|
||||
var entries = Directory.EnumerateFileSystemEntries(fullPath, "*", SearchOption.TopDirectoryOnly).ToArray();
|
||||
logger.LogInformation("Found {Count} entries in directory", entries.Count());
|
||||
|
||||
var sb = new StringBuilder();
|
||||
@@ -115,12 +117,12 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
if (userService.Validate(token, Ip) != 1)
|
||||
{
|
||||
logger.LogInformation("Init authorization failed for token: {Token}", token);
|
||||
return StatusCode(401, "Unauthorized");
|
||||
return _401;
|
||||
}
|
||||
|
||||
var r = await resourceService.Initialize(path, token, owner, Ip);
|
||||
if (r) return Ok(r);
|
||||
return StatusCode(403, new { message = "403 Denied" });
|
||||
return _403;
|
||||
}
|
||||
|
||||
private static string ConvertToLsPerms(string permRaw, bool isDirectory)
|
||||
@@ -135,7 +137,7 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
return (isDirectory ? 'd' : '-') + "---------";
|
||||
}
|
||||
|
||||
string makeTriplet(string token)
|
||||
string MakeTriplet(string token)
|
||||
{
|
||||
if (token.Length < 2) token = "--";
|
||||
var r = token.Length > 0 && token[0] == 'r' ? 'r' : '-';
|
||||
@@ -144,9 +146,9 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
||||
return $"{r}{w}{x}";
|
||||
}
|
||||
|
||||
var owner = makeTriplet(parts[0]);
|
||||
var group = makeTriplet(parts[1]);
|
||||
var other = makeTriplet(parts[2]);
|
||||
var owner = MakeTriplet(parts[0]);
|
||||
var group = MakeTriplet(parts[1]);
|
||||
var other = MakeTriplet(parts[2]);
|
||||
|
||||
return (isDirectory ? 'd' : '-') + owner + group + other;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Security;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Security;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
|
||||
@@ -19,7 +21,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
{
|
||||
var c = await userService.Challenge(user);
|
||||
if (c == null)
|
||||
return StatusCode(403, new { message = "Access forbidden" });
|
||||
return _403;
|
||||
|
||||
return Ok(c);
|
||||
}
|
||||
@@ -29,7 +31,10 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
{
|
||||
var r = await userService.Verify(user, response.Response, Ip);
|
||||
if (r == null)
|
||||
return StatusCode(403, new { message = "Access forbidden" });
|
||||
return _403;
|
||||
|
||||
|
||||
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
@@ -39,7 +44,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
var u = userService.Validate(token, Ip);
|
||||
if (u == -1)
|
||||
{
|
||||
return StatusCode(401, new { message = "Invalid" });
|
||||
return _401;
|
||||
}
|
||||
|
||||
return Ok(u);
|
||||
@@ -51,7 +56,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
var u = userService.Validate(token, Ip);
|
||||
if (u == -1)
|
||||
{
|
||||
return StatusCode(401, new { message = "Invalid" });
|
||||
return _401;
|
||||
}
|
||||
|
||||
userService.Destroy(token);
|
||||
@@ -64,21 +69,21 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
// Valid token
|
||||
var r = await userService.Verify(user, creating.Response, Ip);
|
||||
if (r == null)
|
||||
return StatusCode(403, new { message = "Denied" });
|
||||
return _403;
|
||||
|
||||
// User exists ?
|
||||
var cu = await userService.QueryUser(creating.Name);
|
||||
if (cu != null)
|
||||
return StatusCode(403, new { message = "Denied" });
|
||||
return _403;
|
||||
|
||||
// Valid username string
|
||||
if (!IsAlphanumeric(creating.Name))
|
||||
return StatusCode(403, new { message = "Denied" });
|
||||
return _403;
|
||||
|
||||
// Valid parent && Privilege
|
||||
var ou = await userService.QueryUser(userService.Validate(r, Ip));
|
||||
if (creating.Privilege > ou?.Privilege || ou == null)
|
||||
return StatusCode(403, new { message = "Denied" });
|
||||
return _403;
|
||||
|
||||
await userService.CreateUser(new User
|
||||
{
|
||||
@@ -98,13 +103,13 @@ public class UserController(UserService userService, ILogger<UserController> log
|
||||
var caller = userService.Validate(token, Ip);
|
||||
if (caller != 1)
|
||||
{
|
||||
return StatusCode(403, new { message = "Access forbidden" });
|
||||
return _403;
|
||||
}
|
||||
|
||||
var target = await userService.QueryUser(user);
|
||||
if (target == null)
|
||||
{
|
||||
return StatusCode(404, new { message = "User not found" });
|
||||
return _403;
|
||||
}
|
||||
|
||||
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Media;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
67
Abyss/Components/Services/Media/ComicService.cs
Normal file
67
Abyss/Components/Services/Media/ComicService.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model.Media;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
public class ComicService(ILogger<ComicService> logger, ResourceService rs, ConfigureService config)
|
||||
{
|
||||
public readonly string ImageFolder = Path.Combine(config.MediaRoot, "Images");
|
||||
|
||||
public async Task<bool> InitAsync(string token, string owner, string ip)
|
||||
=> await rs.Initialize(ImageFolder, token, owner, ip);
|
||||
|
||||
public async Task<string[]?> QueryCollections(string token, string ip)
|
||||
=> await rs.Query(ImageFolder, token, ip);
|
||||
|
||||
public async Task<string?> Query(string id, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
|
||||
if(d != null)
|
||||
return await rs.GetString(d, token, ip);
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<Comic?[]> QueryBulk(string token, string[] id, string ip)
|
||||
{
|
||||
var db = id.Select(x => Helpers.SafePathCombine(ImageFolder, [x, "summary.json"])).ToArray();
|
||||
if (db.Any(x => x == null))
|
||||
return [];
|
||||
|
||||
var sm = await rs.GetAllString(db!, token, ip);
|
||||
return sm.Select(x => x.Value == null ? null : JsonConvert.DeserializeObject<Comic>(x.Value)).ToArray();
|
||||
}
|
||||
|
||||
public async Task<bool> Bookmark(string id, string token, Bookmark bookmark, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
|
||||
if (d == null)
|
||||
return false;
|
||||
|
||||
Comic c = JsonConvert.DeserializeObject<Comic>(await File.ReadAllTextAsync(d))!;
|
||||
|
||||
var bookmarkPage = Helpers.SafePathCombine(ImageFolder, [id, bookmark.Page]);
|
||||
if (File.Exists(bookmarkPage))
|
||||
{
|
||||
c.Bookmarks.Add(bookmark);
|
||||
var o = JsonConvert.SerializeObject(c);
|
||||
return await rs.UpdateString(d, token, ip, o);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<PhysicalFileResult?> Page(string id, string file, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(ImageFolder, [id, file]);
|
||||
if (d != null)
|
||||
{
|
||||
return await rs.Get(d, token, ip, "image/jpeg");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Abyss.Components.Services.Misc;
|
||||
using SQLite;
|
||||
using Index = Abyss.Model.Index;
|
||||
namespace Abyss.Components.Services;
|
||||
using Index = Abyss.Model.Media.Index;
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
public class IndexService: IAsyncDisposable
|
||||
{
|
||||
@@ -1,11 +1,12 @@
|
||||
using System.IO.Hashing;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Media;
|
||||
using SQLite;
|
||||
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
public class ResourceDatabaseService
|
||||
{
|
||||
@@ -1,9 +1,13 @@
|
||||
// ResourceService.cs
|
||||
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Services.Security;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Media;
|
||||
using Abyss.Model.Security;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
public enum OperationType
|
||||
{
|
||||
@@ -28,7 +32,7 @@ public class ResourceService
|
||||
}
|
||||
|
||||
// Create UID only for resources, without considering advanced hash security such as adding salt
|
||||
public async Task<Dictionary<string, bool>> ValidAny(string[] paths, string token, OperationType type, string ip)
|
||||
private async Task<Dictionary<string, bool>> ValidAny(string[] paths, string token, OperationType type, string ip)
|
||||
{
|
||||
var result = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
@@ -216,7 +220,7 @@ public class ResourceService
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> ValidAll(string[] paths, string token, OperationType type, string ip)
|
||||
private async Task<bool> ValidAll(string[] paths, string token, OperationType type, string ip)
|
||||
{
|
||||
if (paths.Length == 0)
|
||||
{
|
||||
@@ -340,7 +344,7 @@ public class ResourceService
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> Valid(string path, string token, OperationType type, string ip)
|
||||
private async Task<bool> Valid(string path, string token, OperationType type, string ip)
|
||||
{
|
||||
// Path is abs path here, due to Helpers.SafePathCombine
|
||||
if (!path.StartsWith(Path.GetFullPath(_config.MediaRoot), StringComparison.OrdinalIgnoreCase))
|
||||
@@ -485,19 +489,52 @@ public class ResourceService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> Get(string path, string token, string ip)
|
||||
public async Task<PhysicalFileResult?> Get(string path, string token, string ip, string contentType)
|
||||
{
|
||||
return await Valid(path, token, OperationType.Read, ip);
|
||||
var b = await Valid(path, token, OperationType.Read, ip);
|
||||
if (b) return new PhysicalFileResult(path, contentType)
|
||||
{
|
||||
EnableRangeProcessing = true
|
||||
};
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> GetAll(string[] path, string token, string ip)
|
||||
public async Task<string?> GetString(string path, string token, string ip)
|
||||
{
|
||||
return await ValidAll(path, token, OperationType.Read, ip);
|
||||
var b = await Valid(path, token, OperationType.Read, ip);
|
||||
if (b)
|
||||
{
|
||||
return await File.ReadAllTextAsync(path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> Update(string path, string token, string ip)
|
||||
public async Task<Dictionary<string, string?>> GetAllString(string[] paths, string token, string ip)
|
||||
{
|
||||
return await Valid(path, token, OperationType.Write, ip);
|
||||
Dictionary<string, string?> result = new();
|
||||
var validMap = await ValidAny(paths, token, OperationType.Read, ip);
|
||||
foreach (var entry in validMap)
|
||||
{
|
||||
if (entry.Value)
|
||||
{
|
||||
result[entry.Key] = await File.ReadAllTextAsync(entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateString(string path, string token, string ip, string content)
|
||||
{
|
||||
var b = await Valid(path, token, OperationType.Write, ip);
|
||||
if (b)
|
||||
{
|
||||
await File.WriteAllTextAsync(path, content);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> Initialize(string path, string token, string owner, string ip)
|
||||
@@ -1,10 +1,12 @@
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Services.Security;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model;
|
||||
using Abyss.Model.Media;
|
||||
using Newtonsoft.Json;
|
||||
using SQLite;
|
||||
using Task = Abyss.Model.Task;
|
||||
using Task = Abyss.Model.Media.Task;
|
||||
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +26,7 @@ public class TaskService(ILogger<TaskService> logger, ConfigureService config, R
|
||||
foreach (var i in r ?? [])
|
||||
{
|
||||
var p = Helpers.SafePathCombine(TaskFolder, [i, "task.json"]);
|
||||
var c = JsonConvert.DeserializeObject<Model.Task>(await System.IO.File.ReadAllTextAsync(p ?? ""));
|
||||
var c = JsonConvert.DeserializeObject<Task>(await System.IO.File.ReadAllTextAsync(p ?? ""));
|
||||
|
||||
if(c?.Owner == u) s.Add(i);
|
||||
}
|
||||
@@ -58,8 +60,6 @@ public class TaskService(ILogger<TaskService> logger, ConfigureService config, R
|
||||
|
||||
private async Task<TaskCreationResponse?> CreateVideoTask(string token, string ip, TaskCreation creation)
|
||||
{
|
||||
if(!await rs.Valid(VideoFolder, token, OperationType.Write, ip))
|
||||
return null;
|
||||
var u = user.Validate(token, ip);
|
||||
if(u == -1)
|
||||
return null;
|
||||
162
Abyss/Components/Services/Media/VideoService.cs
Normal file
162
Abyss/Components/Services/Media/VideoService.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Static;
|
||||
using Abyss.Model.Media;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss.Components.Services.Media;
|
||||
|
||||
public class VideoService(ILogger<VideoService> logger, ResourceService rs, ConfigureService config)
|
||||
{
|
||||
public readonly string VideoFolder = Path.Combine(config.MediaRoot, "Videos");
|
||||
|
||||
public async Task<bool> Init(string token, string owner, string ip) => await rs.Initialize(VideoFolder, token, owner, ip);
|
||||
|
||||
public async Task<string[]?> GetClasses(string token, string ip)
|
||||
=> (await rs.Query(VideoFolder, token, ip))?.SortLikeWindows();
|
||||
|
||||
public async Task<string[]?> QueryClass(string klass, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, klass);
|
||||
if (d != null)
|
||||
{
|
||||
return await rs.Query(d, token, ip);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string?> QueryVideo(string klass, string id, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "summary.json"]);
|
||||
if(d != null)
|
||||
return await rs.GetString(d, token, ip);
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<Video?[]> QueryBulk(string klass, string[] id, string token, string ip)
|
||||
{
|
||||
var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray();
|
||||
if (db.Any(x => x == null))
|
||||
return [];
|
||||
|
||||
var sm = await rs.GetAllString(db!, token, ip);
|
||||
return sm.Select(x => x.Value == null ? null : JsonConvert.DeserializeObject<Video>(x.Value)).ToArray();
|
||||
}
|
||||
|
||||
public async Task<PhysicalFileResult?> Cover(string klass, string id, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "cover.jpg"]);
|
||||
if (d != null)
|
||||
{
|
||||
return await rs.Get(d, token, ip, "image/jpeg");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<PhysicalFileResult?> Gallery(string klass, string id, string pic, string token, string ip)
|
||||
{
|
||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "gallery", pic]);
|
||||
if (d != null)
|
||||
{
|
||||
return await rs.Get(d, token, ip, "image/jpeg");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<PhysicalFileResult?> Subtitle(string klass, string id, string token, string ip)
|
||||
{
|
||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
||||
if (folder == null)
|
||||
return null;
|
||||
|
||||
string? subtitlePath;
|
||||
|
||||
try
|
||||
{
|
||||
var preferredVtt = Path.Combine(folder, "subtitle.vtt");
|
||||
if (File.Exists(preferredVtt))
|
||||
{
|
||||
subtitlePath = preferredVtt;
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitlePath = Directory.EnumerateFiles(folder, "*.vtt").FirstOrDefault();
|
||||
|
||||
if (subtitlePath == null)
|
||||
{
|
||||
var preferredAss = Path.Combine(folder, "subtitle.ass");
|
||||
if (File.Exists(preferredAss))
|
||||
{
|
||||
subtitlePath = preferredAss;
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitlePath = Directory.EnumerateFiles(folder, "*.ass").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (subtitlePath == null)
|
||||
return null;
|
||||
|
||||
var ext = Path.GetExtension(subtitlePath).ToLowerInvariant();
|
||||
var contentType = ext switch
|
||||
{
|
||||
".vtt" => "text/vtt",
|
||||
".ass" => "text/x-ssa",
|
||||
_ => "text/plain"
|
||||
};
|
||||
|
||||
return await rs.Get(subtitlePath, token, ip, contentType);
|
||||
}
|
||||
|
||||
public async Task<PhysicalFileResult?> Av(string klass, string id, string token, string ip)
|
||||
{
|
||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
||||
if (folder == null)
|
||||
return null;
|
||||
|
||||
var allowedExt = new[] { ".mp4", ".mkv", ".webm", ".mov", ".ogg" };
|
||||
|
||||
string? videoPath = null;
|
||||
|
||||
foreach (var ext in allowedExt)
|
||||
{
|
||||
var p = Path.Combine(folder, "video" + ext);
|
||||
if (File.Exists(p))
|
||||
{
|
||||
videoPath = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (videoPath == null)
|
||||
return null;
|
||||
|
||||
var provider = new FileExtensionContentTypeProvider();
|
||||
if (!provider.TryGetContentType(videoPath, out var contentType))
|
||||
{
|
||||
var ext = Path.GetExtension(videoPath).ToLowerInvariant();
|
||||
contentType = ext switch
|
||||
{
|
||||
".mkv" => "video/x-matroska",
|
||||
".mp4" => "video/mp4",
|
||||
".webm" => "video/webm",
|
||||
".mov" => "video/quicktime",
|
||||
".ogg" => "video/ogg",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
}
|
||||
|
||||
return await rs.Get(videoPath, token, ip, contentType);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Misc;
|
||||
|
||||
public class ConfigureService
|
||||
{
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Tools;
|
||||
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Security;
|
||||
|
||||
public class AbyssService(ILogger<AbyssService> logger, ConfigureService config, UserService user) : IHostedService, IDisposable
|
||||
{
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Abyss.Model;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Model.Security;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using NSec.Cryptography;
|
||||
using SQLite;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Abyss.Components.Services;
|
||||
namespace Abyss.Components.Services.Security;
|
||||
|
||||
public class UserService
|
||||
{
|
||||
@@ -5,6 +5,11 @@ namespace Abyss.Components.Static;
|
||||
|
||||
public abstract class BaseController : Controller
|
||||
{
|
||||
protected IActionResult _403 => StatusCode(403, new { message = "Access Denied" });
|
||||
protected IActionResult _400 => StatusCode(400, new { message = "Bad Request" });
|
||||
protected IActionResult _401 => StatusCode(404, new { message = "Unauthorized" });
|
||||
protected IActionResult _404 => StatusCode(404, new { message = "Not Found" });
|
||||
|
||||
private string? _ip;
|
||||
|
||||
protected string Ip
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Components.Services.Security;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using NSec.Cryptography;
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ public static Dictionary<string, List<T>> Cluster<T>(
|
||||
public bool EndsWithNumber { get; }
|
||||
public object Payload { get; }
|
||||
|
||||
public Item(string original, object payload = null)
|
||||
public Item(string original, object? payload = null)
|
||||
{
|
||||
Original = original;
|
||||
Payload = payload ?? original;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public class Bookmark
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public enum ChipState
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public class Comic
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public class Comment
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using SQLite;
|
||||
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
[Table("Index")]
|
||||
public class Index
|
||||
@@ -1,6 +1,6 @@
|
||||
using SQLite;
|
||||
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
[Table("ResourceAttributes")]
|
||||
public class ResourceAttribute
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public enum TaskType
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public class TaskCreation
|
||||
{
|
||||
27
Abyss/Model/Media/Video.cs
Normal file
27
Abyss/Model/Media/Video.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss.Model.Media;
|
||||
|
||||
public class Video
|
||||
{
|
||||
[JsonProperty("name")] public string Name { get; set; } = "";
|
||||
|
||||
[JsonProperty("duration")]
|
||||
public ulong Duration { get; set; }
|
||||
|
||||
[JsonProperty("gallery")]
|
||||
public List<string> Gallery { get; set; } = new();
|
||||
|
||||
[JsonProperty("comment")]
|
||||
public List<Comment> Comment { get; set; } = new();
|
||||
|
||||
[JsonProperty("star")]
|
||||
public bool Star { get; set; }
|
||||
|
||||
[JsonProperty("like")] public uint Like { get; set; }
|
||||
|
||||
[JsonProperty("author")] public string Author { get; set; } = "";
|
||||
|
||||
[JsonProperty("group")]
|
||||
public string? Group { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Security;
|
||||
|
||||
public class ChallengeResponse
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using SQLite;
|
||||
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Security;
|
||||
|
||||
[Table("Users")]
|
||||
public class User
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Abyss.Model;
|
||||
namespace Abyss.Model.Security;
|
||||
|
||||
public class UserCreating
|
||||
{
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Abyss.Model;
|
||||
|
||||
public class Video
|
||||
{
|
||||
public string name;
|
||||
public ulong duration;
|
||||
public List<string> gallery = new();
|
||||
public List<Comment> comment = new();
|
||||
public bool star;
|
||||
public uint like;
|
||||
public string author;
|
||||
public string? group;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using System.Threading.RateLimiting;
|
||||
using Abyss.Components.Controllers.Middleware;
|
||||
using Abyss.Components.Controllers.Task;
|
||||
using Abyss.Components.Services;
|
||||
using Abyss.Misc;
|
||||
using Abyss.Model;
|
||||
|
||||
using Abyss.Components.Services.Media;
|
||||
using Abyss.Components.Services.Misc;
|
||||
using Abyss.Components.Services.Security;
|
||||
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Abyss;
|
||||
|
||||
@@ -26,6 +27,8 @@ public class Program
|
||||
builder.Services.AddSingleton<TaskController>();
|
||||
builder.Services.AddSingleton<TaskService>();
|
||||
builder.Services.AddSingleton<IndexService>();
|
||||
builder.Services.AddSingleton<VideoService>();
|
||||
builder.Services.AddSingleton<ComicService>();
|
||||
builder.Services.AddHostedService<AbyssService>();
|
||||
|
||||
builder.Services.AddRateLimiter(options =>
|
||||
|
||||
Reference in New Issue
Block a user