[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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="SqlDialectMappings">
|
<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>
|
</component>
|
||||||
</project>
|
</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" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</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/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="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<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/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/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/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/Media/ComicService.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/Media/IndexService.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/Media/ResourceDatabaseService.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/Media/ResourceService.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/Media/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/Media/VideoService.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/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/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/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/HttpHelper.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Tools/HttpReader.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/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/Media/Bookmark.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Media/Chip.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/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/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/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/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/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/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/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/User.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/UserCreating.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/User.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Video.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Security/UserCreating.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:///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" />
|
||||||
@@ -85,30 +117,30 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
".NET Launch Settings Profile.Abyss: http.executor": "Debug",
|
".NET Launch Settings Profile.Abyss: http.executor": "Run",
|
||||||
".NET Launch Settings Profile.Abyss: https.executor": "Debug",
|
".NET Launch Settings Profile.Abyss: https.executor": "Debug",
|
||||||
".NET Project.AbyssCli.executor": "Run",
|
".NET Project.AbyssCli.executor": "Run",
|
||||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"Publish to folder.Publish Abyss to folder x86.executor": "Run",
|
"Publish to folder.Publish Abyss to folder x86.executor": "Run",
|
||||||
"Publish to folder.Publish Abyss to folder.executor": "Run",
|
"Publish to folder.Publish Abyss to folder.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"XThreadsFramesViewSplitterKey": "0.55813956",
|
"XThreadsFramesViewSplitterKey": "0.55813956",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "main",
|
||||||
"last_opened_file_path": "/home/acite/embd/WebProjects/Abyss/README.md",
|
"last_opened_file_path": "/home/acite/embd/WebProjects/Abyss/README.md",
|
||||||
"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": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
|
"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="Publish to folder.Publish Abyss to folder">
|
<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">
|
||||||
@@ -246,6 +278,8 @@
|
|||||||
<workItem from="1758814543368" duration="642000" />
|
<workItem from="1758814543368" duration="642000" />
|
||||||
<workItem from="1758815224532" duration="430000" />
|
<workItem from="1758815224532" duration="430000" />
|
||||||
<workItem from="1758905391249" duration="128000" />
|
<workItem from="1758905391249" duration="128000" />
|
||||||
|
<workItem from="1758906781361" duration="252000" />
|
||||||
|
<workItem from="1759036019712" duration="20077000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</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">
|
<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_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_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_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_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>
|
<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;
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
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.Static;
|
||||||
using Abyss.Components.Tools;
|
using Abyss.Components.Tools;
|
||||||
using Abyss.Model;
|
using Abyss.Model.Media;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Abyss.Components.Controllers.Media;
|
namespace Abyss.Components.Controllers.Media;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
using Task = System.Threading.Tasks.Task;
|
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[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")]
|
[HttpPost("init")]
|
||||||
public async Task<IActionResult> InitAsync(string token, string owner)
|
public async Task<IActionResult> InitAsync(string token, string owner)
|
||||||
{
|
{
|
||||||
var r = await rs.Initialize(ImageFolder, token, owner, Ip);
|
var r = await comicService.InitAsync(token, owner, Ip);
|
||||||
if(r) return Ok(r);
|
return r ? Ok("Initialize Success") : _403;
|
||||||
return StatusCode(403, new { message = "403 Denied" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> QueryCollections(string token)
|
public async Task<IActionResult> QueryCollections(string token)
|
||||||
{
|
{
|
||||||
var r = await rs.Query(ImageFolder, token, Ip);
|
var r = await comicService.QueryCollections(token, Ip);
|
||||||
|
return r != null ? Ok(r.NaturalSort(x => x)) : _403;
|
||||||
if(r == null)
|
|
||||||
return StatusCode(401, new { message = "Unauthorized" });
|
|
||||||
|
|
||||||
return Ok(r.NaturalSort(x => x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public async Task<IActionResult> Query(string id, string token)
|
public async Task<IActionResult> Query(string id, string token)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
|
var r = await comicService.Query(id, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r != null ? Ok(r) : _403;
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("bulkquery")]
|
[HttpPost("bulkquery")]
|
||||||
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id)
|
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id)
|
||||||
{
|
{
|
||||||
var db = id.Select(x => Helpers.SafePathCombine(ImageFolder, [x, "summary.json"])).ToArray();
|
var r = await comicService.QueryBulk(token, id, Ip);
|
||||||
if (db.Any(x => x == null))
|
return Ok(JsonConvert.SerializeObject(r));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{id}/bookmark")]
|
[HttpPost("{id}/bookmark")]
|
||||||
public async Task<IActionResult> Bookmark(string id, string token, [FromBody] Bookmark bookmark)
|
public async Task<IActionResult> Bookmark(string id, string token, [FromBody] Bookmark bookmark)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(ImageFolder, [id, "summary.json"]);
|
var r = await comicService.Bookmark(id, token, bookmark, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r ? Ok("Success") : _403;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(ImageFolder, [id, file]);
|
var r = await comicService.Page(id, file, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r ?? _403;
|
||||||
|
|
||||||
var r = await rs.Get(d, token, Ip);
|
|
||||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
|
||||||
|
|
||||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using Abyss.Components.Services;
|
using Abyss.Components.Services;
|
||||||
|
using Abyss.Components.Services.Media;
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
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)
|
public async Task<IActionResult> AddLive(string id, string token, int owner)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(LiveFolder, [id]);
|
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,--,--");
|
bool r = await rs.Include(d, token, Ip, owner, "rw,--,--");
|
||||||
|
|
||||||
return r ? Ok("Success") : BadRequest();
|
return r ? Ok("Success") : _400;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
@@ -26,31 +28,25 @@ public class LiveController(ResourceService rs, ConfigureService config): BaseCo
|
|||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(LiveFolder, [id]);
|
var d = Helpers.SafePathCombine(LiveFolder, [id]);
|
||||||
if (d == null)
|
if (d == null)
|
||||||
return StatusCode(403, new { message = "403 Denied" });
|
return _403;
|
||||||
|
|
||||||
bool r = await rs.Exclude(d, token, Ip);
|
bool r = await rs.Exclude(d, token, Ip);
|
||||||
|
|
||||||
return r ? Ok("Success") : BadRequest();
|
return r ? Ok("Success") : _400;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{id}/{token}/{item}")]
|
[HttpGet("{id}/{token}/{item}")]
|
||||||
public async Task<IActionResult> GetLive(string id, string token, string item)
|
public async Task<IActionResult> GetLive(string id, string token, string item)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(LiveFolder, [id, item]);
|
var d = Helpers.SafePathCombine(LiveFolder, [id, item]);
|
||||||
var f = Helpers.SafePathCombine(LiveFolder, [id]);
|
if (d == null) return _400;
|
||||||
if (d == null || f == null) return BadRequest();
|
|
||||||
|
|
||||||
// TODO: (History)ffplay does not add the m3u8 query parameter in ts requests, so special treatment is given to ts here
|
// 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: (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
|
// 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);
|
var r = await rs.Get(d, token, Ip, Helpers.GetContentType(d));
|
||||||
if(!r) return StatusCode(403, new { message = "403 Denied" });
|
return r ?? _404;
|
||||||
|
|
||||||
if(System.IO.File.Exists(d))
|
|
||||||
return PhysicalFile(d, Helpers.GetContentType(d));
|
|
||||||
else
|
|
||||||
return NotFound();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,218 +1,79 @@
|
|||||||
using Abyss.Components.Services;
|
|
||||||
|
using Abyss.Components.Services.Media;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Abyss.Components.Tools;
|
|
||||||
using Abyss.Model;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Abyss.Components.Controllers.Media;
|
namespace Abyss.Components.Controllers.Media;
|
||||||
|
|
||||||
using Task = System.Threading.Tasks.Task;
|
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class VideoController(ILogger<VideoController> logger, ResourceService rs, ConfigureService config)
|
public class VideoController(VideoService videoService)
|
||||||
: BaseController
|
: BaseController
|
||||||
{
|
{
|
||||||
private ILogger<VideoController> _logger = logger;
|
|
||||||
public readonly string VideoFolder = Path.Combine(config.MediaRoot, "Videos");
|
|
||||||
|
|
||||||
[HttpPost("init")]
|
[HttpPost("init")]
|
||||||
public async Task<IActionResult> InitAsync(string token, string owner)
|
public async Task<IActionResult> InitAsync(string token, string owner)
|
||||||
{
|
{
|
||||||
var r = await rs.Initialize(VideoFolder, token, owner, Ip);
|
if (await videoService.Init(token, owner, Ip))
|
||||||
if (r) return Ok(r);
|
return Ok("Initialized Successfully");
|
||||||
return StatusCode(403, new { message = "403 Denied" });
|
return _403;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetClass(string token)
|
public async Task<IActionResult> GetClass(string token)
|
||||||
{
|
{
|
||||||
var r = (await rs.Query(VideoFolder, token, Ip))?.SortLikeWindows();
|
var r = await videoService.GetClasses(token, Ip);
|
||||||
|
return r != null ? Ok(r) : _403;
|
||||||
if (r == null)
|
|
||||||
return StatusCode(401, new { message = "Unauthorized" });
|
|
||||||
|
|
||||||
return Ok(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}")]
|
[HttpGet("{klass}")]
|
||||||
public async Task<IActionResult> QueryClass(string klass, string token)
|
public async Task<IActionResult> QueryClass(string klass, string token)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(VideoFolder, klass);
|
var r = await videoService.QueryClass(klass, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r != null ? Ok(r) : _403;
|
||||||
|
|
||||||
var r = await rs.Query(d, token, Ip);
|
|
||||||
if (r == null) return StatusCode(401, new { message = "Unauthorized" });
|
|
||||||
|
|
||||||
return Ok(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}")]
|
[HttpGet("{klass}/{id}")]
|
||||||
public async Task<IActionResult> QueryVideo(string klass, string id, string token)
|
public async Task<IActionResult> QueryVideo(string klass, string id, string token)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "summary.json"]);
|
var r = await videoService.QueryVideo(klass, id, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r != null ? Ok(r) : _403;
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{klass}/bulkquery")]
|
[HttpPost("{klass}/bulkquery")]
|
||||||
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id,
|
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id,
|
||||||
[FromRoute] string klass)
|
[FromRoute] string klass)
|
||||||
{
|
{
|
||||||
var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray();
|
var r = await videoService.QueryBulk(klass, id, token, Ip);
|
||||||
if (db.Any(x => x == null))
|
return Ok(JsonConvert.SerializeObject(r));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}/cover")]
|
[HttpGet("{klass}/{id}/cover")]
|
||||||
public async Task<IActionResult> Cover(string klass, string id, string token)
|
public async Task<IActionResult> Cover(string klass, string id, string token)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "cover.jpg"]);
|
var r = await videoService.Cover(klass, id, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r ?? _403;
|
||||||
|
|
||||||
var r = await rs.Get(d, token, Ip);
|
|
||||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
|
||||||
|
|
||||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}/gallery/{pic}")]
|
[HttpGet("{klass}/{id}/gallery/{pic}")]
|
||||||
public async Task<IActionResult> Gallery(string klass, string id, string pic, string token)
|
public async Task<IActionResult> Gallery(string klass, string id, string pic, string token)
|
||||||
{
|
{
|
||||||
var d = Helpers.SafePathCombine(VideoFolder, [klass, id, "gallery", pic]);
|
var r = await videoService.Gallery(klass, id, pic, token, Ip);
|
||||||
if (d == null) return StatusCode(403, new { message = "403 Denied" });
|
return r ?? _403;
|
||||||
|
|
||||||
var r = await rs.Get(d, token, Ip);
|
|
||||||
if (!r) return StatusCode(403, new { message = "403 Denied" });
|
|
||||||
|
|
||||||
return PhysicalFile(d, "image/jpeg", enableRangeProcessing: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}/subtitle")]
|
[HttpGet("{klass}/{id}/subtitle")]
|
||||||
public async Task<IActionResult> Subtitle(string klass, string id, string token)
|
public async Task<IActionResult> Subtitle(string klass, string id, string token)
|
||||||
{
|
{
|
||||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
var r = await videoService.Subtitle(klass, id, token, Ip);
|
||||||
if (folder == null)
|
return r ?? _404;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}/av")]
|
[HttpGet("{klass}/{id}/av")]
|
||||||
public async Task<IActionResult> Av(string klass, string id, string token)
|
public async Task<IActionResult> Av(string klass, string id, string token)
|
||||||
{
|
{
|
||||||
var folder = Helpers.SafePathCombine(VideoFolder, new[] { klass, id });
|
var r = await videoService.Av(klass, id, token, Ip);
|
||||||
if (folder == null) return StatusCode(403, new { message = "403 Denied" });
|
return r ?? _403;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Abyss.Components.Services;
|
using Abyss.Components.Services;
|
||||||
|
using Abyss.Components.Services.Media;
|
||||||
|
using Abyss.Components.Services.Security;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -18,12 +20,12 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
|||||||
if (userService.Validate(token, Ip) != 1)
|
if (userService.Validate(token, Ip) != 1)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Chmod authorization failed for token: {Token}", token);
|
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");
|
bool r = await resourceService.Chmod(path, token, permission, Ip, recursive == "true");
|
||||||
logger.LogInformation("Chmod operation completed with result: {Result}", r);
|
logger.LogInformation("Chmod operation completed with result: {Result}", r);
|
||||||
return r ? Ok() : StatusCode(502);
|
return r ? Ok() : StatusCode(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("chown")]
|
[HttpPost("chown")]
|
||||||
@@ -34,7 +36,7 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
|||||||
if (userService.Validate(token, Ip) != 1)
|
if (userService.Validate(token, Ip) != 1)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Chown authorization failed for token: {Token}", token);
|
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");
|
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)
|
if (userService.Validate(token, Ip) != 1)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Ls authorization failed for token: {Token}", token);
|
logger.LogInformation("Ls authorization failed for token: {Token}", token);
|
||||||
return StatusCode(401, "Unauthorized");
|
return _401;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
{
|
{
|
||||||
logger.LogInformation("Ls method received empty path parameter");
|
logger.LogInformation("Ls method received empty path parameter");
|
||||||
return BadRequest("path is required");
|
return _400;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -67,10 +69,10 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
|||||||
if (!Directory.Exists(fullPath))
|
if (!Directory.Exists(fullPath))
|
||||||
{
|
{
|
||||||
logger.LogInformation("Directory does not exist: {FullPath}", 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());
|
logger.LogInformation("Found {Count} entries in directory", entries.Count());
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
@@ -115,12 +117,12 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
|||||||
if (userService.Validate(token, Ip) != 1)
|
if (userService.Validate(token, Ip) != 1)
|
||||||
{
|
{
|
||||||
logger.LogInformation("Init authorization failed for token: {Token}", token);
|
logger.LogInformation("Init authorization failed for token: {Token}", token);
|
||||||
return StatusCode(401, "Unauthorized");
|
return _401;
|
||||||
}
|
}
|
||||||
|
|
||||||
var r = await resourceService.Initialize(path, token, owner, Ip);
|
var r = await resourceService.Initialize(path, token, owner, Ip);
|
||||||
if (r) return Ok(r);
|
if (r) return Ok(r);
|
||||||
return StatusCode(403, new { message = "403 Denied" });
|
return _403;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ConvertToLsPerms(string permRaw, bool isDirectory)
|
private static string ConvertToLsPerms(string permRaw, bool isDirectory)
|
||||||
@@ -135,7 +137,7 @@ public class RootController(ILogger<RootController> logger, UserService userServ
|
|||||||
return (isDirectory ? 'd' : '-') + "---------";
|
return (isDirectory ? 'd' : '-') + "---------";
|
||||||
}
|
}
|
||||||
|
|
||||||
string makeTriplet(string token)
|
string MakeTriplet(string token)
|
||||||
{
|
{
|
||||||
if (token.Length < 2) token = "--";
|
if (token.Length < 2) token = "--";
|
||||||
var r = token.Length > 0 && token[0] == 'r' ? 'r' : '-';
|
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}";
|
return $"{r}{w}{x}";
|
||||||
}
|
}
|
||||||
|
|
||||||
var owner = makeTriplet(parts[0]);
|
var owner = MakeTriplet(parts[0]);
|
||||||
var group = makeTriplet(parts[1]);
|
var group = MakeTriplet(parts[1]);
|
||||||
var other = makeTriplet(parts[2]);
|
var other = MakeTriplet(parts[2]);
|
||||||
|
|
||||||
return (isDirectory ? 'd' : '-') + owner + group + other;
|
return (isDirectory ? 'd' : '-') + owner + group + other;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Abyss.Components.Services;
|
using Abyss.Components.Services;
|
||||||
|
using Abyss.Components.Services.Security;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Abyss.Model;
|
using Abyss.Model;
|
||||||
|
using Abyss.Model.Security;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
{
|
{
|
||||||
var c = await userService.Challenge(user);
|
var c = await userService.Challenge(user);
|
||||||
if (c == null)
|
if (c == null)
|
||||||
return StatusCode(403, new { message = "Access forbidden" });
|
return _403;
|
||||||
|
|
||||||
return Ok(c);
|
return Ok(c);
|
||||||
}
|
}
|
||||||
@@ -29,7 +31,10 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
{
|
{
|
||||||
var r = await userService.Verify(user, response.Response, Ip);
|
var r = await userService.Verify(user, response.Response, Ip);
|
||||||
if (r == null)
|
if (r == null)
|
||||||
return StatusCode(403, new { message = "Access forbidden" });
|
return _403;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Ok(r);
|
return Ok(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +44,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
var u = userService.Validate(token, Ip);
|
var u = userService.Validate(token, Ip);
|
||||||
if (u == -1)
|
if (u == -1)
|
||||||
{
|
{
|
||||||
return StatusCode(401, new { message = "Invalid" });
|
return _401;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(u);
|
return Ok(u);
|
||||||
@@ -51,7 +56,7 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
var u = userService.Validate(token, Ip);
|
var u = userService.Validate(token, Ip);
|
||||||
if (u == -1)
|
if (u == -1)
|
||||||
{
|
{
|
||||||
return StatusCode(401, new { message = "Invalid" });
|
return _401;
|
||||||
}
|
}
|
||||||
|
|
||||||
userService.Destroy(token);
|
userService.Destroy(token);
|
||||||
@@ -64,21 +69,21 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
// Valid token
|
// Valid token
|
||||||
var r = await userService.Verify(user, creating.Response, Ip);
|
var r = await userService.Verify(user, creating.Response, Ip);
|
||||||
if (r == null)
|
if (r == null)
|
||||||
return StatusCode(403, new { message = "Denied" });
|
return _403;
|
||||||
|
|
||||||
// User exists ?
|
// User exists ?
|
||||||
var cu = await userService.QueryUser(creating.Name);
|
var cu = await userService.QueryUser(creating.Name);
|
||||||
if (cu != null)
|
if (cu != null)
|
||||||
return StatusCode(403, new { message = "Denied" });
|
return _403;
|
||||||
|
|
||||||
// Valid username string
|
// Valid username string
|
||||||
if (!IsAlphanumeric(creating.Name))
|
if (!IsAlphanumeric(creating.Name))
|
||||||
return StatusCode(403, new { message = "Denied" });
|
return _403;
|
||||||
|
|
||||||
// Valid parent && Privilege
|
// Valid parent && Privilege
|
||||||
var ou = await userService.QueryUser(userService.Validate(r, Ip));
|
var ou = await userService.QueryUser(userService.Validate(r, Ip));
|
||||||
if (creating.Privilege > ou?.Privilege || ou == null)
|
if (creating.Privilege > ou?.Privilege || ou == null)
|
||||||
return StatusCode(403, new { message = "Denied" });
|
return _403;
|
||||||
|
|
||||||
await userService.CreateUser(new User
|
await userService.CreateUser(new User
|
||||||
{
|
{
|
||||||
@@ -98,13 +103,13 @@ public class UserController(UserService userService, ILogger<UserController> log
|
|||||||
var caller = userService.Validate(token, Ip);
|
var caller = userService.Validate(token, Ip);
|
||||||
if (caller != 1)
|
if (caller != 1)
|
||||||
{
|
{
|
||||||
return StatusCode(403, new { message = "Access forbidden" });
|
return _403;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = await userService.QueryUser(user);
|
var target = await userService.QueryUser(user);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
return StatusCode(404, new { message = "User not found" });
|
return _403;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp;
|
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using Abyss.Components.Services;
|
using Abyss.Components.Services;
|
||||||
|
using Abyss.Components.Services.Media;
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Abyss.Model;
|
using Abyss.Model;
|
||||||
|
using Abyss.Model.Media;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
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 SQLite;
|
||||||
using Index = Abyss.Model.Index;
|
using Index = Abyss.Model.Media.Index;
|
||||||
namespace Abyss.Components.Services;
|
namespace Abyss.Components.Services.Media;
|
||||||
|
|
||||||
public class IndexService: IAsyncDisposable
|
public class IndexService: IAsyncDisposable
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
using System.IO.Hashing;
|
using System.IO.Hashing;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
using Abyss.Components.Static;
|
using Abyss.Components.Static;
|
||||||
using Abyss.Model;
|
using Abyss.Model.Media;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace Abyss.Components.Services;
|
namespace Abyss.Components.Services.Media;
|
||||||
|
|
||||||
public class ResourceDatabaseService
|
public class ResourceDatabaseService
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
// ResourceService.cs
|
// ResourceService.cs
|
||||||
|
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
|
using Abyss.Components.Services.Security;
|
||||||
using Abyss.Components.Static;
|
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
|
public enum OperationType
|
||||||
{
|
{
|
||||||
@@ -28,7 +32,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
|
||||||
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);
|
var result = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
@@ -216,7 +220,7 @@ public class ResourceService
|
|||||||
return result;
|
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)
|
if (paths.Length == 0)
|
||||||
{
|
{
|
||||||
@@ -340,7 +344,7 @@ public class ResourceService
|
|||||||
return true;
|
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
|
// Path is abs path here, due to Helpers.SafePathCombine
|
||||||
if (!path.StartsWith(Path.GetFullPath(_config.MediaRoot), StringComparison.OrdinalIgnoreCase))
|
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)
|
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.Components.Static;
|
||||||
using Abyss.Model;
|
using Abyss.Model.Media;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using SQLite;
|
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 ?? [])
|
foreach (var i in r ?? [])
|
||||||
{
|
{
|
||||||
var p = Helpers.SafePathCombine(TaskFolder, [i, "task.json"]);
|
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);
|
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)
|
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);
|
var u = user.Validate(token, ip);
|
||||||
if(u == -1)
|
if(u == -1)
|
||||||
return null;
|
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
|
public class ConfigureService
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Abyss.Components.Services.Misc;
|
||||||
using Abyss.Components.Tools;
|
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
|
public class AbyssService(ILogger<AbyssService> logger, ConfigureService config, UserService user) : IHostedService, IDisposable
|
||||||
{
|
{
|
||||||
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Abyss.Model;
|
using Abyss.Components.Services.Misc;
|
||||||
|
using Abyss.Model.Security;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using NSec.Cryptography;
|
using NSec.Cryptography;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
using Task = System.Threading.Tasks.Task;
|
using Task = System.Threading.Tasks.Task;
|
||||||
|
|
||||||
namespace Abyss.Components.Services;
|
namespace Abyss.Components.Services.Security;
|
||||||
|
|
||||||
public class UserService
|
public class UserService
|
||||||
{
|
{
|
||||||
@@ -5,6 +5,11 @@ namespace Abyss.Components.Static;
|
|||||||
|
|
||||||
public abstract class BaseController : Controller
|
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;
|
private string? _ip;
|
||||||
|
|
||||||
protected string Ip
|
protected string Ip
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Abyss.Components.Services;
|
using Abyss.Components.Services;
|
||||||
|
using Abyss.Components.Services.Security;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using NSec.Cryptography;
|
using NSec.Cryptography;
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public static Dictionary<string, List<T>> Cluster<T>(
|
|||||||
public bool EndsWithNumber { get; }
|
public bool EndsWithNumber { get; }
|
||||||
public object Payload { get; }
|
public object Payload { get; }
|
||||||
|
|
||||||
public Item(string original, object payload = null)
|
public Item(string original, object? payload = null)
|
||||||
{
|
{
|
||||||
Original = original;
|
Original = original;
|
||||||
Payload = payload ?? original;
|
Payload = payload ?? original;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public class Bookmark
|
public class Bookmark
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public enum ChipState
|
public enum ChipState
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public class Comic
|
public class Comic
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public class Comment
|
public class Comment
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
[Table("Index")]
|
[Table("Index")]
|
||||||
public class Index
|
public class Index
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
[Table("ResourceAttributes")]
|
[Table("ResourceAttributes")]
|
||||||
public class ResourceAttribute
|
public class ResourceAttribute
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public enum TaskType
|
public enum TaskType
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Media;
|
||||||
|
|
||||||
public class TaskCreation
|
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
|
public class ChallengeResponse
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Security;
|
||||||
|
|
||||||
[Table("Users")]
|
[Table("Users")]
|
||||||
public class User
|
public class User
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Abyss.Model;
|
namespace Abyss.Model.Security;
|
||||||
|
|
||||||
public class UserCreating
|
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 System.Threading.RateLimiting;
|
||||||
using Abyss.Components.Controllers.Middleware;
|
using Abyss.Components.Controllers.Middleware;
|
||||||
using Abyss.Components.Controllers.Task;
|
using Abyss.Components.Controllers.Task;
|
||||||
using Abyss.Components.Services;
|
|
||||||
using Abyss.Misc;
|
using Abyss.Components.Services.Media;
|
||||||
using Abyss.Model;
|
using Abyss.Components.Services.Misc;
|
||||||
|
using Abyss.Components.Services.Security;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Abyss;
|
namespace Abyss;
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ public class Program
|
|||||||
builder.Services.AddSingleton<TaskController>();
|
builder.Services.AddSingleton<TaskController>();
|
||||||
builder.Services.AddSingleton<TaskService>();
|
builder.Services.AddSingleton<TaskService>();
|
||||||
builder.Services.AddSingleton<IndexService>();
|
builder.Services.AddSingleton<IndexService>();
|
||||||
|
builder.Services.AddSingleton<VideoService>();
|
||||||
|
builder.Services.AddSingleton<ComicService>();
|
||||||
builder.Services.AddHostedService<AbyssService>();
|
builder.Services.AddHostedService<AbyssService>();
|
||||||
|
|
||||||
builder.Services.AddRateLimiter(options =>
|
builder.Services.AddRateLimiter(options =>
|
||||||
|
|||||||
Reference in New Issue
Block a user