Merge branch 'master' of github.com:bigbluebutton/bigbluebutton

This commit is contained in:
Fred Dixon 2012-07-24 15:46:59 -04:00
commit a78c23e496
15 changed files with 295 additions and 29 deletions

View File

@ -1,33 +1,33 @@
bbb.pageTitle =
bbb.mainshell.locale.version = 0.8
bbb.mainshell.statusProgress.connecting =
bbb.mainshell.statusProgress.connecting =सर्भरसंग सम्पर्क हुदै...
bbb.mainshell.statusProgress.loading =
bbb.mainshell.statusProgress.cannotConnectServer =
bbb.mainshell.statusProgress.cannotConnectServer =सर्भरसंग सम्पर्क हुन नसकेकोमा हामी क्षमाप्रार्थी छौ
bbb.mainshell.copyrightLabel2 =
bbb.mainshell.logBtn.toolTip =
bbb.mainshell.resetLayoutBtn.toolTip =
bbb.mainshell.resetLayoutBtn.toolTip = पुनः आकृति मिलाउनुहोस
bbb.oldlocalewindow.reminder1 =
bbb.oldlocalewindow.reminder2 =
bbb.oldlocalewindow.reminder2 = इन्टरनेट ब्राउजरको cache हटाउनुहोस
bbb.oldlocalewindow.windowTitle =
bbb.micSettings.playSound =
bbb.micSettings.hearFromHeadset =
bbb.micSettings.speakIntoMic =
bbb.micSettings.changeMic =
bbb.micSettings.join =
bbb.micSettings.cancel =
bbb.micSettings.playSound = ध्वनि(आवाज) परिक्षण गर्नुहोस
bbb.micSettings.hearFromHeadset = तपाइले कम्प्युटरबाट नभएर हेडफोनबाट आवाज सुन्नुपर्छ
bbb.micSettings.speakIntoMic =
bbb.micSettings.changeMic = माइक परिबर्तन गर्नुहोस
bbb.micSettings.join = माइक/स्पिकर जोड्नुहोस
bbb.micSettings.cancel = बन्द गर्नुहोस
bbb.mainToolbar.helpBtn = सहयोग
bbb.mainToolbar.logoutBtn =
bbb.mainToolbar.logoutBtn.toolTip =
bbb.mainToolbar.settingsBtn =
bbb.mainToolbar.settingsBtn.toolTip =
bbb.viewers.title =
bbb.mainToolbar.logoutBtn = बहिरिनुहोस
bbb.mainToolbar.logoutBtn.toolTip = बहिरिनुहोस
bbb.mainToolbar.settingsBtn = परिबर्तन गर्न वा मिलाउनको लागी(सेटिंग)
bbb.mainToolbar.settingsBtn.toolTip = सेटिंग खोल्नुहोस
bbb.viewers.title = प्रयोगकर्ता {0} {1}
bbb.viewers.viewersGrid.nameItemRenderer = नाम
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip =
bbb.viewers.viewersGrid.roleItemRenderer =
bbb.viewers.viewersGrid.statusItemRenderer =
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip =
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip =
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip =
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip = तपाई प्रयोगकर्ताको रूपमा भित्र छिर्नु भएको छ
bbb.viewers.viewersGrid.roleItemRenderer = भूमिका
bbb.viewers.viewersGrid.statusItemRenderer = अवस्था
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip == हात उठौनुहोस {0}
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip =हेर्नको लागि क्लिक गर्नुहोस
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip = प्रस्तुतकर्ता
bbb.viewers.presentBtn.toolTip =
bbb.viewers.raiseHandBtn.toolTip =
bbb.viewers.presentBtn.label =

View File

@ -96,10 +96,13 @@ package org.bigbluebutton.modules.present.business
for each(item in list){
var sUri:String = slideUri + "/" + item.@name;
var thumbUri:String = slideUri + "/" + item.@thumb;
var slide:Slide = new Slide(item.@number, sUri, thumbUri);
var txtUri:String = slideUri + "/" + item.@textfile;
var slide:Slide = new Slide(item.@number, sUri, thumbUri,txtUri);
_slides.add(slide);
//LogUtil.debug("Available slide: " + sUri + " number = " + item.@number);
//LogUtil.debug("Available thumb: " + thumbUri);
LogUtil.debug("Available textfile: " + txtUri);
}
//LogUtil.debug("number of slide=" + _slides.size());

View File

@ -34,14 +34,15 @@ package org.bigbluebutton.modules.present.managers
private var _slideHandler:Function;
private var _slideNum:Number;
private var _thumbUri:String;
private var _txtUri:String;
public function Slide(slideNum:Number, slideUri:String, thumbUri:String)
public function Slide(slideNum:Number, slideUri:String, thumbUri:String,txtUri:String)
{
_slideNum = slideNum;
_slideUri = slideUri;
_thumbUri = thumbUri;
_txtUri = txtUri;
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, handleComplete);
_loader.dataFormat = URLLoaderDataFormat.BINARY;

View File

@ -5,3 +5,4 @@ lib
web-app/demo/bbb_api_conf.jsp
target
plugins/*
.classpath.old

View File

@ -43,6 +43,14 @@ class UrlMappings {
"/presentation/$conference/$room/$presentation_name/thumbnail/$id"(controller:"presentation") {
action = [GET:'showThumbnail']
}
"/presentation/$conference/$room/$presentation_name/textfiles"(controller:"presentation") {
action = [GET:'numberOfTextfiles']
}
"/presentation/$conference/$room/$presentation_name/textfile/$id"(controller:"presentation") {
action = [GET:'showTextfile']
}
"/$controller/$action?/$id?"{
constraints {

View File

@ -56,6 +56,10 @@
<property name="blankThumbnail" value="${BLANK_THUMBNAIL}"/>
</bean>
<bean id="textFileCreator" class="org.bigbluebutton.presentation.imp.TextFileCreatorImp">
<property name="imageMagickDir" value="${imageMagickDir}"/>
</bean>
<bean id="generatedSlidesInfoHelper" class="org.bigbluebutton.presentation.GeneratedSlidesInfoHelperImp"/>
<bean id="pdfToSwfSlidesGenerationService" class="org.bigbluebutton.presentation.imp.PdfToSwfSlidesGenerationService">
@ -63,6 +67,7 @@
<property name="pageConverter" ref="pdf2SwfPageConverter"/>
<property name="pdfPageToImageConversionService" ref="imageConvSvc"/>
<property name="thumbnailCreator" ref="thumbCreator"/>
<property name="textFileCreator" ref="textFileCreator"/>
<property name="blankSlide" value="${BLANK_SLIDE}"/>
<property name="maxConversionTime" value="${maxConversionTime}"/>
<property name="swfSlidesGenerationProgressNotifier" ref="swfSlidesGenerationProgressNotifier"/>
@ -72,6 +77,7 @@
<property name="pngPageConverter" ref="png2SwfConverter"/>
<property name="jpgPageConverter" ref="jpg2SwfConverter"/>
<property name="thumbnailCreator" ref="thumbCreator"/>
<property name="textFileCreator" ref="textFileCreator"/>
<property name="blankSlide" value="${BLANK_SLIDE}"/>
<property name="maxConversionTime" value="${maxConversionTime}"/>
<property name="swfSlidesGenerationProgressNotifier" ref="swfSlidesGenerationProgressNotifier"/>

View File

@ -159,6 +159,33 @@ class PresentationController {
return null;
}
def showTextfile = {
def presentationName = params.presentation_name
def conf = params.conference
def rm = params.room
def textfile = params.id
println "Controller: Show thumbnails request for $presentationName $textfile"
InputStream is = null;
try {
def pres = presentationService.showTextfile(conf, rm, presentationName, textfile)
if (pres.exists()) {
println "Controller: Sending textfiles reply for $presentationName $textfile"
def bytes = pres.readBytes()
response.addHeader("Cache-Control", "no-cache")
response.contentType = 'plain/text'
response.outputStream << bytes;
} else {
println "$pres does not exist."
}
} catch (IOException e) {
println("Error reading file.\n" + e.getMessage());
}
return null;
}
def show = {
//def filename = params.id.replace('###', '.')
def filename = params.presentation_name
@ -214,7 +241,7 @@ class PresentationController {
presentation(name:presentationName) {
slides(count:numThumbs) {
for (def i = 1; i <= numThumbs; i++) {
slide(number:"${i}", name:"slide/${i}", thumb:"thumbnail/${i}")
slide(number:"${i}", name:"slide/${i}", thumb:"thumbnail/${i}", textfile:"textfile/${i}")
}
}
}
@ -245,6 +272,27 @@ class PresentationController {
}
}
def numberOfTextfiles = {
def filename = params.presentation_name
def f = confInfo()
def numFiles = presentationService.numberOfTextfiles(f.conference, f.room, filename)
withFormat {
xml {
render(contentType:"text/xml") {
conference(id:f.conference, room:f.room) {
presentation(name:filename) {
textfiles(count:numFiles) {
for (def i=0;i<numFiles;i++) {
textfile(name:"textfiles/${i}")
}
}
}
}
}
}
}
}
def confInfo = {
// Subject currentUser = SecurityUtils.getSubject()
// Session session = currentUser.getSession()

View File

@ -112,12 +112,27 @@ class PresentationService {
log.debug "showing $thumbFile"
new File(thumbFile)
}
def showTextfile = {conf, room, presentationName, textfile ->
println "Show textfiles request for $presentationName $textfile"
def txt = roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar +
"textfiles" + File.separatorChar + "slide-${textfile}.txt"
log.debug "showing $txt"
new File(txt)
}
def numberOfThumbnails = {conf, room, name ->
def thumbDir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "thumbnails")
thumbDir.listFiles().length
}
}
def numberOfTextfiles = {conf, room, name ->
log.debug roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "textfiles"
def textfilesDir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "textfiles")
textfilesDir.listFiles().length
}
def roomDirectory = {conf, room ->
return new File(presentationDir + File.separatorChar + conf + File.separatorChar + room)

View File

@ -34,5 +34,7 @@ public class ConversionMessageConstants {
public static final String GENERATED_SLIDE_KEY = "GENERATED_SLIDE";
public static final String GENERATING_THUMBNAIL_KEY = "GENERATING_THUMBNAIL";
public static final String GENERATED_THUMBNAIL_KEY = "GENERATED_THUMBNAIL";
public static final String GENERATING_TEXTFILES_KEY = "GENERATING_TEXTFILES";
public static final String GENERATED_TEXTFILES_KEY = "GENERATED_TEXTFILES";
public static final String CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED";
}

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/>.
*
* Author: Richard Alam <ritzalam@gmail.com>
* DJP <DJP@architectes.org>
*
* @version $Id: $
*/
package org.bigbluebutton.presentation;
public interface TextFileCreator {
public boolean createTextFiles(UploadedPresentation pres);
}

View File

@ -34,6 +34,7 @@ import java.util.concurrent.TimeoutException;
import org.bigbluebutton.presentation.PageConverter;
import org.bigbluebutton.presentation.ImageToSwfSlide;
import org.bigbluebutton.presentation.TextFileCreator;
import org.bigbluebutton.presentation.ThumbnailCreator;
import org.bigbluebutton.presentation.UploadedPresentation;
import org.slf4j.Logger;
@ -49,6 +50,7 @@ public class ImageToSwfSlidesGenerationService {
private PageConverter jpgToSwfConverter;
private PageConverter pngToSwfConverter;
private ThumbnailCreator thumbnailCreator;
private TextFileCreator textFileCreator;
private long MAX_CONVERSION_TIME = 5*60*1000;
private String BLANK_SLIDE;
@ -67,7 +69,8 @@ public class ImageToSwfSlidesGenerationService {
convertImageToSwf(pres, pageConverter);
}
/* adding accessibility */
createTextFiles(pres);
createThumbnails(pres);
notifier.sendConversionCompletedMessage(pres);
@ -82,6 +85,12 @@ public class ImageToSwfSlidesGenerationService {
return pngToSwfConverter;
}
private void createTextFiles(UploadedPresentation pres) {
log.debug("Creating textfiles for accessibility.");
notifier.sendCreatingTextFilesUpdateMessage(pres);
textFileCreator.createTextFiles(pres);
}
private void createThumbnails(UploadedPresentation pres) {
log.debug("Creating thumbnails.");
notifier.sendCreatingThumbnailsUpdateMessage(pres);
@ -167,6 +176,9 @@ public class ImageToSwfSlidesGenerationService {
public void setThumbnailCreator(ThumbnailCreator thumbnailCreator) {
this.thumbnailCreator = thumbnailCreator;
}
public void setTextFileCreator(TextFileCreator textFileCreator) {
this.textFileCreator = textFileCreator;
}
public void setMaxConversionTime(int minutes) {
MAX_CONVERSION_TIME = minutes * 60 * 1000;

View File

@ -39,6 +39,7 @@ import org.bigbluebutton.presentation.ConversionMessageConstants;
import org.bigbluebutton.presentation.ConversionUpdateMessage;
import org.bigbluebutton.presentation.PageConverter;
import org.bigbluebutton.presentation.PdfToSwfSlide;
import org.bigbluebutton.presentation.TextFileCreator;
import org.bigbluebutton.presentation.ThumbnailCreator;
import org.bigbluebutton.presentation.UploadedPresentation;
import org.bigbluebutton.presentation.ConversionUpdateMessage.MessageBuilder;
@ -53,6 +54,7 @@ public class PdfToSwfSlidesGenerationService {
private PageConverter pdfToSwfConverter;
private PdfPageToImageConversionService imageConvertService;
private ThumbnailCreator thumbnailCreator;
private TextFileCreator textFileCreator;
private long MAX_CONVERSION_TIME = 5*60*1000;
private String BLANK_SLIDE;
@ -62,6 +64,8 @@ public class PdfToSwfSlidesGenerationService {
log.debug("Determined number of pages " + pres.getNumberOfPages());
if (pres.getNumberOfPages() > 0) {
convertPdfToSwf(pres);
/* adding accessibility */
createTextFiles(pres);
createThumbnails(pres);
notifier.sendConversionCompletedMessage(pres);
}
@ -96,6 +100,12 @@ public class PdfToSwfSlidesGenerationService {
thumbnailCreator.createThumbnails(pres);
}
private void createTextFiles(UploadedPresentation pres) {
log.debug("Creating textfiles for accessibility.");
notifier.sendCreatingTextFilesUpdateMessage(pres);
textFileCreator.createTextFiles(pres);
}
private void convertPdfToSwf(UploadedPresentation pres) {
int numPages = pres.getNumberOfPages();
List<PdfToSwfSlide> slides = setupSlides(pres, numPages);
@ -189,6 +199,9 @@ public class PdfToSwfSlidesGenerationService {
public void setThumbnailCreator(ThumbnailCreator thumbnailCreator) {
this.thumbnailCreator = thumbnailCreator;
}
public void setTextFileCreator(TextFileCreator textFileCreator) {
this.textFileCreator = textFileCreator;
}
public void setMaxConversionTime(int minutes) {
MAX_CONVERSION_TIME = minutes * 60 * 1000;

View File

@ -95,4 +95,10 @@ public class SwfSlidesGenerationProgressNotifier {
public void setGeneratedSlidesInfoHelper(GeneratedSlidesInfoHelper helper) {
generatedSlidesInfoHelper = helper;
}
public void sendCreatingTextFilesUpdateMessage(UploadedPresentation pres) {
MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres);
builder.messageKey(ConversionMessageConstants.GENERATING_TEXTFILES_KEY);
notifyProgressListener(builder.build().getMessage());
}
}

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/>.
*
* Author: Richard Alam <ritzalam@gmail.com>
* DJP <DJP@architectes.org>
*
* @version $Id: $
*/
package org.bigbluebutton.presentation.imp;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import org.bigbluebutton.presentation.SupportedFileTypes;
import org.bigbluebutton.presentation.TextFileCreator;
import org.bigbluebutton.presentation.UploadedPresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextFileCreatorImp implements TextFileCreator {
private static Logger log = LoggerFactory.getLogger(TextFileCreatorImp.class);
private String IMAGEMAGICK_DIR;
@Override
public boolean createTextFiles(UploadedPresentation pres) {
boolean success = false;
File textfilesDir = determineTextfilesDirectory(pres.getUploadedFile());
if (! textfilesDir.exists())
textfilesDir.mkdir();
cleanDirectory(textfilesDir);
try {
success = generateTextFiles(textfilesDir, pres);
} catch (InterruptedException e) {
log.warn("Interrupted Exception while generating thumbnails.");
success = false;
}
//TODO: in case that it doesn't generated the textfile, we should create a textfile with some message
// createUnavailableTextFile
return success;
}
private boolean generateTextFiles(File textfilesDir, UploadedPresentation pres) throws InterruptedException {
boolean success = true;
String source = pres.getUploadedFile().getAbsolutePath();
String dest;
String COMMAND = "";
if(SupportedFileTypes.isImageFile(pres.getFileType())){
dest = textfilesDir.getAbsolutePath() + File.separator + "slide-1.txt";
String text = "No text could be retrieved for the slide";
File file = new File(dest);
Writer writer = null;
try {
writer = new BufferedWriter(new FileWriter(file));
writer.write(text);
} catch (IOException e) {
log.error("Error: " + e.getMessage());
success = false;
} finally {
try {
writer.close();
} catch (IOException e) {
log.error("Error: " + e.getMessage());
success = false;
}
}
}else{
dest = textfilesDir.getAbsolutePath() + File.separator + "slide-";
// sudo apt-get install xpdf-utils
for( int i=1; i<=pres.getNumberOfPages(); i++){
COMMAND = IMAGEMAGICK_DIR + "/pdftotext -raw -nopgbrk -f "+ i +" -l " + i + " " + source + " " + dest + i + ".txt";
boolean done = new ExternalProcessExecutor().exec(COMMAND, 60000);
if (!done) {
success = false;
log.warn("Failed to create textfiles: " + COMMAND);
break;
}
}
}
return success;
}
private File determineTextfilesDirectory(File presentationFile) {
return new File(presentationFile.getParent() + File.separatorChar + "textfiles");
}
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;
}
}

View File

@ -22,12 +22,12 @@ public class NullMessagingService implements MessagingService {
}
@Override
/*@Override
public void recordMeetingMetadata(String meetingId,
Map<String, String> metadata) {
// TODO Auto-generated method stub
}
}*/
@Override
public void endMeeting(String meetingId) {