- refactor presentation service

- generate blank slide or thumbnail if conversion fails for that page
- if the resulting swf file is greater than 500K, generate a SWF file using a PNG snapshot to make resulting SWF file smaller. This helps to improve performance when rendering the slide on the client

Config Changes:
/etc/nginx/sites-available/bigbluebutton
 - set client_max_body_size       20m; // Allow 20Mb file upload
 
- put blank slide and thumbnail in /var/bigbluebutton/blank (see bigbluebutton.properties)

git-svn-id: http://bigbluebutton.googlecode.com/svn/trunk@2356 af16638f-c34d-0410-8cfa-b39d5352b314
This commit is contained in:
Richard Alam 2009-09-02 19:42:10 +00:00
parent 1f660af841
commit 4cc227cd99
26 changed files with 16733 additions and 508 deletions

View File

@ -9,7 +9,9 @@ swfToolsDir=/bin
imageMagickDir=/usr/bin
presentationDir=/var/bigbluebutton
ghostScriptExec=/usr/bin/gs
BLANK_SLIDE = /var/bigbluebutton/blank/blank-slide.swf
BLANK_THUMBNAIL = /var/bigbluebutton/blank/blank-thumb.png
beans.presentationService.swfToolsDir=${swfToolsDir}
beans.presentationService.imageMagickDir=${imageMagickDir}
beans.presentationService.presentationDir=${presentationDir}
@ -20,7 +22,7 @@ beans.presentationService.ghostScriptExec=${ghostScriptExec}
#
# This URL needs to reference the host running the tomcat server
bigbluebutton.web.serverURL=http://localhost
bigbluebutton.web.serverURL=http://192.168.0.182
# This is a workaround for a problem converting PDF files, referenced at
# http://groups.google.com/group/comp.lang.postscript/browse_thread/thread/c2e264ca76534ce0?pli=1

View File

@ -1,5 +1,5 @@
/*
* BigBlueButton - http://www.bigbluebutton.org
/* BigBlueButton - http://www.bigbluebutton.org
*
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
@ -84,7 +84,16 @@ class PublicScheduledSessionController {
}
def signIn = {
def signIn = {
if (params.fullname.trim() == "") {
log.debug "USer entered a blank name"
flash.message = "Please enter your name."
render(view:"joinIn", model: [id:params.id, fullname:params.fullname])
return
} else {
log.debug "Fullname is not null ${params.fullname}"
}
log.debug "Attempting to sign in to ${params.id}"
def conference = Conference.findByConferenceNumber(params.id)
def signedIn = false
@ -166,72 +175,7 @@ class PublicScheduledSessionController {
render(view:"joinIn",model: [id:params.id, fullname:params.fullname])
}
}
def signIn2 = {
println 'signIn start'
def confSession = ScheduledSession.findByTokenId(params.id)
def role = ''
def signedIn = false
if (confSession) {
println 'signIn: has conference session'
println 'Found scheduled session'
switch (params.password) {
case confSession.hostPassword:
println 'as host'
// Let us set role to MODERATOR for now as we don't support HOST yet
role = "MODERATOR"
signedIn = true
break
case confSession.moderatorPassword:
println 'as moderator'
role = "MODERATOR"
signedIn = true
break
case confSession.attendeePassword:
println 'as viewer'
role = "VIEWER"
signedIn = true
break
}
if (signedIn) {
println 'successful'
session["fullname"] = params.fullname
session["role"] = role
session["conference"] = params.id
session["room"] = confSession.sessionId
session["voicebridge"] = confSession.voiceConferenceBridge
}
def long _10_MINUTES = 10*60*1000
def now = new Date().time
def startTime = confSession.startDateTime.time - _10_MINUTES
def endTime = confSession.endDateTime.time + _10_MINUTES
if ((startTime <= now) && (now <= endTime)) {
session["mode"] = "LIVE"
session["record"] = false
if (confSession.record) {
session["record"] = true
}
} else {
session["mode"] = "PLAYBACK"
}
println 'rendering signIn'
redirect(action:show)
}
if (!signedIn) {
println 'failed'
flash.message = "Failed to join the conference session."
redirect(action:joinIn,id:params.id, params:[fullname:params.fullname])
}
}
def enter = {
def fname = session["fullname"]
def rl = session["role"]
@ -247,7 +191,7 @@ class PublicScheduledSessionController {
xml {
render(contentType:"text/xml") {
'join'() {
returnCode("FAILED")
returncode("FAILED")
message("Could not find conference ${params.conference}.")
}
}
@ -277,8 +221,11 @@ class PublicScheduledSessionController {
def signOut = {
// Log the user out of the application.
session.invalidate()
def config = ConfigurationHolder.config
def hostURL = config.bigbluebutton.web.serverURL
println "serverURL $hostURL"
// For now, redirect back to the home page.
redirect(uri: '/')
redirect(url: hostURL)
}
}

View File

@ -26,7 +26,11 @@ import javax.jms.MapMessage
import org.springframework.jms.core.JmsTemplate
import java.util.*;
import java.util.concurrent.*;
import java.lang.InterruptedException
import java.lang.InterruptedException
import org.springframework.util.FileCopyUtils
import org.bigbluebutton.presentation.*
class PresentationService {
boolean transactional = false
@ -35,6 +39,8 @@ class PresentationService {
def ghostScriptExec
def swfToolsDir
def presentationDir
def BLANK_SLIDE = '/var/bigbluebutton/blank/blank-slide.swf'
def BLANK_THUMBNAIL = '/var/bigbluebutton/blank/blank-thumb.png'
/*
* This is a workaround for this problem.
@ -101,55 +107,15 @@ class PresentationService {
new Timer().runAfter(1000)
{
//first we need to know how many pages in this pdf
log.debug "Determining number of pages"
int numPages = determineNumberOfPages(presentationFile)
log.debug "Determining number of pages"
PageCounter pageCounter = new Pdf2SwfPageCounter()
pageCounter.setSwfToolsDir(swfToolsDir)
int numPages = pageCounter.countNumberOfPages(presentationFile)
log.info "There are $numPages pages in $presentationFile.absolutePath"
convertUploadedPresentation(room, presentationName, presentationFile, numPages)
}
}
public int determineNumberOfPages(File presentationFile) {
def numPages = -1 //total numbers of this pdf, also used as errorcode(-1)
try
{
def command = swfToolsDir + "/pdf2swf -I " + presentationFile.getAbsolutePath()
log.debug "Executing with waitFor $command"
def p = Runtime.getRuntime().exec(command);
def stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
def stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
def info
def str //output information to console for stdInput and stdError
while ((info = stdInput.readLine()) != null) {
//The output would be something like this 'page=21 width=718.00 height=538.00'.
//We need to extract the page number (i.e. 21) from it.
def infoRegExp = /page=([0-9]+)(?: .+)/
def matcher = (info =~ infoRegExp)
if (matcher.matches()) {
numPages = matcher[0][1]
} else {
println "no match info: ${info}"
}
}
while ((info = stdError.readLine()) != null) {
System.out.println("Got error getting info from file):\n");
System.out.println(str);
}
stdInput.close();
stdError.close();
//if(p.exitValue() != 0) return -1;
// Wait for the process to finish.
int exitVal = p.waitFor()
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
}
return new Integer(numPages).intValue()
}
def showSlide(String conf, String room, String presentationName, String id) {
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "slide-${id}.swf")
@ -193,8 +159,12 @@ class PresentationService {
convertPage(presentationFile, page)
}
log.debug "Creating thumbnails for $presentationFile.absolutePath"
createThumbnails(presentationFile)
log.debug "Creating thumbnails for $presentationFile.absolutePath"
ThumbnailCreatorImp tc = new ThumbnailCreatorImp()
tc.imageMagickDir = imageMagickDir
tc.blankThumbnail = BLANK_THUMBNAIL
tc.createThumbnails(presentationFile, numPages)
def msg = new HashMap()
msg.put("room", room)
@ -207,198 +177,69 @@ class PresentationService {
sendJmsMessage(msg)
}
public boolean convertPage(File presentationFile, int page) {
if (! convertUsingPdf2Swf(presentationFile, page)) {
log.info "cannot convert page $page"
if (extractPageUsingGhostScript(presentationFile, page)) {
log.info "created using ghostscript page $page"
if (convertUsingImageMagick(presentationFile, page)) {
log.info "created using imagemagick page $page"
if (convertUsingJpeg2Swf(presentationFile, page)) {
log.info "create using jpeg page $page"
return true
}
}
}
public boolean convertPage(File presentationFile, int page) {
PageConverter converter = new Pdf2SwfPageConverter()
converter.setSwfToolsDir(swfToolsDir)
File output = new File(presentationFile.getParent() + File.separatorChar + "slide-" + page + ".swf")
if (! converter.convert(presentationFile, output, page)) {
log.info "cannot create ${output.absolutePath}"
println "cannot create ${output.absolutePath}"
convertPageAsAnImage(presentationFile, output, page)
} else {
println "The size of the swf file is " + output.size()
// If the resulting swf file is greater than 500K, it probably contains a lot of objects
// that it becomes very slow to render on the client. Take an image snapshot instead and
// use it to generate the SWF file. (ralam Sept 2, 2009)
if (output.size() > 500000) {
convertPageAsAnImage(presentationFile, output, page)
}
}
return false
// If all fails, generate a blank slide.
if (! output.exists()) {
println "Creating balnk slide for ${output.absolutePath}"
generateBlankSlide(output.getAbsolutePath())
}
return true
}
private boolean convertPageAsAnImage(File presentationFile, File output, int page) {
PageExtractor extractor = new GhostscriptPageExtractor()
extractor.setGhostscriptExec(ghostScriptExec)
extractor.setNoPdfMarkWorkaround(noPdfMarkWorkaround)
def tempDir = new File(presentationFile.parent + File.separatorChar + "temp")
tempDir.mkdir()
File tempPdfFile = new File(tempDir.absolutePath + File.separator + "temp-${page}.pdf")
if (extractor.extractPage(presentationFile, tempPdfFile, page)) {
log.info "created using ghostscript ${tempPdfFile.absolutePath}"
println "created using ghostscript ${tempPdfFile.absolutePath}"
File tempPngFile = new File(tempDir.getAbsolutePath() + "/temp-${page}.png")
PageConverter imConverter = new ImageMagickPageConverter()
imConverter.setImageMagickDir(imageMagickDir)
if (imConverter.convert(tempPdfFile, tempPngFile, 1)) {
log.info "created using imagemagick ${tempPngFile.absolutePath}"
println "created using imagemagick ${tempPngFile.absolutePath}"
PageConverter pngConverter = new Png2SwfPageConverter()
pngConverter.setSwfToolsDir(swfToolsDir)
if (pngConverter.convert(tempPngFile, output, 1)) {
log.info "converted ${tempPngFile.absolutePath} to ${output.absolutePath} "
println "converted ${tempPngFile.absolutePath} to ${output.absolutePath}"
}
}
}
}
public boolean extractPageUsingGhostScript(File presentationFile, int page) {
def tempDir = new File(presentationFile.parent + File.separatorChar + "temp")
tempDir.mkdir()
String OPTIONS = "-sDEVICE=pdfwrite -dNOPAUSE -dQUIET -dBATCH"
String PAGE = "-dFirstPage=${page} -dLastPage=${page}"
String dest = tempDir.absolutePath + File.separator + "temp-${page}.pdf"
//extract that specific page and create a temp-pdf(only one page) with GhostScript
def command = ghostScriptExec + " " + OPTIONS + " " + PAGE + " " + "-sOutputFile=${dest}" + " " + noPdfMarkWorkaround + " " + presentationFile
log.debug "Executing $command"
def process
try {
def now = new Date()
println "GS starting $now"
process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitVal = process.waitFor()
now = new Date()
println "GS starting $now"
def stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
def stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
def str
while ((str = stdInput.readLine()) != null) {
System.out.println(str);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((str = stdError.readLine()) != null) {
System.out.println(str);
}
stdInput.close();
stdError.close();
} catch (InterruptedException e) {
System.out.println(e.toString());
}
if (process.exitValue() == 0) {
return true
} else {
return false
}
}
public boolean convertUsingJpeg2Swf(File presentationFile, int page) {
def tempDir = new File(presentationFile.getParent() + File.separatorChar + "temp")
def source = tempDir.absolutePath + File.separator + "temp-${page}.jpeg"
def dest = presentationFile.parent + File.separatorChar + "slide-${page}.swf"
println "converting $source to $dest"
def now = new Date()
println "JPEG2SWF starting $now"
def command = swfToolsDir + "/jpeg2swf -o " + dest + " " + source
log.debug "Executing $command"
def process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitValue = process.waitFor()
now = new Date()
println "JPEG2SWF ended $now"
def stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
def stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
def str
while ((str = stdInput.readLine()) != null) {
System.out.println(str);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((str = stdError.readLine()) != null) {
System.out.println(str);
}
stdInput.close();
stdError.close();
File destFile = new File(dest)
if (destFile.exists()) return true
return false
}
public boolean convertUsingImageMagick(File presentationFile, int page) {
def tempDir = new File(presentationFile.getParent() + File.separatorChar + "temp")
tempDir.mkdir()
def source = tempDir.getAbsolutePath() + "/temp-${page}.pdf"
def dest = tempDir.getAbsolutePath() + "/temp-${page}.jpeg"
def now = new Date()
println "IMAGEMAGICK starting $now"
def command = imageMagickDir + "/convert " + source + " " + dest
log.debug "Executing $command"
def process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitValue = process.waitFor()
now = new Date()
println "IMAGEMAGICK ends $now"
File destFile = new File(dest)
if (destFile.exists()) return true
return false
}
public boolean convertUsingPdf2Swf(File presentationFile, int page) {
def source = presentationFile.getAbsolutePath()
def dest = presentationFile.parent + File.separatorChar + "slide-" + page + ".swf"
def command = swfToolsDir + "/pdf2swf -p " + page + " " + source + " -o " + dest
log.debug "Executing $command"
def process = Runtime.getRuntime().exec(command)
// Wait for the process to finish
int exitValue = process.waitFor()
File destFile = new File(dest)
if (destFile.exists()) return true
return false
}
public boolean createThumbnails(File presentationFile) {
try {
log.debug "Creating thumbnails:"
def thumbsDir = new File(presentationFile.getParent() + File.separatorChar + "thumbnails")
thumbsDir.mkdir()
def source = presentationFile.getAbsolutePath()
def dest = thumbsDir.getAbsolutePath() + "/temp-thumb.png"
def command = imageMagickDir + "/convert -thumbnail 150x150 " + source + " " + dest
log.debug "Executing $command"
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor()
renameThumbnails(thumbsDir)
if (exitValue == 0) return true
return false
}
catch (InterruptedException e) {
log.error "exception happened - here's what I know: "
log.error e.printStackTrace()
return false
}
}
private renameThumbnails(File dir) {
dir.eachFile{file ->
// filename should be something like 'c:/temp/bigluebutton/presname/thumbnails/temp-thumb-1.png'
def filename = file.absolutePath
// Extract the page number. There should be 3 matches.
// 1. c:/temp/bigluebutton/presname/thumbnails/temp-thumb
// 2. 1 ---> what we are interested in
// 3. .png
def infoRegExp = /(.+-thumb)-([0-9]+)(.png)/
def matcher = (filename =~ infoRegExp)
if (matcher.matches()) {
// We are interested in the second match.
int pageNum = new Integer(matcher[0][2]).intValue()
def newFilename = "thumb-${++pageNum}.png"
File renamedFile = new File(file.parent + File.separator + newFilename)
file.renameTo(renamedFile)
}
}
private void generateBlankSlide(String dest) {
File slide = new File(dest);
FileCopyUtils.copy(new File(BLANK_SLIDE), slide);
}
private sendJmsMessage(HashMap message) {

View File

@ -0,0 +1,47 @@
package org.bigbluebutton.presentation
public class GhostscriptPageExtractor implements PageExtractor{
private String GHOSTSCRIPT_EXEC
private String noPdfMarkWorkaround
public boolean extractPage(File presentationFile, File output, int page){
String OPTIONS = "-sDEVICE=pdfwrite -dNOPAUSE -dQUIET -dBATCH"
String PAGE = "-dFirstPage=${page} -dLastPage=${page}"
String dest = output.getAbsolutePath()
//extract that specific page and create a temp-pdf(only one page) with GhostScript
def command = GHOSTSCRIPT_EXEC + " " + OPTIONS + " " + PAGE + " " + "-sOutputFile=${dest}" + " " + noPdfMarkWorkaround + " " + presentationFile
println "Executing $command"
def process
int exitVal = -1
try {
process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
exitVal = process.waitFor()
} catch (InterruptedException e) {
System.out.println(e.toString());
}
if (exitVal == 0) {
return true
} else {
return false
}
}
public void setGhostscriptExec(String exec) {
GHOSTSCRIPT_EXEC = exec
}
public void setNoPdfMarkWorkaround(String noPdfMarkWorkaround) {
this.noPdfMarkWorkaround = noPdfMarkWorkaround
}
}

View File

@ -0,0 +1,30 @@
package org.bigbluebutton.presentation
public class ImageMagickPageConverter implements PageConverter{
private String IMAGEMAGICK_DIR
public boolean convert(File presentationFile, File output, int page){
def now = new Date()
println "IMAGEMAGICK starting $now"
def command = IMAGEMAGICK_DIR + "/convert -depth 8 " + presentationFile.getAbsolutePath() + " " + output.getAbsolutePath()
println "Executing $command"
def process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitValue = process.waitFor()
now = new Date()
println "IMAGEMAGICK ends $now"
if (output.exists()) return true
return false
}
public void setImageMagickDir(String dir) {
IMAGEMAGICK_DIR = dir
}
}

View File

@ -0,0 +1,31 @@
package org.bigbluebutton.presentation
public class Jpeg2SwfPageConverter implements PageConverter{
private String SWFTOOLS_DIR
public boolean convert(File presentationFile, File output, int page){
def now = new Date()
println "JPEG2SWF starting $now"
def command = SWFTOOLS_DIR + "/jpeg2swf -o " + output.getAbsolutePath() + " " + presentationFile.getAbsolutePath()
println "Executing $command"
def process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitValue = process.waitFor()
now = new Date()
println "JPEG2SWF ended $now"
if (output.exists()) return true
return false
}
public void setSwfToolsDir(String dir) {
SWFTOOLS_DIR = dir
}
}

View File

@ -0,0 +1,8 @@
package org.bigbluebutton.presentation;
import java.io.File;
public interface PageConverter {
public boolean convert(File presentation, File output, int page);
}

View File

@ -0,0 +1,8 @@
package org.bigbluebutton.presentation;
import java.io.File;
public interface PageCounter {
public int countNumberOfPages(File presentation);
}

View File

@ -0,0 +1,8 @@
package org.bigbluebutton.presentation;
import java.io.File;
public interface PageExtractor {
public boolean extractPage(File presentationFile, File output, int page);
}

View File

@ -0,0 +1,58 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
public class Pdf2SwfPageConverter implements PageConverter {
private String SWFTOOLS_DIR;
private String blankSlide;
public boolean convert(File presentation, File output, int page) {
String source = presentation.getAbsolutePath();
//String dest = presentation.getParent() + File.separatorChar + "slide-" + page + ".swf";
String dest = output.getAbsolutePath()
String command = SWFTOOLS_DIR + File.separator + "pdf2swf -p " + page + " " + source + " -o " + dest;
System.out.println("Executing $command");
Process process;
int exitValue = -1;
try {
process = Runtime.getRuntime().exec(command);
// Wait for the process to finish
exitValue = process.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// if (exitValue != 0) {
// generateBlankSlide(dest);
// }
File destFile = new File(dest);
if (destFile.exists()) return true;
return false;
}
public void generateBlankSlide(String dest) {
File slide = new File(dest);
FileCopyUtils.copy(new File(blankSlide), slide);
}
public void setSwfToolsDir(String dir) {
SWFTOOLS_DIR = dir;
}
public void setBlankSlide(String slide) {
blankSlide = slide;
}
}

View File

@ -0,0 +1,54 @@
package org.bigbluebutton.presentation
public class Pdf2SwfPageCounter implements PageCounter{
private String SWFTOOLS_DIR
public int countNumberOfPages(File presentationFile){
def numPages = -1 //total numbers of this pdf, also used as errorcode(-1)
try
{
def command = SWFTOOLS_DIR + "/pdf2swf -I " + presentationFile.getAbsolutePath()
println "Executing with waitFor $command"
def p = Runtime.getRuntime().exec(command);
def stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
def stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
def info
def str //output information to console for stdInput and stdError
while ((info = stdInput.readLine()) != null) {
//The output would be something like this 'page=21 width=718.00 height=538.00'.
//We need to extract the page number (i.e. 21) from it.
def infoRegExp = /page=([0-9]+)(?: .+)/
def matcher = (info =~ infoRegExp)
if (matcher.matches()) {
numPages = matcher[0][1]
} else {
println "no match info: ${info}"
}
}
while ((info = stdError.readLine()) != null) {
System.out.println("Got error getting info from file):\n");
System.out.println(str);
}
stdInput.close();
stdError.close();
// Wait for the process to finish.
int exitVal = p.waitFor()
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
}
return new Integer(numPages).intValue()
}
public void setSwfToolsDir(String dir) {
SWFTOOLS_DIR = dir;
}
}

View File

@ -0,0 +1,31 @@
package org.bigbluebutton.presentation
public class Png2SwfPageConverter implements PageConverter{
private String SWFTOOLS_DIR
public boolean convert(File presentationFile, File output, int page){
def now = new Date()
println "PNG2SWF starting $now"
def command = SWFTOOLS_DIR + "/png2swf -o " + output.getAbsolutePath() + " " + presentationFile.getAbsolutePath()
println "Executing $command"
def process = Runtime.getRuntime().exec(command);
// Wait for the process to finish.
int exitValue = process.waitFor()
now = new Date()
println "PNG2SWF ended $now"
if (output.exists()) return true
return false
}
public void setSwfToolsDir(String dir) {
SWFTOOLS_DIR = dir
}
}

View File

@ -0,0 +1,27 @@
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.presentation;
import java.io.File;
public interface ThumbnailCreator {
public boolean createThumbnails(File presentationFile, int pageCount);
}

View File

@ -0,0 +1,124 @@
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
public class ThumbnailCreatorImp implements ThumbnailCreator {
String imageMagickDir
String blankThumbnail
private static String TEMP_THUMB_NAME = "temp-thumb"
public boolean createThumbnails(File presentationFile, int pageCount){
boolean success = false
File thumbsDir = determineThumbnailDirectory(presentationFile)
if (! thumbsDir.exists())
thumbsDir.mkdir()
cleanDirectory(thumbsDir)
try {
success = generateThumbnails(thumbsDir, presentationFile)
}
catch (InterruptedException e) {
println "exception happened - here's what I know: "
println e.printStackTrace()
success = false
}
if (! success) createBlankThumbnails(thumbsDir, pageCount)
renameThumbnails(thumbsDir)
return true
}
private def generateThumbnails(File thumbsDir, File presentationFile) throws InterruptedException {
println "Creating thumbnails:"
def source = presentationFile.getAbsolutePath()
def dest = thumbsDir.getAbsolutePath() + "/${TEMP_THUMB_NAME}.png"
def command = imageMagickDir + "/convert -thumbnail 150x150 " + source + " " + dest
println "Executing $command"
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor()
if (exitValue == 0) return true
return false
}
private File determineThumbnailDirectory(File presentationFile) {
return new File(presentationFile.getParent() + File.separatorChar + "thumbnails")
}
private def renameThumbnails(File dir) {
dir.eachFile{ file ->
// filename should be something like 'c:/temp/bigluebutton/presname/thumbnails/temp-thumb-1.png'
def filename = file.absolutePath
// Extract the page number. There should be 3 matches.
// 1. c:/temp/bigluebutton/presname/thumbnails/temp-thumb
// 2. 1 ---> what we are interested in
// 3. .png
def infoRegExp = /(.+-thumb)-([0-9]+)(.png)/
def matcher = (filename =~ infoRegExp)
if (matcher.matches()) {
// We are interested in the second match.
int pageNum = new Integer(matcher[0][2]).intValue()
println "Renaming thumnail ${pageNum}"
def newFilename = "thumb-${++pageNum}.png"
File renamedFile = new File(file.parent + File.separator + newFilename)
file.renameTo(renamedFile)
}
}
}
def createBlankThumbnails(File thumbsDir, int pageCount) {
println "Creating blank thumbnail"
File[] thumbs = thumbsDir.listFiles();
if (thumbs.length != pageCount) {
for (int i = 0; i < pageCount; i++) {
File thumb = new File(thumbsDir.absolutePath + File.separator + "${TEMP_THUMB_NAME}-${i}.png")
if (! thumb.exists()) {
copyBlankThumbnail(thumb);
}
}
}
}
private void copyBlankThumbnail(File thumb) {
FileCopyUtils.copy(new File(blankThumbnail), thumb)
}
private def cleanDirectory = {directory ->
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
files[i].delete()
}
}
}

View File

@ -0,0 +1,24 @@
package org.bigbluebutton.presentation
final class Util{
static def deleteDirectory(File directory) {
/**
* Go through each directory and check if it's not empty.
* We need to delete files inside a directory before a
* directory can be deleted.
**/
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i])
} else {
files[i].delete()
}
}
// Now that the directory is empty. Delete it.
directory.delete()
}
}

View File

@ -3,6 +3,8 @@ package org.bigbluebutton.web.services
import org.springframework.util.FileCopyUtils
import org.codehaus.groovy.grails.commons.*
import groovy.mock.interceptor.StubFor
class PresentationServiceTests extends GroovyTestCase {
def SWFTOOLS = "C:/swftools-0.9"
@ -11,7 +13,7 @@ class PresentationServiceTests extends GroovyTestCase {
def PRESENTATIONDIR = "c:/temp/bigbluebutton"
def presService
void setUp() {
/* Get the values from bigbluebutton.properties
* We have to set this manually unlike when running
@ -31,6 +33,7 @@ class PresentationServiceTests extends GroovyTestCase {
presService.presentationDir = PRESENTATIONDIR
presService.noPdfMarkWorkaround = config.noPdfMarkWorkaround
presService.jmsTemplate = new FakeJmsTemplate()
}
void testGetUploadDirectory() {
@ -47,8 +50,7 @@ class PresentationServiceTests extends GroovyTestCase {
assertTrue(uploadedPresentation.exists())
}
void testGetNumberOfPagesForPresentation() {
//def uploadedFilename = 'sample-presentation.pdf'
void testPresentationThatShouldConvertSuccessfully() {
def uploadedFilename = 'PresentationsTips.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
@ -58,212 +60,95 @@ class PresentationServiceTests extends GroovyTestCase {
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
//assertEquals 21, numPages
}
/*
void testConvertUsingPdf2Swf() {
def uploadedFilename = 'sample-presentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "test-presentation"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 8, numPages
for (int page = 1; page <= numPages; page++) {
presService.convertUsingPdf2Swf(uploadedPresentation, page)
}
presService.convertUploadedPresentation(rm, presName, uploadedPresentation, 21)
int numPages = presService.numberOfThumbnails(conf, rm, presName)
assertEquals 21, numPages
}
void testExtractPageUsingGhostscript() {
def uploadedFilename = 'sample-presentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "test-presentation"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 8, numPages
for (int page = 1; page <= numPages; page++) {
def result = presService.extractPageUsingGhostScript(uploadedPresentation, page)
assertTrue result
}
File tempdir = new File(uploadedPresentation.parent + File.separator + "temp")
FilenameFilter filter = new PdfFilter();
String[] files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
def result = presService.convertUsingImageMagick(uploadedPresentation, page)
assertTrue result
}
filter = new JpegFilter();
files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
def result = presService.convertUsingJpeg2Swf(uploadedPresentation, page)
assertTrue result
}
File outDir = new File(uploadedPresentation.parent)
filter = new SwfFilter();
files = outDir.list(filter)
assertEquals numPages, files.length
}
void testProcessOneSlideWithTooManyObjectsPresentation() {
void testProcessOneSlideWithTooManyObjectsPresentation() {
def uploadedFilename = 'big.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "big"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 1, numPages
for (int page = 1; page <= numPages; page++) {
presService.extractPageUsingGhostScript(uploadedPresentation, page)
}
File tempdir = new File(uploadedPresentation.parent + File.separator + "temp")
FilenameFilter filter = new PdfFilter();
String[] files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
presService.convertUsingImageMagick(uploadedPresentation, page)
}
filter = new JpegFilter();
files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
presService.convertUsingJpeg2Swf(uploadedPresentation, page)
}
File outDir = new File(uploadedPresentation.parent)
filter = new SwfFilter();
files = outDir.list(filter)
assertEquals numPages, files.length
}
void testProcessSeveralSlidesWithTooManyObjectsPresentation() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "severalbig"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 5, numPages
for (int page = 1; page <= numPages; page++) {
presService.extractPageUsingGhostScript(uploadedPresentation, page)
}
File tempdir = new File(uploadedPresentation.parent + File.separator + "temp")
FilenameFilter filter = new PdfFilter();
String[] files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
presService.convertUsingImageMagick(uploadedPresentation, page)
}
filter = new JpegFilter();
files = tempdir.list(filter)
assertEquals numPages, files.length
for (int page = 1; page <= numPages; page++) {
presService.convertUsingJpeg2Swf(uploadedPresentation, page)
}
File outDir = new File(uploadedPresentation.parent)
filter = new SwfFilter();
files = outDir.list(filter)
assertEquals numPages, files.length
}
void testConvertPage() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "convertpage"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 5, numPages
for (int page = 1; page <= numPages; page++) {
presService.convertPage(uploadedPresentation, page)
}
File outDir = new File(uploadedPresentation.parent)
FilenameFilter filter = new SwfFilter();
String[] files = outDir.list(filter)
assertEquals numPages, files.length
}
void testCreateThumbnails() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = presService.determineNumberOfPages(uploadedPresentation)
assertEquals 5, numPages
presService.createThumbnails(uploadedPresentation)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
// File outDir = new File(uploadedPresentation.parent)
// FilenameFilter filter = new SwfFilter();
// String[] files = outDir.list(filter)
// assertEquals numPages, files.length
}
*/
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
presService.convertUploadedPresentation(rm, presName, uploadedPresentation, 1)
int numPages = presService.numberOfThumbnails(conf, rm, presName)
assertEquals 1, numPages
}
void testProcessSeveralSlidesWithTooManyObjectsPresentation() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "severalbig"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
presService.convertUploadedPresentation(rm, presName, uploadedPresentation, 5)
int numPages = presService.numberOfThumbnails(conf, rm, presName)
assertEquals 5, numPages
}
void testProcessSlidesWithNoAvailableFontsPresentation() {
def uploadedFilename = 'CaratulasManualesNutrisol.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "caratulas"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
presService.convertUploadedPresentation(rm, presName, uploadedPresentation, 2)
int numPages = presService.numberOfThumbnails(conf, rm, presName)
assertEquals 2, numPages
}
void testUseJpegWhenPresentationHasLotOfObjects() {
def uploadedFilename = 'big-lots-of-objects.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "big-lots-of-objects"
File uploadDir = presService.uploadedPresentationDirectory(conf, rm, presName)
def uploadedPresentation = new File(uploadDir.absolutePath + File.separator + uploadedFilename)
uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
presService.convertUploadedPresentation(rm, presName, uploadedPresentation, 2)
int numPages = presService.numberOfThumbnails(conf, rm, presName)
assertEquals 2, numPages
}
}
/*** Helper classes **/
@ -286,3 +171,8 @@ class SwfFilter implements FilenameFilter {
return (name.endsWith(".swf"));
}
}
/* Stub for JmsTemplate */
class FakeJmsTemplate {
def convertAndSend(String queue, Map message) { /* do nothing */}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,52 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class GhostscriptPageExtractorTests extends GroovyTestCase {
def pageExtractor
def GS_EXEC = '/usr/bin/gs'
static final String PRESENTATIONDIR = '/var/bigbluebutton'
def noPdfMarkWorkaround = "/etc/bigbluebutton/nopdfmark.ps"
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def presDir
void setUp() {
println "Test setup"
pageExtractor = new GhostscriptPageExtractor()
pageExtractor.setGhostscriptExec(GS_EXEC)
pageExtractor.setNoPdfMarkWorkaround(noPdfMarkWorkaround)
presDir = new File("$PRESENTATIONDIR/$conf/$rm/$presName")
if (presDir.exists()) Util.deleteDirectory(presDir)
presDir.mkdirs()
}
void testExtractPage() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File(presDir.absolutePath + "/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
def tempDir = new File(uploadedPresentation.parent + File.separatorChar + "temp")
tempDir.mkdir()
int page = 1
File outFile = new File(tempDir.absolutePath + File.separator + "temp-${page}.pdf")
boolean success = pageExtractor.extractPage(uploadedPresentation, outFile, page)
assertTrue success
page = 3
outFile = new File(tempDir.absolutePath + File.separator + "temp-${page}.pdf")
success = pageExtractor.extractPage(uploadedPresentation, outFile, page)
assertTrue success
}
}

View File

@ -0,0 +1,45 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class ImageMagickPageConverterTests extends GroovyTestCase {
def pageConverter
def IMAGEMAGICK_DIR = '/usr/bin'
static final String PRESENTATIONDIR = '/var/bigbluebutton'
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def presDir
void setUp() {
println "Test setup"
pageConverter = new ImageMagickPageConverter()
pageConverter.setImageMagickDir(IMAGEMAGICK_DIR)
presDir = new File("$PRESENTATIONDIR/$conf/$rm/$presName")
if (presDir.exists()) Util.deleteDirectory(presDir)
presDir.mkdirs()
}
void testConvertSuccess() {
def uploadedFilename = 'big.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File(presDir.absolutePath + "/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
def tempDir = new File(uploadedPresentation.getParent() + File.separatorChar + "temp")
tempDir.mkdir()
int page = 1
File outFile = new File(tempDir.getAbsolutePath() + "/temp-${page}.jpeg")
boolean success = pageConverter.convert(uploadedPresentation, outFile, page)
assertTrue success
}
}

View File

@ -0,0 +1,43 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class Jpeg2SwfPageConverterTests extends GroovyTestCase {
def pageConverter
def SWFTOOLS_DIR = '/bin'
def BLANK_SLIDE = '/var/bigbluebutton/blank/blank-slide.swf'
static final String PRESENTATIONDIR = '/var/bigbluebutton'
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def presDir
void setUp() {
println "Test setup"
pageConverter = new Jpeg2SwfPageConverter()
pageConverter.setSwfToolsDir(SWFTOOLS_DIR)
presDir = new File("$PRESENTATIONDIR/$conf/$rm/$presName")
if (presDir.exists()) Util.deleteDirectory(presDir)
presDir.mkdirs()
}
void testConvertSlidesSuccessfully() {
def uploadedFilename = 'sampleslide.jpeg'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int page = 1
File output = new File(uploadedPresentation.getParent() + File.separatorChar + "slide-" + page + ".swf")
boolean success = pageConverter.convert(uploadedPresentation, output, page)
assertTrue success
}
}

View File

@ -0,0 +1,66 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class Pdf2SwfPageConverterTests extends GroovyTestCase {
def pageConverter
def SWFTOOLS_DIR = '/bin'
def BLANK_SLIDE = '/var/bigbluebutton/blank/blank-slide.swf'
static final String PRESENTATIONDIR = '/var/bigbluebutton'
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def presDir
void setUp() {
println "Test setup"
pageConverter = new Pdf2SwfPageConverter()
pageConverter.setSwfToolsDir(SWFTOOLS_DIR)
pageConverter.setBlankSlide(BLANK_SLIDE)
presDir = new File("$PRESENTATIONDIR/$conf/$rm/$presName")
if (presDir.exists()) Util.deleteDirectory(presDir)
presDir.mkdirs()
}
void testConvertSlidesSuccessfully() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int page = 1
File output = new File(uploadedPresentation.getParent() + File.separatorChar + "slide-" + page + ".swf")
boolean success = pageConverter.convert(uploadedPresentation, output, page)
assertTrue success
page = 3
output = new File(uploadedPresentation.getParent() + File.separatorChar + "slide-" + page + ".swf")
success = pageConverter.convert(uploadedPresentation, output, page)
assertFalse success
}
void testConvertSlidesFail() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int page = 3
File output = new File(uploadedPresentation.getParent() + File.separatorChar + "slide-" + page + ".swf")
boolean success = pageConverter.convert(uploadedPresentation, output, page)
assertFalse success
}
void tearDown() {
}
}

View File

@ -0,0 +1,40 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class Pdf2SwfPageCounterTests extends GroovyTestCase {
def pageCounter
def SWFTOOLS_DIR = '/bin'
static final String PRESENTATIONDIR = '/var/bigbluebutton'
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def presDir
void setUp() {
println "Test setup"
pageCounter = new Pdf2SwfPageCounter()
pageCounter.setSwfToolsDir(SWFTOOLS_DIR)
presDir = new File("$PRESENTATIONDIR/$conf/$rm/$presName")
if (presDir.exists()) Util.deleteDirectory(presDir)
presDir.mkdirs()
}
void testCountPresentationPages() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def uploadedPresentation = new File(presDir.absolutePath + "/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
int numPages = pageCounter.countNumberOfPages(uploadedPresentation)
assertEquals 5, numPages
}
}

View File

@ -0,0 +1,60 @@
package org.bigbluebutton.presentation
import org.springframework.util.FileCopyUtils
class ThumbnailCreatorImpTests extends GroovyTestCase {
ThumbnailCreator tc
static final String IMAGEMAGICK_DIR = "/usr/bin"
static final String PRESENTATIONDIR = '/var/bigbluebutton'
static final String BLANK_THUMBNAIL = '/var/bigbluebutton/blank/blank-thumb.png'
void setUp() {
println "Test setup"
tc = new ThumbnailCreatorImp()
tc.imageMagickDir = IMAGEMAGICK_DIR
tc.blankThumbnail = BLANK_THUMBNAIL
}
void testCreateThumbnails() {
def uploadedFilename = 'SeveralBigPagesPresentation.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
boolean success = tc.createThumbnails(uploadedPresentation, 5)
assertTrue success
}
void testFailToCreateThumbnails() {
def uploadedFilename = 'Caratulas Manuales Nutrisol.pdf'
def uploadedFile = new File("test/resources/$uploadedFilename")
def conf = "test-conf"
def rm = "test-room"
def presName = "thumbs"
def uploadedPresentation = new File("$PRESENTATIONDIR/$conf/$rm/$presName/$uploadedFilename")
int copied = FileCopyUtils.copy(uploadedFile, uploadedPresentation)
assertTrue(uploadedPresentation.exists())
boolean success = tc.createThumbnails(uploadedPresentation, 2)
assertTrue success
}
void testCreateBlankThumbnails() {
tc.createBlankThumbnails(new File("/var/bigbluebutton/test-conf/test-room/thumbs/thumbnails"), 5)
}
void tearDown() {
println "Test Teardown"
}
}