diff --git a/gcc_manpower_uploads/workorderfiles/1011 WO.pdf b/gcc_manpower_uploads/workorderfiles/1011 WO.pdf deleted file mode 100644 index 4c8b015..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/1011 WO.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/485 - 2025 WO 1.pdf b/gcc_manpower_uploads/workorderfiles/485 - 2025 WO 1.pdf deleted file mode 100644 index d557987..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/485 - 2025 WO 1.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/618 Extension WO.pdf b/gcc_manpower_uploads/workorderfiles/618 Extension WO.pdf deleted file mode 100644 index dcde6d3..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/618 Extension WO.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C111802025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C111802025.pdf deleted file mode 100644 index 84a8bb8..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C111802025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C114642025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C114642025.pdf deleted file mode 100644 index 3caad02..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C114642025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C11702026.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C11702026.pdf deleted file mode 100644 index 5eefcb5..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C11702026.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12182025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12182025.pdf deleted file mode 100644 index 6b871c2..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12182025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C124102025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C124102025.pdf deleted file mode 100644 index 6631315..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C124102025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12472026.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12472026.pdf deleted file mode 100644 index 3ae7589..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12472026.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C126592025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C126592025.pdf deleted file mode 100644 index 60b0934..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C126592025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12852026.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12852026.pdf deleted file mode 100644 index 6321fb9..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C12852026.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C132302025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C132302025.pdf deleted file mode 100644 index a69e2ce..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C132302025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C136782025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C136782025.pdf deleted file mode 100644 index bd744cf..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C136782025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C137392025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C137392025.pdf deleted file mode 100644 index 7738601..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C137392025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C139982025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C139982025.pdf deleted file mode 100644 index 74128e9..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C139982025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C145902023.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C145902023.pdf deleted file mode 100644 index b997853..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C145902023.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C14852025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C14852025.pdf deleted file mode 100644 index 801b35c..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C14852025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C15962026.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C15962026.pdf deleted file mode 100644 index 8772f06..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C15962026.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C16182025.pdf b/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C16182025.pdf deleted file mode 100644 index 058043c..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/I.T.C.C.No.C16182025.pdf and /dev/null differ diff --git a/gcc_manpower_uploads/workorderfiles/WO (4).pdf b/gcc_manpower_uploads/workorderfiles/WO (4).pdf deleted file mode 100644 index 4394eba..0000000 Binary files a/gcc_manpower_uploads/workorderfiles/WO (4).pdf and /dev/null differ diff --git a/pom.xml b/pom.xml index c138ae2..4bd30e2 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ com.gcc_manpower - gcc-manpower + gccmanpower 0.0.1-SNAPSHOT @@ -58,6 +58,11 @@ mysql-connector-j runtime + + ws.schild + jave-all-deps + 3.5.0 + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/gcc_manpower/GccManpowerApplication.java b/src/main/java/com/gcc_manpower/GccManpowerApplication.java index b28ca68..4c2c360 100644 --- a/src/main/java/com/gcc_manpower/GccManpowerApplication.java +++ b/src/main/java/com/gcc_manpower/GccManpowerApplication.java @@ -2,8 +2,10 @@ package com.gcc_manpower; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication +@EnableAsync public class GccManpowerApplication { public static void main(String[] args) { diff --git a/src/main/java/com/gcc_manpower/config/DataSourceConfig.java b/src/main/java/com/gcc_manpower/config/DataSourceConfig.java index b79e83f..22ae13f 100644 --- a/src/main/java/com/gcc_manpower/config/DataSourceConfig.java +++ b/src/main/java/com/gcc_manpower/config/DataSourceConfig.java @@ -26,4 +26,14 @@ public class DataSourceConfig { dataSource.setPassword(dbpassword); return dataSource; } + + @Bean(name = "mysqlServiceDocumentsDataSource") + public DataSource mysqlServiceDocumentsDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gccservices_documents"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } } diff --git a/src/main/java/com/gcc_manpower/config/WebConfig.java b/src/main/java/com/gcc_manpower/config/WebConfig.java index 8961f1d..bd9a8b2 100644 --- a/src/main/java/com/gcc_manpower/config/WebConfig.java +++ b/src/main/java/com/gcc_manpower/config/WebConfig.java @@ -12,6 +12,9 @@ public class WebConfig implements WebMvcConfigurer { @Value("${upload.path:gcc_manpower_uploads}") private String uploadPathConfig; + @Value("${document.upload.path:gccservicedocuments}") + private String documentUploadPathConfig; + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Resolve absolute path (supports both relative and absolute paths) @@ -20,5 +23,10 @@ public class WebConfig implements WebMvcConfigurer { // Map URL path /gcc_manpower_uploads/** to the configured folder path registry.addResourceHandler("/gcc_manpower_uploads/**") .addResourceLocations(uploadPath); + + // Map URL path /gccservicedocuments/files/** to the configured document folder path + String docUploadPath = Paths.get(documentUploadPathConfig).toAbsolutePath().toUri().toString(); + registry.addResourceHandler("/gccservicedocuments/files/**") + .addResourceLocations(docUploadPath); } } diff --git a/src/main/java/com/gcc_manpower/controller/GccServiceDocumentController.java b/src/main/java/com/gcc_manpower/controller/GccServiceDocumentController.java new file mode 100644 index 0000000..480a006 --- /dev/null +++ b/src/main/java/com/gcc_manpower/controller/GccServiceDocumentController.java @@ -0,0 +1,192 @@ +package com.gcc_manpower.controller; + +import com.gcc_manpower.service.GccServiceDocumentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import jakarta.servlet.http.HttpSession; +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Controller +@RequestMapping("/gccservicedocuments") +public class GccServiceDocumentController { + + @Autowired + private GccServiceDocumentService documentService; + + @Autowired + private com.gcc_manpower.service.VideoCompressionService videoCompressionService; + + @Value("${document.upload.path:gccservicedocuments}") + private String documentUploadPathConfig; + + @GetMapping({ "", "/" }) + public String viewPortal(Model model, HttpSession session) { + // String usrName = (String) session.getAttribute("usrName"); + // String usrRole = (String) session.getAttribute("usrRole"); + + // boolean isLoggedIn = (usrName != null); + // boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); + + model.addAttribute("isLoggedIn", true); + model.addAttribute("isAdmin", true); + model.addAttribute("usrName", "Guest"); + model.addAttribute("curPage", "gccservicedocuments"); + + return "gccservicedocuments/upload"; + } + + @GetMapping("/view") + public String viewReportPage(Model model, HttpSession session) { + // String usrName = (String) session.getAttribute("usrName"); + // if (usrName == null) { + // return "redirect:/login"; + // } + // String usrRole = (String) session.getAttribute("usrRole"); + // boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); + + model.addAttribute("isLoggedIn", true); + model.addAttribute("isAdmin", true); + model.addAttribute("usrName", "Guest"); + model.addAttribute("curPage", "gccservicedocuments_upload"); + + return "gccservicedocuments/view"; + } + + @GetMapping("/api/list") + @ResponseBody + public List> listDocuments( + @RequestParam(value = "category", required = false) String category, + @RequestParam(value = "fromDate", required = false) String fromDate, + @RequestParam(value = "toDate", required = false) String toDate) { + return documentService.searchDocuments(category, fromDate, toDate); + } + + @GetMapping("/api/categories") + @ResponseBody + public List getCategories() { + return documentService.getAllCategories(); + } + + @GetMapping("/api/file-types") + @ResponseBody + public List> getFileTypes() { + return documentService.getAllFileTypes(); + } + + @PostMapping("/api/upload") + @ResponseBody + public Map uploadFile( + @RequestParam("title") String title, + @RequestParam("category") String category, + @RequestParam("fileType") String fileType, + @RequestParam("file") MultipartFile file, + HttpSession session) { + + Map response = new HashMap<>(); + // String usrName = (String) session.getAttribute("usrName"); + // if (usrName == null) { + // response.put("success", false); + // response.put("error", "Unauthorized access! Please log in."); + // return response; + // } + + if (file.isEmpty()) { + response.put("success", false); + response.put("error", "Please select a file to upload."); + return response; + } + + try { + // Clean category name for folder names (letters, numbers, underscores, dashes, + // spaces) + String cleanCategory = category.trim().replaceAll("[^a-zA-Z0-9-_ ]", "").trim(); + if (cleanCategory.isEmpty()) { + cleanCategory = "General"; + } + + // Build the folder directory path: [documentUploadPathConfig]/[cleanCategory]/ + File uploadDir = new File(documentUploadPathConfig, cleanCategory).getAbsoluteFile(); + if (!uploadDir.exists()) { + uploadDir.mkdirs(); + } + + // Generate unique filename to avoid overwrites + String originalFilename = file.getOriginalFilename(); + String nameWithoutExt = ""; + String ext = ""; + if (originalFilename != null && originalFilename.contains(".")) { + int dotIdx = originalFilename.lastIndexOf("."); + nameWithoutExt = originalFilename.substring(0, dotIdx); + ext = originalFilename.substring(dotIdx); + } else { + nameWithoutExt = originalFilename != null ? originalFilename : "file"; + } + + nameWithoutExt = nameWithoutExt.replaceAll("[^a-zA-Z0-9-_]", "_"); + String savedFilename = nameWithoutExt + "_" + System.currentTimeMillis() + ext; + + File destFile = new File(uploadDir, savedFilename).getAbsoluteFile(); + file.transferTo(destFile); + + // Save Web URL in database: + // "/gccservicedocuments/files/[category]/[savedFilename]" + String fileWebUrl = "/gccservicedocuments/files/" + cleanCategory + "/" + savedFilename; + + boolean saved = documentService.saveDocument( + title.trim(), + cleanCategory, + fileType, + fileWebUrl, + originalFilename); + + if (saved) { + if ("video".equalsIgnoreCase(fileType)) { + videoCompressionService.compressVideoAsync(destFile); + } + response.put("success", true); + response.put("message", "File uploaded and registered successfully."); + } else { + // Remove saved file on DB insert failure + destFile.delete(); + response.put("success", false); + response.put("error", "Failed to record document details in the database."); + } + + } catch (Exception e) { + response.put("success", false); + response.put("error", "File upload failed: " + e.getMessage()); + } + + return response; + } + + @PostMapping("/api/delete") + @ResponseBody + public Map deleteFile(@RequestParam("id") Long id, HttpSession session) { + Map response = new HashMap<>(); + // String usrName = (String) session.getAttribute("usrName"); + // if (usrName == null) { + // response.put("success", false); + // response.put("error", "Unauthorized access! Please log in."); + // return response; + // } + + boolean deleted = documentService.deleteDocument(id); + if (deleted) { + response.put("success", true); + response.put("message", "File record removed successfully."); + } else { + response.put("success", false); + response.put("error", "Failed to delete the file record."); + } + + return response; + } +} diff --git a/src/main/java/com/gcc_manpower/service/GccServiceDocumentService.java b/src/main/java/com/gcc_manpower/service/GccServiceDocumentService.java new file mode 100644 index 0000000..5cd622d --- /dev/null +++ b/src/main/java/com/gcc_manpower/service/GccServiceDocumentService.java @@ -0,0 +1,180 @@ +package com.gcc_manpower.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import javax.sql.DataSource; +import jakarta.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Service +public class GccServiceDocumentService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlServiceDocumentsDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private int getOrCreateCategory(String categoryName) { + // Try parsing as ID first + try { + int id = Integer.parseInt(categoryName.trim()); + String checkIdSql = "SELECT id FROM category_list WHERE id = ? AND is_delete = 0"; + List ids = jdbcTemplate.queryForList(checkIdSql, Integer.class, id); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (NumberFormatException e) { + // Not a number, fallback to name matching + } + + String selectSql = "SELECT id FROM category_list WHERE category_name = ? AND is_delete = 0"; + try { + List ids = jdbcTemplate.queryForList(selectSql, Integer.class, categoryName.trim()); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (Exception e) { + System.err.println("Error checking category: " + e.getMessage()); + } + + // Insert new category + String insertSql = "INSERT INTO category_list (category_name, is_active, is_delete) VALUES (?, 1, 0)"; + try { + jdbcTemplate.update(insertSql, categoryName.trim()); + // Fetch the generated ID + List ids = jdbcTemplate.queryForList(selectSql, Integer.class, categoryName.trim()); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (Exception e) { + System.err.println("Error creating category: " + e.getMessage()); + } + return 0; + } + + private int getOrCreateFileType(String fileTypeName) { + // Try parsing as ID first + try { + int id = Integer.parseInt(fileTypeName.trim()); + String checkIdSql = "SELECT id FROM upload_file_types WHERE id = ? AND is_delete = 0"; + List ids = jdbcTemplate.queryForList(checkIdSql, Integer.class, id); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (NumberFormatException e) { + // Not a number, fallback to name matching + } + + String selectSql = "SELECT id FROM upload_file_types WHERE file_type_name = ? AND is_delete = 0"; + try { + List ids = jdbcTemplate.queryForList(selectSql, Integer.class, fileTypeName.trim()); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (Exception e) { + System.err.println("Error checking file type: " + e.getMessage()); + } + + // Insert new file type + String insertSql = "INSERT INTO upload_file_types (file_type_name, is_active, is_delete) VALUES (?, 1, 0)"; + try { + jdbcTemplate.update(insertSql, fileTypeName.trim()); + // Fetch the generated ID + List ids = jdbcTemplate.queryForList(selectSql, Integer.class, fileTypeName.trim()); + if (!ids.isEmpty()) { + return ids.get(0); + } + } catch (Exception e) { + System.err.println("Error creating file type: " + e.getMessage()); + } + return 0; + } + + public boolean saveDocument(String title, String category, String fileType, String filePath, + String originalFilename) { + int categoryId = getOrCreateCategory(category); + int fileTypeId = getOrCreateFileType(fileType); + + String sql = "INSERT INTO documents_uploads (title, category, file_type, file_path, original_filename, is_active, is_delete) " + + + "VALUES (?, ?, ?, ?, ?, 1, 0)"; + try { + int rows = jdbcTemplate.update(sql, title, String.valueOf(categoryId), String.valueOf(fileTypeId), filePath, + originalFilename); + return rows > 0; + } catch (Exception e) { + System.err.println("Error saving service document: " + e.getMessage()); + return false; + } + } + + public List> searchDocuments(String category, String fromDate, String toDate) { + StringBuilder sql = new StringBuilder( + "SELECT d.id, d.title, c.category_name AS category, f.file_type_name AS file_type, d.file_path, d.original_filename, d.upload_date " + + + "FROM documents_uploads d " + + "LEFT JOIN category_list c ON d.category = c.id " + + "LEFT JOIN upload_file_types f ON d.file_type = f.id " + + "WHERE d.is_active = 1 AND d.is_delete = 0"); + List params = new ArrayList<>(); + + if (category != null && !category.trim().isEmpty()) { + sql.append(" AND c.category_name = ?"); + params.add(category.trim()); + } + if (fromDate != null && !fromDate.trim().isEmpty()) { + sql.append(" AND DATE(d.upload_date) >= ?"); + params.add(fromDate.trim()); + } + if (toDate != null && !toDate.trim().isEmpty()) { + sql.append(" AND DATE(d.upload_date) <= ?"); + params.add(toDate.trim()); + } + + sql.append(" ORDER BY d.category "); + + try { + return jdbcTemplate.queryForList(sql.toString(), params.toArray()); + } catch (Exception e) { + System.err.println("Error searching service documents: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public boolean deleteDocument(Long id) { + String sql = "UPDATE documents_uploads SET is_active = 0, is_delete = 1 WHERE id = ?"; + try { + int rows = jdbcTemplate.update(sql, id); + return rows > 0; + } catch (Exception e) { + System.err.println("Error deleting service document ID " + id + ": " + e.getMessage()); + return false; + } + } + + public List getAllCategories() { + String sql = "SELECT category_name FROM category_list WHERE is_active = 1 AND is_delete = 0 ORDER BY category_name"; + try { + return jdbcTemplate.queryForList(sql, String.class); + } catch (Exception e) { + System.err.println("Error fetching document categories: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public List> getAllFileTypes() { + String sql = "SELECT id, file_type_name FROM upload_file_types WHERE is_active = 1 AND is_delete = 0 ORDER BY file_type_name"; + try { + return jdbcTemplate.queryForList(sql); + } catch (Exception e) { + System.err.println("Error fetching file types: " + e.getMessage()); + return new ArrayList<>(); + } + } +} diff --git a/src/main/java/com/gcc_manpower/service/VideoCompressionService.java b/src/main/java/com/gcc_manpower/service/VideoCompressionService.java new file mode 100644 index 0000000..4bedec9 --- /dev/null +++ b/src/main/java/com/gcc_manpower/service/VideoCompressionService.java @@ -0,0 +1,98 @@ +package com.gcc_manpower.service; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import ws.schild.jave.Encoder; +import ws.schild.jave.MultimediaObject; +import ws.schild.jave.encode.AudioAttributes; +import ws.schild.jave.encode.EncodingAttributes; +import ws.schild.jave.encode.VideoAttributes; +import ws.schild.jave.info.AudioInfo; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Service +public class VideoCompressionService { + + private static final Logger LOGGER = Logger.getLogger(VideoCompressionService.class.getName()); + + @Async + public void compressVideoAsync(File originalFile) { + if (originalFile == null || !originalFile.exists() || !originalFile.isFile()) { + LOGGER.warning("Invalid file provided for compression."); + return; + } + + String originalPath = originalFile.getAbsolutePath(); + long originalSize = originalFile.length(); + LOGGER.info("Starting background video compression for file: " + originalPath + " (Size: " + (originalSize / (1024 * 1024)) + " MB)"); + + // Create a temporary file in the same directory for the compressed output + File tempFile = new File(originalFile.getParentFile(), "temp_" + System.currentTimeMillis() + "_" + originalFile.getName()); + + try { + // Read input file details + MultimediaObject mediaObject = new MultimediaObject(originalFile); + AudioInfo audioInfo = mediaObject.getInfo().getAudio(); + + // Set up video encoding attributes + VideoAttributes video = new VideoAttributes(); + video.setCodec("h264"); // Standard widely supported web codec + video.setBitRate(1500000); // Target 1.5 Mbps for compression + video.setFrameRate(24); + + EncodingAttributes attrs = new EncodingAttributes(); + attrs.setOutputFormat("mp4"); + attrs.setVideoAttributes(video); + + // Set up audio encoding attributes if audio stream exists + if (audioInfo != null) { + AudioAttributes audio = new AudioAttributes(); + audio.setCodec("aac"); + audio.setBitRate(128000); // Target 128 kbps audio + audio.setChannels(2); + audio.setSamplingRate(44100); + attrs.setAudioAttributes(audio); + } + + // Encode/Compress + Encoder encoder = new Encoder(); + encoder.encode(mediaObject, tempFile, attrs); + + // Replace original file with compressed file if successful + if (tempFile.exists() && tempFile.length() > 0) { + long compressedSize = tempFile.length(); + + // Delete original file + boolean deletedOriginal = originalFile.delete(); + if (!deletedOriginal) { + LOGGER.warning("Failed to delete the original uncompressed file. Trying to force replace."); + } + + // Rename temp file to original file name + boolean renamed = tempFile.renameTo(originalFile); + if (renamed) { + long sizeReduction = originalSize - compressedSize; + LOGGER.info("Compression complete! Saved to: " + originalPath); + LOGGER.info(String.format("File size reduced by %.2f%% (from %d MB to %d MB)", + ((double) sizeReduction / originalSize) * 100, + originalSize / (1024 * 1024), + compressedSize / (1024 * 1024))); + } else { + LOGGER.severe("Failed to rename temp compressed file to original filename: " + originalPath); + } + } else { + LOGGER.severe("Compression failed: Temp file was not created or is empty."); + } + + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Exception occurred during video compression for file: " + originalPath, e); + // Cleanup temp file in case of failure + if (tempFile.exists()) { + tempFile.delete(); + } + } + } +} diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 28ba0df..1544b26 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -34,4 +34,8 @@ logging.level.org.hibernate.type.descriptor.sql=TRACE server.servlet.context-path=/ # Disable Thymeleaf caching for hot-swapping templates -spring.thymeleaf.cache=false \ No newline at end of file +spring.thymeleaf.cache=false + +# Multipart File Upload Limits (supports large video files) +spring.servlet.multipart.max-file-size=300MB +spring.servlet.multipart.max-request-size=300MB \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index bdee885..3b26bd1 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -42,3 +42,7 @@ server.servlet.context-path=/gcc_manpower # Disable Thymeleaf caching for hot-swapping templates spring.thymeleaf.cache=false + +# Multipart File Upload Limits (supports large video files) +spring.servlet.multipart.max-file-size=300MB +spring.servlet.multipart.max-request-size=300MB diff --git a/src/main/resources/templates/fragments/documentsheader.html b/src/main/resources/templates/fragments/documentsheader.html new file mode 100644 index 0000000..b30b12d --- /dev/null +++ b/src/main/resources/templates/fragments/documentsheader.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + GREATER + CHENNAI + CORPORATION + பெருநகர சென்னை மாநகராட்சி + + + + GCC Training Material Services Details + + + \ No newline at end of file diff --git a/src/main/resources/templates/gccservicedocuments/upload.html b/src/main/resources/templates/gccservicedocuments/upload.html new file mode 100644 index 0000000..0895f39 --- /dev/null +++ b/src/main/resources/templates/gccservicedocuments/upload.html @@ -0,0 +1,637 @@ + + + + + + + GCC Documents Upload Portal + + + + + + + + + + + + + + + + + + + + + + + + + + + Upload Documents + + + + Back to View Report + + + + + + + + + + Document / Video Title * + + + + + + + File Type * + + - Select File Type - + + + + + Category * + + - Select Category - + + Add Custom Category... + + + + + + + + + + + Drag and drop file here or click to browse + Allowed documents: PDF, Word, Excel, TXT + + + + + + + + filename.pdf + (0 MB) + + + + + + + + + + Uploading file... + 0% + + + + + + + + + Start Upload + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/gccservicedocuments/view.html b/src/main/resources/templates/gccservicedocuments/view.html new file mode 100644 index 0000000..33a30f9 --- /dev/null +++ b/src/main/resources/templates/gccservicedocuments/view.html @@ -0,0 +1,1115 @@ + + + + + + + GCC Service Documents & Videos + + + + + + + + + + + + + + + + + + + + + + + + + Processing... + + + + + + + + + + Service Documents & Videos + + + + + Upload Documents + + + + + + + + + Search Documents + + + + + + Category + + - All Categories - + + + + + + From Date + + + + + + To Date + + + + + + Search + + + + + Reset + + + + + + + + + + + + + + + + + + Category: Category + + + + + + + + + + + + + + + + S.No + Title + File Type + Upload Date + Original Filename + Delete + Action + + + + + + + + + No matching files found for this category. + + + + + + + + + + + + Video Title + × + + + + + + + + + + + + + + + \ No newline at end of file
பெருநகர சென்னை மாநகராட்சி
Drag and drop file here or click to browse
Allowed documents: PDF, Word, Excel, TXT
No matching files found for this category.