[feat] Video Group
This commit is contained in:
2
.idea/.idea.Abyss/.idea/dataSources.local.xml
generated
2
.idea/.idea.Abyss/.idea/dataSources.local.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="dataSourceStorageLocal" created-in="RD-252.25557.182">
|
<component name="dataSourceStorageLocal" created-in="RD-252.26199.154">
|
||||||
<data-source name="user" uuid="91acd9d8-5f8b-442f-9d50-17006d4e1ac7">
|
<data-source name="user" uuid="91acd9d8-5f8b-442f-9d50-17006d4e1ac7">
|
||||||
<database-info product="SQLite" version="3.45.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.45.1.0" dbms="SQLITE" exact-version="3.45.1" exact-driver-version="3.45">
|
<database-info product="SQLite" version="3.45.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.45.1.0" dbms="SQLITE" exact-version="3.45.1" exact-driver-version="3.45">
|
||||||
<identifier-quote-string>"</identifier-quote-string>
|
<identifier-quote-string>"</identifier-quote-string>
|
||||||
|
|||||||
@@ -499,7 +499,7 @@
|
|||||||
</routine>
|
</routine>
|
||||||
<schema id="191" parent="1" name="main">
|
<schema id="191" parent="1" name="main">
|
||||||
<Current>1</Current>
|
<Current>1</Current>
|
||||||
<LastIntrospectionLocalTimestamp>2025-08-23.08:35:53</LastIntrospectionLocalTimestamp>
|
<LastIntrospectionLocalTimestamp>2025-09-25.10:18:41</LastIntrospectionLocalTimestamp>
|
||||||
</schema>
|
</schema>
|
||||||
<argument id="192" parent="16">
|
<argument id="192" parent="16">
|
||||||
<ArgumentDirection>R</ArgumentDirection>
|
<ArgumentDirection>R</ArgumentDirection>
|
||||||
@@ -1590,45 +1590,72 @@
|
|||||||
<argument id="554" parent="190">
|
<argument id="554" parent="190">
|
||||||
<Position>1</Position>
|
<Position>1</Position>
|
||||||
</argument>
|
</argument>
|
||||||
<table id="555" parent="191" name="User"/>
|
<table id="555" parent="191" name="Users"/>
|
||||||
<table id="556" parent="191" name="sqlite_master">
|
<table id="556" parent="191" name="sqlite_master">
|
||||||
<System>1</System>
|
<System>1</System>
|
||||||
</table>
|
</table>
|
||||||
<column id="557" parent="555" name="Name">
|
<table id="557" parent="191" name="sqlite_sequence">
|
||||||
|
<System>1</System>
|
||||||
|
</table>
|
||||||
|
<column id="558" parent="555" name="Uuid">
|
||||||
|
<AutoIncrement>1</AutoIncrement>
|
||||||
|
<NotNull>1</NotNull>
|
||||||
<Position>1</Position>
|
<Position>1</Position>
|
||||||
<StoredType>varchar|0s</StoredType>
|
|
||||||
</column>
|
|
||||||
<column id="558" parent="555" name="Parent">
|
|
||||||
<Position>2</Position>
|
|
||||||
<StoredType>varchar|0s</StoredType>
|
|
||||||
</column>
|
|
||||||
<column id="559" parent="555" name="PublicKey">
|
|
||||||
<Position>3</Position>
|
|
||||||
<StoredType>varchar|0s</StoredType>
|
|
||||||
</column>
|
|
||||||
<column id="560" parent="555" name="Privilege">
|
|
||||||
<Position>4</Position>
|
|
||||||
<StoredType>integer|0s</StoredType>
|
<StoredType>integer|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
<column id="561" parent="556" name="type">
|
<column id="559" parent="555" name="Username">
|
||||||
|
<NotNull>1</NotNull>
|
||||||
|
<Position>2</Position>
|
||||||
|
<StoredType>varchar|0s</StoredType>
|
||||||
|
</column>
|
||||||
|
<column id="560" parent="555" name="ParentId">
|
||||||
|
<NotNull>1</NotNull>
|
||||||
|
<Position>3</Position>
|
||||||
|
<StoredType>integer|0s</StoredType>
|
||||||
|
</column>
|
||||||
|
<column id="561" parent="555" name="PublicKey">
|
||||||
|
<NotNull>1</NotNull>
|
||||||
|
<Position>4</Position>
|
||||||
|
<StoredType>varchar|0s</StoredType>
|
||||||
|
</column>
|
||||||
|
<column id="562" parent="555" name="Privilege">
|
||||||
|
<NotNull>1</NotNull>
|
||||||
|
<Position>5</Position>
|
||||||
|
<StoredType>integer|0s</StoredType>
|
||||||
|
</column>
|
||||||
|
<index id="563" parent="555" name="Users_Username">
|
||||||
|
<ColNames>Username</ColNames>
|
||||||
|
<Unique>1</Unique>
|
||||||
|
</index>
|
||||||
|
<key id="564" parent="555">
|
||||||
|
<ColNames>Uuid</ColNames>
|
||||||
|
<Primary>1</Primary>
|
||||||
|
</key>
|
||||||
|
<column id="565" parent="556" name="type">
|
||||||
<Position>1</Position>
|
<Position>1</Position>
|
||||||
<StoredType>TEXT|0s</StoredType>
|
<StoredType>TEXT|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
<column id="562" parent="556" name="name">
|
<column id="566" parent="556" name="name">
|
||||||
<Position>2</Position>
|
<Position>2</Position>
|
||||||
<StoredType>TEXT|0s</StoredType>
|
<StoredType>TEXT|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
<column id="563" parent="556" name="tbl_name">
|
<column id="567" parent="556" name="tbl_name">
|
||||||
<Position>3</Position>
|
<Position>3</Position>
|
||||||
<StoredType>TEXT|0s</StoredType>
|
<StoredType>TEXT|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
<column id="564" parent="556" name="rootpage">
|
<column id="568" parent="556" name="rootpage">
|
||||||
<Position>4</Position>
|
<Position>4</Position>
|
||||||
<StoredType>INT|0s</StoredType>
|
<StoredType>INT|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
<column id="565" parent="556" name="sql">
|
<column id="569" parent="556" name="sql">
|
||||||
<Position>5</Position>
|
<Position>5</Position>
|
||||||
<StoredType>TEXT|0s</StoredType>
|
<StoredType>TEXT|0s</StoredType>
|
||||||
</column>
|
</column>
|
||||||
|
<column id="570" parent="557" name="name">
|
||||||
|
<Position>1</Position>
|
||||||
|
</column>
|
||||||
|
<column id="571" parent="557" name="seq">
|
||||||
|
<Position>2</Position>
|
||||||
|
</column>
|
||||||
</database-model>
|
</database-model>
|
||||||
</dataSource>
|
</dataSource>
|
||||||
6
.idea/.idea.Abyss/.idea/sqldialects.xml
generated
Normal file
6
.idea/.idea.Abyss/.idea/sqldialects.xml
generated
Normal file
@@ -0,0 +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" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
43
.idea/.idea.Abyss/.idea/workspace.xml
generated
43
.idea/.idea.Abyss/.idea/workspace.xml
generated
@@ -10,7 +10,15 @@
|
|||||||
</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/Misc/StringClusterer.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/dataSources.local.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/dataSources/91acd9d8-5f8b-442f-9d50-17006d4e1ac7.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/dataSources/91acd9d8-5f8b-442f-9d50-17006d4e1ac7.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$/.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/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/IndexService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/IndexService.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Abyss/Model/Video.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Video.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Abyss/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Program.cs" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -28,12 +36,16 @@
|
|||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/25/817def70/ConfiguredValueTaskAwaitable`1.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/25/817def70/ConfiguredValueTaskAwaitable`1.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/4c/4b962087/Monitor.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/4c/4b962087/Monitor.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/af/aac0eaa5/ExceptionDispatchInfo.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/af/aac0eaa5/ExceptionDispatchInfo.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/b5/9de8e4ee/Index.cs" root0="SKIP_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/d0/3b166e9e/String.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/d0/3b166e9e/String.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/457530be4752476295767457c3639889d1a000/f3/fbf95091/SafeFileHandle.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/5df2accb46d040ccbbbe8331bf4d24b61daa00/df/93debd37/ControllerBase.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/5df2accb46d040ccbbbe8331bf4d24b61daa00/df/93debd37/ControllerBase.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/61fe11e9d86b4d2a9bd2b806929b7d381a400/a1/62750ee4/AsyncTableQuery`1.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/61fe11e9d86b4d2a9bd2b806929b7d381a400/e9/67f4a40e/SQLiteAsyncConnection.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/61fe11e9d86b4d2a9bd2b806929b7d381a400/e9/67f4a40e/SQLiteAsyncConnection.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/7598e47d5cdf4107ba88f8220720fdc89000/a6/79d67871/xxHash128.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/7598e47d5cdf4107ba88f8220720fdc89000/a6/79d67871/xxHash128.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/AbyssController.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/AbyssController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Media/IndexController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Middleware/BadRequestExceptionMiddleware.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Middleware/BadRequestExceptionMiddleware.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/RootController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
@@ -41,6 +53,8 @@
|
|||||||
<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/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/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/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/TaskService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
@@ -48,17 +62,25 @@
|
|||||||
<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/Model/Bookmark.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Bookmark.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/ChallengeResponse.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Chip.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Chip.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comic.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comic.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comment.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Comment.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Index.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Task.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Task.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/TaskCreation.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/User.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/UserCreating.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/UserCreating.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Abyss/Model/Video.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Abyss/Model/Video.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="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,7 +107,7 @@
|
|||||||
"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.30266345",
|
"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",
|
||||||
@@ -97,7 +119,7 @@
|
|||||||
"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=".NET Launch Settings Profile.Abyss: http">
|
||||||
<configuration name="Publish Abyss to folder x86" type="DotNetFolderPublish" factoryName="Publish to folder">
|
<configuration name="Publish Abyss to folder x86" type="DotNetFolderPublish" factoryName="Publish to folder">
|
||||||
<riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" ready_to_run="true" self_contained="true" target_folder="/opt/security/https/server" target_framework="net9.0" uuid_high="3690631506471504162" uuid_low="-4858628519588143325">
|
<riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" ready_to_run="true" self_contained="true" target_folder="/opt/security/https/server" target_framework="net9.0" uuid_high="3690631506471504162" uuid_low="-4858628519588143325">
|
||||||
<runtimes>
|
<runtimes>
|
||||||
@@ -229,6 +251,10 @@
|
|||||||
<workItem from="1758350848039" duration="946000" />
|
<workItem from="1758350848039" duration="946000" />
|
||||||
<workItem from="1758352441563" duration="281000" />
|
<workItem from="1758352441563" duration="281000" />
|
||||||
<workItem from="1758599755722" duration="14000" />
|
<workItem from="1758599755722" duration="14000" />
|
||||||
|
<workItem from="1758767744733" duration="12501000" />
|
||||||
|
<workItem from="1758794950242" duration="9381000" />
|
||||||
|
<workItem from="1758814543368" duration="642000" />
|
||||||
|
<workItem from="1758815224532" duration="297000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
@@ -278,6 +304,19 @@
|
|||||||
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
|
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
|
||||||
<option name="timeStamp" value="3" />
|
<option name="timeStamp" value="3" />
|
||||||
</breakpoint>
|
</breakpoint>
|
||||||
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
|
<url>file://$PROJECT_DIR$/Abyss/Program.cs</url>
|
||||||
|
<line>31</line>
|
||||||
|
<properties documentPath="$PROJECT_DIR$/Abyss/Program.cs" containingFunctionPresentation="Method 'Main'">
|
||||||
|
<startOffsets>
|
||||||
|
<option value="1008" />
|
||||||
|
</startOffsets>
|
||||||
|
<endOffsets>
|
||||||
|
<option value="1062" />
|
||||||
|
</endOffsets>
|
||||||
|
</properties>
|
||||||
|
<option name="timeStamp" value="4" />
|
||||||
|
</line-breakpoint>
|
||||||
</breakpoints>
|
</breakpoints>
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<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>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003F4c_003F4b962087_003FMonitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003F4c_003F4b962087_003FMonitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASafeFileHandle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003Ff3_003Ffbf95091_003FSafeFileHandle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceProvider_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F011a191356a243438f987de3ec3d6c6230800_003F04_003F8419ff35_003FServiceProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceProvider_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F011a191356a243438f987de3ec3d6c6230800_003F04_003F8419ff35_003FServiceProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASQLiteAsyncConnection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F61fe11e9d86b4d2a9bd2b806929b7d381a400_003Fe9_003F67f4a40e_003FSQLiteAsyncConnection_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASQLiteAsyncConnection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F61fe11e9d86b4d2a9bd2b806929b7d381a400_003Fe9_003F67f4a40e_003FSQLiteAsyncConnection_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003Fd0_003F3b166e9e_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F457530be4752476295767457c3639889d1a000_003Fd0_003F3b166e9e_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|||||||
@@ -46,19 +46,7 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
|
|||||||
var r = await rs.Query(d, token, Ip);
|
var r = await rs.Query(d, token, Ip);
|
||||||
if (r == null) return StatusCode(401, new { message = "Unauthorized" });
|
if (r == null) return StatusCode(401, new { message = "Unauthorized" });
|
||||||
|
|
||||||
var rv = r.Select(x => { return Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"]); }).ToArray();
|
return Ok(r);
|
||||||
|
|
||||||
for (int i = 0; i < rv.Length; i++)
|
|
||||||
{
|
|
||||||
if (rv[i] == null) continue;
|
|
||||||
rv[i] = await System.IO.File.ReadAllTextAsync(rv[i] ?? "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var sv = rv.Where(x => x != null).Select(x => x ?? "")
|
|
||||||
.Select(x => JsonConvert.DeserializeObject<Video>(x)).ToArray();
|
|
||||||
|
|
||||||
|
|
||||||
return Ok(sv.Zip(r, (x, y) => (x, y)).NaturalSort(x => x.x!.name).Select(x => x.y).ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{klass}/{id}")]
|
[HttpGet("{klass}/{id}")]
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ public class IndexService: IAsyncDisposable
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
|
|
||||||
private IndexService(string dbPath)
|
public IndexService(ConfigureService cs)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(dbPath)) throw new ArgumentNullException(nameof(dbPath));
|
if (string.IsNullOrWhiteSpace(cs.IndexDatabase)) throw new ArgumentNullException(nameof(cs.IndexDatabase));
|
||||||
_db = new SQLiteAsyncConnection(dbPath);
|
_db = new SQLiteAsyncConnection(cs.IndexDatabase);
|
||||||
|
|
||||||
_db.CreateTableAsync<Index>().Wait();
|
_db.CreateTableAsync<Index>().Wait();
|
||||||
EnsureRootExistsAsync().Wait();
|
EnsureRootExistsAsync().Wait();
|
||||||
|
|||||||
244
Abyss/Misc/StringClusterer.cs
Normal file
244
Abyss/Misc/StringClusterer.cs
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Abyss.Misc;
|
||||||
|
|
||||||
|
public static class StringClusterer
|
||||||
|
{
|
||||||
|
public static Dictionary<string, List<string>> Cluster(
|
||||||
|
string[] inputs,
|
||||||
|
double mergeThreshold = 0.20
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Cluster(inputs, s => s, mergeThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, List<T>> Cluster<T>(
|
||||||
|
IEnumerable<T> inputs,
|
||||||
|
Func<T, string> selector,
|
||||||
|
double mergeThreshold = 0.20
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (inputs == null) throw new ArgumentNullException(nameof(inputs));
|
||||||
|
if (selector == null) throw new ArgumentNullException(nameof(selector));
|
||||||
|
|
||||||
|
var items = inputs.Select(x => new Item(selector(x), x)).ToList();
|
||||||
|
|
||||||
|
var groups = new Dictionary<string, Group>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (var it in items)
|
||||||
|
{
|
||||||
|
if (!groups.TryGetValue(it.KeyNorm, out var g))
|
||||||
|
{
|
||||||
|
g = new Group(it.KeyNorm);
|
||||||
|
groups[it.KeyNorm] = g;
|
||||||
|
}
|
||||||
|
g.Items.Add(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = groups.Keys.ToList();
|
||||||
|
var uf = new UnionFind(keys.Count);
|
||||||
|
for (int i = 0; i < keys.Count; i++)
|
||||||
|
{
|
||||||
|
for (int j = i + 1; j < keys.Count; j++)
|
||||||
|
{
|
||||||
|
string k1 = keys[i], k2 = keys[j];
|
||||||
|
int maxLen = Math.Max(k1.Length, k2.Length);
|
||||||
|
if (maxLen == 0) continue;
|
||||||
|
int lenDiff = Math.Abs(k1.Length - k2.Length);
|
||||||
|
if (lenDiff > Math.Max(2, (int)Math.Ceiling(maxLen * 0.5))) continue;
|
||||||
|
|
||||||
|
double distNorm = (double)Levenshtein(k1, k2) / maxLen;
|
||||||
|
if (distNorm <= mergeThreshold && CompatibleForMerge(groups[k1], groups[k2]))
|
||||||
|
{
|
||||||
|
uf.Union(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var merged = new Dictionary<int, List<Group>>();
|
||||||
|
for (int i = 0; i < keys.Count; i++)
|
||||||
|
{
|
||||||
|
int root = uf.Find(i);
|
||||||
|
if (!merged.TryGetValue(root, out var list))
|
||||||
|
{
|
||||||
|
list = new List<Group>();
|
||||||
|
merged[root] = list;
|
||||||
|
}
|
||||||
|
list.Add(groups[keys[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new Dictionary<string, List<T>>();
|
||||||
|
foreach (var kv in merged)
|
||||||
|
{
|
||||||
|
var combinedItems = kv.Value.SelectMany(g => g.Items).ToList();
|
||||||
|
var members = combinedItems.Select(it => it.Original).ToList();
|
||||||
|
|
||||||
|
var uniqueMembers = new List<T>();
|
||||||
|
var seen = new HashSet<string>();
|
||||||
|
foreach (var it in combinedItems)
|
||||||
|
if (seen.Add(it.Original)) uniqueMembers.Add((T)it.Payload);
|
||||||
|
|
||||||
|
string rawPrefix = LongestCommonPrefix(members);
|
||||||
|
string groupName = TrimToTokenBoundary(rawPrefix);
|
||||||
|
groupName = Regex.Replace(groupName, @"[\s_\-\.]+$", "");
|
||||||
|
|
||||||
|
result[groupName] = uniqueMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CompatibleForMerge(Group g1, Group g2)
|
||||||
|
{
|
||||||
|
if (g1.HasAnyAlphaTokenCountGreaterThanOne() != g2.HasAnyAlphaTokenCountGreaterThanOne())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (g1.HasTrailingNumber() != g2.HasTrailingNumber())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Helpers & Internal Types
|
||||||
|
private class Item
|
||||||
|
{
|
||||||
|
public string Original { get; }
|
||||||
|
public string[] Tokens { get; }
|
||||||
|
public string KeyOriginal { get; }
|
||||||
|
public string KeyNorm { get; }
|
||||||
|
public int AlphaTokenCount { get; }
|
||||||
|
public bool EndsWithNumber { get; }
|
||||||
|
public object Payload { get; }
|
||||||
|
|
||||||
|
public Item(string original, object payload = null)
|
||||||
|
{
|
||||||
|
Original = original;
|
||||||
|
Payload = payload ?? original;
|
||||||
|
Tokens = TokenizeAlphaNum(Original).ToArray();
|
||||||
|
EndsWithNumber = Tokens.Length > 0 && Regex.IsMatch(Tokens.Last(), "^[0-9]+$");
|
||||||
|
var alphaTokens = Tokens.Where(t => Regex.IsMatch(t, "^[A-Za-z]+$")).ToList();
|
||||||
|
AlphaTokenCount = alphaTokens.Count;
|
||||||
|
|
||||||
|
string candidate;
|
||||||
|
if (EndsWithNumber && alphaTokens.Count >= 1)
|
||||||
|
candidate = alphaTokens.Last();
|
||||||
|
else if (alphaTokens.Count > 0)
|
||||||
|
candidate = alphaTokens.OrderByDescending(t => t.Length).First();
|
||||||
|
else if (Tokens.Length > 0)
|
||||||
|
candidate = Tokens[0];
|
||||||
|
else
|
||||||
|
candidate = Original.Trim();
|
||||||
|
|
||||||
|
KeyOriginal = candidate;
|
||||||
|
KeyNorm = NormalizeKey(candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IEnumerable<string> TokenizeAlphaNum(string s)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(s)) yield break;
|
||||||
|
var matches = Regex.Matches(s, @"[\p{IsCJKUnifiedIdeographs}\p{IsHiragana}\p{IsKatakana}]+|[A-Za-z]+|[0-9]+");
|
||||||
|
foreach (Match m in matches) yield return m.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Group
|
||||||
|
{
|
||||||
|
public string KeyNorm { get; }
|
||||||
|
public List<Item> Items { get; } = new List<Item>();
|
||||||
|
|
||||||
|
public Group(string keyNorm) { KeyNorm = keyNorm; }
|
||||||
|
|
||||||
|
public bool HasAnyAlphaTokenCountGreaterThanOne()
|
||||||
|
=> Items.Any(it => it.AlphaTokenCount > 1);
|
||||||
|
|
||||||
|
public bool HasTrailingNumber()
|
||||||
|
=> Items.Any(it => it.EndsWithNumber);
|
||||||
|
|
||||||
|
public string RepresentativeOriginal()
|
||||||
|
=> Items.Select(i => i.KeyOriginal).FirstOrDefault() ?? KeyNorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeKey(string s)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(s)) return string.Empty;
|
||||||
|
string formD = s.Normalize(NormalizationForm.FormD);
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var ch in formD)
|
||||||
|
{
|
||||||
|
var uc = CharUnicodeInfo.GetUnicodeCategory(ch);
|
||||||
|
if (uc == UnicodeCategory.NonSpacingMark) continue;
|
||||||
|
if (char.IsLetterOrDigit(ch)) sb.Append(char.ToLowerInvariant(ch));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Levenshtein(string a, string b)
|
||||||
|
{
|
||||||
|
int n = a.Length, m = b.Length;
|
||||||
|
if (n == 0) return m;
|
||||||
|
if (m == 0) return n;
|
||||||
|
var d = new int[n + 1, m + 1];
|
||||||
|
for (int i = 0; i <= n; i++) d[i, 0] = i;
|
||||||
|
for (int j = 0; j <= m; j++) d[0, j] = j;
|
||||||
|
for (int i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
for (int j = 1; j <= m; j++)
|
||||||
|
{
|
||||||
|
int cost = (a[i - 1] == b[j - 1]) ? 0 : 1;
|
||||||
|
d[i, j] = Math.Min(
|
||||||
|
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
|
||||||
|
d[i - 1, j - 1] + cost
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d[n, m];
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UnionFind
|
||||||
|
{
|
||||||
|
private int[] _p;
|
||||||
|
public UnionFind(int n) { _p = Enumerable.Range(0, n).ToArray(); }
|
||||||
|
public int Find(int x) { return _p[x] == x ? x : (_p[x] = Find(_p[x])); }
|
||||||
|
public void Union(int a, int b) { a = Find(a); b = Find(b); if (a != b) _p[b] = a; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string LongestCommonPrefix(List<string> strs)
|
||||||
|
{
|
||||||
|
if (strs.Count == 0) return string.Empty;
|
||||||
|
string prefix = strs[0];
|
||||||
|
foreach (var s in strs)
|
||||||
|
{
|
||||||
|
int len = Math.Min(prefix.Length, s.Length);
|
||||||
|
int i = 0;
|
||||||
|
while (i < len && prefix[i] == s[i]) i++;
|
||||||
|
prefix = prefix.Substring(0, i);
|
||||||
|
if (prefix == string.Empty) break;
|
||||||
|
}
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string TrimToTokenBoundary(string prefix)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(prefix)) return string.Empty;
|
||||||
|
|
||||||
|
var boundary = new Regex(@"[\s0-9_\-\.]");
|
||||||
|
int lastBoundary = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < prefix.Length; i++)
|
||||||
|
{
|
||||||
|
if (boundary.IsMatch(prefix[i].ToString()))
|
||||||
|
lastBoundary = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBoundary >= 0)
|
||||||
|
{
|
||||||
|
return prefix.Substring(0, lastBoundary).TrimEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -9,4 +9,5 @@ public class Video
|
|||||||
public bool star;
|
public bool star;
|
||||||
public uint like;
|
public uint like;
|
||||||
public string author;
|
public string author;
|
||||||
|
public string? group;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
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.Components.Services;
|
||||||
|
using Abyss.Misc;
|
||||||
|
using Abyss.Model;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Abyss;
|
namespace Abyss;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user