docs(docstrings): add clip & vod comments
This commit is contained in:
@@ -46,10 +46,10 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all clips associated with the currently logged-in user.
|
* Returns all clips belonging to the currently authenticated user.
|
||||||
*
|
*
|
||||||
* @return a list of clips belonging to the authenticated user.
|
* @return list of clips owned by the current user, in repository order
|
||||||
* @throws NotAuthenticated if the user is not authenticated.
|
* @throws NotAuthenticated if no user session is present
|
||||||
*/
|
*/
|
||||||
public List<Clip> getClipsByUser() {
|
public List<Clip> getClipsByUser() {
|
||||||
Optional<User> user = userService.getLoggedInUser();
|
Optional<User> user = userService.getLoggedInUser();
|
||||||
@@ -62,11 +62,12 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a clip by its ID, ensuring the user is authenticated to access it.
|
* Returns the clip with the given ID, verifying ownership by the current user.
|
||||||
*
|
*
|
||||||
* @param id the ID of the clip to retrieve.
|
* @param id the ID of the clip to retrieve
|
||||||
* @return an Optional containing the Clip if found and accessible, or empty if not found.
|
* @return an Optional containing the clip; never empty — throws instead of returning empty
|
||||||
* @throws NotAuthenticated if the user is not authorized to access the clip.
|
* @throws ClipNotFound if no clip with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the clip
|
||||||
*/
|
*/
|
||||||
public Optional<Clip> getClipById(Long id) {
|
public Optional<Clip> getClipById(Long id) {
|
||||||
Optional<Clip> clip = clipRepository.findById(id);
|
Optional<Clip> clip = clipRepository.findById(id);
|
||||||
@@ -82,6 +83,17 @@ public class ClipService {
|
|||||||
return clip;
|
return clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a partial update to an existing clip's metadata.
|
||||||
|
* <p>
|
||||||
|
* Only non-null fields in {@code newFields} are written; null fields are left unchanged.
|
||||||
|
*
|
||||||
|
* @param id the ID of the clip to update
|
||||||
|
* @param newFields fields to overwrite; any null field is ignored
|
||||||
|
* @return the updated clip as persisted in the database
|
||||||
|
* @throws ClipNotFound if no clip with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the clip
|
||||||
|
*/
|
||||||
public Clip updateClip(Long id, ClipUpdateRequest newFields) {
|
public Clip updateClip(Long id, ClipUpdateRequest newFields) {
|
||||||
Optional<Clip> possibleClip = clipRepository.findById(id);
|
Optional<Clip> possibleClip = clipRepository.findById(id);
|
||||||
|
|
||||||
@@ -107,11 +119,12 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a clip by its ID, ensuring the user is authenticated to perform the deletion.
|
* Deletes a clip and its associated files from disk.
|
||||||
*
|
*
|
||||||
* @param id the ID of the clip to delete.
|
* @param id the ID of the clip to delete
|
||||||
* @return true if the clip was successfully deleted, false if it was not found.
|
* @return {@code true} on success; always throws rather than returning {@code false}
|
||||||
* @throws NotAuthenticated if the user is not authorized to delete the clip.
|
* @throws ClipNotFound if no clip with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the clip
|
||||||
*/
|
*/
|
||||||
public boolean deleteClip(Long id) {
|
public boolean deleteClip(Long id) {
|
||||||
Optional<Clip> possibleClip = getClipById(id);
|
Optional<Clip> possibleClip = getClipById(id);
|
||||||
@@ -133,10 +146,11 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the currently logged-in user is authenticated to access the specified clip.
|
* Returns whether the current user owns the given clip.
|
||||||
*
|
*
|
||||||
* @param clip the clip to check access for.
|
* @param clip the clip to check ownership of
|
||||||
* @return true if the user is authenticated for the clip, false otherwise.
|
* @return {@code true} if the current user's ID matches the clip's owner; {@code false} if
|
||||||
|
* {@code clip} is null or no user session exists
|
||||||
*/
|
*/
|
||||||
public boolean isAuthenticatedForClip(Clip clip) {
|
public boolean isAuthenticatedForClip(Clip clip) {
|
||||||
Optional<User> user = userService.getLoggedInUser();
|
Optional<User> user = userService.getLoggedInUser();
|
||||||
@@ -146,6 +160,14 @@ public class ClipService {
|
|||||||
return user.get().getId().equals(clip.getUser().getId());
|
return user.get().getId().equals(clip.getUser().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a streamable resource for the clip's video file.
|
||||||
|
*
|
||||||
|
* @param id the ID of the clip to download
|
||||||
|
* @return a {@link Resource} pointing to the clip's video file on disk
|
||||||
|
* @throws ClipNotFound if no clip with {@code id} exists, or the video file is missing on disk
|
||||||
|
* @throws NotAuthenticated if the current user does not own the clip
|
||||||
|
*/
|
||||||
public Resource downloadClip(Long id) {
|
public Resource downloadClip(Long id) {
|
||||||
Optional<Clip> possibleClip = getClipById(id);
|
Optional<Clip> possibleClip = getClipById(id);
|
||||||
|
|
||||||
@@ -169,6 +191,14 @@ public class ClipService {
|
|||||||
return new FileSystemResource(file);
|
return new FileSystemResource(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a streamable resource for the clip's thumbnail image.
|
||||||
|
*
|
||||||
|
* @param id the ID of the clip whose thumbnail to download
|
||||||
|
* @return a {@link Resource} pointing to the thumbnail file on disk
|
||||||
|
* @throws ClipNotFound if no clip with {@code id} exists, or the thumbnail file is missing on disk
|
||||||
|
* @throws NotAuthenticated if the current user does not own the clip
|
||||||
|
*/
|
||||||
public Resource downloadThumbnail(Long id) {
|
public Resource downloadThumbnail(Long id) {
|
||||||
Optional<Clip> possibleClip = getClipById(id);
|
Optional<Clip> possibleClip = getClipById(id);
|
||||||
|
|
||||||
@@ -193,32 +223,21 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists a clip to the database
|
* Copies a processed clip file into permanent storage, generates its thumbnail, and saves
|
||||||
* @param options ClipOptions object of the clip metadata to save to the database. All fields required except for title, description
|
* the clip record to the database.
|
||||||
* @param user User to save the clip to
|
* <p>
|
||||||
* @param videoPath Path of the clip
|
* Thumbnail generation failure is non-fatal — the error is logged and the clip is saved
|
||||||
* @param thumbnailPath Path of the thumbnail
|
* without a thumbnail rather than aborting.
|
||||||
* @return Clip object saved to the database
|
*
|
||||||
|
* @param title title to assign to the clip
|
||||||
|
* @param description description to assign to the clip
|
||||||
|
* @param user owner of the clip
|
||||||
|
* @param clipFile path to the processed video file (typically in the temp output directory)
|
||||||
|
* @param fileName filename used for both the permanent video file and the thumbnail
|
||||||
|
* (thumbnail is stored as {@code fileName + ".png"})
|
||||||
|
* @throws StorageException if copying the file to the clips directory fails
|
||||||
|
* @throws FFMPEGException if reading video metadata from the copied file fails
|
||||||
*/
|
*/
|
||||||
public Clip saveClip(ClipOptions options,
|
|
||||||
User user,
|
|
||||||
Path videoPath,
|
|
||||||
Path thumbnailPath) {
|
|
||||||
Clip clip = new Clip();
|
|
||||||
clip.setUser(user);
|
|
||||||
clip.setTitle(options.getTitle() != null ? options.getTitle() : "Untitled Clip");
|
|
||||||
clip.setDescription(options.getDescription() != null ? options.getDescription() : "");
|
|
||||||
clip.setCreatedAt(Instant.now());
|
|
||||||
clip.setWidth(options.getWidth());
|
|
||||||
clip.setHeight(options.getHeight());
|
|
||||||
clip.setFps(options.getFps());
|
|
||||||
clip.setDuration(options.getDuration() - options.getStartPoint());
|
|
||||||
clip.setFileSize(options.getFileSize());
|
|
||||||
clip.setVideoPath(directoryService.relativisePath(videoPath.toAbsolutePath()).toString());
|
|
||||||
clip.setThumbnailPath(directoryService.relativisePath(thumbnailPath.toAbsolutePath()).toString());
|
|
||||||
return clipRepository.save(clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void persistClip(String title,
|
public void persistClip(String title,
|
||||||
String description,
|
String description,
|
||||||
User user,
|
User user,
|
||||||
@@ -261,6 +280,25 @@ public class ClipService {
|
|||||||
logger.info("Clip created successfully with ID: {}", clip.getId());
|
logger.info("Clip created successfully with ID: {}", clip.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Clip saveClip(ClipOptions metadata,
|
||||||
|
User user,
|
||||||
|
Path videoPath,
|
||||||
|
Path thumbnailPath) {
|
||||||
|
Clip clip = new Clip();
|
||||||
|
clip.setUser(user);
|
||||||
|
clip.setTitle(metadata.getTitle() != null ? metadata.getTitle() : "Untitled Clip");
|
||||||
|
clip.setDescription(metadata.getDescription() != null ? metadata.getDescription() : "");
|
||||||
|
clip.setCreatedAt(Instant.now());
|
||||||
|
clip.setWidth(metadata.getWidth());
|
||||||
|
clip.setHeight(metadata.getHeight());
|
||||||
|
clip.setFps(metadata.getFps());
|
||||||
|
clip.setDuration(metadata.getDuration() - metadata.getStartPoint());
|
||||||
|
clip.setFileSize(metadata.getFileSize());
|
||||||
|
clip.setVideoPath(directoryService.relativisePath(videoPath.toAbsolutePath()).toString());
|
||||||
|
clip.setThumbnailPath(directoryService.relativisePath(thumbnailPath.toAbsolutePath()).toString());
|
||||||
|
return clipRepository.save(clip);
|
||||||
|
}
|
||||||
|
|
||||||
private void deleteClipFiles(Clip clip) {
|
private void deleteClipFiles(Clip clip) {
|
||||||
File clipFile = new File(clip.getVideoPath());
|
File clipFile = new File(clip.getVideoPath());
|
||||||
File thumbnailFile = new File(clip.getThumbnailPath());
|
File thumbnailFile = new File(clip.getThumbnailPath());
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ public class VodService {
|
|||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the VoD with the given ID, verifying ownership by the current user.
|
||||||
|
*
|
||||||
|
* @param id the ID of the VoD to retrieve
|
||||||
|
* @return the matching {@link Vod} entity
|
||||||
|
* @throws VodNotFound if no VoD with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the VoD
|
||||||
|
*/
|
||||||
public Vod getVodById(Long id) {
|
public Vod getVodById(Long id) {
|
||||||
Optional<Vod> vod = vodRepository.findById(id);
|
Optional<Vod> vod = vodRepository.findById(id);
|
||||||
|
|
||||||
@@ -59,6 +67,12 @@ public class VodService {
|
|||||||
return vod.get();
|
return vod.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all VoDs belonging to the currently authenticated user.
|
||||||
|
*
|
||||||
|
* @return list of VoDs owned by the current user, in repository order
|
||||||
|
* @throws NotAuthenticated if no user session is present
|
||||||
|
*/
|
||||||
public List<Vod> getUserVods() {
|
public List<Vod> getUserVods() {
|
||||||
Optional<User> user = userService.getLoggedInUser();
|
Optional<User> user = userService.getLoggedInUser();
|
||||||
|
|
||||||
@@ -69,6 +83,17 @@ public class VodService {
|
|||||||
return vodRepository.findByUser(user.get());
|
return vodRepository.findByUser(user.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a partial update to an existing VoD's metadata.
|
||||||
|
* <p>
|
||||||
|
* Only non-null fields in {@code newFields} are written; null fields are left unchanged.
|
||||||
|
*
|
||||||
|
* @param id the ID of the VoD to update
|
||||||
|
* @param newFields fields to overwrite; any null field is ignored
|
||||||
|
* @return the updated VoD as persisted in the database
|
||||||
|
* @throws VodNotFound if no VoD with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the VoD
|
||||||
|
*/
|
||||||
public Vod updateVod(Long id, VodUpdateRequest newFields) {
|
public Vod updateVod(Long id, VodUpdateRequest newFields) {
|
||||||
Vod vod = getVodById(id);
|
Vod vod = getVodById(id);
|
||||||
|
|
||||||
@@ -83,6 +108,14 @@ public class VodService {
|
|||||||
return vodRepository.saveAndFlush(vod);
|
return vodRepository.saveAndFlush(vod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a VoD and its associated files from disk.
|
||||||
|
*
|
||||||
|
* @param id the ID of the VoD to delete
|
||||||
|
* @return {@code true} on success; always throws rather than returning {@code false}
|
||||||
|
* @throws VodNotFound if no VoD with {@code id} exists
|
||||||
|
* @throws NotAuthenticated if the current user does not own the VoD
|
||||||
|
*/
|
||||||
public boolean deleteVod(Long id) {
|
public boolean deleteVod(Long id) {
|
||||||
Vod vod = getVodById(id);
|
Vod vod = getVodById(id);
|
||||||
|
|
||||||
@@ -93,6 +126,14 @@ public class VodService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a streamable resource for the VoD's video file.
|
||||||
|
*
|
||||||
|
* @param id the ID of the VoD to download
|
||||||
|
* @return a {@link Resource} pointing to the VoD's video file on disk
|
||||||
|
* @throws VodNotFound if no VoD with {@code id} exists, or the video file is missing on disk
|
||||||
|
* @throws NotAuthenticated if the current user does not own the VoD
|
||||||
|
*/
|
||||||
public Resource downloadVod(Long id) {
|
public Resource downloadVod(Long id) {
|
||||||
Vod vod = getVodById(id);
|
Vod vod = getVodById(id);
|
||||||
Path file = directoryService.resolvePath(vod.getVideoPath());
|
Path file = directoryService.resolvePath(vod.getVideoPath());
|
||||||
@@ -104,6 +145,14 @@ public class VodService {
|
|||||||
return new FileSystemResource(file);
|
return new FileSystemResource(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a streamable resource for the VoD's thumbnail image.
|
||||||
|
*
|
||||||
|
* @param id the ID of the VoD whose thumbnail to download
|
||||||
|
* @return a {@link Resource} pointing to the thumbnail file on disk
|
||||||
|
* @throws VodNotFound if no VoD with {@code id} exists, or the thumbnail file is missing on disk
|
||||||
|
* @throws NotAuthenticated if the current user does not own the VoD
|
||||||
|
*/
|
||||||
public Resource downloadThumbnail(Long id) {
|
public Resource downloadThumbnail(Long id) {
|
||||||
Vod vod = getVodById(id);
|
Vod vod = getVodById(id);
|
||||||
Path file = directoryService.resolvePath(vod.getThumbnailPath());
|
Path file = directoryService.resolvePath(vod.getThumbnailPath());
|
||||||
@@ -115,6 +164,22 @@ public class VodService {
|
|||||||
return new FileSystemResource(file);
|
return new FileSystemResource(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a processed VoD file into permanent storage, generates its thumbnail, and saves
|
||||||
|
* the VoD record to the database.
|
||||||
|
* <p>
|
||||||
|
* Thumbnail generation failure is non-fatal — the error is logged and the VoD is saved
|
||||||
|
* without a thumbnail rather than aborting.
|
||||||
|
*
|
||||||
|
* @param title title to assign to the VoD
|
||||||
|
* @param description description to assign to the VoD
|
||||||
|
* @param user owner of the VoD
|
||||||
|
* @param vodFile path to the processed video file to copy into permanent storage
|
||||||
|
* @param fileName filename used for both the permanent video file and the thumbnail
|
||||||
|
* (thumbnail is stored as {@code fileName + ".png"})
|
||||||
|
* @throws StorageException if copying the file to the VoDs directory fails
|
||||||
|
* @throws FFMPEGException if reading video metadata from the copied file fails
|
||||||
|
*/
|
||||||
public void persist(String title,
|
public void persist(String title,
|
||||||
String description,
|
String description,
|
||||||
User user,
|
User user,
|
||||||
|
|||||||
Reference in New Issue
Block a user