backend/src/main/java/com/magamochi/content/controller/ContentController.java

117 lines
4.7 KiB
Java

package com.magamochi.content.controller;
import com.magamochi.common.model.dto.DefaultResponseDTO;
import com.magamochi.content.model.dto.*;
import com.magamochi.content.model.enumeration.ContentArchiveFileType;
import com.magamochi.content.service.ContentDownloadService;
import com.magamochi.content.service.ContentImportService;
import com.magamochi.content.service.ContentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/content")
@RequiredArgsConstructor
public class ContentController {
private final ContentService contentService;
private final ContentDownloadService contentDownloadService;
private final ContentImportService contentImportService;
@Operation(
summary = "Get the content for a specific manga/content provider combination",
description = "Retrieve the content for a specific manga/content provider combination.",
tags = {"Content"},
operationId = "getMangaProviderContent")
@GetMapping("/{mangaContentProviderId}")
public DefaultResponseDTO<List<MangaContentDTO>> getMangaProviderContent(
@PathVariable @NotNull Long mangaContentProviderId) {
return DefaultResponseDTO.ok(contentService.getContent(mangaContentProviderId));
}
@Operation(
summary = "Get the content images for a specific manga/provider combination",
description =
"Retrieve a list of manga content images for a specific manga/provider combination.",
tags = {"Content"},
operationId = "getMangaContentImages")
@GetMapping("/{mangaContentId}/images")
public DefaultResponseDTO<MangaContentImagesDTO> getMangaContentImages(
@PathVariable Long mangaContentId) {
return DefaultResponseDTO.ok(contentService.getContentImages(mangaContentId));
}
@Operation(
summary = "Download content archive",
description = "Download content as a compressed file by its ID.",
tags = {"Content"},
operationId = "downloadContentArchive")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "Successful download",
content =
@Content(
mediaType = "application/octet-stream",
schema = @Schema(type = "string", format = "binary"))),
})
@PostMapping(
value = "/{mangaContentId}/download",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<byte[]> downloadContentArchive(
@PathVariable Long mangaContentId,
@RequestParam ContentArchiveFileType contentArchiveFileType)
throws IOException {
var response = contentDownloadService.downloadContent(mangaContentId, contentArchiveFileType);
return ResponseEntity.ok()
.header("Content-Disposition", "attachment; filename=\"" + response.filename() + "\"")
.body(response.content());
}
@Operation(
summary = "Import multiple files",
description = "Accepts multiple content files via multipart/form-data and processes them.",
tags = {"Content"},
operationId = "importContentFiles")
@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public DefaultResponseDTO<Void> importContentFiles(
@ModelAttribute FileImportRequestDTO requestDTO) {
contentImportService.importFiles(
requestDTO.malId(), requestDTO.aniListId(), requestDTO.files());
return DefaultResponseDTO.ok().build();
}
@Operation(
summary = "Request presigned URL for import",
description =
"Generates a presigned URL to upload a file directly to S3 and registers a pending import job.",
tags = {"Content"},
operationId = "requestPresignedImport")
@PostMapping(value = "/import/presigned")
public DefaultResponseDTO<PresignedImportResponseDTO> requestPresignedImport(
@RequestBody PresignedImportRequestDTO request) {
return DefaultResponseDTO.ok(contentImportService.requestPresignedImport(request));
}
@Operation(
summary = "Get a list of manga import jobs",
description = "Returns a list of manga import jobs.",
tags = {"Content"},
operationId = "getMangaImportJobs")
@GetMapping(value = "/import/jobs")
public DefaultResponseDTO<List<MangaImportJobDTO>> requestPresignedImport() {
return DefaultResponseDTO.ok(contentImportService.getImportJobs());
}
}