ADD thumbnail to database (#12)

* ADD thumbnail to database

* ADD thumbnail generation and retrieval functionality

* ADD thumbnail availability check in VideoCard component

* ADD ClipDTO to reduce exposed internals

* REFactor move APIResponse and VideoMetadata to dto package

* REMOVE unused props from VideoCard

* ADD isThumbnailAvailable function
This commit is contained in:
Dylan De Faoite
2025-07-17 23:21:01 +02:00
committed by GitHub
parent 4c49a1daf8
commit 87ad7e3537
26 changed files with 190 additions and 44 deletions

View File

@@ -1,6 +1,6 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.exceptions.NotAuthenticated;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

View File

@@ -1,6 +1,7 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.ClipDTO;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.entities.Clip;
import com.ddf.vodsystem.exceptions.NotAuthenticated;
import com.ddf.vodsystem.services.ClipService;
@@ -24,19 +25,23 @@ public class ClipController {
}
@GetMapping("/")
public ResponseEntity<APIResponse<List<Clip>>> getClips(@AuthenticationPrincipal OAuth2User principal) {
public ResponseEntity<APIResponse<List<ClipDTO>>> getClips(@AuthenticationPrincipal OAuth2User principal) {
if (principal == null) {
throw new NotAuthenticated("User is not authenticated");
}
List<Clip> clips = clipService.getClipsByUser();
List<ClipDTO> clipDTOs = clips.stream()
.map(this::convertToDTO)
.toList();
return ResponseEntity.ok(
new APIResponse<>("success", "Clips retrieved successfully", clips)
new APIResponse<>("success", "Clips retrieved successfully", clipDTOs)
);
}
@GetMapping("/{id}")
public ResponseEntity<APIResponse<Clip>> getClipById(@AuthenticationPrincipal OAuth2User principal, @PathVariable Long id) {
public ResponseEntity<APIResponse<ClipDTO>> getClipById(@AuthenticationPrincipal OAuth2User principal, @PathVariable Long id) {
if (principal == null) {
throw new NotAuthenticated("User is not authenticated");
}
@@ -46,8 +51,21 @@ public class ClipController {
return ResponseEntity.notFound().build();
}
ClipDTO clipDTO = convertToDTO(clip);
return ResponseEntity.ok(
new APIResponse<>("success", "Clip retrieved successfully", clip)
new APIResponse<>("success", "Clip retrieved successfully", clipDTO)
);
}
private ClipDTO convertToDTO(Clip clip) {
ClipDTO dto = new ClipDTO();
dto.setId(clip.getId());
dto.setUserId(clip.getUser().getId());
dto.setTitle(clip.getTitle());
dto.setDescription(clip.getDescription());
dto.setDuration(clip.getDuration());
dto.setCreatedAt(clip.getCreatedAt());
return dto;
}
}

View File

@@ -65,4 +65,18 @@ public class DownloadController {
.contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM))
.body(resource);
}
@GetMapping("/thumbnail/{id}")
public ResponseEntity<Resource> downloadThumbnail(@AuthenticationPrincipal OAuth2User principal, @PathVariable Long id) {
Resource resource = downloadService.downloadThumbnail(id);
if (resource == null || !resource.exists()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + resource.getFilename() + "\"")
.contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM))
.body(resource);
}
}

View File

@@ -1,12 +1,11 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.VideoMetadata;
import com.ddf.vodsystem.dto.VideoMetadata;
import com.ddf.vodsystem.services.EditService;
import lombok.AllArgsConstructor;
import lombok.Data;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.APIResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

View File

@@ -1,6 +1,6 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.exceptions.FFMPEGException;
import com.ddf.vodsystem.exceptions.JobNotFinished;
import com.ddf.vodsystem.exceptions.JobNotFound;

View File

@@ -1,7 +1,7 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.VideoMetadata;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.VideoMetadata;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.services.JobService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

View File

@@ -1,6 +1,6 @@
package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.dto.APIResponse;
import com.ddf.vodsystem.services.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;