├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.en.yml │ ├── bug-report.zh.yml │ ├── config.yml │ ├── feature-request.en.yml │ └── feature-request.zh.yml ├── PULL_REQUEST_TEMPLATE └── workflows │ ├── ikaros-server-ci.yml │ ├── ikaros_ci_build_dev_container.yml │ ├── ikaros_ci_build_fastjar.yml │ ├── ikaros_ci_build_tag_container.yml │ └── ikaros_ci_release_by_tag.yml ├── .gitignore ├── .gitmodules ├── .run └── RunAppOnWindows.run.xml ├── BUILD.MD ├── CHANGELOG.MD ├── CONTRIBUTING.MD ├── Dockerfile ├── LICENSE ├── README.MD ├── api ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── run │ │ └── ikaros │ │ └── api │ │ ├── constant │ │ ├── AppConst.java │ │ ├── FileConst.java │ │ ├── OpenApiConst.java │ │ ├── SecurityConst.java │ │ └── StringConst.java │ │ ├── core │ │ ├── attachment │ │ │ ├── Attachment.java │ │ │ ├── AttachmentConst.java │ │ │ ├── AttachmentOperate.java │ │ │ ├── AttachmentReference.java │ │ │ ├── AttachmentReferenceOperate.java │ │ │ ├── AttachmentRelation.java │ │ │ ├── AttachmentRelationOperate.java │ │ │ ├── AttachmentSearchCondition.java │ │ │ ├── AttachmentUploadCondition.java │ │ │ ├── VideoSubtitle.java │ │ │ └── exception │ │ │ │ ├── AttachmentException.java │ │ │ │ ├── AttachmentExistsException.java │ │ │ │ ├── AttachmentNotFoundException.java │ │ │ │ ├── AttachmentParentNotFoundException.java │ │ │ │ ├── AttachmentRefMatchingException.java │ │ │ │ ├── AttachmentRemoveException.java │ │ │ │ └── AttachmentUploadException.java │ │ ├── authority │ │ │ ├── Authority.java │ │ │ └── AuthorityCondition.java │ │ ├── character │ │ │ └── Character.java │ │ ├── collection │ │ │ ├── CollectionOperate.java │ │ │ ├── EpisodeCollection.java │ │ │ ├── EpisodeCollectionOperate.java │ │ │ ├── SubjectCollection.java │ │ │ ├── SubjectCollectionOperate.java │ │ │ ├── event │ │ │ │ ├── EpisodeCollectionFinishChangeEvent.java │ │ │ │ ├── SubjectCollectEvent.java │ │ │ │ ├── SubjectCollectProgressChangeEvent.java │ │ │ │ ├── SubjectCollectionUpdateEvent.java │ │ │ │ └── SubjectUnCollectEvent.java │ │ │ └── vo │ │ │ │ └── FindCollectionCondition.java │ │ ├── meta │ │ │ ├── DelegateMetaService.java │ │ │ └── MetaOperate.java │ │ ├── person │ │ │ └── Person.java │ │ ├── role │ │ │ ├── Role.java │ │ │ └── RoleAuthorityReqParams.java │ │ ├── setting │ │ │ ├── ConfigMap.java │ │ │ └── vo │ │ │ │ ├── BasicSetting.java │ │ │ │ ├── GlobalSetting.java │ │ │ │ ├── MailProtocol.java │ │ │ │ ├── MailSetting.java │ │ │ │ └── UserSetting.java │ │ ├── subject │ │ │ ├── Episode.java │ │ │ ├── EpisodeOperate.java │ │ │ ├── EpisodeRecord.java │ │ │ ├── EpisodeResource.java │ │ │ ├── Subject.java │ │ │ ├── SubjectFinder.java │ │ │ ├── SubjectOperate.java │ │ │ ├── SubjectRelation.java │ │ │ ├── SubjectRelationOperate.java │ │ │ ├── SubjectSync.java │ │ │ ├── SubjectSyncOperate.java │ │ │ ├── SubjectSynchronizer.java │ │ │ └── vo │ │ │ │ ├── BatchMatchingEpisodeFile.java │ │ │ │ ├── FindSubjectCondition.java │ │ │ │ └── PostSubjectSyncCondition.java │ │ ├── tag │ │ │ ├── AttachmentTag.java │ │ │ ├── SubjectTag.java │ │ │ ├── Tag.java │ │ │ └── TagOperate.java │ │ ├── task │ │ │ └── TaskOperate.java │ │ └── user │ │ │ ├── UserRoleReqParams.java │ │ │ └── enums │ │ │ └── VerificationCodeType.java │ │ ├── custom │ │ ├── Custom.java │ │ ├── GroupVersionKind.java │ │ ├── Name.java │ │ ├── ReactiveCustomClient.java │ │ ├── exception │ │ │ ├── CustomConvertException.java │ │ │ ├── CustomException.java │ │ │ └── CustomSchemeNotFoundException.java │ │ └── scheme │ │ │ ├── CustomScheme.java │ │ │ └── CustomSchemeManager.java │ │ ├── endpoint │ │ ├── CustomEndpoint.java │ │ └── Endpoint.java │ │ ├── infra │ │ ├── exception │ │ │ ├── NotFoundException.java │ │ │ ├── RegexMatchingException.java │ │ │ ├── console │ │ │ │ └── LoadConsoleBundleException.java │ │ │ ├── file │ │ │ │ ├── FileExistsException.java │ │ │ │ ├── FolderExistsException.java │ │ │ │ ├── FolderHasChildException.java │ │ │ │ ├── FolderNotFoundException.java │ │ │ │ └── ParentFolderNotExistsException.java │ │ │ ├── plugin │ │ │ │ ├── PluginDisabledException.java │ │ │ │ ├── PluginInstallException.java │ │ │ │ └── PluginUpgradeException.java │ │ │ ├── security │ │ │ │ ├── InvalidTokenException.java │ │ │ │ ├── PasswordNotMatchingException.java │ │ │ │ └── UserAuthenticationException.java │ │ │ ├── subject │ │ │ │ ├── EpisodeNotFoundException.java │ │ │ │ ├── NoAvailableSubjectPlatformSynchronizerException.java │ │ │ │ └── SubjectNotFoundException.java │ │ │ └── user │ │ │ │ ├── UserExistsException.java │ │ │ │ └── UserNotFoundException.java │ │ ├── properties │ │ │ └── IkarosProperties.java │ │ └── utils │ │ │ ├── AssertUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── ReactiveBeanUtils.java │ │ │ ├── ReflectUtils.java │ │ │ ├── RegexConst.java │ │ │ ├── RegexUtils.java │ │ │ ├── StringUtils.java │ │ │ └── SystemVarUtils.java │ │ ├── plugin │ │ ├── AllowPluginOperate.java │ │ ├── BasePlugin.java │ │ ├── PluginConst.java │ │ ├── custom │ │ │ └── Plugin.java │ │ └── event │ │ │ ├── PluginAwareEvent.java │ │ │ ├── PluginConfigMapChangeEvent.java │ │ │ ├── PluginConfigMapCreateEvent.java │ │ │ └── PluginConfigMapUpdateEvent.java │ │ ├── search │ │ ├── IndicesSearchService.java │ │ ├── SearchParam.java │ │ ├── SearchResult.java │ │ └── subject │ │ │ ├── SubjectDoc.java │ │ │ ├── SubjectHint.java │ │ │ └── SubjectSearchService.java │ │ ├── store │ │ └── enums │ │ │ ├── AttachmentReferenceType.java │ │ │ ├── AttachmentRelationType.java │ │ │ ├── AttachmentType.java │ │ │ ├── AuthorityType.java │ │ │ ├── CollectionCategory.java │ │ │ ├── CollectionType.java │ │ │ ├── EpisodeGroup.java │ │ │ ├── FileRelationType.java │ │ │ ├── FileType.java │ │ │ ├── SubjectRelationType.java │ │ │ ├── SubjectSyncPlatform.java │ │ │ ├── SubjectType.java │ │ │ ├── TagType.java │ │ │ └── TaskStatus.java │ │ └── wrap │ │ ├── CommonResult.java │ │ └── PagingWrap.java │ └── test │ └── java │ └── run │ └── ikaros │ └── api │ └── infra │ └── utils │ ├── FileUtilsTest.java │ ├── RegexConstTest.java │ └── RegexUtilsTest.java ├── assets └── logo.png ├── config ├── checkstyle │ └── checkstyle.xml └── server │ └── resource │ └── application-local.yaml.example ├── console ├── .env.development ├── .env.production ├── .eslintrc-auto-import.json ├── .eslintrc.cjs ├── .eslintrcignore ├── .gitignore ├── .husky │ ├── commit-msg │ └── pre-commit ├── .prettierignore ├── .prettierrc.cjs ├── LICENSE ├── README.md ├── commitlint.config.cjs ├── index.html ├── package.json ├── packages │ ├── api-client │ │ ├── .eslintignore │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── .prettierrc.cjs │ │ ├── README.md │ │ ├── build.config.ts │ │ ├── openapitools.json │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── .gitignore │ │ │ ├── .npmignore │ │ │ ├── .openapi-generator-ignore │ │ │ ├── .openapi-generator │ │ │ │ ├── FILES │ │ │ │ └── VERSION │ │ │ ├── .openapi_config.yaml │ │ │ ├── api.ts │ │ │ ├── api │ │ │ │ ├── actuator-api.ts │ │ │ │ ├── file-ikaros-run-v1alpha1-file-policy-api.ts │ │ │ │ ├── file-ikaros-run-v1alpha1-file-setting-api.ts │ │ │ │ ├── plugin-ikaros-run-v1alpha1-plugin-api.ts │ │ │ │ ├── plugin-ikaros-run-v1alpha1-stater-api.ts │ │ │ │ ├── setting-ikaros-run-v1alpha1-config-map-api.ts │ │ │ │ ├── setting-ikaros-run-v1alpha1-configmap-api.ts │ │ │ │ ├── starter-ikaros-run-v1alpha1-starter-custom-api.ts │ │ │ │ ├── v1alpha1-attachment-api.ts │ │ │ │ ├── v1alpha1-attachment-reference-api.ts │ │ │ │ ├── v1alpha1-attachment-relation-api.ts │ │ │ │ ├── v1alpha1-authority-api.ts │ │ │ │ ├── v1alpha1-collection-api.ts │ │ │ │ ├── v1alpha1-collection-episode-api.ts │ │ │ │ ├── v1alpha1-collection-subject-api.ts │ │ │ │ ├── v1alpha1-episode-api.ts │ │ │ │ ├── v1alpha1-episode-collection-api.ts │ │ │ │ ├── v1alpha1-episode-file-api.ts │ │ │ │ ├── v1alpha1-file-api.ts │ │ │ │ ├── v1alpha1-file-relation-api.ts │ │ │ │ ├── v1alpha1-folder-api.ts │ │ │ │ ├── v1alpha1-indices-api.ts │ │ │ │ ├── v1alpha1-notify-api.ts │ │ │ │ ├── v1alpha1-plugin-api.ts │ │ │ │ ├── v1alpha1-role-api.ts │ │ │ │ ├── v1alpha1-role-authority-api.ts │ │ │ │ ├── v1alpha1-security-api.ts │ │ │ │ ├── v1alpha1-static-api.ts │ │ │ │ ├── v1alpha1-subject-api.ts │ │ │ │ ├── v1alpha1-subject-collection-api.ts │ │ │ │ ├── v1alpha1-subject-relation-api.ts │ │ │ │ ├── v1alpha1-subject-sync-api.ts │ │ │ │ ├── v1alpha1-subject-sync-platform-api.ts │ │ │ │ ├── v1alpha1-tag-api.ts │ │ │ │ ├── v1alpha1-task-api.ts │ │ │ │ ├── v1alpha1-user-api.ts │ │ │ │ ├── v1alpha1-user-me-api.ts │ │ │ │ └── v1alpha1-user-role-api.ts │ │ │ ├── base.ts │ │ │ ├── common.ts │ │ │ ├── configuration.ts │ │ │ ├── git_push.sh │ │ │ ├── index.ts │ │ │ └── models │ │ │ │ ├── alist-import-post-body.ts │ │ │ │ ├── attachment-reference.ts │ │ │ │ ├── attachment-relation.ts │ │ │ │ ├── attachment-tag.ts │ │ │ │ ├── attachment.ts │ │ │ │ ├── author.ts │ │ │ │ ├── authority.ts │ │ │ │ ├── batch-matching-episode-attachment.ts │ │ │ │ ├── batch-matching-episode-file.ts │ │ │ │ ├── batch-matching-subject-episodes-attachment.ts │ │ │ │ ├── config-map.ts │ │ │ │ ├── create-user-req-params.ts │ │ │ │ ├── episode-collection.ts │ │ │ │ ├── episode-meta.ts │ │ │ │ ├── episode-record.ts │ │ │ │ ├── episode-resource.ts │ │ │ │ ├── episode.ts │ │ │ │ ├── file-batch-request.ts │ │ │ │ ├── file-entity.ts │ │ │ │ ├── file-hint.ts │ │ │ │ ├── file-hints.ts │ │ │ │ ├── file-policy.ts │ │ │ │ ├── file-relations.ts │ │ │ │ ├── file-setting.ts │ │ │ │ ├── find-file-condition.ts │ │ │ │ ├── folder.ts │ │ │ │ ├── index.ts │ │ │ │ ├── jwt-apply-param.ts │ │ │ │ ├── jwt-apply-response.ts │ │ │ │ ├── link.ts │ │ │ │ ├── model-file.ts │ │ │ │ ├── paging-wrap.ts │ │ │ │ ├── plugin-load-location-file-system.ts │ │ │ │ ├── plugin-load-location.ts │ │ │ │ ├── plugin.ts │ │ │ │ ├── post-attachment-relations-param.ts │ │ │ │ ├── role-authority-req-params.ts │ │ │ │ ├── role.ts │ │ │ │ ├── starter-custom.ts │ │ │ │ ├── subject-collection.ts │ │ │ │ ├── subject-hint.ts │ │ │ │ ├── subject-hints.ts │ │ │ │ ├── subject-image.ts │ │ │ │ ├── subject-relation.ts │ │ │ │ ├── subject-sync.ts │ │ │ │ ├── subject-tag.ts │ │ │ │ ├── subject.ts │ │ │ │ ├── subtitle.ts │ │ │ │ ├── tag.ts │ │ │ │ ├── task-entity.ts │ │ │ │ ├── update-user-request.ts │ │ │ │ ├── user-entity.ts │ │ │ │ ├── user-role-req-params.ts │ │ │ │ ├── user.ts │ │ │ │ └── video-subtitle.ts │ │ └── tsconfig.json │ └── shared │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ ├── src │ │ ├── core │ │ │ └── plugins.ts │ │ ├── index.ts │ │ └── types │ │ │ ├── menus.ts │ │ │ └── plugin.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── public │ ├── favicon.ico │ ├── js │ │ └── JavascriptSubtitlesOctopus │ │ │ ├── subtitles-octopus-worker.data │ │ │ ├── subtitles-octopus-worker.js │ │ │ ├── subtitles-octopus-worker.wasm │ │ │ └── subtitles-octopus.js │ └── svg │ │ └── subtitle.svg ├── src │ ├── App.vue │ ├── components │ │ ├── HelloWorld.vue │ │ ├── global-search │ │ │ └── GlobalSearchDialog.vue │ │ ├── icon │ │ │ └── IconParkOutlinePlug.vue │ │ ├── image │ │ │ ├── Cropperjs.vue │ │ │ └── CropperjsDialog.vue │ │ ├── modules │ │ │ └── content │ │ │ │ ├── attachment │ │ │ │ └── AttachmentDirectoryTreeSelect.vue │ │ │ │ └── subject │ │ │ │ ├── SubjectCard.vue │ │ │ │ ├── SubjectCardLink.vue │ │ │ │ └── SubjectCollectDialog.vue │ │ ├── upload │ │ │ ├── AttachmentPondUpload.vue │ │ │ └── UppyUpload.vue │ │ └── video │ │ │ └── Artplayer.vue │ ├── fromkit │ │ ├── formkit.config.ts │ │ └── inputs │ │ │ └── form.ts │ ├── layouts │ │ ├── Aside.vue │ │ ├── BasicLayout.vue │ │ ├── BlankLayout.vue │ │ ├── Header.vue │ │ ├── components │ │ │ ├── Avatar.vue │ │ │ ├── Breadcrumb.vue │ │ │ ├── Hamburger.vue │ │ │ ├── LanguageSelect.vue │ │ │ └── Wellcome.vue │ │ └── menus.config.ts │ ├── libs │ │ └── JavascriptSubtitlesOctopus │ │ │ └── subtitles-octopus.js │ ├── locales │ │ ├── en.yaml │ │ ├── index.ts │ │ └── zh-CN.yaml │ ├── main.ts │ ├── modules │ │ ├── common │ │ │ └── constants.ts │ │ ├── content │ │ │ ├── attachment │ │ │ │ ├── AttachmentDeatilDrawer.vue │ │ │ │ ├── AttachmentDirectorySelectDialog.vue │ │ │ │ ├── AttachmentFragmentUploadDrawer.vue │ │ │ │ ├── AttachmentMultiSelectDialog.vue │ │ │ │ ├── AttachmentRelationsDialog.vue │ │ │ │ ├── AttachmentSelectDialog.vue │ │ │ │ ├── Attachments.vue │ │ │ │ └── module.ts │ │ │ └── subject │ │ │ │ ├── EpisodeDetailsDialog.vue │ │ │ │ ├── EpisodePostDialog.vue │ │ │ │ ├── EpisodePutDialog.vue │ │ │ │ ├── SubjectDetails.vue │ │ │ │ ├── SubjectPost.vue │ │ │ │ ├── SubjectPut.vue │ │ │ │ ├── SubjectRelactionDeleteDrawer.vue │ │ │ │ ├── SubjectRelationDeleteDialog.vue │ │ │ │ ├── SubjectRelationDialog.vue │ │ │ │ ├── SubjectRelationPostDialog.vue │ │ │ │ ├── SubjectRemoteActionDialog.vue │ │ │ │ ├── SubjectSelectDrawer.vue │ │ │ │ ├── SubjectSyncDialog.vue │ │ │ │ ├── SubjectTagEditDialog.vue │ │ │ │ ├── Subjects.vue │ │ │ │ └── module.ts │ │ ├── dashboard │ │ │ ├── Dashboard.vue │ │ │ └── module.ts │ │ ├── index.ts │ │ ├── system │ │ │ ├── about │ │ │ │ ├── About.vue │ │ │ │ └── module.ts │ │ │ ├── plugin │ │ │ │ ├── Plugin.vue │ │ │ │ ├── PluginDetail.vue │ │ │ │ ├── PluginUploadDrawer.vue │ │ │ │ └── module.ts │ │ │ ├── role │ │ │ │ ├── RoleAuthorities.vue │ │ │ │ ├── Roles.vue │ │ │ │ └── module.ts │ │ │ ├── setting │ │ │ │ ├── Setting.vue │ │ │ │ └── module.ts │ │ │ ├── task │ │ │ │ ├── TaskDetails.vue │ │ │ │ ├── Tasks.vue │ │ │ │ └── module.ts │ │ │ └── user │ │ │ │ ├── Users.vue │ │ │ │ └── module.ts │ │ └── user │ │ │ ├── Collection.vue │ │ │ ├── Login.vue │ │ │ ├── Profile.vue │ │ │ └── module.ts │ ├── router │ │ ├── guards │ │ │ └── auth-check.ts │ │ ├── index.ts │ │ └── routes.config.ts │ ├── stores │ │ ├── font.ts │ │ ├── index.ts │ │ ├── layout.ts │ │ ├── plugin.ts │ │ ├── setting.ts │ │ ├── subject.ts │ │ └── user.ts │ ├── styles │ │ ├── index.scss │ │ ├── reset.scss │ │ └── variables.module.scss │ ├── utils │ │ ├── api-client.ts │ │ ├── date.ts │ │ ├── file.ts │ │ ├── id.ts │ │ ├── moment.ts │ │ └── string-util.ts │ ├── views │ │ ├── exception │ │ │ ├── Exception.vue │ │ │ ├── Forbidden.vue │ │ │ └── NotFound.vue │ │ └── system │ │ │ └── Redirect.vue │ └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lombok.config ├── platform ├── plugin │ └── build.gradle └── server │ └── build.gradle ├── server ├── .gitignore ├── build.gradle └── src │ ├── main │ ├── java │ │ └── run │ │ │ └── ikaros │ │ │ └── server │ │ │ ├── IkarosApplication.java │ │ │ ├── cache │ │ │ ├── CacheAspect.java │ │ │ ├── CacheConfiguration.java │ │ │ ├── CacheProperties.java │ │ │ ├── CacheType.java │ │ │ ├── MemoryReactiveCacheManager.java │ │ │ ├── ReactiveCacheManager.java │ │ │ ├── RedisAutoConfigDisableConfiguration.java │ │ │ ├── RedisReactiveCacheManager.java │ │ │ ├── annotation │ │ │ │ ├── FluxCacheEvict.java │ │ │ │ ├── FluxCacheable.java │ │ │ │ ├── MonoCacheEvict.java │ │ │ │ └── MonoCacheable.java │ │ │ └── condition │ │ │ │ ├── CacheMemoryEnableCondition.java │ │ │ │ ├── CacheRedisDisableCondition.java │ │ │ │ └── CacheRedisEnableCondition.java │ │ │ ├── config │ │ │ ├── AsyncConfiguration.java │ │ │ ├── FlywayDatabaseConfig.java │ │ │ ├── GlobalExceptionHandlerConfig.java │ │ │ ├── IkarosConfiguration.java │ │ │ ├── ScheduledConfiguration.java │ │ │ ├── SwaggerConfig.java │ │ │ ├── TaskConfiguration.java │ │ │ ├── ThemeConfig.java │ │ │ └── WebFluxConfig.java │ │ │ ├── console │ │ │ ├── ConsoleAutoConfiguration.java │ │ │ └── ConsoleProperties.java │ │ │ ├── controller │ │ │ ├── AppLinkController.java │ │ │ ├── IndexController.java │ │ │ └── SubjectController.java │ │ │ ├── core │ │ │ ├── CoreCustomSchemeInitializer.java │ │ │ ├── actuator │ │ │ │ └── IkarosAppInfoContributor.java │ │ │ ├── attachment │ │ │ │ ├── endpoint │ │ │ │ │ ├── AttachmentEndpoint.java │ │ │ │ │ ├── AttachmentReferenceEndpoint.java │ │ │ │ │ └── AttachmentRelationEndpoint.java │ │ │ │ ├── event │ │ │ │ │ ├── AttachmentReferenceSaveEvent.java │ │ │ │ │ ├── AttachmentRemoveEvent.java │ │ │ │ │ └── EpisodeAttachmentUpdateEvent.java │ │ │ │ ├── listener │ │ │ │ │ ├── AttachmentRefSubjectCoverChangeListener.java │ │ │ │ │ ├── AttachmentRefUserAvatarUpdateListener.java │ │ │ │ │ ├── AttachmentRelVideoSubtitleListener.java │ │ │ │ │ ├── AttachmentRemoveListener.java │ │ │ │ │ └── AttachmentSubjectCoverChangeListener.java │ │ │ │ ├── operator │ │ │ │ │ ├── AttachmentOperator.java │ │ │ │ │ ├── AttachmentReferenceOperator.java │ │ │ │ │ └── AttachmentRelationOperator.java │ │ │ │ ├── service │ │ │ │ │ ├── AttachmentReferenceService.java │ │ │ │ │ ├── AttachmentRelationService.java │ │ │ │ │ ├── AttachmentService.java │ │ │ │ │ └── impl │ │ │ │ │ │ ├── AttachmentReferenceServiceImpl.java │ │ │ │ │ │ ├── AttachmentRelationServiceImpl.java │ │ │ │ │ │ └── AttachmentServiceImpl.java │ │ │ │ └── vo │ │ │ │ │ ├── BatchMatchingEpisodeAttachment.java │ │ │ │ │ ├── BatchMatchingSubjectEpisodesAttachment.java │ │ │ │ │ └── PostAttachmentRelationsParam.java │ │ │ ├── authority │ │ │ │ ├── AuthorityEndpoint.java │ │ │ │ ├── AuthorityInitializer.java │ │ │ │ ├── AuthorityService.java │ │ │ │ └── DefaultAuthorityService.java │ │ │ ├── collection │ │ │ │ ├── CollectionEndpoint.java │ │ │ │ ├── CollectionService.java │ │ │ │ ├── CollectionSubjectRemoveEventListener.java │ │ │ │ ├── DefaultCollectionService.java │ │ │ │ ├── EpisodeCollectionEndpoint.java │ │ │ │ ├── EpisodeCollectionOperator.java │ │ │ │ ├── EpisodeCollectionService.java │ │ │ │ ├── EpisodeCollectionServiceImpl.java │ │ │ │ ├── SubjectCollectionEndpoint.java │ │ │ │ ├── SubjectCollectionImpl.java │ │ │ │ ├── SubjectCollectionOperator.java │ │ │ │ ├── SubjectCollectionService.java │ │ │ │ ├── event │ │ │ │ │ ├── SubjectCollectionCreateEvent.java │ │ │ │ │ └── SubjectCollectionScoreUpdateEvent.java │ │ │ │ └── listener │ │ │ │ │ └── SubjectCollectionCreateEventListener.java │ │ │ ├── episode │ │ │ │ ├── DefaultEpisodeOperate.java │ │ │ │ ├── DefaultEpisodeService.java │ │ │ │ ├── EpisodeAttachmentUpdateEventListener.java │ │ │ │ ├── EpisodeEndpoint.java │ │ │ │ ├── EpisodeRemoveEvent.java │ │ │ │ ├── EpisodeRemoveEventListener.java │ │ │ │ └── EpisodeService.java │ │ │ ├── meta │ │ │ │ ├── DefaultMetaService.java │ │ │ │ ├── MetaOperator.java │ │ │ │ └── MetaService.java │ │ │ ├── notify │ │ │ │ ├── MailService.java │ │ │ │ ├── NotifyEndpoint.java │ │ │ │ ├── NotifyService.java │ │ │ │ ├── model │ │ │ │ │ ├── MailConfig.java │ │ │ │ │ ├── MailProtocol.java │ │ │ │ │ └── MailRequest.java │ │ │ │ └── service │ │ │ │ │ ├── MailServiceImpl.java │ │ │ │ │ └── NotifyServiceImpl.java │ │ │ ├── plugin │ │ │ │ ├── PluginCoreEndpoint.java │ │ │ │ ├── PluginOperate.java │ │ │ │ ├── PluginService.java │ │ │ │ ├── PluginServiceImpl.java │ │ │ │ └── PluginStateOperate.java │ │ │ ├── profile │ │ │ │ └── Unstructured.java │ │ │ ├── role │ │ │ │ ├── DefaultRoleAuthorityService.java │ │ │ │ ├── DefaultRoleService.java │ │ │ │ ├── RoleAuthorityEndpoint.java │ │ │ │ ├── RoleAuthorityService.java │ │ │ │ ├── RoleEndpoint.java │ │ │ │ ├── RoleService.java │ │ │ │ ├── event │ │ │ │ │ ├── RoleChangeEvent.java │ │ │ │ │ ├── RoleCreatedEvent.java │ │ │ │ │ ├── RoleRelationChangeEvent.java │ │ │ │ │ ├── RoleRelationCreatedEvent.java │ │ │ │ │ ├── RoleRelationRemoveEvent.java │ │ │ │ │ └── RoleRemoveEvent.java │ │ │ │ └── listener │ │ │ │ │ ├── RoleCreatedListener.java │ │ │ │ │ ├── RoleRelationListener.java │ │ │ │ │ └── RoleRemoveListener.java │ │ │ ├── setting │ │ │ │ ├── DefaultSettingService.java │ │ │ │ ├── SettingService.java │ │ │ │ └── SystemSettingInitListener.java │ │ │ ├── statics │ │ │ │ ├── StaticEndpoint.java │ │ │ │ ├── StaticService.java │ │ │ │ └── StaticServiceImpl.java │ │ │ ├── subject │ │ │ │ ├── SubjectOperator.java │ │ │ │ ├── SubjectRelationCourt.java │ │ │ │ ├── SubjectRelationOperator.java │ │ │ │ ├── SubjectSyncOperator.java │ │ │ │ ├── endpoint │ │ │ │ │ ├── SubjectEndpoint.java │ │ │ │ │ ├── SubjectRelationEndpoint.java │ │ │ │ │ └── SubjectSyncEndpoint.java │ │ │ │ ├── event │ │ │ │ │ ├── SubjectAddEvent.java │ │ │ │ │ ├── SubjectRemoveEvent.java │ │ │ │ │ └── SubjectUpdateEvent.java │ │ │ │ ├── listener │ │ │ │ │ ├── SubjectAddEventListener.java │ │ │ │ │ └── SubjectCollectionScoreUpdateEventListener.java │ │ │ │ └── service │ │ │ │ │ ├── SubjectRelationService.java │ │ │ │ │ ├── SubjectService.java │ │ │ │ │ ├── SubjectSyncService.java │ │ │ │ │ └── impl │ │ │ │ │ ├── SubjectRelationServiceImpl.java │ │ │ │ │ ├── SubjectServiceImpl.java │ │ │ │ │ └── SubjectSyncServiceImpl.java │ │ │ ├── tag │ │ │ │ ├── DefaultTagOperator.java │ │ │ │ ├── DefaultTagService.java │ │ │ │ ├── TagEndpoint.java │ │ │ │ ├── TagService.java │ │ │ │ ├── event │ │ │ │ │ ├── TagChangeEvent.java │ │ │ │ │ ├── TagCreateEvent.java │ │ │ │ │ └── TagRemoveEvent.java │ │ │ │ └── listener │ │ │ │ │ └── TagChangeEventListener.java │ │ │ ├── task │ │ │ │ ├── FindTaskCondition.java │ │ │ │ ├── PluginTask.java │ │ │ │ ├── Task.java │ │ │ │ ├── TaskEndpoint.java │ │ │ │ ├── TaskInit.java │ │ │ │ ├── TaskOperator.java │ │ │ │ ├── TaskService.java │ │ │ │ └── TaskServiceImpl.java │ │ │ ├── user │ │ │ │ ├── CreateUserReqParams.java │ │ │ │ ├── UpdateUserRequest.java │ │ │ │ ├── User.java │ │ │ │ ├── UserAvatarUpdateEvent.java │ │ │ │ ├── UserEndpoint.java │ │ │ │ ├── UserService.java │ │ │ │ ├── UserServiceImpl.java │ │ │ │ ├── me │ │ │ │ │ └── UserMeEndpoint.java │ │ │ │ └── role │ │ │ │ │ ├── DefaultUserRoleService.java │ │ │ │ │ ├── UserRoleEndpoint.java │ │ │ │ │ └── UserRoleService.java │ │ │ └── webclient │ │ │ │ ├── WeClientService.java │ │ │ │ ├── WeClientServiceImpl.java │ │ │ │ ├── WebClientConfig.java │ │ │ │ └── WebClientConst.java │ │ │ ├── custom │ │ │ ├── CustomAutoConfiguration.java │ │ │ ├── CustomClient.java │ │ │ ├── CustomClientImpl.java │ │ │ ├── CustomConverter.java │ │ │ ├── CustomDto.java │ │ │ ├── ReactiveCustomClientImpl.java │ │ │ ├── event │ │ │ │ ├── CustomCreateEvent.java │ │ │ │ ├── CustomDeleteEvent.java │ │ │ │ └── CustomUpdateEvent.java │ │ │ ├── router │ │ │ │ ├── CustomCompositeRouterFunction.java │ │ │ │ ├── CustomCreateHandler.java │ │ │ │ ├── CustomDeleteHandler.java │ │ │ │ ├── CustomGetHandler.java │ │ │ │ ├── CustomGetMetaHandler.java │ │ │ │ ├── CustomListHandler.java │ │ │ │ ├── CustomListPagingHandler.java │ │ │ │ ├── CustomRouterFunctionFactory.java │ │ │ │ ├── CustomUpdateHandler.java │ │ │ │ └── CustomUpdateMetaHandler.java │ │ │ └── scheme │ │ │ │ ├── CustomSchemeWatcherManager.java │ │ │ │ ├── DefaultCustomSchemeManager.java │ │ │ │ ├── DefaultCustomSchemeWatcherManager.java │ │ │ │ └── SchemeInitializedEvent.java │ │ │ ├── endpoint │ │ │ ├── CoreEndpoint.java │ │ │ ├── CoreEndpointsBuilder.java │ │ │ ├── CustomEndpointsBuilder.java │ │ │ └── EndpointsBuilder.java │ │ │ ├── infra │ │ │ ├── constants │ │ │ │ ├── NumberConst.java │ │ │ │ ├── SettingKeyConst.java │ │ │ │ ├── ThemeConst.java │ │ │ │ └── ThymeleafConst.java │ │ │ ├── properties │ │ │ │ └── IkarosTaskProperties.java │ │ │ └── utils │ │ │ │ ├── AesEncryptUtils.java │ │ │ │ ├── ByteArrUtils.java │ │ │ │ ├── DataBufferUtils.java │ │ │ │ ├── GenericClassUtils.java │ │ │ │ ├── JsonUtils.java │ │ │ │ ├── PathUtils.java │ │ │ │ ├── QueryParamBuildUtil.java │ │ │ │ ├── RandomUtils.java │ │ │ │ ├── SqlUtils.java │ │ │ │ └── TimeUtils.java │ │ │ ├── plugin │ │ │ ├── BasePluginFactory.java │ │ │ ├── ExtensionComponentsFinder.java │ │ │ ├── FixedPathDevelopmentPluginRepository.java │ │ │ ├── IkarosDevelopmentPluginLoader.java │ │ │ ├── IkarosExtensionFactory.java │ │ │ ├── IkarosExtensionFinder.java │ │ │ ├── IkarosJarPluginLoader.java │ │ │ ├── IkarosPluginDescriptor.java │ │ │ ├── IkarosPluginManager.java │ │ │ ├── PluginApplicationContext.java │ │ │ ├── PluginApplicationContextRegistry.java │ │ │ ├── PluginApplicationInitializer.java │ │ │ ├── PluginConfiguration.java │ │ │ ├── PluginException.java │ │ │ ├── PluginExtensionAnnotationPostProcessor.java │ │ │ ├── PluginProperties.java │ │ │ ├── PluginStartingError.java │ │ │ ├── PropertyPluginStatusProvider.java │ │ │ ├── SharedApplicationContext.java │ │ │ ├── SharedApplicationContextHolder.java │ │ │ ├── YamlPluginDescriptorFinder.java │ │ │ ├── YamlPluginFinder.java │ │ │ ├── YamlPluginLoader.java │ │ │ ├── event │ │ │ │ └── IkarosPluginDeleteEvent.java │ │ │ ├── listener │ │ │ │ ├── ApplicationReadyEventPluginBroadcaster.java │ │ │ │ ├── ConfigMapCustomCreateEventListener.java │ │ │ │ ├── ConfigMapCustomUpdateEventListener.java │ │ │ │ ├── IkarosPluginDeleteEventListener.java │ │ │ │ ├── PluginAwareEventListener.java │ │ │ │ ├── PluginDatabaseUtils.java │ │ │ │ ├── PluginPropertiesEnablesInitListener.java │ │ │ │ └── PluginStateChangedListener.java │ │ │ └── resource │ │ │ │ ├── BundleResourceUtils.java │ │ │ │ ├── PluginCompositeRouterFunction.java │ │ │ │ └── PluginResourceProxyRouterFunctionRegistry.java │ │ │ ├── search │ │ │ ├── IndicesConfiguration.java │ │ │ ├── IndicesEndpoint.java │ │ │ ├── IndicesInitializer.java │ │ │ ├── IndicesProperties.java │ │ │ ├── IndicesService.java │ │ │ ├── IndicesServiceImpl.java │ │ │ └── subject │ │ │ │ ├── LuceneSubjectSearchService.java │ │ │ │ ├── ReactiveSubjectDocConverter.java │ │ │ │ └── SubjectEventListener.java │ │ │ ├── security │ │ │ ├── CorsConfigurer.java │ │ │ ├── CsrfConfigurer.java │ │ │ ├── DefaultUserDetailService.java │ │ │ ├── IkarosGrantedAuthority.java │ │ │ ├── MasterInitializer.java │ │ │ ├── SecurityConfiguration.java │ │ │ ├── SecurityEndpoint.java │ │ │ ├── SecurityProperties.java │ │ │ ├── authentication │ │ │ │ ├── SecurityConfigurer.java │ │ │ │ ├── basicauth │ │ │ │ │ ├── BasicAuthenticationConfigurer.java │ │ │ │ │ └── BasicAuthenticationFilter.java │ │ │ │ ├── formlogin │ │ │ │ │ ├── FormLoginConfigurer.java │ │ │ │ │ ├── FormLoginFailureHandler.java │ │ │ │ │ └── FormLoginSuccessHandler.java │ │ │ │ ├── jwt │ │ │ │ │ ├── JwtApplyParam.java │ │ │ │ │ ├── JwtApplyResponse.java │ │ │ │ │ ├── JwtAuthenticationConfigurer.java │ │ │ │ │ ├── JwtAuthenticationFilter.java │ │ │ │ │ ├── JwtAuthenticationProvider.java │ │ │ │ │ └── JwtReactiveAuthenticationManager.java │ │ │ │ ├── logout │ │ │ │ │ ├── LogoutConfigurer.java │ │ │ │ │ └── LogoutSuccessHandler.java │ │ │ │ └── oauth2 │ │ │ │ │ └── Oauth2Configurer.java │ │ │ ├── authorization │ │ │ │ └── RequestAuthorizationManager.java │ │ │ └── exception │ │ │ │ ├── AuthenticationExceptionConfigurer.java │ │ │ │ └── JsonServerAuthenticationEntryPoint.java │ │ │ ├── store │ │ │ ├── entity │ │ │ │ ├── AttachmentEntity.java │ │ │ │ ├── AttachmentReferenceEntity.java │ │ │ │ ├── AttachmentRelationEntity.java │ │ │ │ ├── AuthorityEntity.java │ │ │ │ ├── BaseEntity.java │ │ │ │ ├── CharacterEntity.java │ │ │ │ ├── CustomEntity.java │ │ │ │ ├── CustomMetadataEntity.java │ │ │ │ ├── EpisodeCollectionEntity.java │ │ │ │ ├── EpisodeEntity.java │ │ │ │ ├── EpisodeListCollectionEntity.java │ │ │ │ ├── EpisodeListEntity.java │ │ │ │ ├── EpisodeListEpisodeEntity.java │ │ │ │ ├── PersonCharacterEntity.java │ │ │ │ ├── PersonEntity.java │ │ │ │ ├── RoleAuthorityEntity.java │ │ │ │ ├── RoleEntity.java │ │ │ │ ├── SubjectCharacterEntity.java │ │ │ │ ├── SubjectCollectionEntity.java │ │ │ │ ├── SubjectEntity.java │ │ │ │ ├── SubjectPersonEntity.java │ │ │ │ ├── SubjectRelationEntity.java │ │ │ │ ├── SubjectSyncEntity.java │ │ │ │ ├── TagEntity.java │ │ │ │ ├── TaskEntity.java │ │ │ │ ├── UserEntity.java │ │ │ │ └── UserRoleEntity.java │ │ │ └── repository │ │ │ │ ├── AttachmentReferenceRepository.java │ │ │ │ ├── AttachmentRelationRepository.java │ │ │ │ ├── AttachmentRepository.java │ │ │ │ ├── AuthorityRepository.java │ │ │ │ ├── CharacterRepository.java │ │ │ │ ├── CustomMetadataRepository.java │ │ │ │ ├── CustomRepository.java │ │ │ │ ├── EpisodeCollectionRepository.java │ │ │ │ ├── EpisodeListCollectionRepository.java │ │ │ │ ├── EpisodeListEpisodeRepository.java │ │ │ │ ├── EpisodeListRepository.java │ │ │ │ ├── EpisodeRepository.java │ │ │ │ ├── PersonRepository.java │ │ │ │ ├── RoleAuthorityRepository.java │ │ │ │ ├── RoleRepository.java │ │ │ │ ├── SubjectCharacterRepository.java │ │ │ │ ├── SubjectCollectionRepository.java │ │ │ │ ├── SubjectPersonRepository.java │ │ │ │ ├── SubjectRelationRepository.java │ │ │ │ ├── SubjectRepository.java │ │ │ │ ├── SubjectSyncRepository.java │ │ │ │ ├── TagRepository.java │ │ │ │ ├── TaskRepository.java │ │ │ │ ├── UserRepository.java │ │ │ │ └── UserRoleRepository.java │ │ │ └── theme │ │ │ ├── DefaultThemeService.java │ │ │ └── ThemeService.java │ └── resources │ │ ├── application-dev.yaml │ │ ├── application-postgresql.yaml │ │ ├── application-win-dev.yaml │ │ ├── application-win.yaml │ │ ├── application.yaml │ │ ├── banner.txt │ │ ├── db │ │ ├── h2 │ │ │ └── migration │ │ │ │ ├── V0.13.0_0000__DDL_IKUSER.SQL │ │ │ │ ├── V0.13.0_0001__DDL_ATTACHMENT.SQL │ │ │ │ ├── V0.13.0_0002__DDL_ATTACHMENT_RELATION.SQL │ │ │ │ ├── V0.13.0_0003__DDL_ATTACHMENT_REFERENCE.SQL │ │ │ │ ├── V0.13.0_0004__DDL_AUTHORITY.SQL │ │ │ │ ├── V0.13.0_0005__DDL_CHARACTER.SQL │ │ │ │ ├── V0.13.0_0006__DDL_EPISODE_COLLECTION.SQL │ │ │ │ ├── V0.13.0_0007__DDL_SUBJECT_COLLECTION.SQL │ │ │ │ ├── V0.13.0_0008__DDL_EPISODE.SQL │ │ │ │ ├── V0.13.0_0009__DDL_PERSON_CHARACTER.SQL │ │ │ │ ├── V0.13.0_0010__DDL_PERSON.SQL │ │ │ │ ├── V0.13.0_0011__DDL_ROLE.SQL │ │ │ │ ├── V0.13.0_0012__DDL_SUBJECT_CHARACTER.SQL │ │ │ │ ├── V0.13.0_0013__DDL_SUBJECT.SQL │ │ │ │ ├── V0.13.0_0014__DDL_SUBJECT_PERSON.SQL │ │ │ │ ├── V0.13.0_0015__DDL_SUBJECT_RELATION.SQL │ │ │ │ ├── V0.13.0_0016__DDL_SUBJECT_SYNC.SQL │ │ │ │ ├── V0.13.0_0017__DDL_CUSTOM.SQL │ │ │ │ ├── V0.13.0_0018__DDL_CUSTOM_METADATA.SQL │ │ │ │ ├── V0.13.0_0019__DDL_TAG.SQL │ │ │ │ ├── V0.13.0_0020__DDL_TASK.SQL │ │ │ │ ├── V0.13.0_0021__DDL_USER_ROLE.SQL │ │ │ │ ├── V0.13.0_0022__DDL_ROLE_AUTHORITY.SQL │ │ │ │ ├── V0.13.0_0023__DML_ATTACHMENT_INIT.SQL │ │ │ │ ├── V0.15.0_0001__DDL_EPISODE_LIST.SQL │ │ │ │ ├── V0.15.0_0002__DDL_EPISODE_LIST_EPISODE.SQL │ │ │ │ ├── V0.15.0_0003__DDL_EPISODE_LIST_COLLECTION.SQL │ │ │ │ ├── V0.15.0_0004__DML_EPISODE_UK.SQL │ │ │ │ ├── V0.15.2_0001__DDL_EPISODE_SEQUENCE.SQL │ │ │ │ ├── V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL │ │ │ │ ├── V0.20.7_0002__DML_SUBJECT_COLUMN.SQL │ │ │ │ └── V0.20.9_0001__DML_TAG_COLUMN.SQL │ │ └── postgresql │ │ │ └── migration │ │ │ ├── V0.13.0_0000__DDL_IKUSER.SQL │ │ │ ├── V0.13.0_0001__DDL_ATTACHMENT.SQL │ │ │ ├── V0.13.0_0002__DDL_ATTACHMENT_RELATION.SQL │ │ │ ├── V0.13.0_0003__DDL_ATTACHMENT_REFERENCE.SQL │ │ │ ├── V0.13.0_0004__DDL_AUTHORITY.SQL │ │ │ ├── V0.13.0_0005__DDL_CHARACTER.SQL │ │ │ ├── V0.13.0_0006__DDL_EPISODE_COLLECTION.SQL │ │ │ ├── V0.13.0_0007__DDL_SUBJECT_COLLECTION.SQL │ │ │ ├── V0.13.0_0008__DDL_EPISODE.SQL │ │ │ ├── V0.13.0_0009__DDL_PERSON_CHARACTER.SQL │ │ │ ├── V0.13.0_0010__DDL_PERSON.SQL │ │ │ ├── V0.13.0_0011__DDL_ROLE.SQL │ │ │ ├── V0.13.0_0012__DDL_SUBJECT_CHARACTER.SQL │ │ │ ├── V0.13.0_0013__DDL_SUBJECT.SQL │ │ │ ├── V0.13.0_0014__DDL_SUBJECT_PERSON.SQL │ │ │ ├── V0.13.0_0015__DDL_SUBJECT_RELATION.SQL │ │ │ ├── V0.13.0_0016__DDL_SUBJECT_SYNC.SQL │ │ │ ├── V0.13.0_0017__DDL_CUSTOM.SQL │ │ │ ├── V0.13.0_0018__DDL_CUSTOM_METADATA.SQL │ │ │ ├── V0.13.0_0019__DDL_TAG.SQL │ │ │ ├── V0.13.0_0020__DDL_TASK.SQL │ │ │ ├── V0.13.0_0021__DDL_USER_ROLE.SQL │ │ │ ├── V0.13.0_0022__DDL_ROLE_AUTHORITY.SQL │ │ │ ├── V0.13.0_0023__DML_ATTACHMENT_INIT.SQL │ │ │ ├── V0.15.0_0001__DDL_EPISODE_LIST.SQL │ │ │ ├── V0.15.0_0002__DDL_EPISODE_LIST_EPISODE.SQL │ │ │ ├── V0.15.0_0003__DDL_EPISODE_LIST_COLLECTION.SQL │ │ │ ├── V0.15.0_0004__DML_EPISODE_UK.SQL │ │ │ ├── V0.15.2_0001__DDL_EPISODE_SEQUENCE.SQL │ │ │ ├── V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL │ │ │ ├── V0.20.7_0002__DML_SUBJECT_COLUMN.SQL │ │ │ └── V0.20.9_0001__DML_TAG_COLUMN.SQL │ │ ├── logback-spring.xml │ │ └── templates │ │ ├── default │ │ └── index.html │ │ ├── error │ │ └── error.html │ │ ├── mail │ │ ├── anime_update.html │ │ └── notify_test.html │ │ └── temp │ │ └── app-link-to.html │ └── test │ ├── java │ └── run │ │ └── ikaros │ │ └── server │ │ ├── IkarosApplicationTests.java │ │ ├── core │ │ ├── attachment │ │ │ ├── listener │ │ │ │ └── AttachmentRelVideoSubtitleListenerTest.java │ │ │ └── service │ │ │ │ └── AttachmentServiceTest.java │ │ ├── collection │ │ │ ├── EpisodeCollectionServiceTest.java │ │ │ └── SubjectCollectionServiceTest.java │ │ ├── constant │ │ │ └── SecurityConstTest.java │ │ ├── notify │ │ │ └── MailServiceTest.java │ │ ├── subject │ │ │ ├── SubjectEndpointTest.java │ │ │ ├── SubjectRelationEndpointTest.java │ │ │ ├── SubjectRelationServiceTest.java │ │ │ ├── SubjectServiceTest.java │ │ │ ├── service │ │ │ │ └── SubjectSyncServiceTest.java │ │ │ └── vo │ │ │ │ └── FindSubjectConditionTest.java │ │ ├── task │ │ │ └── TaskServiceTest.java │ │ ├── user │ │ │ └── UserServiceTest.java │ │ ├── warp │ │ │ └── PagingWrapTest.java │ │ └── webclient │ │ │ └── WeClientServiceTest.java │ │ ├── custom │ │ ├── CustomConverterTest.java │ │ ├── DemoCustom.java │ │ ├── DemoOnlyNameCustom.java │ │ └── ReactiveCustomClientTest.java │ │ ├── infra │ │ ├── properties │ │ │ └── IkarosPropertiesTest.java │ │ └── utils │ │ │ ├── AesEncryptUtilsTest.java │ │ │ └── JsonUtilsTest.java │ │ ├── plugin │ │ ├── ExtensionComponentsFinderTest.java │ │ ├── IkarosExtensionFactoryTest.java │ │ ├── IkarosJarPluginLoaderTest.java │ │ ├── IkarosPluginManagerTest.java │ │ ├── PluginApplicationContextTest.java │ │ └── PluginPropertiesTest.java │ │ ├── security │ │ ├── authentication │ │ │ ├── FormLoginTests.java │ │ │ └── FormLogoutTests.java │ │ └── authorization │ │ │ └── RequestAuthorizationManagerTest.java │ │ ├── store │ │ └── repository │ │ │ ├── AttachmentReferenceRepositoryTest.java │ │ │ ├── AttachmentRepositoryTest.java │ │ │ ├── CustomMetadataRepositoryTest.java │ │ │ ├── CustomRepositoryTest.java │ │ │ ├── SubjectCollectionRepositoryTest.java │ │ │ ├── SubjectRepositoryTest.java │ │ │ └── SubjectSyncRepositoryTest.java │ │ └── test │ │ ├── DateUtilTest.java │ │ ├── ReactorTest.java │ │ ├── TestConst.java │ │ ├── TimeTest.java │ │ └── reflect │ │ └── MemberMatcher.java │ └── resources │ ├── application.yaml │ ├── console │ └── index.html │ ├── core │ └── file │ │ └── UnitTestDocFile.TXT │ ├── plugin │ ├── unittest-a-1.0.0.jar │ └── unittest-b-1.0.0.jar │ └── schema-h2.sql └── settings.gradle /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Ikaros docs 4 | url: https://docs.ikaros.run 5 | about: Ikaros offical docs site 6 | - name: Ask a question or get support 7 | url: https://github.com/ikaros-dev/ikaros/discussions 8 | about: Ask a question or request support for using Ikaros -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | 39 | ### Local Dev Files 40 | /logs/ 41 | /upload/ 42 | /media/ 43 | /downloads/ 44 | /database/ 45 | /tripartite/ 46 | /original/ 47 | /plugins/ 48 | 49 | ### Console ### 50 | /server/src/main/resources/console/ 51 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "server/src/main/resources/templates/simple"] 2 | path = server/src/main/resources/templates/simple 3 | url = https://github.com/ikaros-dev/theme-simple.git 4 | -------------------------------------------------------------------------------- /.run/RunAppOnWindows.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/constant/AppConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.constant; 2 | 3 | import java.time.Duration; 4 | 5 | /** 6 | * application constants. 7 | * 8 | * @author: li-guohao 9 | */ 10 | public interface AppConst { 11 | String LOGIN_SUCCESS_LOCATION = "/console/"; 12 | String LOGIN_FAILURE_LOCATION = "/console/?error#/login"; 13 | String LOGOUT_SUCCESS_LOCATION = "/console/?logout"; 14 | Duration BLOCK_TIMEOUT = Duration.ofMillis(2000L); 15 | String CACHE_DIR_NAME = "caches"; 16 | String STATIC_DIR_NAME = "statics"; 17 | String STATIC_FONT_DIR_NAME = "fonts"; 18 | String THEME_DIR_NAME = "themes"; 19 | 20 | /** 21 | * currentTime / TotalTime . 22 | */ 23 | Double EPISODE_FINISH = 0.9375 * 0.85; 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/constant/OpenApiConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.constant; 2 | 3 | public interface OpenApiConst { 4 | String CORE_GROUP = "core.ikaros.run"; 5 | String PLUGIN_GROUP = "plugin.ikaros.run"; 6 | String CORE_VERSION = "v1alpha1"; 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/constant/StringConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.constant; 2 | 3 | public interface StringConst { 4 | String SPACE = " "; 5 | } 6 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/AttachmentConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | public interface AttachmentConst { 4 | Long ROOT_DIRECTORY_PARENT_ID = 0L; 5 | Long ROOT_DIRECTORY_ID = 0L; 6 | Long COVER_DIRECTORY_ID = 1L; 7 | Long DOWNLOAD_DIRECTORY_ID = 2L; 8 | String ROOT_DIR_NAME = "/"; 9 | String COVER_DIR_NAME = "Covers"; 10 | String DOWNLOAD_DIR_NAME = "Downloads"; 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/AttachmentReference.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | import run.ikaros.api.store.enums.AttachmentReferenceType; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Accessors(chain = true) 15 | public class AttachmentReference { 16 | private Long id; 17 | private AttachmentReferenceType type; 18 | private Long attachmentId; 19 | private Long referenceId; 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/AttachmentRelation.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import run.ikaros.api.store.enums.AttachmentRelationType; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class AttachmentRelation { 17 | private Long id; 18 | @JsonProperty("attachment_id") 19 | private Long attachmentId; 20 | private AttachmentRelationType type; 21 | @JsonProperty("relation_attachment_id") 22 | private Long relationAttachmentId; 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/AttachmentRelationOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | import reactor.core.publisher.Flux; 4 | import run.ikaros.api.plugin.AllowPluginOperate; 5 | import run.ikaros.api.store.enums.AttachmentRelationType; 6 | 7 | public interface AttachmentRelationOperate extends AllowPluginOperate { 8 | 9 | Flux findAllByTypeAndAttachmentId(AttachmentRelationType type, 10 | Long attachmentId); 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/AttachmentUploadCondition.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import org.springframework.core.io.buffer.DataBuffer; 7 | import reactor.core.publisher.Flux; 8 | 9 | @Data 10 | @Builder 11 | public class AttachmentUploadCondition { 12 | 13 | @Schema(nullable = true, description = "父附件的ID,可为空,为空则代表附件在逻辑根目录下。") 14 | private Long parentId; 15 | @Schema(description = "经过Basic64编码的附件名称,附件名称字段模糊查询。") 16 | private String name; 17 | @Schema(implementation = Flux.class, description = "附件的数据。") 18 | private Flux dataBufferFlux; 19 | @Schema(nullable = true, description = "当出现和已有文件相同名称,并且在同一父目录下时,是否重命名。") 20 | private Boolean isAutoReName; 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/VideoSubtitle.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @EqualsAndHashCode 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class VideoSubtitle { 16 | @JsonProperty("master_attachment_id") 17 | private Long masterAttachmentId; 18 | @JsonProperty("attachment_id") 19 | private Long attachmentId; 20 | private String name; 21 | private String url; 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentException extends RuntimeException { 4 | 5 | 6 | public AttachmentException(String message) { 7 | super(message); 8 | } 9 | 10 | public AttachmentException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentExistsException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentExistsException extends AttachmentException { 4 | public AttachmentExistsException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentNotFoundException extends AttachmentException { 4 | public AttachmentNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentParentNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentParentNotFoundException extends AttachmentException { 4 | public AttachmentParentNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentRefMatchingException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentRefMatchingException extends AttachmentException { 4 | public AttachmentRefMatchingException(String message) { 5 | super(message); 6 | } 7 | 8 | public AttachmentRefMatchingException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentRemoveException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentRemoveException extends AttachmentException { 4 | public AttachmentRemoveException(String message) { 5 | super(message); 6 | } 7 | 8 | public AttachmentRemoveException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/attachment/exception/AttachmentUploadException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.attachment.exception; 2 | 3 | public class AttachmentUploadException extends AttachmentException { 4 | public AttachmentUploadException(String message, Throwable cause) { 5 | super(message, cause); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/authority/Authority.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.authority; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | import run.ikaros.api.store.enums.AuthorityType; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Accessors(chain = true) 15 | public class Authority { 16 | private Long id; 17 | private Boolean allow; 18 | private AuthorityType type; 19 | private String target; 20 | private String authority; 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/authority/AuthorityCondition.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.authority; 2 | 3 | 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import run.ikaros.api.store.enums.AuthorityType; 7 | 8 | @Data 9 | @Builder 10 | public class AuthorityCondition { 11 | private Boolean allow; 12 | private AuthorityType type; 13 | private String target; 14 | private String authority; 15 | private Integer page; 16 | private Integer size; 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/character/Character.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.character; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @Accessors(chain = true) 14 | public class Character { 15 | private Long id; 16 | private String name; 17 | private String infobox; 18 | private String summary; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/collection/CollectionOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.collection; 2 | 3 | import run.ikaros.api.plugin.AllowPluginOperate; 4 | 5 | public interface CollectionOperate extends AllowPluginOperate { 6 | } 7 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/collection/EpisodeCollectionOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.collection; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | public interface EpisodeCollectionOperate extends CollectionOperate { 6 | Mono create(Long userId, Long episodeId); 7 | 8 | Mono findByUserIdAndEpisodeId(Long userId, Long episodeId); 9 | 10 | Mono updateEpisodeCollectionProgress(Long userId, Long episodeId, 11 | Long progress); 12 | 13 | Mono updateEpisodeCollection(Long userId, Long episodeId, 14 | Long progress, Long duration); 15 | 16 | Mono updateEpisodeCollectionFinish(Long userId, Long episodeId, 17 | Boolean finish); 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/collection/event/SubjectCollectEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.collection.event; 2 | 3 | import lombok.Getter; 4 | import run.ikaros.api.core.collection.SubjectCollection; 5 | 6 | @Getter 7 | public class SubjectCollectEvent extends SubjectCollectionUpdateEvent { 8 | /** 9 | * Construct. 10 | */ 11 | public SubjectCollectEvent(Object source, 12 | SubjectCollection subjectCollection) { 13 | super(source, subjectCollection, true); 14 | } 15 | 16 | /** 17 | * Construct. 18 | */ 19 | public SubjectCollectEvent(Object source, String pluginId, 20 | SubjectCollection subjectCollection, boolean collect) { 21 | super(source, pluginId, subjectCollection, collect); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/collection/vo/FindCollectionCondition.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.collection.vo; 2 | 3 | import jakarta.annotation.Nullable; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import run.ikaros.api.store.enums.CollectionCategory; 7 | import run.ikaros.api.store.enums.CollectionType; 8 | 9 | @Data 10 | @Builder 11 | public class FindCollectionCondition { 12 | /** 13 | * default is 1. 14 | */ 15 | private Integer page; 16 | /** 17 | * default is 10. 18 | */ 19 | private Integer size; 20 | private CollectionCategory category; 21 | @Nullable 22 | private CollectionType type; 23 | @Nullable 24 | private String time; 25 | /** 26 | * default is false. 27 | */ 28 | private Boolean updateTimeDesc; 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/meta/DelegateMetaService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.meta; 2 | 3 | import org.pf4j.ExtensionPoint; 4 | import reactor.core.publisher.Flux; 5 | import run.ikaros.api.core.subject.Subject; 6 | 7 | public interface DelegateMetaService extends ExtensionPoint { 8 | Flux findAll(String keyword); 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/meta/MetaOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.meta; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.subject.Subject; 6 | import run.ikaros.api.plugin.AllowPluginOperate; 7 | 8 | public interface MetaOperate extends AllowPluginOperate { 9 | Mono findOne(String keyword); 10 | 11 | Flux findAll(String keyword); 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/person/Person.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.person; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @Accessors(chain = true) 14 | public class Person { 15 | private Long id; 16 | private String name; 17 | private String infobox; 18 | private String summary; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/role/Role.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.role; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | @Data 11 | @Builder 12 | @EqualsAndHashCode 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class Role { 17 | private Long id; 18 | private String name; 19 | private Long parentId; 20 | private String description; 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/role/RoleAuthorityReqParams.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.role; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | @Data 11 | @Builder 12 | @EqualsAndHashCode 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class RoleAuthorityReqParams { 17 | private Long roleId; 18 | private Long[] authorityIds; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/setting/vo/BasicSetting.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.setting.vo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class BasicSetting { 7 | private String siteTitle; 8 | private String siteSubhead; 9 | private String logo; 10 | private String favicon; 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/setting/vo/GlobalSetting.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.setting.vo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class GlobalSetting { 7 | private String header; 8 | private String footer; 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/setting/vo/MailProtocol.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.setting.vo; 2 | 3 | 4 | public enum MailProtocol { 5 | SMTP 6 | } 7 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/setting/vo/MailSetting.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.setting.vo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class MailSetting { 7 | private Boolean enable; 8 | private MailProtocol protocol; 9 | private String smtpHost; 10 | private String smtpPort; 11 | private String smtpAccount; 12 | private String smtpPassword; 13 | private String smtpAccountAlias; 14 | private String smtpReceiveAddress; 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/setting/vo/UserSetting.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.setting.vo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class UserSetting { 7 | private Boolean allowRegister; 8 | private String defaultRole; 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/EpisodeRecord.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 剧集相关数据的组合,使用复杂的数据,会增加单个接口的耗时,但对整个条目来说,能有效降低并发请求次数. 7 | * 8 | * @param episode 剧集 9 | * @param resources 剧集附件资源集合 10 | */ 11 | public record EpisodeRecord(Episode episode, List resources) { 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/EpisodeResource.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject; 2 | 3 | import java.util.Set; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @EqualsAndHashCode 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class EpisodeResource { 16 | private Long attachmentId; 17 | private Long parentAttachmentId; 18 | private Long episodeId; 19 | private String url; 20 | private boolean canRead; 21 | private String name; 22 | /** 23 | * Such as 1080p 720p. 24 | */ 25 | private Set tags; 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/SubjectFinder.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject; 2 | 3 | import org.pf4j.ExtensionPoint; 4 | import run.ikaros.api.store.enums.SubjectSyncPlatform; 5 | 6 | public interface SubjectFinder extends ExtensionPoint { 7 | /** 8 | * 当前插件同步处理的对应的平台,比如是bgmtv的同步插件则返回对应的平台枚举. 9 | * 10 | * @see SubjectSyncPlatform 11 | */ 12 | SubjectSyncPlatform getSyncPlatform(); 13 | 14 | Subject findByKeyword(String keyword); 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/SubjectRelationOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.plugin.AllowPluginOperate; 6 | import run.ikaros.api.store.enums.SubjectRelationType; 7 | 8 | public interface SubjectRelationOperate extends AllowPluginOperate { 9 | Flux findAllBySubjectId(Long subjectId); 10 | 11 | Mono findBySubjectIdAndType(Long subjectId, SubjectRelationType relationType); 12 | 13 | Mono createSubjectRelation(SubjectRelation subjectRelation); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/SubjectSync.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | import lombok.experimental.Accessors; 10 | import run.ikaros.api.store.enums.SubjectSyncPlatform; 11 | 12 | @Data 13 | @Builder 14 | @EqualsAndHashCode 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | @Accessors(chain = true) 18 | public class SubjectSync { 19 | private Long subjectId; 20 | private SubjectSyncPlatform platform; 21 | private String platformId; 22 | private LocalDateTime syncTime; 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/vo/BatchMatchingEpisodeFile.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject.vo; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | @Data 9 | public class BatchMatchingEpisodeFile { 10 | @Schema(requiredMode = REQUIRED, description = "subject id for episode belong.") 11 | private Long subjectId; 12 | @Schema(requiredMode = REQUIRED, description = "file id array.") 13 | private Long[] fileIds; 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/subject/vo/PostSubjectSyncCondition.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.subject.vo; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import org.springframework.lang.Nullable; 6 | import run.ikaros.api.store.enums.SubjectSyncPlatform; 7 | 8 | @Data 9 | @Builder 10 | public class PostSubjectSyncCondition { 11 | /** 12 | * 为空则是拉取创建新的,不为空则是先查询数据库,存在则更新,不存在则新增. 13 | */ 14 | @Nullable 15 | private Long subjectId; 16 | private SubjectSyncPlatform platform; 17 | private String platformId; 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/tag/AttachmentTag.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.tag; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class AttachmentTag { 17 | private Long id; 18 | private Long attachmentId; 19 | private String name; 20 | private Long userId; 21 | private LocalDateTime createTime; 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/tag/SubjectTag.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.tag; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class SubjectTag { 17 | private Long id; 18 | private Long subjectId; 19 | private String name; 20 | private Long userId; 21 | private LocalDateTime createTime; 22 | /** 23 | * 十六进制字符串颜色,与条目无关,与标签名一对一,与用户ID关联. 24 | * 25 | * @see Tag 26 | */ 27 | private String color; 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/tag/Tag.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.tag; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import run.ikaros.api.store.enums.TagType; 10 | 11 | /** 12 | * 标签,用户可以在同一类型的标签里共享,比如条目类型的标签可以多个条目共享. 13 | */ 14 | @Data 15 | @Builder 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @Accessors(chain = true) 19 | public class Tag { 20 | private Long id; 21 | private TagType type; 22 | private Long masterId; 23 | private String name; 24 | private Long userId; 25 | private LocalDateTime createTime; 26 | /** 27 | * 十六进制字符串颜色,与条目无关,与标签名一对一,与用户ID关联. 28 | */ 29 | private String color; 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/tag/TagOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.tag; 2 | 3 | import org.springframework.lang.Nullable; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.api.plugin.AllowPluginOperate; 7 | import run.ikaros.api.store.enums.TagType; 8 | 9 | public interface TagOperate extends AllowPluginOperate { 10 | 11 | Flux findAll(TagType type, Long masterId, @Nullable String name); 12 | 13 | Flux findSubjectTags(Long subjectId); 14 | 15 | Mono create(Tag tag); 16 | } 17 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/task/TaskOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.task; 2 | 3 | import java.time.Duration; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.plugin.AllowPluginOperate; 6 | 7 | public interface TaskOperate extends AllowPluginOperate { 8 | Mono submit(String name, Runnable runnable); 9 | 10 | Mono submit(String name, Runnable runnable, Duration delay); 11 | 12 | Mono cancel(String name); 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/user/UserRoleReqParams.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.user; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | @Data 11 | @Builder 12 | @EqualsAndHashCode 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Accessors(chain = true) 16 | public class UserRoleReqParams { 17 | private Long userId; 18 | private Long[] roleIds; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/core/user/enums/VerificationCodeType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.core.user.enums; 2 | 3 | public enum VerificationCodeType { 4 | EMAIL, 5 | PHONE_MSG, 6 | OTHER 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/custom/Custom.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.custom; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface Custom { 11 | /** 12 | * custom group. 13 | */ 14 | String group(); 15 | 16 | /** 17 | * custom version. 18 | */ 19 | String version(); 20 | 21 | /** 22 | * custom kind. 23 | */ 24 | String kind(); 25 | 26 | /** 27 | * Custom singular. 28 | */ 29 | String singular(); 30 | 31 | /** 32 | * Custom plural. 33 | */ 34 | String plural(); 35 | } 36 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/custom/GroupVersionKind.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.custom; 2 | 3 | public record GroupVersionKind(String group, String version, String kind) { 4 | } 5 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/custom/Name.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.custom; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target(ElementType.FIELD) 11 | public @interface Name { 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/custom/exception/CustomConvertException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.custom.exception; 2 | 3 | public class CustomConvertException extends CustomException { 4 | public CustomConvertException(String message) { 5 | super(message); 6 | } 7 | 8 | public CustomConvertException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/custom/exception/CustomSchemeNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.custom.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import run.ikaros.api.custom.GroupVersionKind; 5 | 6 | public class CustomSchemeNotFoundException extends CustomException { 7 | public CustomSchemeNotFoundException(String message) { 8 | super(message); 9 | } 10 | 11 | public CustomSchemeNotFoundException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public CustomSchemeNotFoundException(GroupVersionKind gvk) { 16 | super(HttpStatus.INTERNAL_SERVER_ERROR, "Scheme not found for " + gvk, null, null, 17 | new Object[] {gvk}); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/endpoint/CustomEndpoint.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.endpoint; 2 | 3 | 4 | import run.ikaros.api.custom.GroupVersionKind; 5 | 6 | public interface CustomEndpoint extends Endpoint { 7 | GroupVersionKind groupVersionKind(); 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/endpoint/Endpoint.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.endpoint; 2 | 3 | 4 | import org.springframework.web.reactive.function.server.RouterFunction; 5 | import org.springframework.web.reactive.function.server.ServerResponse; 6 | 7 | public interface Endpoint { 8 | RouterFunction endpoint(); 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception; 2 | 3 | public class NotFoundException extends RuntimeException { 4 | public NotFoundException(String message) { 5 | super(message); 6 | } 7 | 8 | public NotFoundException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | 12 | public NotFoundException(Throwable cause) { 13 | super(cause); 14 | } 15 | 16 | public NotFoundException(String message, Throwable cause, boolean enableSuppression, 17 | boolean writableStackTrace) { 18 | super(message, cause, enableSuppression, writableStackTrace); 19 | } 20 | 21 | public NotFoundException() { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/RegexMatchingException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception; 2 | 3 | public class RegexMatchingException extends RuntimeException { 4 | public RegexMatchingException() { 5 | } 6 | 7 | public RegexMatchingException(String message) { 8 | super(message); 9 | } 10 | 11 | public RegexMatchingException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public RegexMatchingException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | public RegexMatchingException(String message, Throwable cause, boolean enableSuppression, 20 | boolean writableStackTrace) { 21 | super(message, cause, enableSuppression, writableStackTrace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/console/LoadConsoleBundleException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.console; 2 | 3 | public class LoadConsoleBundleException extends RuntimeException { 4 | 5 | public LoadConsoleBundleException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/file/FileExistsException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.file; 2 | 3 | public class FileExistsException extends RuntimeException { 4 | public FileExistsException() { 5 | } 6 | 7 | public FileExistsException(String message) { 8 | super(message); 9 | } 10 | 11 | public FileExistsException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public FileExistsException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | public FileExistsException(String message, Throwable cause, boolean enableSuppression, 20 | boolean writableStackTrace) { 21 | super(message, cause, enableSuppression, writableStackTrace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/file/FolderExistsException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.file; 2 | 3 | public class FolderExistsException extends RuntimeException { 4 | public FolderExistsException() { 5 | } 6 | 7 | public FolderExistsException(String message) { 8 | super(message); 9 | } 10 | 11 | public FolderExistsException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public FolderExistsException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | public FolderExistsException(String message, Throwable cause, boolean enableSuppression, 20 | boolean writableStackTrace) { 21 | super(message, cause, enableSuppression, writableStackTrace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/file/FolderHasChildException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.file; 2 | 3 | public class FolderHasChildException extends RuntimeException { 4 | public FolderHasChildException() { 5 | } 6 | 7 | public FolderHasChildException(String message) { 8 | super(message); 9 | } 10 | 11 | public FolderHasChildException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public FolderHasChildException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | public FolderHasChildException(String message, Throwable cause, boolean enableSuppression, 20 | boolean writableStackTrace) { 21 | super(message, cause, enableSuppression, writableStackTrace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/file/FolderNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.file; 2 | 3 | import run.ikaros.api.infra.exception.NotFoundException; 4 | 5 | public class FolderNotFoundException extends NotFoundException { 6 | public FolderNotFoundException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/plugin/PluginDisabledException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.plugin; 2 | 3 | import org.pf4j.PluginRuntimeException; 4 | 5 | public class PluginDisabledException extends PluginRuntimeException { 6 | public PluginDisabledException() { 7 | } 8 | 9 | public PluginDisabledException(String message) { 10 | super(message); 11 | } 12 | 13 | public PluginDisabledException(Throwable cause) { 14 | super(cause); 15 | } 16 | 17 | public PluginDisabledException(Throwable cause, String message, Object... args) { 18 | super(cause, message, args); 19 | } 20 | 21 | public PluginDisabledException(String message, Object... args) { 22 | super(message, args); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/plugin/PluginInstallException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.plugin; 2 | 3 | import org.pf4j.PluginRuntimeException; 4 | 5 | public class PluginInstallException extends PluginRuntimeException { 6 | public PluginInstallException() { 7 | } 8 | 9 | public PluginInstallException(String message) { 10 | super(message); 11 | } 12 | 13 | public PluginInstallException(Throwable cause) { 14 | super(cause); 15 | } 16 | 17 | public PluginInstallException(Throwable cause, String message, Object... args) { 18 | super(cause, message, args); 19 | } 20 | 21 | public PluginInstallException(String message, Object... args) { 22 | super(message, args); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/plugin/PluginUpgradeException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.plugin; 2 | 3 | import org.pf4j.PluginRuntimeException; 4 | 5 | public class PluginUpgradeException extends PluginRuntimeException { 6 | public PluginUpgradeException() { 7 | } 8 | 9 | public PluginUpgradeException(String message) { 10 | super(message); 11 | } 12 | 13 | 14 | public PluginUpgradeException(Throwable cause) { 15 | super(cause); 16 | } 17 | 18 | public PluginUpgradeException(Throwable cause, String message, Object... args) { 19 | super(cause, message, args); 20 | } 21 | 22 | public PluginUpgradeException(String message, Object... args) { 23 | super(message, args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/security/InvalidTokenException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | public class InvalidTokenException extends AuthenticationException { 6 | public InvalidTokenException(String msg) { 7 | super(msg); 8 | } 9 | 10 | public InvalidTokenException(String msg, Throwable cause) { 11 | super(msg, cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/security/PasswordNotMatchingException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | public class PasswordNotMatchingException extends AuthenticationException { 6 | public PasswordNotMatchingException(String msg) { 7 | super(msg); 8 | } 9 | 10 | public PasswordNotMatchingException(String msg, Throwable cause) { 11 | super(msg, cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/security/UserAuthenticationException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | public class UserAuthenticationException extends AuthenticationException { 6 | public UserAuthenticationException(String msg) { 7 | super(msg); 8 | } 9 | 10 | public UserAuthenticationException(String msg, Throwable cause) { 11 | super(msg, cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/subject/EpisodeNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.subject; 2 | 3 | import run.ikaros.api.infra.exception.NotFoundException; 4 | 5 | public class EpisodeNotFoundException extends NotFoundException { 6 | public EpisodeNotFoundException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/subject/NoAvailableSubjectPlatformSynchronizerException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.subject; 2 | 3 | public class NoAvailableSubjectPlatformSynchronizerException extends RuntimeException { 4 | public NoAvailableSubjectPlatformSynchronizerException(String message) { 5 | super(message); 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/subject/SubjectNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.subject; 2 | 3 | import run.ikaros.api.infra.exception.NotFoundException; 4 | 5 | public class SubjectNotFoundException extends NotFoundException { 6 | public SubjectNotFoundException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/user/UserExistsException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.user; 2 | 3 | import run.ikaros.api.infra.exception.NotFoundException; 4 | 5 | public class UserExistsException extends NotFoundException { 6 | public UserExistsException(String message) { 7 | super(message); 8 | } 9 | 10 | public UserExistsException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/exception/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.exception.user; 2 | 3 | import run.ikaros.api.infra.exception.NotFoundException; 4 | 5 | public class UserNotFoundException extends NotFoundException { 6 | public UserNotFoundException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/infra/properties/IkarosProperties.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.infra.properties; 2 | 3 | import jakarta.validation.constraints.NotNull; 4 | import java.net.URI; 5 | import java.nio.file.Path; 6 | import lombok.Data; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.validation.annotation.Validated; 9 | 10 | /** 11 | * Ikaros base properties. 12 | * 13 | * @author: chivehao 14 | */ 15 | @Data 16 | @Validated 17 | @ConfigurationProperties(prefix = "ikaros") 18 | public class IkarosProperties { 19 | @NotNull 20 | private Path workDir; 21 | @NotNull 22 | private URI externalUrl; 23 | private Boolean showTheme; 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/AllowPluginOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin; 2 | 3 | public interface AllowPluginOperate { 4 | } 5 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/BasePlugin.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin; 2 | 3 | import org.pf4j.Plugin; 4 | import org.pf4j.PluginWrapper; 5 | 6 | /** 7 | * All plugin will extend this class to construct plugin or application. 8 | */ 9 | public class BasePlugin extends Plugin { 10 | public BasePlugin(PluginWrapper wrapper) { 11 | super(wrapper); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/PluginConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin; 2 | 3 | public interface PluginConst { 4 | 5 | String PLUGIN_NAME_LABEL_NAME = "plugin.ikaros.run/plugin-name"; 6 | 7 | String SYSTEM_PLUGIN_NAME = "system"; 8 | 9 | String RELOAD_ANNO = "plugin.ikaros.run/reload"; 10 | 11 | String PLUGIN_PATH = "plugin.ikaros.run/plugin-path"; 12 | 13 | static String assertsRoutePrefix(String pluginName) { 14 | return "/plugins/" + pluginName + "/assets/"; 15 | } 16 | 17 | String STATIC_RESOURCE_DIR_CONSOLE = "console"; 18 | String STATIC_RESOURCE_DIR_STATIC = "static"; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/event/PluginAwareEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | 6 | @Getter 7 | public class PluginAwareEvent extends ApplicationEvent { 8 | private String pluginId = "ALL"; 9 | 10 | public PluginAwareEvent(Object source) { 11 | super(source); 12 | } 13 | 14 | public PluginAwareEvent(Object source, String pluginId) { 15 | super(source); 16 | this.pluginId = pluginId; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/event/PluginConfigMapChangeEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin.event; 2 | 3 | import lombok.Getter; 4 | import run.ikaros.api.core.setting.ConfigMap; 5 | 6 | @Getter 7 | public class PluginConfigMapChangeEvent extends PluginAwareEvent { 8 | private final ConfigMap configMap; 9 | 10 | public PluginConfigMapChangeEvent(Object source, String pluginId, ConfigMap configMap) { 11 | super(source, pluginId); 12 | this.configMap = configMap; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/event/PluginConfigMapCreateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin.event; 2 | 3 | import lombok.Getter; 4 | import run.ikaros.api.core.setting.ConfigMap; 5 | 6 | @Getter 7 | public class PluginConfigMapCreateEvent extends PluginConfigMapChangeEvent { 8 | 9 | public PluginConfigMapCreateEvent(Object source, String pluginId, ConfigMap configMap) { 10 | super(source, pluginId, configMap); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/plugin/event/PluginConfigMapUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.plugin.event; 2 | 3 | import lombok.Getter; 4 | import run.ikaros.api.core.setting.ConfigMap; 5 | 6 | @Getter 7 | public class PluginConfigMapUpdateEvent extends PluginConfigMapChangeEvent { 8 | public PluginConfigMapUpdateEvent(Object source, String pluginId, ConfigMap configMap) { 9 | super(source, pluginId, configMap); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/search/IndicesSearchService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.search; 2 | 3 | import java.util.Set; 4 | import org.pf4j.ExtensionPoint; 5 | 6 | public interface IndicesSearchService extends ExtensionPoint { 7 | 8 | void removeDocuments(Set termTexts) throws Exception; 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/search/SearchResult.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.search; 2 | 3 | import java.util.List; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class SearchResult { 8 | private List hits; 9 | private String keyword; 10 | private Long total; 11 | private int limit; 12 | private long processingTimeMillis; 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/search/subject/SubjectDoc.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.search.subject; 2 | 3 | import java.util.List; 4 | import lombok.Data; 5 | import run.ikaros.api.store.enums.SubjectType; 6 | 7 | @Data 8 | public class SubjectDoc { 9 | private Long id; 10 | private SubjectType type; 11 | private String name; 12 | private String nameCn; 13 | private String infobox; 14 | private String summary; 15 | private Boolean nsfw; 16 | private Long airTime; 17 | private String cover; 18 | private List tags; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/search/subject/SubjectSearchService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.search.subject; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import run.ikaros.api.search.IndicesSearchService; 6 | import run.ikaros.api.search.SearchParam; 7 | import run.ikaros.api.search.SearchResult; 8 | 9 | public interface SubjectSearchService extends IndicesSearchService { 10 | 11 | SearchResult search(SearchParam param) throws Exception; 12 | 13 | void updateDocument(List subjectDocs) throws Exception; 14 | 15 | void rebuild(List subjectDocs) throws IOException; 16 | } 17 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/AttachmentReferenceType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum AttachmentReferenceType { 4 | SUBJECT, 5 | EPISODE, 6 | USER_AVATAR 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/AttachmentRelationType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum AttachmentRelationType { 4 | VIDEO_SUBTITLE 5 | } 6 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/AttachmentType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum AttachmentType { 4 | File, 5 | Directory 6 | } 7 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/AuthorityType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum AuthorityType { 4 | ALL, 5 | API, 6 | APIS, 7 | MENU, 8 | URL, 9 | OTHERS 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/CollectionCategory.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum CollectionCategory { 4 | SUBJECT, 5 | EPISODE; 6 | } 7 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/CollectionType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum CollectionType { 4 | /** 5 | * Wist watch. 6 | */ 7 | WISH, 8 | /** 9 | * Watching. 10 | */ 11 | DOING, 12 | /** 13 | * Watch done. 14 | */ 15 | DONE, 16 | /** 17 | * No time to watch it. 18 | */ 19 | SHELVE, 20 | /** 21 | * Discard it. 22 | */ 23 | DISCARD; 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/FileRelationType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum FileRelationType { 4 | VIDEO_SUBTITLE; 5 | } 6 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/FileType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | /** 4 | * file type. 5 | * 6 | * @author li-guohao 7 | */ 8 | public enum FileType { 9 | IMAGE, 10 | 11 | 12 | VIDEO, 13 | 14 | 15 | DOCUMENT, 16 | 17 | 18 | VOICE, 19 | 20 | 21 | UNKNOWN; 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/SubjectSyncPlatform.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum SubjectSyncPlatform { 4 | /** 5 | * Bangumi 番组计划. 6 | */ 7 | BGM_TV, 8 | /** 9 | * The Move Database(TMDb).. 10 | */ 11 | TMDB, 12 | /** 13 | * AniDB. 14 | */ 15 | AniDB, 16 | /** 17 | * 18 | * tvdb. 19 | */ 20 | TVDB, 21 | /** 22 | * The Visual Novel Database. 23 | */ 24 | VNDB, 25 | 26 | /** 27 | * 豆瓣. 28 | */ 29 | DOU_BAN, 30 | /** 31 | * other platform. 32 | */ 33 | OTHER; 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/SubjectType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum SubjectType { 4 | ANIME, 5 | COMIC, 6 | GAME, 7 | MUSIC, 8 | NOVEL, 9 | REAL, 10 | OTHER 11 | 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/TagType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum TagType { 4 | SUBJECT, 5 | EPISODE, 6 | /** 7 | * Attachment Tag. 8 | *
    9 | *
  • 10 | * subject:000 11 | *
  • 12 | *
13 | */ 14 | ATTACHMENT 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/store/enums/TaskStatus.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.store.enums; 2 | 3 | public enum TaskStatus { 4 | CREATE, 5 | RUNNING, 6 | FINISH, 7 | CANCEL, 8 | FAIL, 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/run/ikaros/api/wrap/CommonResult.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.api.wrap; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class CommonResult { 7 | private String exception; 8 | private String message; 9 | } 10 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/assets/logo.png -------------------------------------------------------------------------------- /console/.env.development: -------------------------------------------------------------------------------- 1 | VITE_API_URL= 2 | VITE_BASE_URL=/console/ 3 | VITE_SERVER_URL=http://localhost:9999 4 | -------------------------------------------------------------------------------- /console/.env.production: -------------------------------------------------------------------------------- 1 | VITE_API_URL= 2 | VITE_BASE_URL=/console/ 3 | VITE_SERVER_URL= -------------------------------------------------------------------------------- /console/.eslintrcignore: -------------------------------------------------------------------------------- 1 | *.sh 2 | node_modules 3 | *.md 4 | *.woff 5 | *.ttf 6 | .vscode 7 | .idea 8 | dist 9 | /public 10 | /docs 11 | .husky 12 | /bin 13 | .eslintrc.js 14 | prettier.config.js 15 | /src/mock/* 16 | 17 | # Logs 18 | logs 19 | *.log 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | pnpm-debug.log* 24 | lerna-debug.log* 25 | 26 | .DS_Store 27 | dist-ssr 28 | *.local 29 | 30 | /cypress/videos/ 31 | /cypress/screenshots/ 32 | 33 | # Editor directories and files 34 | .vscode 35 | !.vscode/extensions.json 36 | .idea 37 | *.suo 38 | *.njsproj 39 | *.sln 40 | *.sw? 41 | 42 | components.d.ts -------------------------------------------------------------------------------- /console/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | histoire-dist 15 | coverage 16 | *.local 17 | 18 | /cypress/videos/ 19 | /cypress/screenshots/ 20 | 21 | # Editor directories and files 22 | .vscode/* 23 | !.vscode/extensions.json 24 | .idea 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | 31 | # Generated files by unplugin-auto-import 32 | .stylelintcache 33 | auto-imports.d.ts 34 | components.d.ts 35 | 36 | # ts build info, such as version 37 | tsconfig.tsbuildinfo 38 | 39 | # others 40 | vite.config.ts.timestamp-*.mjs -------------------------------------------------------------------------------- /console/.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | cd console 4 | npx --no -- commitlint --edit 5 | -------------------------------------------------------------------------------- /console/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | cd console 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /console/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | .local 3 | .output.js 4 | /node_modules/** 5 | src/.DS_Store 6 | 7 | **/*.svg 8 | **/*.sh 9 | 10 | /public/* 11 | components.d.ts -------------------------------------------------------------------------------- /console/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | tabWidth: 2, 4 | useTabs: true, 5 | semi: true, 6 | singleQuote: true, 7 | quoteProps: 'as-needed', 8 | jsxSingleQuote: false, 9 | trailingComma: 'es5', 10 | bracketSpacing: true, 11 | arrowParens: 'always', 12 | rangeStart: 0, 13 | rangeEnd: Infinity, 14 | requirePragma: false, 15 | insertPragma: false, 16 | proseWrap: 'always', 17 | htmlWhitespaceSensitivity: 'css', 18 | endOfLine: 'auto', 19 | }; -------------------------------------------------------------------------------- /console/README.md: -------------------------------------------------------------------------------- 1 | # Ikaros Console 2 | 3 | Ikaros Web Console 模块 4 | 5 | # 环境 6 | 7 | - node: 18.16.0 8 | - npm: 9.6.7 9 | - pnpm: 8.3.0 10 | 11 | ### 编译依赖包 12 | 13 | ``` 14 | pnpm packagesBuild 15 | ``` 16 | 17 | 这个命令执行了安装对应的`packages`目录下的两个包: 18 | 19 | - `@runikaros/api-client`: 这个包封装了`axios`的`OpenAPI`接口 20 | - `@runikaros/shared`: 这个包是一些通用类型定义 21 | 22 | 23 | ### 安装依赖 24 | 25 | 安装依赖前,请先进行[编译依赖包](#编译依赖包),不然运行的时候会报错。 26 | 27 | 本地开发和构建打包前,都需要前安装依赖。 28 | 29 | ``` 30 | pnpm install 31 | ``` 32 | 33 | ### 本地开发 34 | 35 | ``` 36 | pnpm dev 37 | ``` 38 | 39 | ### 构建打包 40 | 41 | ``` 42 | pnpm build 43 | ``` 44 | 45 | 构建的产物在父目录的对应目录里:`../server/src/main/resources/console` 46 | 47 | ### 初始化综合命令(可选) 48 | 49 | 如不清楚上述命令是否需要执行,只需要执行一次下方命令即可,后续可以正常`pnpm dev` 或者 `pnpm build` 50 | 51 | ``` 52 | pnpm packagesBuild && pnpm install && pnpm build 53 | ``` 54 | -------------------------------------------------------------------------------- /console/packages/api-client/.eslintignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | node_modules/* 3 | -------------------------------------------------------------------------------- /console/packages/api-client/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["../../.eslintrc.cjs"], 3 | }; 4 | -------------------------------------------------------------------------------- /console/packages/api-client/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /console/packages/api-client/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["../../.prettierrc.cjs"], 3 | }; 4 | -------------------------------------------------------------------------------- /console/packages/api-client/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild'; 2 | 3 | export default defineBuildConfig({ 4 | entries: ['src/index'], 5 | declaration: true, 6 | clean: true, 7 | rollup: { 8 | emitCJS: true, 9 | }, 10 | externals: ['axios'], 11 | }); 12 | -------------------------------------------------------------------------------- /console/packages/api-client/openapitools.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", 3 | "spaces": 2, 4 | "generator-cli": { 5 | "version": "6.3.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /console/packages/api-client/src/.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/*.js 2 | node_modules 3 | typings 4 | dist 5 | -------------------------------------------------------------------------------- /console/packages/api-client/src/.npmignore: -------------------------------------------------------------------------------- 1 | # empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm -------------------------------------------------------------------------------- /console/packages/api-client/src/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 6.3.0 -------------------------------------------------------------------------------- /console/packages/api-client/src/.openapi_config.yaml: -------------------------------------------------------------------------------- 1 | supportsES6: true 2 | useSingleRequestParameter: true 3 | withSeparateModelsAndApi: true 4 | apiPackage: api 5 | modelPackage: models 6 | -------------------------------------------------------------------------------- /console/packages/api-client/src/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | export * from "./api"; 16 | export * from "./configuration"; 17 | export * from "./models"; 18 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/alist-import-post-body.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface AListImportPostBody 19 | */ 20 | export interface AListImportPostBody { 21 | /** 22 | * 导入的路径,需要警告base64进行编码。 23 | * @type {string} 24 | * @memberof AListImportPostBody 25 | */ 26 | path: string; 27 | } 28 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/author.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface Author 19 | */ 20 | export interface Author { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof Author 25 | */ 26 | name?: string; 27 | /** 28 | * 29 | * @type {string} 30 | * @memberof Author 31 | */ 32 | website?: string; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/config-map.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface ConfigMap 19 | */ 20 | export interface ConfigMap { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof ConfigMap 25 | */ 26 | name?: string; 27 | /** 28 | * 29 | * @type {{ [key: string]: string; }} 30 | * @memberof ConfigMap 31 | */ 32 | data?: { [key: string]: string }; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/file-batch-request.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface FileBatchRequest 19 | */ 20 | export interface FileBatchRequest { 21 | /** 22 | * 文件ID数组 23 | * @type {Array} 24 | * @memberof FileBatchRequest 25 | */ 26 | fileIds: Array; 27 | /** 28 | * 远端 29 | * @type {string} 30 | * @memberof FileBatchRequest 31 | */ 32 | remote: string; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/file-policy.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface FilePolicy 19 | */ 20 | export interface FilePolicy { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof FilePolicy 25 | */ 26 | name?: string; 27 | } 28 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/file-setting.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface FileSetting 19 | */ 20 | export interface FileSetting { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof FileSetting 25 | */ 26 | policy?: string; 27 | } 28 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/link.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface Link 19 | */ 20 | export interface Link { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof Link 25 | */ 26 | href?: string; 27 | /** 28 | * 29 | * @type {boolean} 30 | * @memberof Link 31 | */ 32 | templated?: boolean; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/role-authority-req-params.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface RoleAuthorityReqParams 19 | */ 20 | export interface RoleAuthorityReqParams { 21 | /** 22 | * 23 | * @type {number} 24 | * @memberof RoleAuthorityReqParams 25 | */ 26 | roleId?: number; 27 | /** 28 | * 29 | * @type {Array} 30 | * @memberof RoleAuthorityReqParams 31 | */ 32 | authorityIds?: Array; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/starter-custom.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface StarterCustom 19 | */ 20 | export interface StarterCustom { 21 | /** 22 | * 23 | * @type {string} 24 | * @memberof StarterCustom 25 | */ 26 | title?: string; 27 | /** 28 | * 29 | * @type {number} 30 | * @memberof StarterCustom 31 | */ 32 | number?: number; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/user-role-req-params.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | /** 16 | * 17 | * @export 18 | * @interface UserRoleReqParams 19 | */ 20 | export interface UserRoleReqParams { 21 | /** 22 | * 23 | * @type {number} 24 | * @memberof UserRoleReqParams 25 | */ 26 | userId?: number; 27 | /** 28 | * 29 | * @type {Array} 30 | * @memberof UserRoleReqParams 31 | */ 32 | roleIds?: Array; 33 | } 34 | -------------------------------------------------------------------------------- /console/packages/api-client/src/models/user.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Ikaros Open API Documentation 5 | * Documentation for Ikaros Open API 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | // May contain unused imports in some cases 16 | // @ts-ignore 17 | import { UserEntity } from "./user-entity"; 18 | 19 | /** 20 | * 21 | * @export 22 | * @interface User 23 | */ 24 | export interface User { 25 | /** 26 | * 27 | * @type {UserEntity} 28 | * @memberof User 29 | */ 30 | entity?: UserEntity; 31 | } 32 | -------------------------------------------------------------------------------- /console/packages/api-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "moduleResolution": "node", 7 | "esModuleInterop": true, 8 | "strict": true, 9 | "strictNullChecks": true, 10 | "resolveJsonModule": true, 11 | "skipLibCheck": true, 12 | "skipDefaultLibCheck": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /console/packages/shared/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /console/packages/shared/README.md: -------------------------------------------------------------------------------- 1 | # Ikaros Shared 2 | 3 | Project ikaros web console shared package 4 | 5 | ``` 6 | npm run i @runikaros/shared 7 | npm run build 8 | ``` 9 | -------------------------------------------------------------------------------- /console/packages/shared/src/core/plugins.ts: -------------------------------------------------------------------------------- 1 | import type { PluginModule } from '../types/plugin'; 2 | 3 | export function definePlugin(plugin: PluginModule): PluginModule { 4 | return plugin; 5 | } 6 | -------------------------------------------------------------------------------- /console/packages/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types/plugin'; 2 | export * from './types/menus'; 3 | export * from './core/plugins'; 4 | -------------------------------------------------------------------------------- /console/packages/shared/src/types/menus.ts: -------------------------------------------------------------------------------- 1 | import type { Component } from 'vue'; 2 | 3 | export type CoreMenuGroupId = 4 | | 'dashboard' 5 | | 'user' 6 | | 'content' 7 | | 'interface' 8 | | 'system' 9 | | 'tool'; 10 | 11 | export interface MenuGroupType { 12 | id: CoreMenuGroupId | string; 13 | name?: string; 14 | priority?: number; 15 | items?: MenuItemType[]; 16 | } 17 | 18 | export interface MenuItemType { 19 | name: string; 20 | path: string; 21 | mobile?: boolean; 22 | icon?: Component; 23 | meta?: Record; 24 | children?: MenuItemType[]; 25 | } 26 | -------------------------------------------------------------------------------- /console/packages/shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /console/packages/shared/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /console/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/**" 3 | -------------------------------------------------------------------------------- /console/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/console/public/favicon.ico -------------------------------------------------------------------------------- /console/public/js/JavascriptSubtitlesOctopus/subtitles-octopus-worker.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/console/public/js/JavascriptSubtitlesOctopus/subtitles-octopus-worker.data -------------------------------------------------------------------------------- /console/public/js/JavascriptSubtitlesOctopus/subtitles-octopus-worker.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/console/public/js/JavascriptSubtitlesOctopus/subtitles-octopus-worker.wasm -------------------------------------------------------------------------------- /console/public/svg/subtitle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /console/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /console/src/components/icon/IconParkOutlinePlug.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /console/src/components/modules/content/subject/SubjectCardLink.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /console/src/fromkit/formkit.config.ts: -------------------------------------------------------------------------------- 1 | import { zh } from '@formkit/i18n'; 2 | import { DefaultConfigOptions } from '@formkit/vue'; 3 | import { generateClasses } from '@formkit/themes'; 4 | import { genesisIcons } from '@formkit/icons'; 5 | // @ts-ignore 6 | import genesis from '@formkit/themes/tailwindcss/genesis'; 7 | 8 | import '@formkit/themes/genesis'; 9 | 10 | const config: DefaultConfigOptions = { 11 | locales: { zh }, 12 | locale: 'zh', 13 | icons: { 14 | ...genesisIcons, 15 | }, 16 | config: { 17 | classes: generateClasses(genesis), 18 | }, 19 | inputs: {}, 20 | }; 21 | 22 | export default config; 23 | -------------------------------------------------------------------------------- /console/src/layouts/BlankLayout.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /console/src/layouts/components/Hamburger.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /console/src/layouts/components/Wellcome.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /console/src/layouts/menus.config.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'vue'; 2 | 3 | export interface MenuItem { 4 | // menu item index 5 | id: string; 6 | // menu item route 7 | path: string; 8 | // menu item span 9 | name: string; 10 | // @element-plus/icons-vue 11 | elIcon: Component; 12 | // sub menu item 13 | children: Array; 14 | } 15 | export const menus: Array = []; 16 | export default menus; 17 | -------------------------------------------------------------------------------- /console/src/modules/content/attachment/module.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from '@runikaros/shared'; 2 | import { markRaw } from 'vue'; 3 | import { Folder as FolderIcon } from '@element-plus/icons-vue'; 4 | import Attachments from './Attachments.vue'; 5 | 6 | // 7 | export default definePlugin({ 8 | name: 'User', 9 | components: {}, 10 | routes: [ 11 | { 12 | parentName: 'Root', 13 | route: { 14 | path: '/attachments', 15 | name: 'Attachments', 16 | component: Attachments, 17 | meta: { 18 | title: 'module.attachment.title', 19 | menu: { 20 | name: 'module.attachment.sidebar', 21 | group: 'content', 22 | icon: markRaw(FolderIcon), 23 | priority: 0, 24 | }, 25 | }, 26 | }, 27 | }, 28 | ], 29 | }); 30 | -------------------------------------------------------------------------------- /console/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | import Dashboard from './dashboard/module'; 2 | import User from './user/module'; 3 | import Attachment from './content/attachment/module'; 4 | import Subject from './content/subject/module'; 5 | import Plugin from './system/plugin/module'; 6 | import Setting from './system/setting/module'; 7 | import About from './system/about/module'; 8 | import Tasks from './system/task/module'; 9 | import Users from './system/user/module'; 10 | import Roles from './system/role/module'; 11 | 12 | const coreModules = [ 13 | Dashboard, 14 | User, 15 | Attachment, 16 | Subject, 17 | Plugin, 18 | Setting, 19 | About, 20 | Tasks, 21 | Users, 22 | Roles, 23 | ]; 24 | 25 | export { coreModules }; 26 | -------------------------------------------------------------------------------- /console/src/modules/system/about/module.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from '@runikaros/shared'; 2 | import { markRaw } from 'vue'; 3 | import { Ship } from '@element-plus/icons-vue'; 4 | import About from './About.vue'; 5 | 6 | export default definePlugin({ 7 | name: 'SystemAbout', 8 | components: {}, 9 | routes: [ 10 | { 11 | parentName: 'Root', 12 | route: { 13 | path: '/about', 14 | name: 'About', 15 | component: About, 16 | meta: { 17 | title: 'module.about.title', 18 | menu: { 19 | name: 'module.about.sidebar', 20 | group: 'system', 21 | icon: markRaw(Ship), 22 | priority: 99, 23 | }, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }); 29 | -------------------------------------------------------------------------------- /console/src/modules/system/setting/module.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from '@runikaros/shared'; 2 | import Setting from './Setting.vue'; 3 | import { Setting as SettingIcon } from '@element-plus/icons-vue'; 4 | import { markRaw } from 'vue'; 5 | 6 | export default definePlugin({ 7 | name: 'SystemSetting', 8 | components: {}, 9 | routes: [ 10 | { 11 | parentName: 'Root', 12 | route: { 13 | path: '/setting', 14 | name: 'Setting', 15 | component: Setting, 16 | meta: { 17 | title: 'module.setting.title', 18 | menu: { 19 | name: 'module.setting.sidebar', 20 | group: 'system', 21 | icon: markRaw(SettingIcon), 22 | priority: 0, 23 | }, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }); 29 | -------------------------------------------------------------------------------- /console/src/modules/system/user/module.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from '@runikaros/shared'; 2 | import { UserFilled } from '@element-plus/icons-vue'; 3 | import { markRaw } from 'vue'; 4 | import Users from './Users.vue'; 5 | 6 | export default definePlugin({ 7 | name: 'SystemSetting', 8 | components: {}, 9 | routes: [ 10 | { 11 | parentName: 'Root', 12 | route: { 13 | path: '/users', 14 | name: 'Users', 15 | component: Users, 16 | meta: { 17 | title: 'module.users.title', 18 | menu: { 19 | name: 'module.users.sidebar', 20 | group: 'system', 21 | icon: markRaw(UserFilled), 22 | priority: 2, 23 | }, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }); 29 | -------------------------------------------------------------------------------- /console/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createRouter, 3 | createWebHashHistory, 4 | type RouteLocationNormalized, 5 | type RouteLocationNormalizedLoaded, 6 | } from 'vue-router'; 7 | import routesConfig from './routes.config'; 8 | import { setupAuthCheckGuard } from './guards/auth-check'; 9 | 10 | const router = createRouter({ 11 | history: createWebHashHistory(import.meta.env.BASE_URL), 12 | routes: routesConfig, 13 | scrollBehavior: ( 14 | to: RouteLocationNormalized, 15 | from: RouteLocationNormalizedLoaded 16 | ) => { 17 | if (to.name !== from.name) { 18 | return { left: 0, top: 0 }; 19 | } 20 | }, 21 | }); 22 | 23 | setupAuthCheckGuard(router); 24 | 25 | export default router; 26 | -------------------------------------------------------------------------------- /console/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | import { createPinia } from 'pinia'; 3 | import piniaPersist from 'pinia-plugin-persist'; 4 | 5 | const pinia = createPinia(); 6 | pinia.use(piniaPersist); 7 | 8 | export function setupPinia(app: App) { 9 | app.use(pinia); 10 | } 11 | 12 | export default pinia; 13 | -------------------------------------------------------------------------------- /console/src/stores/plugin.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | import type { PluginModule as PluginModuleRaw } from '@runikaros/shared'; 3 | 4 | export interface PluginModule extends PluginModuleRaw {} 5 | 6 | interface PluginStoreState { 7 | pluginModules: PluginModule[]; 8 | } 9 | 10 | export const usePluginModuleStore = defineStore('plugin', { 11 | state: (): PluginStoreState => ({ 12 | pluginModules: [], 13 | }), 14 | actions: { 15 | registerPluginModule(pluginModule: PluginModule) { 16 | this.pluginModules.push(pluginModule); 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /console/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './reset.scss'; 2 | 3 | @import 'element-plus/theme-chalk/el-message.css'; 4 | @import 'element-plus/theme-chalk/el-message-box.css'; 5 | @import 'element-plus/theme-chalk/index.css'; 6 | 7 | @tailwind base; 8 | @tailwind components; 9 | @tailwind utilities; 10 | -------------------------------------------------------------------------------- /console/src/styles/variables.module.scss: -------------------------------------------------------------------------------- 1 | // sidebar 2 | $menuText: #bfcbd9; 3 | $menuActiveText: #ffffff; 4 | $subMenuActiveText: #f4f4f5; 5 | 6 | $menuBg: #304156; 7 | $menuHover: #263445; 8 | 9 | $subMenuBg: #1f2d3d; 10 | $subMenuHover: #001528; 11 | 12 | $sideBarWidth: 210px; 13 | $hideSideBarWidth: 67px; 14 | $sideBarDuration: 0.28s; 15 | 16 | 17 | :export { 18 | menuText: $menuText; 19 | menuActiveText: $menuActiveText; 20 | subMenuActiveText: $subMenuActiveText; 21 | menuBg: $menuBg; 22 | menuHover: $menuHover; 23 | subMenuBg: $subMenuBg; 24 | subMenuHover: $subMenuHover; 25 | sideBarWidth: $sideBarWidth; 26 | hideSideBarWidth: $hideSideBarWidth; 27 | } 28 | -------------------------------------------------------------------------------- /console/src/utils/id.ts: -------------------------------------------------------------------------------- 1 | export function randomUUID() { 2 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 3 | const r = (Math.random() * 16) | 0, 4 | v = c === 'x' ? r : (r & 0x3) | 0x8; 5 | return v.toString(16); 6 | }); 7 | } 8 | -------------------------------------------------------------------------------- /console/src/utils/moment.ts: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | 3 | export const dateFormat = (row, column) => { 4 | var date = row[column.property]; 5 | 6 | if (date == undefined) { 7 | return ''; 8 | } 9 | 10 | return moment(date).format('YYYY-MM-DD HH:mm:ss'); 11 | }; 12 | -------------------------------------------------------------------------------- /console/src/views/exception/Forbidden.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /console/src/views/exception/NotFound.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /console/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /console/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const FormKitVariants = require('@formkit/themes/tailwindcss'); 3 | export default { 4 | content: [ 5 | './src/**/*.{html,js,ts,vue}', 6 | './node_modules/@formkit/themes/dist/tailwindcss/genesis/index.cjs', 7 | ], 8 | theme: { 9 | extend: {}, 10 | }, 11 | plugins: [FormKitVariants], 12 | }; 13 | -------------------------------------------------------------------------------- /console/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=1.0.0 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | lombok.addLombokGeneratedAnnotation = true -------------------------------------------------------------------------------- /platform/plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-platform' 3 | id 'maven-publish' 4 | } 5 | 6 | group = 'run.ikaros.platform.plugin' 7 | description = 'This is the platform that other plugins depend on. ' + 8 | 'We can put the plugin API as a dependency at here.' 9 | 10 | javaPlatform { 11 | allowDependencies() 12 | } 13 | 14 | dependencies { 15 | api platform(project(':platform:server')) 16 | constraints { 17 | api project(':api') 18 | // TODO other plugin API dependencies 19 | } 20 | } 21 | 22 | publishing { 23 | publications { 24 | pluginPlatform(MavenPublication) { 25 | from components.javaPlatform 26 | } 27 | } 28 | repositories { 29 | mavenLocal() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store 43 | 44 | 45 | ### Local Dev Files 46 | application-local.yaml -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/IkarosApplication.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import run.ikaros.api.infra.properties.IkarosProperties; 7 | 8 | /** 9 | * Ikaros entry class. 10 | * 11 | * @author: li-guohao 12 | */ 13 | @EnableConfigurationProperties({IkarosProperties.class}) 14 | @SpringBootApplication(scanBasePackages = "run.ikaros.server") 15 | public class IkarosApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(IkarosApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/cache/CacheType.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.cache; 2 | 3 | public enum CacheType { 4 | Memory, Redis 5 | } 6 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/cache/ReactiveCacheManager.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.cache; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | public interface ReactiveCacheManager { 6 | 7 | Mono containsKey(String key); 8 | 9 | Mono get(String key); 10 | 11 | Mono put(String key, Object value); 12 | 13 | Mono remove(String key); 14 | 15 | Mono clear(); 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/cache/RedisAutoConfigDisableConfiguration.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.cache; 2 | 3 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 4 | import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.context.annotation.Configuration; 7 | import run.ikaros.server.cache.condition.CacheRedisDisableCondition; 8 | 9 | @Configuration(proxyBeanMethods = false) 10 | @Conditional(CacheRedisDisableCondition.class) 11 | @EnableAutoConfiguration(exclude = {RedisAutoConfiguration.class}) 12 | public class RedisAutoConfigDisableConfiguration { 13 | } 14 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/config/IkarosConfiguration.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | 5 | @Configuration(proxyBeanMethods = false) 6 | public class IkarosConfiguration { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/config/ScheduledConfiguration.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.scheduling.annotation.EnableScheduling; 5 | 6 | @EnableScheduling 7 | @Configuration(proxyBeanMethods = false) 8 | public class ScheduledConfiguration { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/console/ConsoleAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.console; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration 7 | @EnableConfigurationProperties(ConsoleProperties.class) 8 | public class ConsoleAutoConfiguration { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/console/ConsoleProperties.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.console; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.validation.annotation.Validated; 6 | 7 | @Data 8 | @Validated 9 | @ConfigurationProperties(prefix = "ikaros.console") 10 | public class ConsoleProperties { 11 | private String location = "classpath:/console/"; 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/attachment/event/AttachmentReferenceSaveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.attachment.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.server.store.entity.AttachmentReferenceEntity; 6 | 7 | @Getter 8 | public class AttachmentReferenceSaveEvent extends ApplicationEvent { 9 | 10 | private final AttachmentReferenceEntity entity; 11 | 12 | public AttachmentReferenceSaveEvent(Object source, AttachmentReferenceEntity entity) { 13 | super(source); 14 | this.entity = entity; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/attachment/event/AttachmentRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.attachment.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.server.store.entity.AttachmentEntity; 6 | 7 | @Getter 8 | public class AttachmentRemoveEvent extends ApplicationEvent { 9 | private final AttachmentEntity entity; 10 | 11 | public AttachmentRemoveEvent(Object source, AttachmentEntity entity) { 12 | super(source); 13 | this.entity = entity; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/attachment/vo/BatchMatchingEpisodeAttachment.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.attachment.vo; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | @Data 9 | public class BatchMatchingEpisodeAttachment { 10 | @Schema(requiredMode = REQUIRED, description = "episode id for subject.") 11 | private Long episodeId; 12 | @Schema(requiredMode = REQUIRED, description = "attachment id array.") 13 | private Long[] attachmentIds; 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/attachment/vo/PostAttachmentRelationsParam.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.attachment.vo; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import java.util.List; 7 | import lombok.Data; 8 | import run.ikaros.api.store.enums.AttachmentRelationType; 9 | 10 | @Data 11 | public class PostAttachmentRelationsParam { 12 | @Schema(requiredMode = REQUIRED, description = "Master attachment id.") 13 | private Long masterId; 14 | @Schema(requiredMode = REQUIRED, description = "Type of attachment.") 15 | private AttachmentRelationType type; 16 | @Schema(requiredMode = REQUIRED, description = "Related attachment ids.") 17 | private List relationIds; 18 | } 19 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/collection/CollectionService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.collection; 2 | 3 | import reactor.core.publisher.Mono; 4 | import run.ikaros.api.core.collection.vo.FindCollectionCondition; 5 | import run.ikaros.api.store.enums.CollectionType; 6 | import run.ikaros.api.wrap.PagingWrap; 7 | 8 | public interface CollectionService { 9 | Mono findTypeBySubjectId(Long subjectId); 10 | 11 | Mono listCollectionsByCondition(FindCollectionCondition condition); 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/collection/event/SubjectCollectionScoreUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.collection.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import org.springframework.context.ApplicationEvent; 6 | 7 | @Getter 8 | public class SubjectCollectionScoreUpdateEvent extends ApplicationEvent { 9 | private final Long subjectId; 10 | 11 | public SubjectCollectionScoreUpdateEvent(Object source, Long subjectId) { 12 | super(source); 13 | this.subjectId = subjectId; 14 | } 15 | 16 | public SubjectCollectionScoreUpdateEvent(Object source, Clock clock, Long subjectId) { 17 | super(source, clock); 18 | this.subjectId = subjectId; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/episode/EpisodeRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.episode; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import org.springframework.context.ApplicationEvent; 6 | import run.ikaros.server.store.entity.EpisodeEntity; 7 | 8 | @Getter 9 | public class EpisodeRemoveEvent extends ApplicationEvent { 10 | private final EpisodeEntity entity; 11 | 12 | public EpisodeRemoveEvent(Object source, EpisodeEntity entity) { 13 | super(source); 14 | this.entity = entity; 15 | } 16 | 17 | public EpisodeRemoveEvent(Object source, Clock clock, EpisodeEntity entity) { 18 | super(source, clock); 19 | this.entity = entity; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/meta/MetaService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.meta; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.subject.Subject; 6 | 7 | /** 8 | * Meta service. 9 | */ 10 | public interface MetaService { 11 | Mono findOne(String keyword); 12 | 13 | Flux findAll(String keyword); 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/notify/MailService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.notify; 2 | 3 | import jakarta.mail.MessagingException; 4 | import org.thymeleaf.context.Context; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.server.core.notify.model.MailConfig; 7 | import run.ikaros.server.core.notify.model.MailRequest; 8 | 9 | public interface MailService { 10 | MailConfig getMailConfig(); 11 | 12 | Mono updateConfig(); 13 | 14 | Mono send(MailRequest request) throws MessagingException; 15 | 16 | Mono send(MailRequest request, String template, Context context); 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/notify/NotifyService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.notify; 2 | 3 | import org.thymeleaf.context.Context; 4 | import reactor.core.publisher.Mono; 5 | 6 | public interface NotifyService { 7 | Mono sendMail(String title, String context); 8 | 9 | Mono send(String title, String template, Context context); 10 | 11 | Mono testMail(); 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/notify/model/MailConfig.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.notify.model; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class MailConfig { 7 | private Boolean enable; 8 | private MailProtocol protocol; 9 | private String host; 10 | private Integer port; 11 | private String account; 12 | private String password; 13 | private String accountAlias; 14 | private String receiveAddress; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/notify/model/MailProtocol.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.notify.model; 2 | 3 | public enum MailProtocol { 4 | SMTP 5 | } 6 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/notify/model/MailRequest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.notify.model; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class MailRequest { 7 | private String address; 8 | private String title; 9 | private String content; 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/plugin/PluginOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.plugin; 2 | 3 | public enum PluginOperate { 4 | INSTALL, 5 | UNINSTALL, 6 | UPGRADE 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/plugin/PluginStateOperate.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.plugin; 2 | 3 | public enum PluginStateOperate { 4 | START, 5 | STOP, 6 | ENABLE, 7 | DISABLE, 8 | LOAD, 9 | LOAD_ALL(), 10 | RELOAD, 11 | RELOAD_ALL, 12 | RELOAD_ALL_STARTED, 13 | DELETE, 14 | UNLOAD 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/profile/Unstructured.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.profile; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Unstructured { 7 | 8 | private final Map data; 9 | 10 | public Unstructured() { 11 | this(new HashMap()); 12 | } 13 | 14 | public Unstructured(Map data) { 15 | this.data = data; 16 | } 17 | 18 | public Map getData() { 19 | return data; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/RoleAuthorityService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.authority.Authority; 6 | 7 | public interface RoleAuthorityService { 8 | Flux addAuthoritiesForRole(Long roleId, Long[] authorityIds); 9 | 10 | Mono deleteAuthoritiesForRole(Long roleId, Long[] authorityIds); 11 | 12 | Flux getAuthoritiesForRole(Long roleId); 13 | } 14 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/RoleService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.role.Role; 6 | 7 | public interface RoleService { 8 | Mono findById(Long roleId); 9 | 10 | Mono findNameById(Long roleId); 11 | 12 | Mono createIfNotExist(String role); 13 | 14 | Flux findAll(); 15 | 16 | Mono deleteById(Long roleId); 17 | 18 | Mono save(Role role); 19 | } 20 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleChangeEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import org.springframework.context.ApplicationEvent; 6 | import run.ikaros.server.store.entity.RoleEntity; 7 | 8 | @Getter 9 | public class RoleChangeEvent extends ApplicationEvent { 10 | private final RoleEntity roleEntity; 11 | 12 | public RoleChangeEvent(Object source, RoleEntity roleEntity) { 13 | super(source); 14 | this.roleEntity = roleEntity; 15 | } 16 | 17 | public RoleChangeEvent(Object source, Clock clock, RoleEntity roleEntity) { 18 | super(source, clock); 19 | this.roleEntity = roleEntity; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import run.ikaros.server.store.entity.RoleEntity; 5 | 6 | public class RoleCreatedEvent extends RoleChangeEvent { 7 | 8 | public RoleCreatedEvent(Object source, RoleEntity roleEntity) { 9 | super(source, roleEntity); 10 | } 11 | 12 | public RoleCreatedEvent(Object source, Clock clock, RoleEntity roleEntity) { 13 | super(source, clock, roleEntity); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleRelationChangeEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import run.ikaros.server.store.entity.RoleEntity; 6 | 7 | @Getter 8 | public class RoleRelationChangeEvent extends RoleChangeEvent { 9 | private final Long userId; 10 | 11 | public RoleRelationChangeEvent(Object source, RoleEntity roleEntity, Long userId) { 12 | super(source, roleEntity); 13 | this.userId = userId; 14 | } 15 | 16 | public RoleRelationChangeEvent(Object source, Clock clock, RoleEntity roleEntity, Long userId) { 17 | super(source, clock, roleEntity); 18 | this.userId = userId; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleRelationCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import run.ikaros.server.store.entity.RoleEntity; 5 | 6 | public class RoleRelationCreatedEvent extends RoleRelationChangeEvent { 7 | 8 | public RoleRelationCreatedEvent(Object source, RoleEntity roleEntity, Long userId) { 9 | super(source, roleEntity, userId); 10 | } 11 | 12 | public RoleRelationCreatedEvent(Object source, Clock clock, RoleEntity roleEntity, 13 | Long userId) { 14 | super(source, clock, roleEntity, userId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleRelationRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import run.ikaros.server.store.entity.RoleEntity; 5 | 6 | public class RoleRelationRemoveEvent extends RoleRelationChangeEvent { 7 | 8 | public RoleRelationRemoveEvent(Object source, RoleEntity roleEntity, Long userId) { 9 | super(source, roleEntity, userId); 10 | } 11 | 12 | public RoleRelationRemoveEvent(Object source, Clock clock, RoleEntity roleEntity, 13 | Long userId) { 14 | super(source, clock, roleEntity, userId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/event/RoleRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.event; 2 | 3 | import java.time.Clock; 4 | import run.ikaros.server.store.entity.RoleEntity; 5 | 6 | public class RoleRemoveEvent extends RoleChangeEvent { 7 | 8 | public RoleRemoveEvent(Object source, RoleEntity roleEntity) { 9 | super(source, roleEntity); 10 | } 11 | 12 | public RoleRemoveEvent(Object source, Clock clock, RoleEntity roleEntity) { 13 | super(source, clock, roleEntity); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/listener/RoleRelationListener.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.listener; 2 | 3 | public class RoleRelationListener { 4 | } 5 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/role/listener/RoleRemoveListener.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.role.listener; 2 | 3 | public class RoleRemoveListener { 4 | } 5 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/setting/SettingService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.setting; 2 | 3 | import reactor.core.publisher.Mono; 4 | import run.ikaros.api.core.setting.vo.GlobalSetting; 5 | 6 | public interface SettingService { 7 | Mono getGlobalSetting(); 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/statics/StaticService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.statics; 2 | 3 | import reactor.core.publisher.Flux; 4 | 5 | public interface StaticService { 6 | Flux listStaticsFonts(); 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/subject/event/SubjectAddEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.subject.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | import run.ikaros.server.store.entity.SubjectEntity; 5 | 6 | public class SubjectAddEvent extends ApplicationEvent { 7 | private final SubjectEntity entity; 8 | 9 | public SubjectAddEvent(Object source, SubjectEntity entity) { 10 | super(source); 11 | this.entity = entity; 12 | } 13 | 14 | public SubjectEntity getEntity() { 15 | return entity; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/subject/event/SubjectRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.subject.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | import run.ikaros.server.store.entity.SubjectEntity; 5 | 6 | public class SubjectRemoveEvent extends ApplicationEvent { 7 | private final SubjectEntity entity; 8 | 9 | public SubjectRemoveEvent(Object source, SubjectEntity entity) { 10 | super(source); 11 | this.entity = entity; 12 | } 13 | 14 | public SubjectEntity getEntity() { 15 | return entity; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/subject/event/SubjectUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.subject.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.server.store.entity.SubjectEntity; 6 | 7 | @Getter 8 | public class SubjectUpdateEvent extends ApplicationEvent { 9 | private final SubjectEntity oldEntity; 10 | private final SubjectEntity newEntity; 11 | 12 | /** 13 | * Construct. 14 | */ 15 | public SubjectUpdateEvent(Object source, 16 | SubjectEntity oldEntity, SubjectEntity newEntity) { 17 | super(source); 18 | this.oldEntity = oldEntity; 19 | this.newEntity = newEntity; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/subject/service/SubjectRelationService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.subject.service; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.subject.SubjectRelation; 6 | import run.ikaros.api.store.enums.SubjectRelationType; 7 | 8 | public interface SubjectRelationService { 9 | Flux findAllBySubjectId(Long subjectId); 10 | 11 | Mono findBySubjectIdAndType(Long subjectId, SubjectRelationType relationType); 12 | 13 | Mono createSubjectRelation(SubjectRelation subjectRelation); 14 | 15 | Mono removeSubjectRelation(SubjectRelation subjectRelation); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/tag/TagService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.tag; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.tag.AttachmentTag; 6 | import run.ikaros.api.core.tag.SubjectTag; 7 | import run.ikaros.api.core.tag.Tag; 8 | import run.ikaros.api.store.enums.TagType; 9 | 10 | public interface TagService { 11 | Flux findAll(TagType type, Long masterId, Long userId, String name); 12 | 13 | Flux findSubjectTags(Long subjectId); 14 | 15 | Flux findAttachmentTags(Long attachmentId); 16 | 17 | Mono create(Tag tag); 18 | 19 | Mono remove(TagType type, Long masterId, String name); 20 | 21 | Mono removeById(Long tagId); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/tag/event/TagChangeEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.tag.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import org.springframework.context.ApplicationEvent; 6 | import run.ikaros.server.store.entity.TagEntity; 7 | 8 | @Getter 9 | public class TagChangeEvent extends ApplicationEvent { 10 | private final TagEntity entity; 11 | 12 | public TagChangeEvent(Object source, TagEntity entity) { 13 | super(source); 14 | this.entity = entity; 15 | } 16 | 17 | public TagChangeEvent(Object source, Clock clock, TagEntity entity) { 18 | super(source, clock); 19 | this.entity = entity; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/tag/event/TagCreateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.tag.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import run.ikaros.server.store.entity.TagEntity; 6 | 7 | @Getter 8 | public class TagCreateEvent extends TagChangeEvent { 9 | 10 | public TagCreateEvent(Object source, TagEntity entity) { 11 | super(source, entity); 12 | } 13 | 14 | public TagCreateEvent(Object source, Clock clock, TagEntity entity) { 15 | super(source, clock, entity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/tag/event/TagRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.tag.event; 2 | 3 | import java.time.Clock; 4 | import lombok.Getter; 5 | import run.ikaros.server.store.entity.TagEntity; 6 | 7 | @Getter 8 | public class TagRemoveEvent extends TagChangeEvent { 9 | 10 | public TagRemoveEvent(Object source, TagEntity entity) { 11 | super(source, entity); 12 | } 13 | 14 | public TagRemoveEvent(Object source, Clock clock, TagEntity entity) { 15 | super(source, clock, entity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/task/FindTaskCondition.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.task; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import run.ikaros.api.store.enums.TaskStatus; 9 | 10 | @Data 11 | @Builder 12 | public class FindTaskCondition { 13 | @Schema(requiredMode = REQUIRED, description = "第几页,从1开始, 默认为1.") 14 | private Integer page; 15 | @Schema(requiredMode = REQUIRED, description = "每页条数,默认为10.") 16 | private Integer size; 17 | @Schema(description = "经过Basic64编码的任务名称,模糊匹配.") 18 | private String name; 19 | @Schema(implementation = TaskStatus.class, description = "任务状态,精准匹配.") 20 | private TaskStatus status; 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/task/PluginTask.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.task; 2 | 3 | import run.ikaros.server.store.entity.TaskEntity; 4 | import run.ikaros.server.store.repository.TaskRepository; 5 | 6 | public class PluginTask extends Task { 7 | public PluginTask(TaskEntity entity, 8 | TaskRepository repository) { 9 | super(entity, repository); 10 | } 11 | 12 | @Override 13 | protected String getTaskEntityName() { 14 | return this.getClass().getName() + "-"; 15 | } 16 | 17 | @Override 18 | protected void doRun() throws Exception { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/task/TaskInit.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.task; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.context.event.ApplicationReadyEvent; 5 | import org.springframework.context.event.EventListener; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Slf4j 9 | @Component 10 | public class TaskInit { 11 | private final TaskService taskService; 12 | 13 | public TaskInit(TaskService taskService) { 14 | this.taskService = taskService; 15 | } 16 | 17 | @EventListener(ApplicationReadyEvent.class) 18 | public void init() { 19 | taskService.updateAllRunningAndCreatedTaskStatusToCancel(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/task/TaskService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.task; 2 | 3 | import reactor.core.publisher.Mono; 4 | import run.ikaros.api.wrap.PagingWrap; 5 | import run.ikaros.server.store.entity.TaskEntity; 6 | 7 | public interface TaskService { 8 | void updateTaskStatus(); 9 | 10 | void updateAllRunningAndCreatedTaskStatusToCancel(); 11 | 12 | Mono findById(Long id); 13 | 14 | Mono submit(Task task); 15 | 16 | Mono cancel(String name); 17 | 18 | Mono> listEntitiesByCondition(FindTaskCondition findTaskCondition); 19 | 20 | Mono getProcess(Long id); 21 | 22 | void setDefaultFieldValue(TaskEntity entity); 23 | } 24 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/user/CreateUserReqParams.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.user; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | @Data 9 | public class CreateUserReqParams { 10 | @Schema(requiredMode = REQUIRED) 11 | private String username; 12 | private String password; 13 | private Boolean enabled; 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/user/UpdateUserRequest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.user; 2 | 3 | import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import lombok.Data; 7 | 8 | @Data 9 | public class UpdateUserRequest { 10 | @Schema(requiredMode = REQUIRED) 11 | private String username; 12 | private String avatar; 13 | private String nickname; 14 | private String introduce; 15 | private String site; 16 | private Boolean enable; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/user/User.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.user; 2 | 3 | import run.ikaros.server.store.entity.UserEntity; 4 | 5 | public record User(UserEntity entity) { 6 | } 7 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/user/UserAvatarUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.user; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | 6 | @Getter 7 | public class UserAvatarUpdateEvent extends ApplicationEvent { 8 | private final String oldAvatar; 9 | private final String avatar; 10 | private final Long userId; 11 | private final String username; 12 | 13 | /** 14 | * Construct. 15 | */ 16 | public UserAvatarUpdateEvent(Object source, 17 | String oldAvatar, String avatar, Long userId, String username) { 18 | super(source); 19 | this.oldAvatar = oldAvatar; 20 | this.avatar = avatar; 21 | this.userId = userId; 22 | this.username = username; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/user/role/UserRoleService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.user.role; 2 | 3 | import reactor.core.publisher.Flux; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.api.core.role.Role; 6 | import run.ikaros.server.store.entity.UserRoleEntity; 7 | 8 | public interface UserRoleService { 9 | 10 | Mono saveEntity(UserRoleEntity entity); 11 | 12 | Flux addUserRoles(Long userId, Long[] roleIds); 13 | 14 | Mono deleteUserRoles(Long userId, Long[] roleIds); 15 | 16 | Flux getRolesForUser(Long userId); 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/webclient/WeClientService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.webclient; 2 | 3 | import jakarta.annotation.Nonnull; 4 | import jakarta.validation.constraints.NotBlank; 5 | import org.springframework.retry.annotation.Retryable; 6 | import reactor.core.publisher.Mono; 7 | import run.ikaros.api.core.attachment.Attachment; 8 | 9 | public interface WeClientService { 10 | /** 11 | * Download network image by url, and upload file system. 12 | * 13 | * @param url network image url 14 | * @return new file url in file system. 15 | */ 16 | @Nonnull 17 | @Retryable 18 | Mono downloadImageWithGet(@NotBlank String policy, 19 | @NotBlank String url); 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/core/webclient/WebClientConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.webclient; 2 | 3 | public interface WebClientConst { 4 | String HOME_PAGE = "https://ikaros.run"; 5 | String REPO_GITHUB_NAME = "ikaros-dev/ikaros"; 6 | 7 | // 当前 User-Agent格式 ikaros-dev/ikaros (https://ikaros.run) 8 | String REST_TEMPLATE_USER_AGENT = REPO_GITHUB_NAME + " (" + HOME_PAGE + ")"; 9 | String TOKEN_PREFIX = "Bearer "; 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/custom/CustomDto.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom; 2 | 3 | import jakarta.annotation.Nonnull; 4 | import jakarta.annotation.Nullable; 5 | import java.util.List; 6 | import org.springframework.util.Assert; 7 | import run.ikaros.server.store.entity.CustomEntity; 8 | import run.ikaros.server.store.entity.CustomMetadataEntity; 9 | 10 | public record CustomDto(@Nonnull CustomEntity customEntity, 11 | @Nullable List customMetadataEntityList) { 12 | 13 | CustomDto updateMetadataCustomId() { 14 | Long customId = customEntity.getId(); 15 | Assert.notNull(customId, "custom id must not null"); 16 | customMetadataEntityList.forEach( 17 | customMetadataEntity -> customMetadataEntity.setCustomId(customId)); 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/custom/event/CustomCreateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.api.custom.scheme.CustomScheme; 6 | 7 | @Getter 8 | public class CustomCreateEvent extends ApplicationEvent { 9 | private final CustomScheme scheme; 10 | private final String name; 11 | 12 | /** 13 | * Construct. 14 | */ 15 | public CustomCreateEvent(Object source, CustomScheme scheme, String name) { 16 | super(source); 17 | this.scheme = scheme; 18 | this.name = name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/custom/event/CustomDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.api.custom.scheme.CustomScheme; 6 | 7 | 8 | @Getter 9 | public class CustomDeleteEvent extends ApplicationEvent { 10 | private final CustomScheme scheme; 11 | private final String name; 12 | 13 | /** 14 | * Construct. 15 | */ 16 | public CustomDeleteEvent(Object source, CustomScheme scheme, String name) { 17 | super(source); 18 | this.scheme = scheme; 19 | this.name = name; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/custom/event/CustomUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom.event; 2 | 3 | import lombok.Getter; 4 | import org.springframework.context.ApplicationEvent; 5 | import run.ikaros.api.custom.scheme.CustomScheme; 6 | 7 | @Getter 8 | public class CustomUpdateEvent extends ApplicationEvent { 9 | private final CustomScheme scheme; 10 | private final String name; 11 | 12 | /** 13 | * Construct. 14 | */ 15 | public CustomUpdateEvent(Object source, CustomScheme scheme, String name) { 16 | super(source); 17 | this.scheme = scheme; 18 | this.name = name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/custom/scheme/SchemeInitializedEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom.scheme; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | public class SchemeInitializedEvent extends ApplicationEvent { 6 | 7 | public SchemeInitializedEvent(Object source) { 8 | super(source); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/endpoint/CoreEndpoint.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.endpoint; 2 | 3 | 4 | import run.ikaros.api.endpoint.Endpoint; 5 | 6 | public interface CoreEndpoint extends Endpoint { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/endpoint/EndpointsBuilder.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.endpoint; 2 | 3 | import org.springframework.web.reactive.function.server.RouterFunction; 4 | import org.springframework.web.reactive.function.server.ServerResponse; 5 | import run.ikaros.api.endpoint.Endpoint; 6 | 7 | public interface EndpointsBuilder { 8 | B add(E endpoint); 9 | 10 | RouterFunction build(); 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/constants/NumberConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.constants; 2 | 3 | public interface NumberConst { 4 | Long UN_USE_ID = -1L; 5 | } 6 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/constants/SettingKeyConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.constants; 2 | 3 | public interface SettingKeyConst { 4 | String THEME_SELECT = "THEME_SELECT"; 5 | } 6 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/constants/ThemeConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.constants; 2 | 3 | public interface ThemeConst { 4 | String SIMPLE = "simple"; 5 | String DEFAULT = SIMPLE; 6 | } 7 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/constants/ThymeleafConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.constants; 2 | 3 | public interface ThymeleafConst { 4 | String ANIME_UPDATE = "mail/anime_update"; 5 | } 6 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/properties/IkarosTaskProperties.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.validation.annotation.Validated; 6 | 7 | @Data 8 | @Validated 9 | @ConfigurationProperties(prefix = "ikaros.task") 10 | public class IkarosTaskProperties { 11 | private Integer corePoolSize; 12 | private Integer maximumPoolSize; 13 | private Long keepAliveTime; 14 | private Integer queueCount; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/utils/RandomUtils.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.utils; 2 | 3 | import java.util.Random; 4 | import lombok.Getter; 5 | 6 | public class RandomUtils { 7 | @Getter 8 | private static final Random random = new Random(); 9 | 10 | /** 11 | * Random string by length. 12 | * 13 | * @param length string length 14 | * @return string 15 | */ 16 | public static String randomString(int length) { 17 | if (length <= 0) { 18 | length = 10; 19 | } 20 | StringBuilder sb = new StringBuilder(); 21 | for (int i = 0; i < length; i++) { 22 | sb.append(random.nextInt(10)); 23 | } 24 | return sb.toString(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/infra/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.infra.utils; 2 | 3 | 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | public class TimeUtils { 8 | /** 9 | * 格式化日期时间戳. 10 | */ 11 | public static String formatTimestamp(Long timestamp) { 12 | return formatTimestamp(timestamp, "yyyy-MM-dd"); 13 | } 14 | 15 | /** 16 | * 格式化日期时间戳. 17 | */ 18 | public static String formatTimestamp(Long timestamp, String pattern) { 19 | Date date = new Date(timestamp); 20 | SimpleDateFormat sdf = new SimpleDateFormat(pattern); 21 | return sdf.format(date); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/plugin/PluginException.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin; 2 | 3 | public class PluginException extends RuntimeException { 4 | public PluginException(String message, Throwable cause) { 5 | super(message, cause); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/plugin/PluginStartingError.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin; 2 | 3 | import java.io.Serializable; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | 7 | @Data 8 | @AllArgsConstructor(staticName = "of") 9 | public class PluginStartingError implements Serializable { 10 | private String pluginId; 11 | 12 | private String message; 13 | 14 | private String devMessage; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/plugin/SharedApplicationContext.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin; 2 | 3 | import org.springframework.context.support.GenericApplicationContext; 4 | 5 | /** 6 | * all plugin application context parent, can contain some bean that can be accessed by plugin. 7 | * 8 | * @author li-guohao 9 | */ 10 | public class SharedApplicationContext extends GenericApplicationContext { 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/plugin/event/IkarosPluginDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | public class IkarosPluginDeleteEvent extends ApplicationEvent { 6 | private final String pluginId; 7 | 8 | public IkarosPluginDeleteEvent(Object source, String pluginId) { 9 | super(source); 10 | this.pluginId = pluginId; 11 | } 12 | 13 | public String getPluginId() { 14 | return pluginId; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/plugin/listener/ApplicationReadyEventPluginBroadcaster.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.context.event.ApplicationReadyEvent; 5 | import org.springframework.context.event.EventListener; 6 | import org.springframework.stereotype.Component; 7 | import run.ikaros.server.plugin.PluginApplicationContextRegistry; 8 | 9 | @Slf4j 10 | @Component 11 | public class ApplicationReadyEventPluginBroadcaster { 12 | @EventListener(ApplicationReadyEvent.class) 13 | public void onApplicationReadyEvent(ApplicationReadyEvent event) { 14 | PluginApplicationContextRegistry.getInstance().getPluginApplicationContexts() 15 | .forEach(pluginApplicationContext -> pluginApplicationContext.publishEvent(event)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/search/IndicesConfiguration.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.search; 2 | 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration(proxyBeanMethods = false) 7 | @EnableConfigurationProperties(IndicesProperties.class) 8 | public class IndicesConfiguration { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/search/IndicesProperties.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.search; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * Properties for indices. 8 | * 9 | * @see IndicesConfiguration 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "ikaros.indices") 13 | public class IndicesProperties { 14 | private final Initializer initializer = new Initializer(); 15 | 16 | @Data 17 | public static class Initializer { 18 | private boolean enabled = true; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/search/IndicesService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.search; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | public interface IndicesService { 6 | 7 | Mono rebuildSubjectIndices(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/IkarosGrantedAuthority.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security; 2 | 3 | import static run.ikaros.api.constant.SecurityConst.AUTHORITY_DIVIDE; 4 | 5 | import org.springframework.security.core.GrantedAuthority; 6 | import run.ikaros.api.core.authority.Authority; 7 | 8 | public record IkarosGrantedAuthority(Authority authority) 9 | implements GrantedAuthority { 10 | 11 | @Override 12 | public String getAuthority() { 13 | return authority.getType().name() 14 | + AUTHORITY_DIVIDE + authority.getTarget() 15 | + AUTHORITY_DIVIDE + authority.getAuthority(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/authentication/SecurityConfigurer.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security.authentication; 2 | 3 | import org.springframework.security.config.web.server.ServerHttpSecurity; 4 | 5 | public interface SecurityConfigurer { 6 | void configure(ServerHttpSecurity http); 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/authentication/jwt/JwtApplyResponse.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security.authentication.jwt; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Accessors(chain = true) 15 | public class JwtApplyResponse { 16 | @Schema(description = "用户名") 17 | private String username; 18 | @Schema(description = "Access Token") 19 | private String accessToken; 20 | @Schema(description = "Refresh Token") 21 | private String refreshToken; 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/authentication/logout/LogoutConfigurer.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security.authentication.logout; 2 | 3 | 4 | import org.springframework.security.config.web.server.ServerHttpSecurity; 5 | import org.springframework.stereotype.Component; 6 | import run.ikaros.server.security.authentication.SecurityConfigurer; 7 | 8 | @Component 9 | public class LogoutConfigurer implements SecurityConfigurer { 10 | 11 | @Override 12 | public void configure(ServerHttpSecurity http) { 13 | http.logout() 14 | .logoutSuccessHandler(new LogoutSuccessHandler()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/authentication/oauth2/Oauth2Configurer.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security.authentication.oauth2; 2 | 3 | import org.springframework.security.config.web.server.ServerHttpSecurity; 4 | import org.springframework.stereotype.Component; 5 | import run.ikaros.server.security.authentication.SecurityConfigurer; 6 | 7 | @Component 8 | public class Oauth2Configurer implements SecurityConfigurer { 9 | @Override 10 | public void configure(ServerHttpSecurity http) { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/security/exception/AuthenticationExceptionConfigurer.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.security.exception; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.security.config.web.server.ServerHttpSecurity; 5 | import org.springframework.stereotype.Component; 6 | import run.ikaros.server.security.authentication.SecurityConfigurer; 7 | 8 | @Slf4j 9 | @Component 10 | public class AuthenticationExceptionConfigurer implements SecurityConfigurer { 11 | @Override 12 | public void configure(ServerHttpSecurity http) { 13 | http.exceptionHandling().authenticationEntryPoint(new JsonServerAuthenticationEntryPoint()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/AuthorityEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Table; 10 | import run.ikaros.api.store.enums.AuthorityType; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "authority") 17 | @Accessors(chain = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class AuthorityEntity extends BaseEntity { 20 | private Boolean allow; 21 | private AuthorityType type; 22 | private String target; 23 | private String authority; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/CharacterEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Table; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Table(name = "character") 16 | @Accessors(chain = true) 17 | @EqualsAndHashCode(callSuper = true) 18 | public class CharacterEntity extends BaseEntity { 19 | private String name; 20 | private String infobox; 21 | private String summary; 22 | } 23 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/CustomMetadataEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | import org.springframework.data.annotation.Id; 7 | import org.springframework.data.relational.core.mapping.Column; 8 | import org.springframework.data.relational.core.mapping.Table; 9 | 10 | /** 11 | * custom resource definition entity metadata. 12 | * 13 | * @author: li-guohao 14 | */ 15 | @Data 16 | @Builder 17 | @Table("custom_metadata") 18 | @Accessors(chain = true) 19 | public class CustomMetadataEntity { 20 | @Id 21 | private Long id; 22 | @Column("custom_id") 23 | private Long customId; 24 | @Column("cm_key") 25 | private String key; 26 | @Column("cm_value") 27 | private byte[] value; 28 | } 29 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/EpisodeListEpisodeEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | import org.springframework.data.annotation.Id; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "episode_list_episode") 17 | @Accessors(chain = true) 18 | public class EpisodeListEpisodeEntity { 19 | @Id 20 | private Long id; 21 | @Column("episode_list_id") 22 | private Long episodeListId; 23 | @Column("episode_id") 24 | private Long episodeId; 25 | } 26 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/PersonCharacterEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "person_character") 17 | @Accessors(chain = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class PersonCharacterEntity extends BaseEntity { 20 | @Column("person_id") 21 | private Long personId; 22 | @Column("character_id") 23 | private Long characterId; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/PersonEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Table; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Table(name = "person") 16 | @Accessors(chain = true) 17 | @EqualsAndHashCode(callSuper = true) 18 | public class PersonEntity extends BaseEntity { 19 | private String name; 20 | private String infobox; 21 | private String summary; 22 | } 23 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/RoleAuthorityEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import jakarta.persistence.Id; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "role_authority") 17 | @Accessors(chain = true) 18 | public class RoleAuthorityEntity { 19 | @Id 20 | private Long id; 21 | @Column("role_id") 22 | private Long roleId; 23 | @Column("authority_id") 24 | private Long authorityId; 25 | } 26 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/RoleEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "role") 17 | @Accessors(chain = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class RoleEntity extends BaseEntity { 20 | private String name; 21 | @Column("parent_id") 22 | private Long parentId; 23 | private String description; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/SubjectCharacterEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "subject_character") 17 | @Accessors(chain = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class SubjectCharacterEntity extends BaseEntity { 20 | @Column("subject_id") 21 | private Long subjectId; 22 | @Column("character_id") 23 | private Long characterId; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/SubjectPersonEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.Accessors; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "subject_person") 17 | @Accessors(chain = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class SubjectPersonEntity extends BaseEntity { 20 | @Column("subject_id") 21 | private Long subjectId; 22 | @Column("person_id") 23 | private Long personId; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/entity/UserRoleEntity.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.experimental.Accessors; 8 | import org.springframework.data.annotation.Id; 9 | import org.springframework.data.relational.core.mapping.Column; 10 | import org.springframework.data.relational.core.mapping.Table; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Table(name = "ikuser_role") 17 | @Accessors(chain = true) 18 | public class UserRoleEntity { 19 | @Id 20 | private Long id; 21 | @Column("user_id") 22 | private Long userId; 23 | @Column("role_id") 24 | private Long roleId; 25 | } 26 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/AuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.api.store.enums.AuthorityType; 7 | import run.ikaros.server.store.entity.AuthorityEntity; 8 | 9 | public interface AuthorityRepository extends R2dbcRepository { 10 | Mono findByTypeAndTargetAndAuthority( 11 | AuthorityType type, String target, String authority 12 | ); 13 | 14 | Mono findByAllowAndTypeAndTargetAndAuthority( 15 | boolean allow, AuthorityType type, String target, String authority 16 | ); 17 | 18 | Flux findAllByType(AuthorityType type); 19 | } 20 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/CharacterRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.server.store.entity.CharacterEntity; 6 | 7 | public interface CharacterRepository extends R2dbcRepository { 8 | Mono findByName(String name); 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/EpisodeCollectionRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.server.store.entity.EpisodeCollectionEntity; 7 | 8 | public interface EpisodeCollectionRepository 9 | extends R2dbcRepository { 10 | 11 | Mono findByUserIdAndEpisodeId(Long userId, Long episodeId); 12 | 13 | Flux findAllByUserIdAndSubjectId(Long userId, Long subjectId); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/EpisodeListCollectionRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import run.ikaros.server.store.entity.EpisodeListCollectionEntity; 5 | 6 | public interface EpisodeListCollectionRepository 7 | extends R2dbcRepository { 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/EpisodeListEpisodeRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import run.ikaros.server.store.entity.EpisodeListEpisodeEntity; 5 | 6 | public interface EpisodeListEpisodeRepository 7 | extends R2dbcRepository { 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/EpisodeListRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import run.ikaros.server.store.entity.EpisodeListEntity; 5 | 6 | public interface EpisodeListRepository extends R2dbcRepository { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/PersonRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.server.store.entity.PersonEntity; 6 | 7 | public interface PersonRepository extends R2dbcRepository { 8 | Mono findByName(String name); 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/RoleAuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.server.store.entity.RoleAuthorityEntity; 7 | 8 | public interface RoleAuthorityRepository extends R2dbcRepository { 9 | Flux findByRoleId(Long roleId); 10 | 11 | Mono deleteByRoleIdAndAuthorityId(Long roleId, Long authorityId); 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.server.store.entity.RoleEntity; 6 | 7 | public interface RoleRepository extends R2dbcRepository { 8 | Mono findByName(String name); 9 | 10 | Mono existsByName(String name); 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/SubjectCharacterRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.server.store.entity.SubjectCharacterEntity; 6 | 7 | public interface SubjectCharacterRepository 8 | extends R2dbcRepository { 9 | Mono findBySubjectIdAndCharacterId(Long subjectId, Long characterId); 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/SubjectPersonRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Mono; 5 | import run.ikaros.server.store.entity.SubjectPersonEntity; 6 | 7 | public interface SubjectPersonRepository 8 | extends R2dbcRepository { 9 | Mono findBySubjectIdAndPersonId(Long subjectId, Long personId); 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/store/repository/UserRoleRepository.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | import org.springframework.data.r2dbc.repository.R2dbcRepository; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | import run.ikaros.server.store.entity.UserRoleEntity; 7 | 8 | public interface UserRoleRepository extends R2dbcRepository { 9 | Flux findByUserId(Long userId); 10 | 11 | Mono findByUserIdAndRoleId(Long userId, Long roleId); 12 | 13 | Mono deleteByUserIdAndRoleId(Long userId, Long roleId); 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/run/ikaros/server/theme/ThemeService.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.theme; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | public interface ThemeService { 6 | Mono getCurrentTheme(); 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/resources/application-dev.yaml: -------------------------------------------------------------------------------- 1 | ikaros: 2 | show-theme: false 3 | plugin: 4 | runtime-mode: development 5 | 6 | # auto-start-plugin: false 7 | security: 8 | # 30 day for local dev token expire 9 | jwt-expiration-time: 18144000000 10 | initializer: 11 | master-username: tomoki 12 | master-password: tomoki 13 | work-dir: ${user.home}/ikaros-dev 14 | 15 | spring: 16 | thymeleaf: 17 | cache: false 18 | jpa: 19 | show-sql: true 20 | properties: 21 | hibernate: 22 | format_sql: true 23 | 24 | 25 | springdoc: 26 | api-docs: 27 | enabled: true 28 | swagger-ui: 29 | enabled: true 30 | 31 | -------------------------------------------------------------------------------- /server/src/main/resources/application-postgresql.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | r2dbc: 3 | url: r2dbc:pool:postgresql://localhost:5432/postgres 4 | username: postgres 5 | password: openpostgresql 6 | 7 | flyway: 8 | locations: classpath:db/postgresql/migration 9 | url: jdbc:postgresql://localhost:5432/postgres 10 | user: postgres 11 | password: openpostgresql 12 | -------------------------------------------------------------------------------- /server/src/main/resources/application-win-dev.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | r2dbc: 3 | url: r2dbc:h2:file:///~/ikaros-dev/database/ikaros?MODE=MySQL&DB_CLOSE_ON_EXIT=FALSE 4 | flyway: 5 | url: jdbc:h2:file:~/ikaros-dev/database/ikaros 6 | -------------------------------------------------------------------------------- /server/src/main/resources/application-win.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | r2dbc: 3 | url: r2dbc:h2:file:///~/.ikaros/database/ikaros?MODE=MySQL&DB_CLOSE_ON_EXIT=FALSE 4 | -------------------------------------------------------------------------------- /server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ### 2 | # # # ## ##### #### #### 3 | # # # # # # # # # # 4 | # #### # # # # # # #### 5 | # # # ###### ##### # # # 6 | # # # # # # # # # # # 7 | ### # # # # # # #### #### -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0001__DDL_ATTACHMENT.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists attachment 2 | ( 3 | id int8 not null auto_increment, 4 | parent_id int8 null, 5 | type varchar(255) not null, 6 | url varchar(5000) null, 7 | path varchar(5000) not null, 8 | fs_path varchar(5000) null, 9 | name varchar(255) not null, 10 | size int8 null, 11 | update_time timestamp(6) null, 12 | constraint type_parent_name_uk unique (type, parent_id, name), 13 | constraint attachment_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0002__DDL_ATTACHMENT_RELATION.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists attachment_relation 2 | ( 3 | id int8 not null auto_increment, 4 | attachment_id int8 not null, 5 | type varchar(255) not null, 6 | relation_attachment_id int8 not null, 7 | constraint attachment_relation_pkey primary key (id) 8 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0003__DDL_ATTACHMENT_REFERENCE.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists attachment_reference 2 | ( 3 | id int8 not null auto_increment, 4 | type varchar(255) not null, 5 | attachment_id int8 not null, 6 | reference_id int8 not null, 7 | constraint type_attachment_reference_uk unique (type, attachment_id, reference_id), 8 | constraint attachment_reference_pkey primary key (id) 9 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0004__DDL_AUTHORITY.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists authority 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | allow bool not null, 11 | type varchar(100) not null, 12 | target varchar(255) not null, 13 | authority varchar(10000) not null, 14 | constraint type_target_authority_uk unique (type, target, authority), 15 | constraint authority_pkey primary key (id) 16 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0005__DDL_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists character 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | name varchar(255) not null, 11 | infobox varchar(50000) null, 12 | summary varchar(50000) null, 13 | constraint character_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0006__DDL_EPISODE_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists episode_collection 2 | ( 3 | id int8 not null auto_increment, 4 | user_id int8 not null, 5 | subject_id int8 not null, 6 | episode_id int8 not null, 7 | finish bool not null, 8 | progress int8 null, 9 | duration int8 null, 10 | update_time timestamp(6) null, 11 | constraint user_episode_id_uk unique (user_id, episode_id), 12 | constraint episode_collection_pkey primary key (id) 13 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0007__DDL_SUBJECT_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject_collection 2 | ( 3 | id int8 not null auto_increment, 4 | user_id int8 not null, 5 | subject_id int8 not null, 6 | type varchar(255) not null, 7 | main_ep_progress int8 not null, 8 | is_private bool not null, 9 | constraint user_subject_id_uk unique (user_id, subject_id), 10 | constraint subject_collection_pkey primary key (id) 11 | ); 12 | -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0009__DDL_PERSON_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists person_character 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | person_id int8 not null, 11 | character_id int8 not null, 12 | constraint person_character_pkey primary key (id) 13 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0010__DDL_PERSON.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists person 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | name varchar(255) not null, 11 | infobox varchar(50000) null, 12 | summary varchar(50000) null, 13 | constraint person_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0011__DDL_ROLE.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists role 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | parent_id int8 not null, 11 | name varchar(255) not null, 12 | description varchar(50000) null, 13 | constraint role_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0012__DDL_SUBJECT_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject_character 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | subject_id int8 not null, 11 | character_id int8 not null, 12 | constraint subject_character_pkey primary key (id) 13 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0013__DDL_SUBJECT.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | type varchar(255) not null, 11 | name varchar(255) not null, 12 | name_cn varchar(255) null, 13 | cover varchar(10000) null, 14 | infobox varchar(50000) null, 15 | summary varchar(50000) null, 16 | nsfw bool not null, 17 | air_time timestamp(6) null, 18 | constraint subject_pkey primary key (id) 19 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0014__DDL_SUBJECT_PERSON.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject_person 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | subject_id int8 not null, 11 | person_id int8 not null, 12 | constraint subject_person_pkey primary key (id) 13 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0015__DDL_SUBJECT_RELATION.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject_relation 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | subject_id int8 not null, 11 | relation_type varchar(255) not null, 12 | relation_subject_id int8 not null, 13 | constraint subject_relation_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0016__DDL_SUBJECT_SYNC.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists subject_sync 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | subject_id int8 not null, 11 | platform varchar(255) not null, 12 | platform_id varchar(255) not null, 13 | sync_time timestamp(6) null, 14 | constraint platform_pid_ukey unique (platform, platform_id), 15 | constraint subject_sync_pkey primary key (id) 16 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0017__DDL_CUSTOM.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists `custom` 2 | ( 3 | id int8 not null auto_increment, 4 | c_group varchar(255) not null, 5 | version varchar(255) not null, 6 | kind varchar(255) not null, 7 | name varchar(255) not null, 8 | constraint custom_gvkn unique (c_group, version, kind, name), 9 | constraint custom_pkey primary key (id) 10 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0018__DDL_CUSTOM_METADATA.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists `custom_metadata` 2 | ( 3 | id int8 not null auto_increment, 4 | custom_id int8 not null, 5 | cm_key varchar(255) not null, 6 | cm_value blob, 7 | constraint custom_metadata_e_id_em_key unique (custom_id, cm_key), 8 | constraint custom_metadata_pkey primary key (id) 9 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0019__DDL_TAG.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists tag 2 | ( 3 | id int8 not null auto_increment, 4 | type varchar(255) not null, 5 | master_id int8 not null, 6 | name varchar(255) not null, 7 | user_id int8 not null, 8 | create_time timestamp(6) null, 9 | constraint tag_pkey primary key (id) 10 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0020__DDL_TASK.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists `task` 2 | ( 3 | id int8 not null auto_increment, 4 | name varchar(255) not null, 5 | status varchar(255) not null, 6 | create_time timestamp(6) null, 7 | start_time timestamp(6) null, 8 | end_time timestamp(6) null, 9 | total int8 null, 10 | index int8 null, 11 | fail_message varchar(2000) null, 12 | constraint task_pkey primary key (id) 13 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0021__DDL_USER_ROLE.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists ikuser_role 2 | ( 3 | id int8 not null auto_increment, 4 | user_id int8 not null, 5 | role_id int8 not null, 6 | constraint user_role_id_uk unique (user_id, role_id), 7 | constraint ikuser_role_pkey primary key (id) 8 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.13.0_0022__DDL_ROLE_AUTHORITY.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists role_authority 2 | ( 3 | id int8 not null auto_increment, 4 | role_id int8 not null, 5 | authority_id int8 not null, 6 | constraint role_authority_id_uk unique (role_id, authority_id), 7 | constraint role_authority_pkey primary key (id) 8 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.15.0_0001__DDL_EPISODE_LIST.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists episode_list 2 | ( 3 | id int8 not null auto_increment, 4 | create_time timestamp(6) null, 5 | create_uid int8 null, 6 | delete_status bool null, 7 | update_time timestamp(6) null, 8 | update_uid int8 null, 9 | ol_version int8 null, 10 | name varchar(255) not null, 11 | name_cn varchar(255) null, 12 | cover varchar(10000) null, 13 | description varchar(50000) null, 14 | nsfw bool not null, 15 | constraint episode_list_pkey primary key (id) 16 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.15.0_0002__DDL_EPISODE_LIST_EPISODE.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists tag 2 | ( 3 | id int8 not null auto_increment, 4 | episode_list_id int8 not null, 5 | episode_id int8 not null, 6 | constraint tag_pkey primary key (id) 7 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.15.0_0003__DDL_EPISODE_LIST_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists episode_list_collection 2 | ( 3 | id int8 not null auto_increment, 4 | user_id int8 not null, 5 | episode_list_id int8 not null, 6 | update_time timestamp(6) null, 7 | constraint episode_list_collection_pkey primary key (id) 8 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.15.0_0004__DML_EPISODE_UK.SQL: -------------------------------------------------------------------------------- 1 | alter table episode 2 | drop constraint subject_group_seq_uk; 3 | 4 | ALTER TABLE episode 5 | ADD CONSTRAINT subject_group_seq_name_uk UNIQUE (subject_id, ep_group, sequence, name); -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.15.2_0001__DDL_EPISODE_SEQUENCE.SQL: -------------------------------------------------------------------------------- 1 | alter table EPISODE 2 | alter column SEQUENCE float; -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'comment' in table 'subject_collection', @see run.ikaros.server.store.entity.SubjectCollectionEntity 2 | alter table subject_collection add column comment varchar(5000); 3 | 4 | -- add column 'score' in table 'subject_collection', @see run.ikaros.server.store.entity.SubjectCollectionEntity 5 | alter table subject_collection add column score int8; 6 | -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.20.7_0002__DML_SUBJECT_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'score' in table 'subject', @see SubjectEntity 2 | alter table subject add column score DOUBLE; 3 | -------------------------------------------------------------------------------- /server/src/main/resources/db/h2/migration/V0.20.9_0001__DML_TAG_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'color' in table 'tag', @see TagEntity 2 | alter table tag add column color varchar(200); 3 | -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0001__DDL_ATTACHMENT.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists attachment_seq 2 | increment 1 3 | start 10 4 | minvalue 10 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists attachment 9 | ( 10 | id int8 not null default nextval('attachment_seq'), 11 | parent_id int8 null, 12 | type varchar(255) not null, 13 | url varchar(5000) null, 14 | path varchar(5000) not null, 15 | fs_path varchar(5000) null, 16 | name varchar(255) not null, 17 | size int8 null, 18 | update_time timestamp(6) null, 19 | constraint type_parent_name_uk unique (type, parent_id, name), 20 | constraint attachment_pkey primary key (id) 21 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0002__DDL_ATTACHMENT_RELATION.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists attachment_relation_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists attachment_relation 9 | ( 10 | id int8 not null default nextval('attachment_relation_seq'), 11 | attachment_id int8 not null, 12 | type varchar(255) not null, 13 | relation_attachment_id int8 not null, 14 | constraint attachment_relation_pkey primary key (id) 15 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0003__DDL_ATTACHMENT_REFERENCE.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists attachment_reference_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists attachment_reference 9 | ( 10 | id int8 not null default nextval('attachment_reference_seq'), 11 | type varchar(255) not null, 12 | attachment_id int8 not null, 13 | reference_id int8 not null, 14 | constraint type_attachment_reference_uk unique (type, attachment_id, reference_id), 15 | constraint attachment_reference_pkey primary key (id) 16 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0005__DDL_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists character_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists character 9 | ( 10 | id int8 not null default nextval('character_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | name varchar(255) not null, 18 | infobox varchar(50000) null, 19 | summary varchar(50000) null, 20 | constraint character_pkey primary key (id) 21 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0006__DDL_EPISODE_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists episode_collection_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists episode_collection 9 | ( 10 | id int8 not null default nextval('episode_collection_seq'), 11 | user_id int8 not null, 12 | subject_id int8 not null, 13 | episode_id int8 not null, 14 | finish bool not null, 15 | progress int8 null, 16 | duration int8 null, 17 | update_time timestamp(6) null, 18 | constraint user_episode_id_uk unique (user_id, episode_id), 19 | constraint episode_collection_pkey primary key (id) 20 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0007__DDL_SUBJECT_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists subject_collection_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists subject_collection 9 | ( 10 | id int8 not null default nextval('subject_collection_seq'), 11 | user_id int8 not null, 12 | subject_id int8 not null, 13 | type varchar(255) not null, 14 | main_ep_progress int8 not null, 15 | is_private bool not null, 16 | constraint user_subject_id_uk unique (user_id, subject_id), 17 | constraint subject_collection_pkey primary key (id) 18 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0009__DDL_PERSON_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists person_character_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists person_character 9 | ( 10 | id int8 not null default nextval('person_character_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | person_id int8 not null, 18 | character_id int8 not null, 19 | constraint person_character_pkey primary key (id) 20 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0010__DDL_PERSON.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists person_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists person 9 | ( 10 | id int8 not null default nextval('person_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | name varchar(255) not null, 18 | infobox varchar(50000) null, 19 | summary varchar(50000) null, 20 | constraint person_pkey primary key (id) 21 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0011__DDL_ROLE.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists role_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists role 9 | ( 10 | id int8 not null default nextval('role_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | parent_id int8 not null, 18 | name varchar(255) not null, 19 | description varchar(50000) null, 20 | constraint role_pkey primary key (id) 21 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0012__DDL_SUBJECT_CHARACTER.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists subject_character_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists subject_character 9 | ( 10 | id int8 not null default nextval('subject_character_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | subject_id int8 not null, 18 | character_id int8 not null, 19 | constraint subject_character_pkey primary key (id) 20 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0014__DDL_SUBJECT_PERSON.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists subject_person_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists subject_person 9 | ( 10 | id int8 not null default nextval('subject_person_seq'), 11 | create_time timestamp(6) null, 12 | create_uid int8 null, 13 | delete_status bool null, 14 | update_time timestamp(6) null, 15 | update_uid int8 null, 16 | ol_version int8 null, 17 | subject_id int8 not null, 18 | person_id int8 not null, 19 | constraint subject_person_pkey primary key (id) 20 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0017__DDL_CUSTOM.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists custom_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists custom 9 | ( 10 | id int8 not null default nextval('custom_seq'), 11 | c_group varchar(255) not null, 12 | "version" varchar(255) not null, 13 | kind varchar(255) not null, 14 | name varchar(255) not null, 15 | constraint custom_gvkn unique (c_group, "version", kind, name), 16 | constraint custom_pkey primary key (id) 17 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0018__DDL_CUSTOM_METADATA.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists custom_metadata_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists custom_metadata 9 | ( 10 | id int8 not null default nextval('custom_metadata_seq'), 11 | custom_id int8 not null, 12 | cm_key varchar(255) not null, 13 | cm_value bytea, 14 | constraint custom_metadata_custom_id_em_key unique (custom_id, cm_key), 15 | constraint custom_metadata_pkey primary key (id) 16 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0019__DDL_TAG.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists tag_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists tag 9 | ( 10 | id int8 not null default nextval('tag_seq'), 11 | type varchar(255) not null, 12 | master_id int8 not null, 13 | name varchar(255) not null, 14 | user_id int8 not null, 15 | create_time timestamp(6) null, 16 | constraint tag_pkey primary key (id) 17 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0020__DDL_TASK.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists task_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists task 9 | ( 10 | id int8 not null default nextval('task_seq'), 11 | name varchar(255) not null, 12 | status varchar(255) not null, 13 | create_time timestamp(6) null, 14 | start_time timestamp(6) null, 15 | end_time timestamp(6) null, 16 | total int8 null, 17 | index int8 null, 18 | fail_message varchar(2000) null, 19 | constraint task_pkey primary key (id) 20 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0021__DDL_USER_ROLE.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists ikuser_role_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists ikuser_role 9 | ( 10 | id int8 not null default nextval('ikuser_role_seq'), 11 | user_id int8 not null, 12 | role_id int8 not null, 13 | constraint user_role_id_uk unique (user_id, role_id), 14 | constraint ikuser_role_pkey primary key (id) 15 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.13.0_0022__DDL_ROLE_AUTHORITY.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists role_authority_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists role_authority 9 | ( 10 | id int8 not null default nextval('role_authority_seq'), 11 | role_id int8 not null, 12 | authority_id int8 not null, 13 | constraint role_authority_id_uk unique (role_id, authority_id), 14 | constraint role_authority_pkey primary key (id) 15 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.15.0_0002__DDL_EPISODE_LIST_EPISODE.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists episode_list_episode_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists episode_list_episode 9 | ( 10 | id int8 not null default nextval('episode_list_episode_seq'), 11 | episode_list_id int8 not null, 12 | episode_id int8 not null, 13 | constraint episode_list_episode_pkey primary key (id) 14 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.15.0_0003__DDL_EPISODE_LIST_COLLECTION.SQL: -------------------------------------------------------------------------------- 1 | create sequence if not exists episode_list_collection_seq 2 | increment 1 3 | start 1 4 | minvalue 1 5 | cache 1 6 | no cycle; 7 | 8 | create table if not exists episode_list_collection 9 | ( 10 | id int8 not null default nextval('episode_list_collection_seq'), 11 | user_id int8 not null, 12 | episode_list_id int8 not null, 13 | update_time timestamp(6) null, 14 | constraint episode_list_collection_pkey primary key (id) 15 | ); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.15.0_0004__DML_EPISODE_UK.SQL: -------------------------------------------------------------------------------- 1 | alter table episode 2 | drop constraint subject_group_seq_uk; 3 | 4 | ALTER TABLE episode 5 | ADD CONSTRAINT subject_group_seq_name_uk UNIQUE (subject_id, ep_group, sequence, name); -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.15.2_0001__DDL_EPISODE_SEQUENCE.SQL: -------------------------------------------------------------------------------- 1 | ALTER TABLE episode 2 | ALTER COLUMN sequence TYPE real USING sequence; -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'comment' in table 'subject_collection', @see run.ikaros.server.store.entity.SubjectCollectionEntity 2 | alter table subject_collection add column comment varchar(5000); 3 | 4 | -- add column 'score' in table 'subject_collection', @see run.ikaros.server.store.entity.SubjectCollectionEntity 5 | alter table subject_collection add column score int8; 6 | -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.20.7_0002__DML_SUBJECT_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'score' in table 'subject', @see SubjectEntity 2 | alter table subject add column score DOUBLE PRECISION; 3 | -------------------------------------------------------------------------------- /server/src/main/resources/db/postgresql/migration/V0.20.9_0001__DML_TAG_COLUMN.SQL: -------------------------------------------------------------------------------- 1 | -- add column 'color' in table 'tag', @see TagEntity 2 | alter table tag add column color varchar(200); 3 | -------------------------------------------------------------------------------- /server/src/main/resources/templates/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ikaros 6 | 7 | 8 |
9 |

10 | Ikaros theme display close. 11 |

12 |
13 | 14 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/IkarosApplicationTests.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import run.ikaros.api.infra.properties.IkarosProperties; 9 | import run.ikaros.server.plugin.PluginProperties; 10 | 11 | @SpringBootTest 12 | class IkarosApplicationTests { 13 | @Autowired 14 | IkarosProperties ikarosProperties; 15 | @Autowired 16 | PluginProperties pluginProperties; 17 | 18 | @Test 19 | void contextLoads() { 20 | } 21 | 22 | @Test 23 | void ikarosProps() { 24 | assertThat(ikarosProperties).isNotNull(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/core/constant/SecurityConstTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.constant; 2 | 3 | 4 | import static org.assertj.core.api.Assertions.assertThat; 5 | 6 | import org.junit.jupiter.api.Test; 7 | import run.ikaros.api.constant.SecurityConst; 8 | 9 | class SecurityConstTest { 10 | @Test 11 | void isAnonymousUser() { 12 | assertThat(SecurityConst.AnonymousUser.isAnonymousUser("others")).isFalse(); 13 | assertThat(SecurityConst.AnonymousUser.isAnonymousUser("anonymousUser")).isTrue(); 14 | } 15 | } -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/core/subject/vo/FindSubjectConditionTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.core.subject.vo; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import run.ikaros.api.core.subject.vo.FindSubjectCondition; 6 | 7 | class FindSubjectConditionTest { 8 | 9 | @Test 10 | void getNsfw() { 11 | Boolean nsfw = null; 12 | FindSubjectCondition condition = FindSubjectCondition.builder().nsfw(nsfw).build(); 13 | Assertions.assertThat(condition.getNsfw()).isNull(); 14 | } 15 | } -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/custom/DemoOnlyNameCustom.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.custom; 2 | 3 | import run.ikaros.api.custom.Custom; 4 | import run.ikaros.api.custom.Name; 5 | 6 | @Custom(group = "demo.ikaros.run", version = "v1alpha1", 7 | kind = "DemoOnlyNameCustom", singular = "demo", plural = "demos") 8 | public class DemoOnlyNameCustom { 9 | @Name 10 | private String title; 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public DemoOnlyNameCustom setTitle(String title) { 17 | this.title = title; 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/plugin/PluginApplicationContextTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class PluginApplicationContextTest { 7 | 8 | @Test 9 | void getPluginId() { 10 | String pluginId = "TestPluginId"; 11 | PluginApplicationContext pluginApplicationContext = new PluginApplicationContext(pluginId); 12 | Assertions.assertThat(pluginApplicationContext.getPluginId()) 13 | .isEqualTo(pluginId); 14 | } 15 | } -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/plugin/PluginPropertiesTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.plugin; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | 8 | @SpringBootTest 9 | class PluginPropertiesTest { 10 | 11 | @Autowired 12 | PluginProperties pluginProperties; 13 | 14 | @Test 15 | void getSystemVersion() { 16 | Assertions.assertThat(pluginProperties).isNotNull(); 17 | String systemVersion = pluginProperties.getSystemVersion(); 18 | Assertions.assertThat(systemVersion).isNotBlank(); 19 | } 20 | } -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/store/repository/SubjectCollectionRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.store.repository; 2 | 3 | 4 | import org.junit.jupiter.api.AfterEach; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import reactor.test.StepVerifier; 8 | 9 | @SpringBootTest 10 | class SubjectCollectionRepositoryTest { 11 | 12 | @Autowired 13 | SubjectCollectionRepository repository; 14 | 15 | 16 | @AfterEach 17 | void tearDown() { 18 | StepVerifier.create(repository.deleteAll()).verifyComplete(); 19 | } 20 | 21 | 22 | 23 | 24 | } -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/test/DateUtilTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.test; 2 | 3 | import java.text.ParseException; 4 | import java.time.OffsetDateTime; 5 | import java.time.ZoneOffset; 6 | import java.util.Date; 7 | import org.apache.commons.lang3.time.DateUtils; 8 | import org.assertj.core.api.Assertions; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class DateUtilTest { 12 | @Test 13 | void test() throws ParseException { 14 | Date date = DateUtils.parseDate("2023-02-12 11:32:12", "yyyy-MM-dd HH:mm:ss"); 15 | Assertions.assertThat(date).isNotNull(); 16 | ZoneOffset offset = OffsetDateTime.now().getOffset(); 17 | System.out.println(offset); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/test/ReactorTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.test; 2 | 3 | import reactor.core.publisher.Mono; 4 | 5 | public class ReactorTest { 6 | /** 7 | * Test reactor demo. 8 | */ 9 | public static void main(String[] args) { 10 | boolean exists = true; 11 | Mono.just(exists) 12 | .filter(e -> !e) 13 | .flatMap(e -> Mono.just(e) 14 | .doOnSuccess(a -> System.out.println(1))) 15 | .doOnSuccess(e -> System.out.println(2)) 16 | .subscribe(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/test/TestConst.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.test; 2 | 3 | public interface TestConst { 4 | String PROCESS_SHOULD_NOT_RUN_TO_THIS = "process should not run to this"; 5 | } 6 | -------------------------------------------------------------------------------- /server/src/test/java/run/ikaros/server/test/TimeTest.java: -------------------------------------------------------------------------------- 1 | package run.ikaros.server.test; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.Year; 5 | import org.assertj.core.api.Assertions; 6 | 7 | public class TimeTest { 8 | // @Test 9 | void parseTime() { 10 | LocalDateTime t1 = 11 | Year.parse("2020").atMonth(1).atDay(1).atStartOfDay(); 12 | Assertions.assertThat(t1.getYear()).isEqualTo(2020); 13 | 14 | LocalDateTime t2 = LocalDateTime.parse("2020.01"); 15 | Assertions.assertThat(t2.getMonthValue()).isEqualTo(1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/src/test/resources/console/index.html: -------------------------------------------------------------------------------- 1 | ikaros unit test console index 2 | -------------------------------------------------------------------------------- /server/src/test/resources/core/file/UnitTestDocFile.TXT: -------------------------------------------------------------------------------- 1 | Hello Ikaros -------------------------------------------------------------------------------- /server/src/test/resources/plugin/unittest-a-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/server/src/test/resources/plugin/unittest-a-1.0.0.jar -------------------------------------------------------------------------------- /server/src/test/resources/plugin/unittest-b-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikaros-dev/ikaros/3fefbebfb83b6dcea1e4371abe82643c491faea2/server/src/test/resources/plugin/unittest-b-1.0.0.jar -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = 'ikaros' 8 | include 'api', 'server', 'platform:server', 'platform:plugin' 9 | 10 | --------------------------------------------------------------------------------