Files
vod-system/src/main/java/com/ddf/vodsystem/controllers/JobController.java
Dylan De Faoite da6bf16d07 refactor(media): consolidate upload/edit/download into MediaService
Merge UploadService, EditService, JobOrchestrationService, and
DownloadService into a single MediaService with a unified Job lifecycle
(READY → PROCESSING → SUCCEEDED/FAILED via JobState enum).

- Add MediaController (/api/v1/media) exposing compress, save, and clip
- Add JobController (/api/v1/job) for status polling and file download
- Move clip/thumbnail download into ClipController (/{id}/media, /{id}/thumbnail)
- Move stream saveSection/clip from StreamService into MediaService
- Simplify Job DTO: remove dual ClipOptions/files, add ProgressTracker and download file
- Refactor JobRegistryService.add() → generateJob() to co-locate creation and registration
- Wire FFmpeg out_time_ms progress parsing into StreamActionsService via CommandRunner
- Rename GET /api/v1/auth/user → GET /api/v1/user/me
- Delete DownloadController, MetadataController, UploadController
2026-06-22 20:54:16 +01:00

70 lines
2.6 KiB
Java

package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.controllers.dto.JobResponse;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.dto.Job;
import com.ddf.vodsystem.exceptions.NotReadyException;
import com.ddf.vodsystem.services.JobRegistryService;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("api/v1/job")
public class JobController {
private final JobRegistryService jobRegistryService;
private static final String SUCCESS = "success";
private static final String FILENAME_HEADER = "inline; filename=\"%s\"";
public JobController(JobRegistryService jobRegistryService){
this.jobRegistryService = jobRegistryService;
}
@GetMapping("/{uuid}")
public ResponseEntity<APIResponse<JobResponse>> getJob(@PathVariable String uuid) {
Job job = jobRegistryService.getJob(uuid);
JobResponse jobResponse = new JobResponse(
job.getUuid(),
job.getProgressTracker().getProgress(),
job.getProgressTracker().isComplete(),
job.getState(),
job.getErrorOutput(),
job.getCreatedAt()
);
return ResponseEntity.ok(new APIResponse<>(
SUCCESS,
"Job successfully retreived",
jobResponse
));
}
@GetMapping("/{uuid}/download")
public ResponseEntity<Resource> downloadJobFile(@PathVariable String uuid) {
Job job = jobRegistryService.getJob(uuid);
if (job.getDownload() == null) {
throw new NotReadyException("Job " + uuid + " not ready for download.");
}
Resource resource = new FileSystemResource(job.getDownload());
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, String.format(FILENAME_HEADER, resource.getFilename()))
.contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM))
.body(resource);
}
}