feat: implement manga chapter download producer and consumer with RabbitMQ integration
This commit is contained in:
parent
581f436c5f
commit
bfd415a60d
@ -10,12 +10,18 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class RabbitConfig {
|
public class RabbitConfig {
|
||||||
public static final String MANGA_DATA_UPDATE_QUEUE = "mangaDataUpdateQueue";
|
public static final String MANGA_DATA_UPDATE_QUEUE = "mangaDataUpdateQueue";
|
||||||
|
public static final String MANGA_CHAPTER_DOWNLOAD_QUEUE = "mangaChapterDownloadQueue";
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Queue mangaDataUpdateQueue() {
|
public Queue mangaDataUpdateQueue() {
|
||||||
return new Queue(MANGA_DATA_UPDATE_QUEUE, false);
|
return new Queue(MANGA_DATA_UPDATE_QUEUE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Queue mangaChapterDownloadQueue() {
|
||||||
|
return new Queue(MANGA_CHAPTER_DOWNLOAD_QUEUE, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Jackson2JsonMessageConverter messageConverter() {
|
public Jackson2JsonMessageConverter messageConverter() {
|
||||||
return new Jackson2JsonMessageConverter();
|
return new Jackson2JsonMessageConverter();
|
||||||
|
|||||||
@ -51,6 +51,18 @@ public class MangaController {
|
|||||||
return DefaultResponseDTO.ok(mangaService.getMangaChapters(mangaProviderId));
|
return DefaultResponseDTO.ok(mangaService.getMangaChapters(mangaProviderId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Fetch all chapters",
|
||||||
|
description = "Fetch all not yet downloaded chapters from the provider",
|
||||||
|
tags = {"Manga Chapter"},
|
||||||
|
operationId = "fetchAllChapters")
|
||||||
|
@PostMapping(value = "/{mangaProviderId}/fetch-all-chapters")
|
||||||
|
public DefaultResponseDTO<Void> fetchAllChapters(@PathVariable Long mangaProviderId) {
|
||||||
|
mangaService.fetchAllNotDownloadedChapters(mangaProviderId);
|
||||||
|
|
||||||
|
return DefaultResponseDTO.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Fetch the available chapters for a specific manga/provider combination",
|
summary = "Fetch the available chapters for a specific manga/provider combination",
|
||||||
description = "Fetch a list of manga chapters for a specific manga/provider combination.",
|
description = "Fetch a list of manga chapters for a specific manga/provider combination.",
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
package com.magamochi.mangamochi.model.dto;
|
||||||
|
|
||||||
|
public record MangaChapterDownloadCommand(Long chapterId) {}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.magamochi.mangamochi.queue;
|
||||||
|
|
||||||
|
import com.magamochi.mangamochi.config.RabbitConfig;
|
||||||
|
import com.magamochi.mangamochi.model.dto.MangaChapterDownloadCommand;
|
||||||
|
import com.magamochi.mangamochi.service.MangaChapterService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MangaChapterDownloadConsumer {
|
||||||
|
private final MangaChapterService mangaChapterService;
|
||||||
|
|
||||||
|
@RabbitListener(queues = RabbitConfig.MANGA_CHAPTER_DOWNLOAD_QUEUE)
|
||||||
|
public void receiveMangaChapterDownloadCommand(MangaChapterDownloadCommand command) {
|
||||||
|
log.info("Received manga chapter download command: {}", command);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mangaChapterService.fetchChapter(command.chapterId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Couldn't download chapter {}. {}", command.chapterId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.magamochi.mangamochi.queue;
|
||||||
|
|
||||||
|
import com.magamochi.mangamochi.config.RabbitConfig;
|
||||||
|
import com.magamochi.mangamochi.model.dto.MangaChapterDownloadCommand;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MangaChapterDownloadProducer {
|
||||||
|
private final RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
public void sendMangaChapterDownloadCommand(MangaChapterDownloadCommand command) {
|
||||||
|
rabbitTemplate.convertAndSend(RabbitConfig.MANGA_CHAPTER_DOWNLOAD_QUEUE, command);
|
||||||
|
log.info("Sent manga chapter download command: {}", command);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ import com.magamochi.mangamochi.model.entity.MangaChapter;
|
|||||||
import com.magamochi.mangamochi.model.entity.MangaProvider;
|
import com.magamochi.mangamochi.model.entity.MangaProvider;
|
||||||
import com.magamochi.mangamochi.model.repository.*;
|
import com.magamochi.mangamochi.model.repository.*;
|
||||||
import com.magamochi.mangamochi.model.specification.MangaSpecification;
|
import com.magamochi.mangamochi.model.specification.MangaSpecification;
|
||||||
|
import com.magamochi.mangamochi.queue.MangaChapterDownloadProducer;
|
||||||
import com.magamochi.mangamochi.service.providers.ContentProviderFactory;
|
import com.magamochi.mangamochi.service.providers.ContentProviderFactory;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -33,6 +34,27 @@ public class MangaService {
|
|||||||
private final ContentProviderFactory contentProviderFactory;
|
private final ContentProviderFactory contentProviderFactory;
|
||||||
private final UserFavoriteMangaRepository userFavoriteMangaRepository;
|
private final UserFavoriteMangaRepository userFavoriteMangaRepository;
|
||||||
|
|
||||||
|
private final MangaChapterDownloadProducer mangaChapterDownloadProducer;
|
||||||
|
|
||||||
|
public void fetchAllNotDownloadedChapters(Long mangaProviderId) {
|
||||||
|
var mangaProvider =
|
||||||
|
mangaProviderRepository
|
||||||
|
.findById(mangaProviderId)
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new NotFoundException("Manga Provider not found for ID: " + mangaProviderId));
|
||||||
|
|
||||||
|
var chapterIds =
|
||||||
|
mangaProvider.getMangaChapters().stream()
|
||||||
|
.filter(mangaChapter -> !mangaChapter.getDownloaded())
|
||||||
|
.map(MangaChapter::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
chapterIds.forEach(
|
||||||
|
chapterId ->
|
||||||
|
mangaChapterDownloadProducer.sendMangaChapterDownloadCommand(
|
||||||
|
new MangaChapterDownloadCommand(chapterId)));
|
||||||
|
}
|
||||||
|
|
||||||
public Page<MangaListDTO> getMangas(MangaListFilterDTO filterDTO, Pageable pageable) {
|
public Page<MangaListDTO> getMangas(MangaListFilterDTO filterDTO, Pageable pageable) {
|
||||||
var user = userService.getLoggedUser();
|
var user = userService.getLoggedUser();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user