diff --git a/src/main/java/com/magamochi/catalog/controller/MangaIngestReviewController.java b/src/main/java/com/magamochi/catalog/controller/MangaIngestReviewController.java index da269bb..8806884 100644 --- a/src/main/java/com/magamochi/catalog/controller/MangaIngestReviewController.java +++ b/src/main/java/com/magamochi/catalog/controller/MangaIngestReviewController.java @@ -43,8 +43,10 @@ public class MangaIngestReviewController { operationId = "resolveMangaIngestReview") @PostMapping("/ingest-reviews") public DefaultResponseDTO resolveMangaIngestReview( - @RequestParam Long id, @RequestParam String malId) { - mangaIngestReviewService.resolveImportReview(id, malId); + @RequestParam Long id, + @RequestParam(required = false) Long malId, + @RequestParam(required = false) Long aniListId) { + mangaIngestReviewService.resolveIngestReview(id, aniListId, malId); return DefaultResponseDTO.ok().build(); } diff --git a/src/main/java/com/magamochi/catalog/service/MangaIngestReviewService.java b/src/main/java/com/magamochi/catalog/service/MangaIngestReviewService.java index 24d188f..f4098af 100644 --- a/src/main/java/com/magamochi/catalog/service/MangaIngestReviewService.java +++ b/src/main/java/com/magamochi/catalog/service/MangaIngestReviewService.java @@ -1,66 +1,96 @@ package com.magamochi.catalog.service; +import static java.util.Objects.isNull; + import com.magamochi.catalog.model.dto.MangaIngestReviewDTO; +import com.magamochi.catalog.model.entity.MangaContentProvider; import com.magamochi.catalog.model.entity.MangaIngestReview; +import com.magamochi.catalog.model.repository.MangaContentProviderRepository; import com.magamochi.catalog.model.repository.MangaIngestReviewRepository; import com.magamochi.common.exception.NotFoundException; +import com.magamochi.ingestion.service.ContentProviderService; import java.util.List; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.NotImplementedException; +import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; +@Log4j2 @Service @RequiredArgsConstructor public class MangaIngestReviewService { + private final MangaResolutionService mangaResolutionService; + private final ContentProviderService contentProviderService; + private final MangaIngestReviewRepository mangaIngestReviewRepository; + private final MangaContentProviderRepository mangaContentProviderRepository; public List get() { return mangaIngestReviewRepository.findAll().stream().map(MangaIngestReviewDTO::from).toList(); } public void deleteIngestReview(Long id) { - var importReview = getImportReviewThrowIfNotFound(id); + var importReview = get(id); mangaIngestReviewRepository.delete(importReview); } - public void resolveImportReview(Long id, String malId) { - throw new NotImplementedException(); - // var importReview = getImportReviewThrowIfNotFound(id); - // - // jikanRateLimiter.acquire(); - // var jikanResult = jikanClient.getMangaById(Long.parseLong(malId)).data(); - // - // if (isNull(jikanResult)) { - // throw new NotFoundException("MyAnimeList manga not found for ID: " + id); - // } - // - // var manga = - // mangaRepository - // .findByTitleIgnoreCase(jikanResult.title()) - // .orElseGet( - // () -> - // mangaRepository.save( - // Manga.builder() - // .title(jikanResult.title()) - // .malId(Long.parseLong(malId)) - // .build())); - // - // if (!mangaContentProviderRepository.existsByMangaAndContentProviderAndUrlIgnoreCase( - // manga, importReview.getContentProvider(), importReview.getUrl())) { - // mangaContentProviderRepository.save( - // MangaContentProvider.builder() - // .manga(manga) - // .mangaTitle(importReview.getMangaTitle()) - // .contentProvider(importReview.getContentProvider()) - // .url(importReview.getUrl()) - // .build()); - // } - // - // mangaIngestReviewRepository.delete(importReview); + public void resolveIngestReview(Long id, Long aniListId, Long malId) { + if (aniListId == 0) { + aniListId = null; + } + + if (malId == 0) { + malId = null; + } + + if (isNull(aniListId) && isNull(malId)) { + throw new IllegalArgumentException("At least one of aniListId or malId must be provided"); + } + + var ingestReview = get(id); + var mangaTitle = ingestReview.getMangaTitle(); + var contentProviderId = ingestReview.getContentProvider().getId(); + + if (mangaContentProviderRepository.existsByMangaTitleIgnoreCaseAndContentProvider_Id( + mangaTitle, contentProviderId)) { + log.info( + "Manga with mangaTitle '{}' already exists for provider '{}', skipping ingest", + mangaTitle, + contentProviderId); + return; + } + + var manga = mangaResolutionService.findOrCreateManga(aniListId, malId); + + try { + var contentProvider = contentProviderService.find(contentProviderId); + + mangaContentProviderRepository.save( + MangaContentProvider.builder() + .manga(manga) + .mangaTitle(mangaTitle) + .contentProvider(contentProvider) + .url(ingestReview.getUrl()) + .build()); + } catch (Exception e) { + log.error( + "Failed to ingest manga with mangaTitle '{}' from provider '{}'", + mangaTitle, + contentProviderId, + e); + + throw e; + } + + mangaIngestReviewRepository.delete(ingestReview); + + log.info( + "Successfully ingested manga with mangaTitle '{}' from provider {}", + mangaTitle, + contentProviderId); } - private MangaIngestReview getImportReviewThrowIfNotFound(Long id) { + private MangaIngestReview get(Long id) { return mangaIngestReviewRepository .findById(id) .orElseThrow(() -> new NotFoundException("Import review not found for ID: " + id));