117 lines
4.7 KiB
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());
|
|
}
|
|
}
|