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
|
||||
public class RabbitConfig {
|
||||
public static final String MANGA_DATA_UPDATE_QUEUE = "mangaDataUpdateQueue";
|
||||
public static final String MANGA_CHAPTER_DOWNLOAD_QUEUE = "mangaChapterDownloadQueue";
|
||||
|
||||
@Bean
|
||||
public Queue mangaDataUpdateQueue() {
|
||||
return new Queue(MANGA_DATA_UPDATE_QUEUE, false);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Queue mangaChapterDownloadQueue() {
|
||||
return new Queue(MANGA_CHAPTER_DOWNLOAD_QUEUE, false);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Jackson2JsonMessageConverter messageConverter() {
|
||||
return new Jackson2JsonMessageConverter();
|
||||
|
||||
@ -51,6 +51,18 @@ public class MangaController {
|
||||
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(
|
||||
summary = "Fetch the available 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.repository.*;
|
||||
import com.magamochi.mangamochi.model.specification.MangaSpecification;
|
||||
import com.magamochi.mangamochi.queue.MangaChapterDownloadProducer;
|
||||
import com.magamochi.mangamochi.service.providers.ContentProviderFactory;
|
||||
import java.net.*;
|
||||
import java.util.Comparator;
|
||||
@ -33,6 +34,27 @@ public class MangaService {
|
||||
private final ContentProviderFactory contentProviderFactory;
|
||||
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) {
|
||||
var user = userService.getLoggedUser();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user