/** * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ * * Copyright (c) 2014 BigBlueButton Inc. and by respective authors (see below). * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software * Foundation; either version 3.0 of the License, or (at your option) any later * version. * * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * */ package org.bigbluebutton.presentation.imp; import java.io.File; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import org.bigbluebutton.presentation.SupportedFileTypes; import org.bigbluebutton.presentation.ThumbnailCreator; import org.bigbluebutton.presentation.UploadedPresentation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ThumbnailCreatorImp implements ThumbnailCreator { private static Logger log = LoggerFactory .getLogger(ThumbnailCreatorImp.class); private static final Pattern PAGE_NUMBER_PATTERN = Pattern .compile("(.+-thumb)-([0-9]+)(.png)"); private String IMAGEMAGICK_DIR; private String BLANK_THUMBNAIL; private static String TEMP_THUMB_NAME = "temp-thumb"; public boolean createThumbnails(UploadedPresentation pres) { boolean success = false; File thumbsDir = determineThumbnailDirectory(pres.getUploadedFile()); if (!thumbsDir.exists()) thumbsDir.mkdir(); cleanDirectory(thumbsDir); try { success = generateThumbnails(thumbsDir, pres); } catch (InterruptedException e) { log.warn("Interrupted Exception while generating thumbnails."); success = false; } // Create blank thumbnails for pages that failed to generate a thumbnail. createBlankThumbnails(thumbsDir, pres.getNumberOfPages()); renameThumbnails(thumbsDir); return success; } private boolean generateThumbnails(File thumbsDir, UploadedPresentation pres) throws InterruptedException { String source = pres.getUploadedFile().getAbsolutePath(); String dest; String COMMAND = ""; dest = thumbsDir.getAbsolutePath() + File.separator + TEMP_THUMB_NAME; if (SupportedFileTypes.isImageFile(pres.getFileType())) { COMMAND = IMAGEMAGICK_DIR + File.separator + "convert -thumbnail 150x150 " + source + " " + dest + ".png"; } else { COMMAND = "pdftocairo -png -scale-to 150 " + source + " " + dest; } boolean done = new ExternalProcessExecutor().exec(COMMAND, 60000); if (done) { return true; } else { log.warn("Failed to create thumbnails: " + COMMAND); } return false; } private File determineThumbnailDirectory(File presentationFile) { return new File( presentationFile.getParent() + File.separatorChar + "thumbnails"); } private void renameThumbnails(File dir) { /* * If more than 1 file, filename like 'temp-thumb-X.png' else filename is * 'temp-thumb.png' */ if (dir.list().length > 1) { File[] files = dir.listFiles(); Matcher matcher; for (int i = 0; i < files.length; i++) { matcher = PAGE_NUMBER_PATTERN.matcher(files[i].getAbsolutePath()); if (matcher.matches()) { // Path should be something like // 'c:/temp/bigluebutton/presname/thumbnails/temp-thumb-1.png' // Extract the page number. There should be 4 matches. // 0. c:/temp/bigluebutton/presname/thumbnails/temp-thumb-1.png // 1. c:/temp/bigluebutton/presname/thumbnails/temp-thumb // 2. 1 ---> what we are interested in // 3. .png // We are interested in the second match. int pageNum = Integer.valueOf(matcher.group(2).trim()).intValue(); String newFilename = "thumb-" + (pageNum) + ".png"; File renamedFile = new File( dir.getAbsolutePath() + File.separator + newFilename); files[i].renameTo(renamedFile); } } } else if (dir.list().length == 1) { File oldFilename = new File( dir.getAbsolutePath() + File.separator + dir.list()[0]); String newFilename = "thumb-1.png"; File renamedFile = new File( oldFilename.getParent() + File.separator + newFilename); oldFilename.renameTo(renamedFile); } } private void createBlankThumbnails(File thumbsDir, int pageCount) { File[] thumbs = thumbsDir.listFiles(); if (thumbs.length != pageCount) { for (int i = 0; i < pageCount; i++) { File thumb = new File(thumbsDir.getAbsolutePath() + File.separator + TEMP_THUMB_NAME + "-" + i + ".png"); if (!thumb.exists()) { log.info("Copying blank thumbnail for slide " + i); copyBlankThumbnail(thumb); } } } } private void copyBlankThumbnail(File thumb) { try { FileUtils.copyFile(new File(BLANK_THUMBNAIL), thumb); } catch (IOException e) { log.error("IOException while copying blank thumbnail."); } } private void cleanDirectory(File directory) { File[] files = directory.listFiles(); for (int i = 0; i < files.length; i++) { files[i].delete(); } } public void setImageMagickDir(String imageMagickDir) { IMAGEMAGICK_DIR = imageMagickDir; } public void setBlankThumbnail(String blankThumbnail) { BLANK_THUMBNAIL = blankThumbnail; } }