package com.magamochi.content.service; import static java.util.Objects.isNull; import com.magamochi.catalog.service.LanguageService; import com.magamochi.catalog.service.MangaContentProviderService; import com.magamochi.common.exception.NotFoundException; import com.magamochi.common.model.enumeration.ContentType; import com.magamochi.common.queue.command.ImageFetchCommand; import com.magamochi.common.queue.producer.ImageFetchProducer; import com.magamochi.content.model.entity.MangaContent; import com.magamochi.content.model.entity.MangaContentImage; import com.magamochi.content.model.repository.MangaContentImageRepository; import com.magamochi.content.model.repository.MangaContentRepository; import com.magamochi.image.service.ImageService; import jakarta.validation.constraints.NotBlank; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Log4j2 @Service @RequiredArgsConstructor public class ContentIngestService { private final ContentService contentService; private final MangaContentProviderService mangaContentProviderService; private final LanguageService languageService; private final MangaContentRepository mangaContentRepository; private final MangaContentImageRepository mangaContentImageRepository; private final ImageFetchProducer imageFetchProducer; private final ImageService imageService; public void ingest( long mangaContentProviderId, @NotBlank String title, @NotBlank String url, @NotBlank String languageCode) { log.info("Ingesting Manga Content ({}) for provider {}", title, mangaContentProviderId); var mangaContentProvider = mangaContentProviderService.find(mangaContentProviderId); if (mangaContentRepository.existsByMangaContentProvider_IdAndUrlIgnoreCase( mangaContentProvider.getId(), url)) { log.info( "Manga Content ({}) for provider {} already exists. Skipped.", title, mangaContentProviderId); return; } var language = languageService.find(languageCode); var mangaContent = mangaContentRepository.save( MangaContent.builder() .mangaContentProvider(mangaContentProvider) .title(title) .url(url) .language(language) .build()); log.info( "Ingested Manga Content ({}) for provider {}: {}", title, mangaContentProviderId, mangaContent.getId()); } @Transactional public void ingestImages( long mangaContentId, @NotBlank String url, int position, boolean isLast) { log.info( "Ingesting Manga Content Image for MangaContent {}, position {}", mangaContentId, position); var mangaContent = contentService.find(mangaContentId); if (mangaContentImageRepository.existsByMangaContent_IdAndPosition(mangaContentId, position)) { return; } var mangaContentImage = mangaContentImageRepository.save( MangaContentImage.builder().mangaContent(mangaContent).position(position).build()); imageFetchProducer.sendImageFetchCommand( new ImageFetchCommand(mangaContentImage.getId(), ContentType.CONTENT_IMAGE, url)); if (isLast) { mangaContent.setDownloaded(true); } } @Transactional public void updateMangaContentImage(long mangaContentImageId, UUID imageId) { if (isNull(imageId)) { log.error("Null imageID received!"); return; } var mangaContentImage = mangaContentImageRepository .findById(mangaContentImageId) .orElseThrow( () -> new NotFoundException("Image not found for ID: " + mangaContentImageId)); var image = imageService.find(imageId); mangaContentImage.setImage(image); } }