From 9d60fa23819c987ab44c76b8670c1b807040e2e2 Mon Sep 17 00:00:00 2001 From: GuoHao Date: Sat, 15 Jun 2024 15:46:46 +0800 Subject: [PATCH] feat: support subject sync create and remove for plugin. (#562) * feat: support subject sync create and remove for plugin. * docs: update CHANGELOG.MD * fix: checkstyle --- CHANGELOG.MD | 4 ++ .../api/core/subject}/SubjectSyncAction.java | 2 +- .../subject/SubjectSyncPlatformOperate.java | 30 ++++++++ .../subject/vo/BatchMatchingEpisodeFile.java | 2 +- .../core/subject/vo/FindSubjectCondition.java | 2 +- .../subject/vo/PostSubjectSyncCondition.java | 4 +- .../server/controller/SubjectController.java | 2 +- .../subject/SubjectSyncPlatformOperator.java | 68 +++++++++++++++++++ .../subject/endpoint/SubjectEndpoint.java | 2 +- .../endpoint/SubjectSyncPlatformEndpoint.java | 4 +- .../core/subject/service/SubjectService.java | 2 +- .../service/SubjectSyncPlatformService.java | 20 +++++- .../service/impl/SubjectServiceImpl.java | 2 +- .../impl/SubjectSyncPlatformServiceImpl.java | 65 +++++++++++++++++- .../repository/SubjectSyncRepository.java | 5 +- .../subject/vo/FindSubjectConditionTest.java | 1 + 16 files changed, 199 insertions(+), 16 deletions(-) rename {server/src/main/java/run/ikaros/server/core/subject/enums => api/src/main/java/run/ikaros/api/core/subject}/SubjectSyncAction.java (78%) create mode 100644 api/src/main/java/run/ikaros/api/core/subject/SubjectSyncPlatformOperate.java rename {server/src/main/java/run/ikaros/server => api/src/main/java/run/ikaros/api}/core/subject/vo/BatchMatchingEpisodeFile.java (90%) rename {server/src/main/java/run/ikaros/server => api/src/main/java/run/ikaros/api}/core/subject/vo/FindSubjectCondition.java (95%) rename {server/src/main/java/run/ikaros/server => api/src/main/java/run/ikaros/api}/core/subject/vo/PostSubjectSyncCondition.java (74%) create mode 100644 server/src/main/java/run/ikaros/server/core/subject/SubjectSyncPlatformOperator.java diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 173b9da03..a6b16a89c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,10 @@ - 添加匹配移除条目剧集附件绑定 #554 - JWT令牌认证支持 #560 +## 插件 + +- 插件接口添加条目同步平台相关接口 #557 + ## 优化 - 条目同步的平台ID输入框最大字符限制提升到了100 diff --git a/server/src/main/java/run/ikaros/server/core/subject/enums/SubjectSyncAction.java b/api/src/main/java/run/ikaros/api/core/subject/SubjectSyncAction.java similarity index 78% rename from server/src/main/java/run/ikaros/server/core/subject/enums/SubjectSyncAction.java rename to api/src/main/java/run/ikaros/api/core/subject/SubjectSyncAction.java index 0877abd0f..0ea896e9a 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/enums/SubjectSyncAction.java +++ b/api/src/main/java/run/ikaros/api/core/subject/SubjectSyncAction.java @@ -1,4 +1,4 @@ -package run.ikaros.server.core.subject.enums; +package run.ikaros.api.core.subject; public enum SubjectSyncAction { /** diff --git a/api/src/main/java/run/ikaros/api/core/subject/SubjectSyncPlatformOperate.java b/api/src/main/java/run/ikaros/api/core/subject/SubjectSyncPlatformOperate.java new file mode 100644 index 000000000..2014d8e39 --- /dev/null +++ b/api/src/main/java/run/ikaros/api/core/subject/SubjectSyncPlatformOperate.java @@ -0,0 +1,30 @@ +package run.ikaros.api.core.subject; + +import jakarta.annotation.Nullable; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import run.ikaros.api.core.subject.vo.PostSubjectSyncCondition; +import run.ikaros.api.plugin.AllowPluginOperate; +import run.ikaros.api.store.enums.SubjectSyncPlatform; + +public interface SubjectSyncPlatformOperate extends AllowPluginOperate { + Mono sync(@Nullable Long subjectId, SubjectSyncPlatform platform, String platformId); + + Mono sync(PostSubjectSyncCondition condition); + + Mono save(SubjectSync subjectSync); + + Mono remove(SubjectSync subjectSync); + + Flux findSubjectSyncsBySubjectId(long subjectId); + + Mono findSubjectSyncBySubjectIdAndPlatform(long subjectId, + SubjectSyncPlatform platform); + + Flux findSubjectSyncsByPlatformAndPlatformId(SubjectSyncPlatform platform, + String platformId); + + Mono findBySubjectIdAndPlatformAndPlatformId(Long subjectId, + SubjectSyncPlatform platform, + String platformId); +} diff --git a/server/src/main/java/run/ikaros/server/core/subject/vo/BatchMatchingEpisodeFile.java b/api/src/main/java/run/ikaros/api/core/subject/vo/BatchMatchingEpisodeFile.java similarity index 90% rename from server/src/main/java/run/ikaros/server/core/subject/vo/BatchMatchingEpisodeFile.java rename to api/src/main/java/run/ikaros/api/core/subject/vo/BatchMatchingEpisodeFile.java index f98ed7cb1..72d4a8d71 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/vo/BatchMatchingEpisodeFile.java +++ b/api/src/main/java/run/ikaros/api/core/subject/vo/BatchMatchingEpisodeFile.java @@ -1,4 +1,4 @@ -package run.ikaros.server.core.subject.vo; +package run.ikaros.api.core.subject.vo; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/server/src/main/java/run/ikaros/server/core/subject/vo/FindSubjectCondition.java b/api/src/main/java/run/ikaros/api/core/subject/vo/FindSubjectCondition.java similarity index 95% rename from server/src/main/java/run/ikaros/server/core/subject/vo/FindSubjectCondition.java rename to api/src/main/java/run/ikaros/api/core/subject/vo/FindSubjectCondition.java index 5252bb304..b767d0ddd 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/vo/FindSubjectCondition.java +++ b/api/src/main/java/run/ikaros/api/core/subject/vo/FindSubjectCondition.java @@ -1,4 +1,4 @@ -package run.ikaros.server.core.subject.vo; +package run.ikaros.api.core.subject.vo; import java.util.Objects; diff --git a/server/src/main/java/run/ikaros/server/core/subject/vo/PostSubjectSyncCondition.java b/api/src/main/java/run/ikaros/api/core/subject/vo/PostSubjectSyncCondition.java similarity index 74% rename from server/src/main/java/run/ikaros/server/core/subject/vo/PostSubjectSyncCondition.java rename to api/src/main/java/run/ikaros/api/core/subject/vo/PostSubjectSyncCondition.java index 6670a9b35..4e712be22 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/vo/PostSubjectSyncCondition.java +++ b/api/src/main/java/run/ikaros/api/core/subject/vo/PostSubjectSyncCondition.java @@ -1,9 +1,9 @@ -package run.ikaros.server.core.subject.vo; +package run.ikaros.api.core.subject.vo; import lombok.Builder; import lombok.Data; +import run.ikaros.api.core.subject.SubjectSyncAction; import run.ikaros.api.store.enums.SubjectSyncPlatform; -import run.ikaros.server.core.subject.enums.SubjectSyncAction; @Data @Builder diff --git a/server/src/main/java/run/ikaros/server/controller/SubjectController.java b/server/src/main/java/run/ikaros/server/controller/SubjectController.java index 521225a67..cf1069101 100644 --- a/server/src/main/java/run/ikaros/server/controller/SubjectController.java +++ b/server/src/main/java/run/ikaros/server/controller/SubjectController.java @@ -11,11 +11,11 @@ import reactor.core.publisher.Mono; import run.ikaros.api.core.attachment.VideoSubtitle; import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.vo.FindSubjectCondition; import run.ikaros.api.store.enums.SubjectType; import run.ikaros.server.core.attachment.service.AttachmentRelationService; import run.ikaros.server.core.statics.StaticService; import run.ikaros.server.core.subject.service.SubjectService; -import run.ikaros.server.core.subject.vo.FindSubjectCondition; import run.ikaros.server.theme.ThemeService; @Controller diff --git a/server/src/main/java/run/ikaros/server/core/subject/SubjectSyncPlatformOperator.java b/server/src/main/java/run/ikaros/server/core/subject/SubjectSyncPlatformOperator.java new file mode 100644 index 000000000..363cf6725 --- /dev/null +++ b/server/src/main/java/run/ikaros/server/core/subject/SubjectSyncPlatformOperator.java @@ -0,0 +1,68 @@ +package run.ikaros.server.core.subject; + +import jakarta.annotation.Nullable; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.SubjectSync; +import run.ikaros.api.core.subject.SubjectSyncPlatformOperate; +import run.ikaros.api.core.subject.vo.PostSubjectSyncCondition; +import run.ikaros.api.store.enums.SubjectSyncPlatform; +import run.ikaros.server.core.subject.service.SubjectSyncPlatformService; + +@Slf4j +@Component +public class SubjectSyncPlatformOperator implements SubjectSyncPlatformOperate { + private final SubjectSyncPlatformService service; + + public SubjectSyncPlatformOperator(SubjectSyncPlatformService service) { + this.service = service; + } + + @Override + public Mono sync(@Nullable Long subjectId, SubjectSyncPlatform platform, + String platformId) { + return service.sync(subjectId, platform, platformId); + } + + @Override + public Mono sync(PostSubjectSyncCondition condition) { + return service.sync(condition); + } + + @Override + public Mono save(SubjectSync subjectSync) { + return service.save(subjectSync); + } + + @Override + public Mono remove(SubjectSync subjectSync) { + return service.remove(subjectSync); + } + + @Override + public Flux findSubjectSyncsBySubjectId(long subjectId) { + return service.findSubjectSyncsBySubjectId(subjectId); + } + + @Override + public Mono findSubjectSyncBySubjectIdAndPlatform(long subjectId, + SubjectSyncPlatform platform) { + return service.findSubjectSyncBySubjectIdAndPlatform(subjectId, platform); + } + + @Override + public Flux findSubjectSyncsByPlatformAndPlatformId(SubjectSyncPlatform platform, + String platformId) { + return service.findSubjectSyncsByPlatformAndPlatformId(platform, platformId); + } + + @Override + public Mono findBySubjectIdAndPlatformAndPlatformId(Long subjectId, + SubjectSyncPlatform platform, + String platformId) { + return service.findBySubjectIdAndPlatformAndPlatformId(subjectId, platform, platformId); + } +} diff --git a/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectEndpoint.java b/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectEndpoint.java index cfc6351e6..c73a5cf12 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectEndpoint.java +++ b/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectEndpoint.java @@ -23,11 +23,11 @@ import reactor.core.publisher.Mono; import run.ikaros.api.constant.OpenApiConst; import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.vo.FindSubjectCondition; import run.ikaros.api.infra.exception.NotFoundException; import run.ikaros.api.store.enums.SubjectType; import run.ikaros.api.wrap.PagingWrap; import run.ikaros.server.core.subject.service.SubjectService; -import run.ikaros.server.core.subject.vo.FindSubjectCondition; import run.ikaros.server.endpoint.CoreEndpoint; @Slf4j diff --git a/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectSyncPlatformEndpoint.java b/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectSyncPlatformEndpoint.java index bdeb37f5f..2a36c4f86 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectSyncPlatformEndpoint.java +++ b/server/src/main/java/run/ikaros/server/core/subject/endpoint/SubjectSyncPlatformEndpoint.java @@ -16,11 +16,11 @@ import reactor.core.publisher.Mono; import run.ikaros.api.constant.OpenApiConst; import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.SubjectSyncAction; +import run.ikaros.api.core.subject.vo.PostSubjectSyncCondition; import run.ikaros.api.infra.exception.subject.NoAvailableSubjectPlatformSynchronizerException; import run.ikaros.api.store.enums.SubjectSyncPlatform; -import run.ikaros.server.core.subject.enums.SubjectSyncAction; import run.ikaros.server.core.subject.service.SubjectSyncPlatformService; -import run.ikaros.server.core.subject.vo.PostSubjectSyncCondition; import run.ikaros.server.endpoint.CoreEndpoint; @Slf4j diff --git a/server/src/main/java/run/ikaros/server/core/subject/service/SubjectService.java b/server/src/main/java/run/ikaros/server/core/subject/service/SubjectService.java index 53fef2b0c..c76c32161 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/service/SubjectService.java +++ b/server/src/main/java/run/ikaros/server/core/subject/service/SubjectService.java @@ -6,9 +6,9 @@ import reactor.core.publisher.Mono; import run.ikaros.api.core.subject.Subject; import run.ikaros.api.core.subject.SubjectMeta; +import run.ikaros.api.core.subject.vo.FindSubjectCondition; import run.ikaros.api.store.enums.SubjectSyncPlatform; import run.ikaros.api.wrap.PagingWrap; -import run.ikaros.server.core.subject.vo.FindSubjectCondition; public interface SubjectService { Mono findById(Long id); diff --git a/server/src/main/java/run/ikaros/server/core/subject/service/SubjectSyncPlatformService.java b/server/src/main/java/run/ikaros/server/core/subject/service/SubjectSyncPlatformService.java index 90d2f7bec..fa702ec4e 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/service/SubjectSyncPlatformService.java +++ b/server/src/main/java/run/ikaros/server/core/subject/service/SubjectSyncPlatformService.java @@ -1,13 +1,31 @@ package run.ikaros.server.core.subject.service; import jakarta.annotation.Nullable; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.SubjectSync; +import run.ikaros.api.core.subject.vo.PostSubjectSyncCondition; import run.ikaros.api.store.enums.SubjectSyncPlatform; -import run.ikaros.server.core.subject.vo.PostSubjectSyncCondition; public interface SubjectSyncPlatformService { Mono sync(@Nullable Long subjectId, SubjectSyncPlatform platform, String platformId); Mono sync(PostSubjectSyncCondition condition); + + Mono save(SubjectSync subjectSync); + + Mono remove(SubjectSync subjectSync); + + Flux findSubjectSyncsBySubjectId(long subjectId); + + Mono findSubjectSyncBySubjectIdAndPlatform(long subjectId, + SubjectSyncPlatform platform); + + Flux findSubjectSyncsByPlatformAndPlatformId(SubjectSyncPlatform platform, + String platformId); + + Mono findBySubjectIdAndPlatformAndPlatformId(Long subjectId, + SubjectSyncPlatform platform, + String platformId); } diff --git a/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectServiceImpl.java b/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectServiceImpl.java index 6f9ade39b..d406a2f4d 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectServiceImpl.java +++ b/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectServiceImpl.java @@ -32,6 +32,7 @@ import run.ikaros.api.core.subject.Subject; import run.ikaros.api.core.subject.SubjectMeta; import run.ikaros.api.core.subject.SubjectSync; +import run.ikaros.api.core.subject.vo.FindSubjectCondition; import run.ikaros.api.infra.exception.NotFoundException; import run.ikaros.api.infra.utils.StringUtils; import run.ikaros.api.store.enums.AttachmentReferenceType; @@ -41,7 +42,6 @@ import run.ikaros.server.core.subject.event.SubjectAddEvent; import run.ikaros.server.core.subject.event.SubjectRemoveEvent; import run.ikaros.server.core.subject.service.SubjectService; -import run.ikaros.server.core.subject.vo.FindSubjectCondition; import run.ikaros.server.infra.utils.ReactiveBeanUtils; import run.ikaros.server.store.entity.AttachmentEntity; import run.ikaros.server.store.entity.AttachmentReferenceEntity; diff --git a/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectSyncPlatformServiceImpl.java b/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectSyncPlatformServiceImpl.java index 93a4cabbd..9629e4d8f 100644 --- a/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectSyncPlatformServiceImpl.java +++ b/server/src/main/java/run/ikaros/server/core/subject/service/impl/SubjectSyncPlatformServiceImpl.java @@ -1,5 +1,7 @@ package run.ikaros.server.core.subject.service.impl; +import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties; + import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; import java.util.Objects; @@ -14,13 +16,14 @@ import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; import run.ikaros.api.core.subject.Subject; +import run.ikaros.api.core.subject.SubjectSync; +import run.ikaros.api.core.subject.SubjectSyncAction; import run.ikaros.api.core.subject.SubjectSynchronizer; +import run.ikaros.api.core.subject.vo.PostSubjectSyncCondition; import run.ikaros.api.infra.exception.subject.NoAvailableSubjectPlatformSynchronizerException; import run.ikaros.api.store.enums.SubjectSyncPlatform; -import run.ikaros.server.core.subject.enums.SubjectSyncAction; import run.ikaros.server.core.subject.service.SubjectService; import run.ikaros.server.core.subject.service.SubjectSyncPlatformService; -import run.ikaros.server.core.subject.vo.PostSubjectSyncCondition; import run.ikaros.server.plugin.ExtensionComponentsFinder; import run.ikaros.server.store.entity.SubjectSyncEntity; import run.ikaros.server.store.repository.SubjectSyncRepository; @@ -51,7 +54,8 @@ public synchronized Mono sync(@Nullable Long subjectId, SubjectSyncPlat Assert.notNull(platform, "'platform' must not null."); Assert.hasText(platformId, "'platformId' must has text."); // 查询是否已经同步过了,如果已经同步过则返回对应的条目信息 - return subjectSyncRepository.findByPlatformAndPlatformId(platform, platformId) + return subjectSyncRepository.findBySubjectIdAndPlatformAndPlatformId( + subjectId, platform, platformId) .map(SubjectSyncEntity::getSubjectId) .flatMap(subjectService::findById) .switchIfEmpty(syncBySubjectSynchronizer(subjectId, platform, platformId)); @@ -101,6 +105,61 @@ public Mono sync(PostSubjectSyncCondition condition) { } + @Override + public Mono save(SubjectSync subjectSync) { + return copyProperties(subjectSync, SubjectSyncEntity.builder().build()) + .flatMap(subjectSyncRepository::save) + .flatMap(subjectSyncEntity -> copyProperties(subjectSyncEntity, subjectSync)); + } + + @Override + public Mono remove(SubjectSync subjectSync) { + return copyProperties(subjectSync, SubjectSyncEntity.builder().build()) + .flatMap(subjectSyncRepository::delete); + } + + @Override + public Flux findSubjectSyncsBySubjectId(long subjectId) { + Assert.isTrue(subjectId > 0, "'subjectId' must gt 0."); + return subjectSyncRepository.findAllBySubjectId(subjectId) + .flatMap(subjectSyncEntity -> copyProperties(subjectSyncEntity, + SubjectSync.builder().build())); + } + + @Override + public Mono findSubjectSyncBySubjectIdAndPlatform(long subjectId, + SubjectSyncPlatform platform) { + Assert.isTrue(subjectId > 0, "'subjectId' must gt 0."); + Assert.notNull(platform, "'platform' must not null."); + return subjectSyncRepository.findBySubjectIdAndPlatform(subjectId, platform) + .flatMap(subjectSyncEntity -> copyProperties(subjectSyncEntity, + SubjectSync.builder().build())); + } + + @Override + public Flux findSubjectSyncsByPlatformAndPlatformId(SubjectSyncPlatform platform, + String platformId) { + Assert.notNull(platform, "'platform' must not null."); + Assert.hasText(platformId, "'platformId' must has text."); + return subjectSyncRepository.findByPlatformAndPlatformId(platform, platformId) + .flatMap(subjectSyncEntity -> copyProperties(subjectSyncEntity, + SubjectSync.builder().build())); + } + + @Override + public Mono findBySubjectIdAndPlatformAndPlatformId(Long subjectId, + SubjectSyncPlatform platform, + String platformId) { + Assert.isTrue(subjectId > 0, "'subjectId' must gt 0."); + Assert.notNull(platform, "'platform' must not null."); + Assert.hasText(platformId, "'platformId' must has text."); + return subjectSyncRepository.findBySubjectIdAndPlatformAndPlatformId( + subjectId, platform, platformId) + .flatMap(subjectSyncEntity -> copyProperties(subjectSyncEntity, + SubjectSync.builder().build())); + } + + private Mono syncBySubjectSynchronizer(@Nullable Long subjectId, SubjectSyncPlatform platform, String platformId) { diff --git a/server/src/main/java/run/ikaros/server/store/repository/SubjectSyncRepository.java b/server/src/main/java/run/ikaros/server/store/repository/SubjectSyncRepository.java index 8571d3bac..f393463d0 100644 --- a/server/src/main/java/run/ikaros/server/store/repository/SubjectSyncRepository.java +++ b/server/src/main/java/run/ikaros/server/store/repository/SubjectSyncRepository.java @@ -7,9 +7,12 @@ import run.ikaros.server.store.entity.SubjectSyncEntity; public interface SubjectSyncRepository extends R2dbcRepository { - Mono findByPlatformAndPlatformId(SubjectSyncPlatform platform, + Flux findByPlatformAndPlatformId(SubjectSyncPlatform platform, String platformId); + Mono findBySubjectIdAndPlatform(Long subjectId, + SubjectSyncPlatform platform); + Mono findBySubjectIdAndPlatformAndPlatformId(Long subjectId, SubjectSyncPlatform platform, String platformId); diff --git a/server/src/test/java/run/ikaros/server/core/subject/vo/FindSubjectConditionTest.java b/server/src/test/java/run/ikaros/server/core/subject/vo/FindSubjectConditionTest.java index d5d9a372d..f17eb25d4 100644 --- a/server/src/test/java/run/ikaros/server/core/subject/vo/FindSubjectConditionTest.java +++ b/server/src/test/java/run/ikaros/server/core/subject/vo/FindSubjectConditionTest.java @@ -2,6 +2,7 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import run.ikaros.api.core.subject.vo.FindSubjectCondition; class FindSubjectConditionTest {