From 366f1f7e691f13f60ae668e0f3128c3856dd5748 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Thu, 21 Sep 2023 20:49:24 -0500 Subject: [PATCH] Externalized thumbnail generation from controller; added insert to db --- .gitignore | 1 + .../api/ThumbnailApiApplication.java | 2 + .../controller/ThumbnailerApiController.java | 69 ++++-------------- .../itdominator/api/entities/Thumbnails.java | 10 +++ .../api/repositories/ThumbnailRepository.java | 1 + .../api/services/ThumbnailerService.java | 6 ++ .../com/itdominator/api/util/Thumbnailer.java | 67 +++++++++++++++++ src/main/resources/static/db/database.db | Bin 16384 -> 0 bytes 8 files changed, 102 insertions(+), 54 deletions(-) create mode 100644 src/main/java/com/itdominator/api/util/Thumbnailer.java delete mode 100644 src/main/resources/static/db/database.db diff --git a/.gitignore b/.gitignore index ffdf11c..b68f4ee 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Compiled class file *.class .vscode +database.db # Log file *.log diff --git a/src/main/java/com/itdominator/api/ThumbnailApiApplication.java b/src/main/java/com/itdominator/api/ThumbnailApiApplication.java index 013d9fa..dfc8653 100644 --- a/src/main/java/com/itdominator/api/ThumbnailApiApplication.java +++ b/src/main/java/com/itdominator/api/ThumbnailApiApplication.java @@ -2,10 +2,12 @@ package com.itdominator.api; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @SpringBootApplication +@ComponentScan("com.itdominator.api") @Configuration public class ThumbnailApiApplication { diff --git a/src/main/java/com/itdominator/api/controller/ThumbnailerApiController.java b/src/main/java/com/itdominator/api/controller/ThumbnailerApiController.java index aa46ba2..c033aa6 100644 --- a/src/main/java/com/itdominator/api/controller/ThumbnailerApiController.java +++ b/src/main/java/com/itdominator/api/controller/ThumbnailerApiController.java @@ -2,16 +2,13 @@ package com.itdominator.api.controller; import java.io.IOException; -import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.codec.digest.DigestUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.validation.annotation.Validated; @@ -23,7 +20,9 @@ import org.springframework.web.bind.annotation.RestController; import com.itdominator.api.dto.ThumbnailDto; import com.itdominator.api.dto.ThumbnailSearchCriteria; +import com.itdominator.api.entities.Thumbnails; import com.itdominator.api.services.ThumbnailerService; +import com.itdominator.api.util.Thumbnailer; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; @@ -43,9 +42,7 @@ import lombok.extern.slf4j.Slf4j; public class ThumbnailerApiController { private final ThumbnailerService thumbnailerService; - - @Value("${videos.filter}") - private final String[] videoFilter; + private final Thumbnailer thumbnailer; @PreAuthorize("hasRole('User')") @@ -83,60 +80,24 @@ public class ThumbnailerApiController { @PreAuthorize("hasRole('User')") @GetMapping("/temp-videos-list-test") - public Set getAllVideoFiles() { - Set paths = collectVideoFilePaths("/home/abaddon/Downloads"); + public Set getAllVideoFiles() throws IOException { + Set paths = thumbnailer.collectVideoFilePaths("/home/abaddon/Downloads"); Set files = new HashSet<>(); - generateThumbnails(paths); + thumbnailer.generateThumbnails(paths); for (Path path : paths) { - files.add( path.getFileName().toString() ); + String fileName = path.getFileName().toString(); + String fileHash = DigestUtils.sha256Hex(fileName); + + // files.add( path.getFileName().toString() ); + files.add( path.toString() ); + + thumbnailerService.saveThumbnail( + new Thumbnails(fileName, fileHash, Files.readAllBytes( Path.of("/tmp/" + fileHash + ".jpg") ) ) + ); } return files; } - - public Set collectVideoFilePaths(final String dir) { - Set paths = new HashSet<>(); - - try (DirectoryStream stream = Files.newDirectoryStream( Paths.get(dir) )) { - for (Path path : stream) { - if ( !Files.isDirectory(path) ) { - String target = path.getFileName().toString(); - for (String filterItem : videoFilter) { - if ( target.endsWith(filterItem) ) { - paths.add(path); - } - } - } - } - } catch (IOException e) { - log.debug("Invalid path given to scan..."); - } - - return paths; - } - - public void generateThumbnails(Set paths) { - for (Path path : paths) { - String fileName = path.getFileName().toString(); - String fileHash = DigestUtils.sha256Hex(fileName); - generateThumbnail(path.toString(), "/home/abaddon/Downloads/tmp/" + fileHash + ".jpg","65%"); - } - } - - - - // proc = subprocess.Popen([self.FFMPG_THUMBNLR, "-t", scrub_percent, "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_path]) - public void generateThumbnail(final String full_path, final String hash_img_path, final String scrub_percent) { - try { - ProcessBuilder pb = new ProcessBuilder("ffmpegthumbnailer", "-t", scrub_percent, "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_path); - Process p = pb.start(); - } catch (Exception e) { - log.debug("Thumbnail couldn't be generated..."); - // Note: Need supporting logic for failed loads. Maybe return empty byte[] - } - - } - } diff --git a/src/main/java/com/itdominator/api/entities/Thumbnails.java b/src/main/java/com/itdominator/api/entities/Thumbnails.java index e15062d..2afef2f 100644 --- a/src/main/java/com/itdominator/api/entities/Thumbnails.java +++ b/src/main/java/com/itdominator/api/entities/Thumbnails.java @@ -5,6 +5,8 @@ import java.io.Serializable; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.validation.constraints.Pattern; @@ -24,6 +26,7 @@ public class Thumbnails implements Serializable { @Id @Column(name = "id", nullable = false) @EqualsAndHashCode.Include + @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "file_name", nullable = false) @@ -35,4 +38,11 @@ public class Thumbnails implements Serializable { @Column(name = "image", columnDefinition="BLOB NOT NULL") private byte[] image; + + public Thumbnails(String fileName, String fileHash, byte[] image) { + this.fileName = fileName; + this.fileHash = fileHash; + this.image = image; + } + } diff --git a/src/main/java/com/itdominator/api/repositories/ThumbnailRepository.java b/src/main/java/com/itdominator/api/repositories/ThumbnailRepository.java index 1160700..8251dcf 100644 --- a/src/main/java/com/itdominator/api/repositories/ThumbnailRepository.java +++ b/src/main/java/com/itdominator/api/repositories/ThumbnailRepository.java @@ -24,4 +24,5 @@ public interface ThumbnailRepository extends JpaRepository collectVideoFilePaths(final String dir) throws IOException { + Set paths = new HashSet<>(); + + DirectoryStream stream = Files.newDirectoryStream( Paths.get(dir) ); + for (Path path : stream) { + if ( !Files.isDirectory(path) ) { + String target = path.getFileName().toString(); + for (String filterItem : videoFilter) { + if ( target.endsWith(filterItem) ) { + paths.add(path); + } + } + } + } + + return paths; + } + + public void generateThumbnails(Set paths) throws IOException { + for (Path path : paths) { + String fileName = path.getFileName().toString(); + String fileHash = DigestUtils.sha256Hex(fileName); + generateThumbnail(path.toString(), "/tmp/" + fileHash + ".jpg","65%"); + } + } + + // proc = subprocess.Popen([self.FFMPG_THUMBNLR, "-t", scrub_percent, "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_path]) + private void generateThumbnail(final String full_path, final String hash_img_path, final String scrub_percent) throws IOException { + ProcessBuilder pb = new ProcessBuilder("ffmpegthumbnailer", "-t", scrub_percent, "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_path); + Process p = pb.start(); + while (p.isAlive()) { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/resources/static/db/database.db b/src/main/resources/static/db/database.db deleted file mode 100644 index 62cd3a2752fb2a6ac5f7621feb704f35a494e72b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%&uYRj90%~!ikpIeZo*EnCq)?yUto0vDXXn^Da=!;Gisr&xK`M8dy>7&-e{*C zmx`{N8+!ox2GS(_^7qqTLhmMKkP5n3KSq8^`=mh>g5ViJ7YVY+oSs+0G0uX=z1Rwwb2tWV=5P$##ehG}#QnTAtrl~&*MY0LyWz|c> zW-H={<7V;3VLE4&>jRU~qrUCfk3>(7>^xh_S+mtrUY5H#)73Vb#eNVbd9CncCM^$W zv|TA{!CWgF7H31|P|N1ja!r%EmN9WzPlgvkD7*vs;?L4f&c^{009U< q00Izz00bZa0SN2_@c$nl0t6rc0SG_<0uX=z1Rwwb2teTU1wH`{U3LNh