Skip to content

Commit

Permalink
feat: video subtitle attachment relation new when AttachmentReference…
Browse files Browse the repository at this point in the history
…SaveEvent and EpisodeAttachmentUpdateEvent (#496)
  • Loading branch information
chivehao committed Oct 25, 2023
1 parent 8f6b5e0 commit 39a19f8
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

# 0.11.2

## 新功能

- 视频字幕关系:当类型为剧集的附件引用表新增事件发生时,和剧集资源匹配更新事件发生时,会根据当前附件的名称模糊查询字幕文件,如果存在则新增一条类型为视频字幕的附件关系记录。

## 优化

- 统一返回结果,优化错误提示 #489
Expand Down
20 changes: 0 additions & 20 deletions api/src/main/java/run/ikaros/api/core/subject/Subtitle.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package run.ikaros.server.core.attachment.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;
import run.ikaros.server.store.entity.AttachmentReferenceEntity;

@Getter
public class AttachmentReferenceSaveEvent extends ApplicationEvent {

private final AttachmentReferenceEntity entity;

public AttachmentReferenceSaveEvent(Object source, AttachmentReferenceEntity entity) {
super(source);
this.entity = entity;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package run.ikaros.server.core.attachment.listener;

import static run.ikaros.api.store.enums.AttachmentType.File;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.ikaros.api.core.attachment.VideoSubtitle;
import run.ikaros.api.infra.utils.FileUtils;
import run.ikaros.api.store.enums.AttachmentReferenceType;
import run.ikaros.api.store.enums.AttachmentRelationType;
import run.ikaros.server.core.attachment.event.AttachmentReferenceSaveEvent;
import run.ikaros.server.core.attachment.event.EpisodeAttachmentUpdateEvent;
import run.ikaros.server.store.entity.AttachmentEntity;
import run.ikaros.server.store.entity.AttachmentReferenceEntity;
import run.ikaros.server.store.entity.AttachmentRelationEntity;
import run.ikaros.server.store.repository.AttachmentRelationRepository;
import run.ikaros.server.store.repository.AttachmentRepository;

@Slf4j
@Component
public class AttachmentRelVideoSubtitleListener {
private final AttachmentRepository attachmentRepository;
private final AttachmentRelationRepository attachmentRelationRepository;

public AttachmentRelVideoSubtitleListener(
AttachmentRepository attachmentRepository,
AttachmentRelationRepository attachmentRelationRepository) {
this.attachmentRepository = attachmentRepository;
this.attachmentRelationRepository = attachmentRelationRepository;
}

/**
* 监听附件关系保存事件{@link AttachmentReferenceSaveEvent},
* 如果保存的类型是剧集引用,则查询一次对应的附件是否存在同名字幕,
* 如果存在则在附件关系表新增一条视频字幕类型的关系记录.
*/
@EventListener(AttachmentReferenceSaveEvent.class)
public Mono<Void> onAttachmentReferenceSaveEvent(AttachmentReferenceSaveEvent event) {
AttachmentReferenceEntity entity = event.getEntity();
if (!AttachmentReferenceType.EPISODE.equals(entity.getType())) {
return Mono.empty();
}
Long attachmentId = entity.getAttachmentId();

return findAttachmentSubtitlesAndSaveRelationIfNotExists(attachmentId);
}


/**
* 监听剧集资源匹配更新事件{@link EpisodeAttachmentUpdateEvent}, 查询对应的剧集附件,
* 在数据库中,是否存在相同名称的字幕文件,
* 如果存在则新增一条附件间关系{@link run.ikaros.api.store.enums.AttachmentRelationType#VIDEO_SUBTITLE}.
*/
@EventListener(EpisodeAttachmentUpdateEvent.class)
public Mono<Void> onSubjectAdd(EpisodeAttachmentUpdateEvent event) {
Long attachmentId = event.getAttachmentId();
return findAttachmentSubtitlesAndSaveRelationIfNotExists(attachmentId);
}

private Mono<Void> findAttachmentSubtitlesAndSaveRelationIfNotExists(Long attachmentId) {
return attachmentRepository.findById(attachmentId)
.map(AttachmentEntity::getName)
.flatMapMany(this::findAllAttachmentSubtitles)
.map(VideoSubtitle::getAttachmentId)
.flatMap(relationAttId -> attachmentRelationRepository
.existsByTypeAndAttachmentIdAndRelationAttachmentId(
AttachmentRelationType.VIDEO_SUBTITLE, attachmentId, relationAttId)
.filter(exists -> !exists)
.map(exists -> AttachmentRelationEntity.builder()
.type(AttachmentRelationType.VIDEO_SUBTITLE)
.attachmentId(attachmentId)
.relationAttachmentId(relationAttId)
.build())
.flatMap(attachmentRelationEntity -> attachmentRelationRepository
.save(attachmentRelationEntity)
.doOnSuccess(entity -> log.debug("Save new attachment relation record"
+ " for type={} attId={} relAttId={}",
AttachmentRelationType.VIDEO_SUBTITLE,
attachmentId, relationAttId))))
.then();
}

private Flux<VideoSubtitle> findAllAttachmentSubtitles(String attachmentName) {
String postfix = FileUtils.parseFilePostfix(attachmentName);
attachmentName = attachmentName.substring(0, attachmentName.indexOf(postfix));
return attachmentRepository.findAllByTypeAndNameLike(File, attachmentName + "%")
.filter(attachmentEntity -> attachmentEntity.getName().endsWith("ass"))
.map(attachmentEntity -> VideoSubtitle.builder()
.attachmentId(attachmentEntity.getId())
.name(attachmentEntity.getName())
.url(attachmentEntity.getUrl())
.build());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import run.ikaros.api.infra.utils.RegexUtils;
import run.ikaros.api.store.enums.AttachmentReferenceType;
import run.ikaros.api.store.enums.EpisodeGroup;
import run.ikaros.server.core.attachment.event.AttachmentReferenceSaveEvent;
import run.ikaros.server.core.attachment.event.EpisodeAttachmentUpdateEvent;
import run.ikaros.server.core.attachment.service.AttachmentReferenceService;
import run.ikaros.server.store.entity.AttachmentReferenceEntity;
Expand Down Expand Up @@ -51,9 +52,16 @@ public AttachmentReferenceServiceImpl(AttachmentReferenceRepository repository,
public Mono<AttachmentReference> save(AttachmentReference attachmentReference) {
Assert.notNull(attachmentReference, "'attachmentReference' must not null.");
return checkAttachmentRef(attachmentReference)
.flatMap(
attachmentRef -> copyProperties(attachmentRef, new AttachmentReferenceEntity()))
.flatMap(repository::save)
.flatMap(attachmentRef ->
copyProperties(attachmentRef, new AttachmentReferenceEntity()))
.flatMap(attachmentReferenceEntity -> repository.save(attachmentReferenceEntity)
.doOnSuccess(entity -> {
AttachmentReferenceSaveEvent event =
new AttachmentReferenceSaveEvent(this, entity);
applicationEventPublisher.publishEvent(event);
log.debug("publish AttachmentReferenceSaveEvent "
+ "for attachment reference entity: [{}]", entity);
}))
.flatMap(entity -> copyProperties(entity, attachmentReference));
}

Expand Down Expand Up @@ -153,7 +161,19 @@ public Mono<Void> matchingAttachmentsForEpisode(Long episodeId, Long[] attachmen
.map(attId -> AttachmentReferenceEntity.builder()
.type(EPISODE).attachmentId(attId).referenceId(episodeId)
.build())
.flatMap(repository::save)
.flatMap(attachmentReferenceEntity -> repository.save(attachmentReferenceEntity)
.doOnSuccess(entity -> {
log.info("save episode file matching "
+ "for attId:[{}] and episodeId:[{}]. ",
entity.getAttachmentId(), entity.getReferenceId());
EpisodeAttachmentUpdateEvent event =
new EpisodeAttachmentUpdateEvent(this,
entity.getReferenceId(),
entity.getId(), false);
applicationEventPublisher.publishEvent(event);
log.debug("publish event EpisodeAttachmentUpdateEvent "
+ "for attachmentReferenceEntity: {}", attachmentReferenceEntity);
}))
.then();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

import org.springframework.data.r2dbc.repository.R2dbcRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.ikaros.api.store.enums.AttachmentRelationType;
import run.ikaros.server.store.entity.AttachmentRelationEntity;

public interface AttachmentRelationRepository
extends R2dbcRepository<AttachmentRelationEntity, Long> {
Flux<AttachmentRelationEntity> findAllByTypeAndAttachmentId(AttachmentRelationType type,
Long attachmentId);

Mono<Boolean> existsByTypeAndAttachmentIdAndRelationAttachmentId(AttachmentRelationType type,
Long attachmentId,
Long relationAttachmentId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Mono<AttachmentEntity> findByTypeAndParentIdAndName(

Flux<AttachmentEntity> findAllByParentId(Long parentId);

Flux<AttachmentEntity> findAllByTypeAndNameLike(AttachmentType type, String name);

Mono<AttachmentEntity> findByUrl(String url);

Mono<Long> countByType(AttachmentType type);
Expand Down

0 comments on commit 39a19f8

Please sign in to comment.