From b6e31375961ef2a6a1dcce184eceb648912e322e Mon Sep 17 00:00:00 2001 From: alexandrekreis Date: Thu, 28 Nov 2013 11:16:52 -0200 Subject: [PATCH 1/4] refs #930 --- .../ConversionUpdatesMessageListener.java | 5 + .../presentation/PresentationApplication.java | 13 +- .../presentation/PresentationRoom.java | 39 +++- .../PresentationRoomsManager.java | 13 +- .../presentation/PresentationService.java | 22 +- .../locale/en_US/bbbResources.properties | 7 + .../present/business/FileUploadService.as | 10 +- .../modules/present/business/PresentProxy.as | 49 +++- .../present/business/PresentSOService.as | 44 +++- .../modules/present/events/DownloadEvent.as | 37 +++ .../modules/present/events/UploadEvent.as | 126 +++++----- .../present/managers/PresentManager.as | 78 +++++-- .../modules/present/maps/PresentEventMap.mxml | 21 ++ .../views/DownloadPresentationRenderer.mxml | 27 +++ .../present/ui/views/FileDownloadWindow.mxml | 89 +++++++ .../present/ui/views/FileUploadWindow.mxml | 26 ++- .../present/ui/views/PresentationWindow.mxml | 24 ++ .../grails-app/conf/UrlMappings.groovy | 4 + .../controllers/PresentationController.groovy | 46 +++- .../web/services/PresentationService.groovy | 217 ++++++++++-------- .../presentation/ConversionUpdateMessage.java | 7 + .../presentation/UploadedPresentation.java | 19 ++ 22 files changed, 724 insertions(+), 199 deletions(-) create mode 100755 bigbluebutton-client/src/org/bigbluebutton/modules/present/events/DownloadEvent.as mode change 100755 => 100644 bigbluebutton-client/src/org/bigbluebutton/modules/present/events/UploadEvent.as create mode 100755 bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml create mode 100755 bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java index 555336f993..87c231356e 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java @@ -89,6 +89,11 @@ public class ConversionUpdatesMessageListener { conversionUpdatesProcessor.process(message); } else if(messageKey.equalsIgnoreCase(CONVERSION_COMPLETED_KEY)){ + + String fileName = (String) mapMessage.get("fileName"); + message.put("fileName", fileName); + log.debug("Came the following file name: " + fileName); + String slidesInfo = (String) mapMessage.get("slidesInfo"); message.put("slidesInfo", StringEscapeUtils.unescapeXml(slidesInfo)); conversionUpdatesProcessor.process(message); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationApplication.java index cf6a62cfa7..d5eb8f26b2 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationApplication.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationApplication.java @@ -22,10 +22,11 @@ import org.slf4j.Logger; import org.bigbluebutton.conference.ClientMessage; import org.bigbluebutton.conference.ConnectionInvokerService; import org.red5.logging.Red5LoggerFactory; -import org.red5.server.api.Red5; import java.util.ArrayList; +import org.red5.server.api.Red5; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; - + public class PresentationApplication { private static Logger log = Red5LoggerFactory.getLogger( PresentationApplication.class, "bigbluebutton" ); @@ -75,6 +76,14 @@ public class PresentationApplication { log.warn("Getting presentations on a non-existant room " + room); return null; } + + public ArrayList getFileNamesToDownload(String room){ + if (roomsManager.hasRoom(room)){ + return roomsManager.getFileNamesToDownload(room); + } + log.warn("Getting file names on a non-existant room " + room); + return null; + } public void removePresentation(String room, String name){ if (roomsManager.hasRoom(room)){ diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoom.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoom.java index 8151040680..a2129c3f48 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoom.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoom.java @@ -22,8 +22,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.red5.logging.Red5LoggerFactory; -import net.jcip.annotations.ThreadSafe; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; +import net.jcip.annotations.ThreadSafe; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; /** @@ -49,6 +53,7 @@ public class PresentationRoom { Double yPercent = 0D; ArrayList presentationNames = new ArrayList(); + ArrayList fileNames = new ArrayList(); public PresentationRoom(String name) { this.name = name; @@ -81,6 +86,7 @@ public class PresentationRoom { } storePresentationNames(message); + storeFileNames(message); } @SuppressWarnings("unchecked") @@ -89,10 +95,19 @@ public class PresentationRoom { String messageKey = (String) message.get("messageKey"); if (messageKey.equalsIgnoreCase("CONVERSION_COMPLETED")) { - log.debug(messageKey + "[" + presentationName + "]"); + log.debug("adding presentation name: " + messageKey + "[" + presentationName + "]"); presentationNames.add(presentationName); } } + + + @SuppressWarnings("unchecked") + private void storeFileNames(Map message){ + String fileName = (String) message.get("fileName"); + if(!fileName.equals("")) { + fileNames.add(fileName); + } + } public void sendCursorUpdate(Double xPercent, Double yPercent) { this.xPercent = xPercent; @@ -178,7 +193,19 @@ public class PresentationRoom { if (currentPresentation.equals(presentationName)) { log.debug("[" + remPresentation + "] is the current presentation. Unsharing that presentation."); sharePresentation(presentationName, false); - } + } + + + //remove the corresponding file name + for(int i = 0 ; i < fileNames.size() ; i++) { + + String presentationNameFromFileName = fileNames.get(i).substring(0,fileNames.get(i).lastIndexOf('.')); + + if( presentationNameFromFileName.equals(presentationName) ) { + log.debug("Removing file name: " + fileNames.get(i)); + fileNames.remove(i); + } + } } public String getCurrentPresentation() { @@ -197,6 +224,10 @@ public class PresentationRoom { return presentationNames; } + public ArrayList getFileNamesToDownload() { + return fileNames; + } + public Double getxOffset() { return xOffset; } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoomsManager.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoomsManager.java index 5b3cb200e8..4554bbfb41 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoomsManager.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationRoomsManager.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.HashMap; import net.jcip.annotations.ThreadSafe; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentHashMap; /** * This encapsulates access to Room and messages. This class must be threadsafe. */ @@ -179,7 +179,16 @@ public class PresentationRoomsManager { if (r != null) { return r.getPresentationNames(); } - log.warn("Getting current presentation on a non-existing room " + room); + log.warn("Getting presentation names on a non-existing room " + room); + return null; + } + + public ArrayList getFileNamesToDownload(String room){ + PresentationRoom r = getRoom(room); + if (r != null) { + return r.getFileNamesToDownload(); + } + log.warn("Getting file names on a non-existing room " + room); return null; } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationService.java index 859d7b2e33..4b97a96e87 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/PresentationService.java @@ -17,11 +17,14 @@ * */ package org.bigbluebutton.conference.service.presentation; - import java.util.ArrayList; + +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; -import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.Red5; import org.red5.server.api.scope.IScope; +import org.red5.logging.Red5LoggerFactory; +import org.red5.server.api.Red5; +import org.red5.server.api.scope.IScope; import org.bigbluebutton.conference.service.participants.ParticipantsApplication; public class PresentationService { @@ -82,6 +85,21 @@ public class PresentationService { log.info("getPresentationInfo::service - Sending presentation information..."); return presentationInfo; } + + @SuppressWarnings("unchecked") + public Map getFileNames() { + log.debug("Getting the downloadable file names."); + IScope scope = Red5.getConnectionLocal().getScope(); + + ArrayList downloadableFileNames = presentationApplication.getFileNamesToDownload(scope.getName()); + + Map fileNames = new HashMap(); + fileNames.put("fileNames", downloadableFileNames); + + log.info("getFileNames::service - Sending downloadable file names..."); + return fileNames; + + } public void gotoSlide(int slideNum) { log.debug("Request to go to slide " + slideNum); diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties index 351c02b8ff..7ec60f226e 100755 --- a/bigbluebutton-client/locale/en_US/bbbResources.properties +++ b/bigbluebutton-client/locale/en_US/bbbResources.properties @@ -83,6 +83,7 @@ bbb.presentation.quickLink.label = Presentation Window bbb.presentation.fitToWidth.toolTip = Fit presentation to width bbb.presentation.fitToPage.toolTip = Fit presentation to page bbb.presentation.uploadPresBtn.toolTip = Open the Upload Presentation dialog box +bbb.presentation.downloadPresBtn.toolTip = Click here to download the presentations bbb.presentation.backBtn.toolTip = Previous slide bbb.presentation.btnSlideNum.toolTip = Select a slide bbb.presentation.forwardBtn.toolTip = Next slide @@ -125,6 +126,12 @@ bbb.fileupload.okCancelBtn = Close bbb.fileupload.okCancelBtn.toolTip = Close the File Upload dialog box bbb.fileupload.genThumbText = Generating thumbnails.. bbb.fileupload.progBarLbl = Progress: +bbb.fileupload.letUserDownload = Let the users download the presentation +bbb.fileupload.letUserDownload.tooltip = Check here if you want the other users to download your presentation +bbb.filedownload.title = Download the Presentations +bbb.filedownload.fileLbl = Choose File to Download: +bbb.filedownload.downloadBtn = Download +bbb.filedownload.downloadBtn.toolTip = Download Presentation bbb.chat.title = Chat bbb.chat.quickLink.label = Chat Window bbb.chat.cmpColorPicker.toolTip = Text Color diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as index a229e7d7a1..93c2c8da4d 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as @@ -26,7 +26,7 @@ package org.bigbluebutton.modules.present.business import flash.net.URLRequestMethod; import flash.net.URLVariables; import org.bigbluebutton.modules.present.events.UploadEvent; - import org.bigbluebutton.common.LogUtil; + import org.bigbluebutton.common.LogUtil; public class FileUploadService { public static const ID:String = "FileUploadService"; @@ -60,8 +60,9 @@ package org.bigbluebutton.modules.present.business * @param file - The FileReference class of the file we wish to send * */ - public function upload(presentationName:String, file:FileReference):void { + public function upload(presentationName:String, file:FileReference, downloadable: Boolean):void { sendVars.presentation_name = presentationName; + sendVars.is_downloadable = downloadable; var fileToUpload : FileReference = new FileReference(); fileToUpload = file; @@ -74,7 +75,10 @@ package org.bigbluebutton.modules.present.business request.method = URLRequestMethod.POST; + LogUtil.debug("@FileUploadFile: sendVars.is_downloadable: " + sendVars.is_downloadable); + // "fileUpload" is the variable name of the uploaded file in the server + LogUtil.debug("fileToUpload.name = " + fileToUpload.name); fileToUpload.upload(request, "fileUpload", true); } @@ -130,4 +134,4 @@ package org.bigbluebutton.modules.present.business LogUtil.error("A security error occured while trying to upload the presentation. " + event.toString()); } } -} \ No newline at end of file +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as index c28fa40d58..edf9dd096b 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as @@ -23,6 +23,7 @@ package org.bigbluebutton.modules.present.business import flash.events.TimerEvent; import flash.net.NetConnection; import flash.utils.Timer; + import flash.net.navigateToURL; import mx.controls.Alert; @@ -37,7 +38,14 @@ package org.bigbluebutton.modules.present.business import org.bigbluebutton.modules.present.events.RemovePresentationEvent; import org.bigbluebutton.modules.present.events.SlideEvent; import org.bigbluebutton.modules.present.events.UploadEvent; + import org.bigbluebutton.modules.present.events.DownloadEvent; import org.bigbluebutton.modules.present.managers.PresentationSlides; + + import flash.events.*; + import flash.net.FileReference; + import flash.net.URLRequest; + import flash.errors.*; + public class PresentProxy { @@ -77,8 +85,45 @@ package org.bigbluebutton.modules.present.business */ public function startUpload(e:UploadEvent):void{ if (uploadService == null) uploadService = new FileUploadService(host + "/bigbluebutton/presentation/upload", conference, room); - uploadService.upload(e.presentationName, e.fileToUpload); + LogUtil.debug("Presentation is downloadable? " + e.isDownloadable); + uploadService.upload(e.presentationName, e.fileToUpload, e.isDownloadable); } + + /** + * Start downloading the selected file + * @param e + * + */ + public function startDownload(e:DownloadEvent):void { + + var presentationName:String = getPresentationName(e.fileNameToDownload) + var downloadUri:String = host + "/bigbluebutton/presentation/" + conference + "/" + room + "/" + presentationName + "/download"; + + LogUtil.debug("PresentationApplication::downloadPresentation()... " + downloadUri); + + var req:URLRequest = new URLRequest(downloadUri); + navigateToURL(req,"_blank"); + } + + + /** + * return the presentation name given a file name + * @param fileName + */ + private function getPresentationName(fileName:String):String { + var filenamePattern:RegExp = /(.+)(\..+)/i; + // Get the first match which should be the filename without the extension. + return fileName.replace(filenamePattern, "$1") + } + + /** + * updates the list of downloadable file names + */ + public function getFileNamesFromServer():void{ + if (soService == null) return; + soService.getFileNamesToDownload(); + } + /** * To to the specified slide @@ -182,4 +227,4 @@ package org.bigbluebutton.modules.present.business } } -} \ No newline at end of file +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentSOService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentSOService.as index 1cc6e9703f..60efa4de5e 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentSOService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentSOService.as @@ -35,7 +35,8 @@ package org.bigbluebutton.modules.present.business { import org.bigbluebutton.modules.present.events.NavigationEvent; import org.bigbluebutton.modules.present.events.RemovePresentationEvent; import org.bigbluebutton.modules.present.events.UploadEvent; - import org.bigbluebutton.modules.present.events.ZoomEvent; + import org.bigbluebutton.modules.present.events.DownloadEvent; + import org.bigbluebutton.modules.present.events.ZoomEvent; public class PresentSOService { public static const NAME:String = "PresentSOService"; @@ -388,7 +389,7 @@ package org.bigbluebutton.modules.present.business { sendPresentationName(u as String); } } - + // Force switching the presenter. triggerSwitchPresenter(); @@ -410,6 +411,37 @@ package org.bigbluebutton.modules.present.business { ) //new Responder ); //_netConnection.call } + + public function getFileNamesToDownload():void { + nc.call( "presentation.getFileNames",// Remote function name + new Responder( + // result - On successful result + function(result:Object):void { + LogUtil.debug("Getting from server: file names to download"); + if(result.fileNames) { + for(var f:Object in result.fileNames) { + var u:Object = result.fileNames[f] + LogUtil.debug("Got from server the downloadable file: " + u as String); + sendFileName(u as String); + } + } + else + LogUtil.debug("result.fileNames is FALSE..."); + }, + + // status - On error occurred + function(status:Object):void { + LogUtil.error("Error occurred:"); + for (var x:Object in status) { + LogUtil.error(x + " : " + status[x]); + } + } + ) //new Responder + ); //_netConnection.call + } + + + /*** * NOTE: @@ -453,6 +485,12 @@ package org.bigbluebutton.modules.present.business { uploadEvent.presentationName = presentationName; dispatcher.dispatchEvent(uploadEvent) } + + private function sendFileName(fileName:String):void { + var e:DownloadEvent = new DownloadEvent(DownloadEvent.ADD_NEW_FILENAME); + e.fileNameToDownload = fileName; + dispatcher.dispatchEvent(e); + } /** * Send an event out to the server to go to a new page in the SlidesDeck @@ -672,4 +710,4 @@ package org.bigbluebutton.modules.present.business { _soErrors.push(error); } } -} \ No newline at end of file +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/DownloadEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/DownloadEvent.as new file mode 100755 index 0000000000..4ba6f36464 --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/DownloadEvent.as @@ -0,0 +1,37 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 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 . +* +*/ +package org.bigbluebutton.modules.present.events +{ + import flash.events.Event; + + public class DownloadEvent extends Event { + public static const OPEN_DOWNLOAD_WINDOW:String = "OPEN_DOWNLOAD_WINDOW"; + public static const CLOSE_DOWNLOAD_WINDOW:String = "CLOSE_DOWNLOAD_WINDOW"; + public static const DOWNLOAD_PRESENTATION:String = "DOWNLOAD_PRESENTATION"; + public static const UPDATE_FILE_NAMES:String = "UPDATE_FILE_NAMES"; + public static const ADD_NEW_FILENAME:String = "ADD_NEW_FILENAME"; + + public var fileNameToDownload:String; + + public function DownloadEvent(type:String) { + super(type, true, false); + } + + } +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/UploadEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/UploadEvent.as old mode 100755 new mode 100644 index 14c6b54538..2a5777100a --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/UploadEvent.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/UploadEvent.as @@ -1,62 +1,64 @@ -/** -* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -* -* Copyright (c) 2012 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 . -* -*/ -package org.bigbluebutton.modules.present.events -{ - import flash.events.Event; - import flash.net.FileReference; - - public class UploadEvent extends Event { - public static const OPEN_EXTERNAL_UPLOAD_WINDOW:String = "OPEN_EXTERNAL_UPLOAD_WINDOW"; - public static const OPEN_UPLOAD_WINDOW:String = "OPEN_UPLOAD_WINDOW"; - public static const CLOSE_UPLOAD_WINDOW:String = "CLOSE_UPLOAD_WINDOW"; - public static const CLEAR_PRESENTATION:String = "CLEAR_PRESENTATION"; - public static const CONVERT_SUCCESS:String = "CONVERT_SUCCESS"; - public static const CONVERT_UPDATE:String = "CONVERT_UPDATE"; - public static const CONVERT_ERROR:String = "CONVERT_ERROR"; - public static const START_UPLOAD:String = "START_UPLOAD"; - public static const UPLOAD_PROGRESS_UPDATE:String = "UPLOAD_PROGRESS_UPDATE"; - public static const UPLOAD_COMPLETE:String = "UPLOAD_COMPLETE"; - public static const UPLOAD_IO_ERROR:String = "UPLOAD_IO_ERROR"; - public static const UPLOAD_SECURITY_ERROR:String = "UPLOAD_SECURITY_ERROR"; - public static const UPDATE_PROGRESS:String = "UPDATE_PROGRESS"; - public static const THUMBNAILS_UPDATE:String = "THUMBNAILS_UPDATE"; - public static const PRESENTATION_READY:String = "PRESENTATION_READY"; - - public static const OFFICE_DOC_CONVERSION_SUCCESS:String = "OFFICE_DOC_CONVERSION_SUCCESS"; - public static const OFFICE_DOC_CONVERSION_FAILED:String = "OFFICE_DOC_CONVERSION_FAILED"; - public static const SUPPORTED_DOCUMENT:String = "SUPPORTED_DOCUMENT"; - public static const UNSUPPORTED_DOCUMENT:String = "UNSUPPORTED_DOCUMENT"; - public static const PAGE_COUNT_FAILED:String = "PAGE_COUNT_FAILED"; - public static const PAGE_COUNT_EXCEEDED:String = "PAGE_COUNT_EXCEEDED"; - - public var presentationName:String; - public var data:Object; - public var completedSlides:Number; - public var totalSlides:Number; - public var fileToUpload:FileReference; - public var percentageComplete:Number; - public var maximumSupportedNumberOfSlides:int; - public var maxFileSize:Number; - - public function UploadEvent(type:String) { - super(type, true, false); - } - - } -} \ No newline at end of file +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 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 . +* +*/ +package org.bigbluebutton.modules.present.events +{ + import flash.events.Event; + import flash.net.FileReference; + + public class UploadEvent extends Event { + public static const OPEN_EXTERNAL_UPLOAD_WINDOW:String = "OPEN_EXTERNAL_UPLOAD_WINDOW"; + public static const OPEN_UPLOAD_WINDOW:String = "OPEN_UPLOAD_WINDOW"; + public static const CLOSE_UPLOAD_WINDOW:String = "CLOSE_UPLOAD_WINDOW"; + public static const CLEAR_PRESENTATION:String = "CLEAR_PRESENTATION"; + public static const CONVERT_SUCCESS:String = "CONVERT_SUCCESS"; + public static const CONVERT_UPDATE:String = "CONVERT_UPDATE"; + public static const CONVERT_ERROR:String = "CONVERT_ERROR"; + public static const START_UPLOAD:String = "START_UPLOAD"; + public static const UPLOAD_PROGRESS_UPDATE:String = "UPLOAD_PROGRESS_UPDATE"; + public static const UPLOAD_COMPLETE:String = "UPLOAD_COMPLETE"; + public static const UPLOAD_IO_ERROR:String = "UPLOAD_IO_ERROR"; + public static const UPLOAD_SECURITY_ERROR:String = "UPLOAD_SECURITY_ERROR"; + public static const UPDATE_PROGRESS:String = "UPDATE_PROGRESS"; + public static const THUMBNAILS_UPDATE:String = "THUMBNAILS_UPDATE"; + public static const PRESENTATION_READY:String = "PRESENTATION_READY"; + + public static const OFFICE_DOC_CONVERSION_SUCCESS:String = "OFFICE_DOC_CONVERSION_SUCCESS"; + public static const OFFICE_DOC_CONVERSION_FAILED:String = "OFFICE_DOC_CONVERSION_FAILED"; + public static const SUPPORTED_DOCUMENT:String = "SUPPORTED_DOCUMENT"; + public static const UNSUPPORTED_DOCUMENT:String = "UNSUPPORTED_DOCUMENT"; + public static const PAGE_COUNT_FAILED:String = "PAGE_COUNT_FAILED"; + public static const PAGE_COUNT_EXCEEDED:String = "PAGE_COUNT_EXCEEDED"; + + + public var presentationName:String; + public var data:Object; + public var completedSlides:Number; + public var totalSlides:Number; + public var isDownloadable:Boolean; + public var fileToUpload:FileReference; + public var percentageComplete:Number; + public var maximumSupportedNumberOfSlides:int; + public var maxFileSize:Number; + + public function UploadEvent(type:String) { + super(type, true, false); + } + + } +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as index 8e2371815f..aea8794c32 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as @@ -33,18 +33,22 @@ package org.bigbluebutton.modules.present.managers import org.bigbluebutton.modules.present.events.PresentModuleEvent; import org.bigbluebutton.modules.present.events.QueryListOfPresentationsReplyEvent; import org.bigbluebutton.modules.present.events.RemovePresentationEvent; + import org.bigbluebutton.modules.present.events.DownloadEvent; import org.bigbluebutton.modules.present.events.UploadEvent; + import org.bigbluebutton.modules.present.ui.views.FileDownloadWindow; import org.bigbluebutton.modules.present.ui.views.FileUploadWindow; import org.bigbluebutton.modules.present.ui.views.PresentationWindow; public class PresentManager { private var globalDispatcher:Dispatcher; + private var downloadWindow:FileDownloadWindow; private var uploadWindow:FileUploadWindow; private var presentWindow:PresentationWindow; //format: presentationNames = [{label:"00"}, {label:"11"}, {label:"22"} ]; [Bindable] public var presentationNames:ArrayCollection = new ArrayCollection(); + [Bindable] public var fileNamesToDownload:ArrayCollection = new ArrayCollection(); public function PresentManager() { globalDispatcher = new Dispatcher(); @@ -66,8 +70,23 @@ package org.bigbluebutton.modules.present.managers private function openWindow(window:IBbbModuleWindow):void{ var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT); - event.window = window; - globalDispatcher.dispatchEvent(event); + event.window = window; + globalDispatcher.dispatchEvent(event); + } + + public function handleOpenDownloadWindow():void{ + if (downloadWindow != null) return; + + globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); + + downloadWindow = new FileDownloadWindow(); + downloadWindow.fileNamesToDownload = fileNamesToDownload; + mx.managers.PopUpManager.addPopUp(downloadWindow, presentWindow, true); + } + + public function handleCloseDownloadWindow():void{ + PopUpManager.removePopUp(downloadWindow); + downloadWindow = null; } public function handleOpenUploadWindow(e:UploadEvent):void{ @@ -85,24 +104,57 @@ package org.bigbluebutton.modules.present.managers } public function updatePresentationNames(e:UploadEvent):void{ - LogUtil.debug("Adding presentation " + e.presentationName); + LogUtil.debug("Adding presentation NAME " + e.presentationName); for (var i:int = 0; i < presentationNames.length; i++) { if (presentationNames[i] == e.presentationName) return; } - presentationNames.addItem(e.presentationName); + presentationNames.addItem(e.presentationName); } + public function updateFileNamesToDownload(e:DownloadEvent):void{ + LogUtil.debug("Adding file to download NAME " + e.fileNameToDownload); + for (var i:int = 0; i < fileNamesToDownload.length; i++) { + if (fileNamesToDownload[i] == e.fileNameToDownload) return; + } + fileNamesToDownload.addItem(e.fileNameToDownload); + } + + public function removePresentation(e:RemovePresentationEvent):void { LogUtil.debug("Removing presentation " + e.presentationName); - var p:String; - - for (var i:int = 0; i < presentationNames.length; i++) { - p = presentationNames.getItemAt(i) as String; - if (p == e.presentationName) { - presentationNames.removeItemAt(i); - } - } + var p:String; + + for (var i:int = 0; i < presentationNames.length; i++) { + p = presentationNames.getItemAt(i) as String; + if (p == e.presentationName) { + presentationNames.removeItemAt(i); + } + } + + removeFileNameToDownload(e.presentationName); } + + + public function removeFileNameToDownload(presentationName:String):void { + var p:String; + + for (var i:int = 0; i < fileNamesToDownload.length; i++) { + p = getPresentationName(fileNamesToDownload.getItemAt(i) as String); + if (p == presentationName) { + LogUtil.debug("Removing file name to download " + presentationName); + fileNamesToDownload.removeItemAt(i); + } + } + } + + + private function getPresentationName(fileName:String):String + { + var filenamePattern:RegExp = /(.+)(\..+)/i; + // Get the first match which should be the filename without the extension. + return fileName.replace(filenamePattern, "$1") + } + public function queryPresentations():void { var pArray:Array = new Array(); @@ -113,4 +165,4 @@ package org.bigbluebutton.modules.present.managers globalDispatcher.dispatchEvent(qEvent); } } -} \ No newline at end of file +} diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml index 753ae4b95d..ef4a9ae305 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml @@ -34,6 +34,7 @@ with BigBlueButton; if not, see . import org.bigbluebutton.modules.present.events.QueryPresentationsListEvent; import org.bigbluebutton.modules.present.events.RemovePresentationEvent; import org.bigbluebutton.modules.present.events.SlideEvent; + import org.bigbluebutton.modules.present.events.DownloadEvent; import org.bigbluebutton.modules.present.events.UploadEvent; import org.bigbluebutton.modules.present.managers.PresentManager; import org.bigbluebutton.modules.present.ui.views.PresentationWindow; @@ -60,6 +61,26 @@ with BigBlueButton; if not, see . + + + + + + + + + + + + + + + + + + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml new file mode 100755 index 0000000000..4181ad4acb --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml new file mode 100755 index 0000000000..51915404f5 --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml index e618dd1d2a..a44c874760 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml @@ -139,18 +139,25 @@ with BigBlueButton; if not, see . displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert')); } else { var presentationName:String = StringUtil.trim(fileToUpload.name); - trace("Uploading file : " + presentationName); + LogUtil.debug("Uploading file : " + presentationName); var filenamePattern:RegExp = /(.+)(\..+)/i; // Get the first match which should be the filename without the extension. presentationName = presentationName.replace(filenamePattern, "$1") // Replace any character other than a word character (A-Z, a-z, 0-9, or _). presentationName = presentationName.replace(/[^0-9a-zA-Z_\.]/g, "-"); - trace("Uploadling presentation name: " + presentationName); + LogUtil.debug("Uploadling presentation name: " + presentationName); - var uploadEvent:UploadEvent = new UploadEvent(UploadEvent.START_UPLOAD); + var isDownloadable:Boolean = new Boolean(letUserDownload.selected); + + var uploadEvent:UploadEvent = new UploadEvent(UploadEvent.START_UPLOAD); uploadEvent.presentationName = presentationName; uploadEvent.fileToUpload = fileToUpload; + uploadEvent.isDownloadable = isDownloadable; + + LogUtil.debug("uploadEvent.isDownloadable = " + uploadEvent.isDownloadable); + + globalDispatch.dispatchEvent(uploadEvent); progBarLbl.visible = true; @@ -289,9 +296,15 @@ with BigBlueButton; if not, see . toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn.toolTip')}" click="startUpload()" enabled="false" icon="{bulletGoIcon}"/> + + + + + + - + @@ -306,20 +319,19 @@ with BigBlueButton; if not, see . - + - + - diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml index bce2ca0b03..629f56f1c0 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml @@ -99,6 +99,7 @@ with BigBlueButton; if not, see . import org.bigbluebutton.modules.present.events.SlideEvent; import org.bigbluebutton.modules.present.events.SlideResizedEvent; import org.bigbluebutton.modules.present.events.UploadEvent; + import org.bigbluebutton.modules.present.events.DownloadEvent; import org.bigbluebutton.modules.present.events.WindowResizedEvent; import org.bigbluebutton.modules.present.events.ZoomEvent; import org.bigbluebutton.modules.present.managers.Slide; @@ -163,6 +164,9 @@ with BigBlueButton; if not, see . minimizeBtn.tabIndex = baseIndex+1; maximizeRestoreBtn.tabIndex = baseIndex+2; closeBtn.tabIndex = baseIndex+3; + + var images:Images = new Images(); + downloadPres.setStyle("icon", images.disk); slideView.slideLoader.tabIndex = baseIndex+4; hotkeyCapture(); @@ -359,6 +363,7 @@ with BigBlueButton; if not, see . private function setupPresenter(isPresenter:Boolean, presentersName:String):void { this.isPresenter = isPresenter; uploadPres.visible = isPresenter; + downloadPres.visible = true; if (presentationLoaded) { displaySlideNumber(slideView.selectedSlide + 1); @@ -607,10 +612,24 @@ with BigBlueButton; if not, see . onFitToPage(true); } } + + private function onDownloadButtonClicked():void { + openDownloadWindow(); + + } + + private function openDownloadWindow():void { + var event:DownloadEvent = new DownloadEvent(DownloadEvent.OPEN_DOWNLOAD_WINDOW); + dispatchEvent(event); + } + + private function onUploadButtonClicked():void { openUploadWindow(); } + + private function openUploadWindow():void { if (presentOptions.openExternalFileUploadDialog) { @@ -635,6 +654,11 @@ with BigBlueButton; if not, see . + + + diff --git a/bigbluebutton-web/grails-app/conf/UrlMappings.groovy b/bigbluebutton-web/grails-app/conf/UrlMappings.groovy index ef6b9a64e2..32e5bce6a0 100755 --- a/bigbluebutton-web/grails-app/conf/UrlMappings.groovy +++ b/bigbluebutton-web/grails-app/conf/UrlMappings.groovy @@ -51,6 +51,10 @@ class UrlMappings { "/presentation/$conference/$room/$presentation_name/textfile/$id"(controller:"presentation") { action = [GET:'showTextfile'] } + + "/presentation/$conference/$room/$presentation_name/download"(controller:"presentation") { + action = [GET:'downloadFile'] + } "/api/setConfigXML"(controller:"api") { action = [POST:'setConfigXML'] diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/PresentationController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/PresentationController.groovy index 05e7355b9e..f4b12fbd3f 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/PresentationController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/PresentationController.groovy @@ -76,9 +76,26 @@ class PresentationController { def newFilename = file.getOriginalFilename().replaceAll(notValidCharsRegExp, '-') def pres = new File( uploadDir.absolutePath + File.separatorChar + newFilename ) - file.transferTo(pres) + file.transferTo(pres) + + def isDownloadable = params.boolean('is_downloadable') //instead of params.is_downloadable + + if(isDownloadable) { + log.debug "@Creating download directory..." + File downloadDir = presentationService.downloadPresentationDirectory(uploadDir.absolutePath) + def downloadableFile = new File( downloadDir.absolutePath + File.separatorChar + newFilename ) + + downloadableFile << pres.newInputStream() + } UploadedPresentation uploadedPres = new UploadedPresentation(params.conference, params.room, presentationName); + + if(isDownloadable) { + log.debug "@Setting file to be downloadable..." + uploadedPres.setDownloadable(); + uploadedPres.setFileNameToDownload(newFilename); + } + uploadedPres.setUploadedFile(pres); presentationService.processUploadedPresentation(uploadedPres) } else { @@ -184,6 +201,33 @@ class PresentationController { return null; } + + def downloadFile = { + def presentationName = params.presentation_name + def conf = params.conference + def rm = params.room + println "Controller: Download request for $presentationName" + + InputStream is = null; + try { + def pres = presentationService.getFile(conf, rm, presentationName) + if (pres.exists()) { + println "Controller: Sending pdf reply for $presentationName" + + def bytes = pres.readBytes() + def responseName = pres.getName(); + response.addHeader("content-disposition", "filename=$responseName") + response.addHeader("Cache-Control", "no-cache") + 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('###', '.') diff --git a/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy b/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy index 7930f6dede..43df1b1882 100755 --- a/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy +++ b/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy @@ -16,15 +16,15 @@ * with BigBlueButton; if not, see . * */ -package org.bigbluebutton.web.services - -import java.util.concurrent.*; +package org.bigbluebutton.web.services + +import java.util.concurrent.*; import java.lang.InterruptedException import org.bigbluebutton.presentation.DocumentConversionService import org.bigbluebutton.presentation.UploadedPresentation - -class PresentationService { - + +class PresentationService { + static transactional = false DocumentConversionService documentConversionService def presentationDir @@ -33,81 +33,89 @@ class PresentationService { def testPresentationName def testUploadedPresentation def defaultUploadedPresentation - - def deletePresentation = {conf, room, filename -> - def directory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename) - deleteDirectory(directory) - } - - def deleteDirectory = {directory -> - log.debug "delete = ${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() - } - - def listPresentations = {conf, room -> - def presentationsList = [] - def directory = roomDirectory(conf, room) - log.debug "directory ${directory.absolutePath}" - if( directory.exists() ){ - directory.eachFile(){ file-> - System.out.println(file.name) - if( file.isDirectory() ) - presentationsList.add( file.name ) - } - } - return presentationsList - } - - public File uploadedPresentationDirectory(String conf, String room, String presentation_name) { - File dir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentation_name) - println "Uploaded presentation ${presentation_name} for conf ${conf} and room ${room} to dir ${dir.absolutePath}" - - /* If the presentation name already exist, delete it. We should provide a check later on to notify user - that there is already a presentation with that name. */ - if (dir.exists()) deleteDirectory(dir) - dir.mkdirs() - - assert dir.exists() - return dir - } - - def processUploadedPresentation = {uploadedPres -> - // Run conversion on another thread. - new Timer().runAfter(1000) - { + + def deletePresentation = {conf, room, filename -> + def directory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename) + deleteDirectory(directory) + } + + def deleteDirectory = {directory -> + log.debug "delete = ${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() + } + + def listPresentations = {conf, room -> + def presentationsList = [] + def directory = roomDirectory(conf, room) + log.debug "directory ${directory.absolutePath}" + if( directory.exists() ){ + directory.eachFile(){ file-> + System.out.println(file.name) + if( file.isDirectory() ) + presentationsList.add( file.name ) + } + } + return presentationsList + } + + public File uploadedPresentationDirectory(String conf, String room, String presentation_name) { + File dir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentation_name) + println "Uploaded presentation ${presentation_name} for conf ${conf} and room ${room} to dir ${dir.absolutePath}" + + /* If the presentation name already exist, delete it. We should provide a check later on to notify user + that there is already a presentation with that name. */ + if (dir.exists()) deleteDirectory(dir) + dir.mkdirs() + + assert dir.exists() + return dir + } + + public File downloadPresentationDirectory(String uploadDirectory) { + File dir = new File(uploadDirectory + File.separatorChar + "download") + dir.mkdirs() + assert dir.exists() + + return dir + } + + def processUploadedPresentation = {uploadedPres -> + // Run conversion on another thread. + new Timer().runAfter(1000) + { documentConversionService.processDocument(uploadedPres) - } - } - - def showSlide(String conf, String room, String presentationName, String id) { - new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "slide-${id}.swf") - } - - def showPresentation = {conf, room, filename -> - new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename + File.separatorChar + "slides.swf") - } - + } + } + + def showSlide(String conf, String room, String presentationName, String id) { + new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "slide-${id}.swf") + } + + def showPresentation = {conf, room, filename -> + new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename + File.separatorChar + "slides.swf") + } + def showThumbnail = {conf, room, presentationName, thumb -> - println "Show thumbnails request for $presentationName $thumb" - def thumbFile = roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + - "thumbnails" + File.separatorChar + "thumb-${thumb}.png" - log.debug "showing $thumbFile" - - new File(thumbFile) + println "Show thumbnails request for $presentationName $thumb" + def thumbFile = roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + + "thumbnails" + File.separatorChar + "thumb-${thumb}.png" + log.debug "showing $thumbFile" + + new File(thumbFile) } def showTextfile = {conf, room, presentationName, textfile -> @@ -117,21 +125,34 @@ class PresentationService { 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 getFile = {conf, room, presentationName -> + println "download request for $presentationName" + + def fileDirectory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + + "download") + + //list the files of the download directory ; it must have only 1 file to download + def list = fileDirectory.listFiles() + + //new File(pdfFile) + list[0] + } + + 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) + } + + def roomDirectory = {conf, room -> + return new File(presentationDir + File.separatorChar + conf + File.separatorChar + room) } def testConversionProcess() { @@ -155,14 +176,14 @@ class PresentationService { } } - -} - -/*** Helper classes **/ -import java.io.FilenameFilter; -import java.io.File; -class PngFilter implements FilenameFilter { - public boolean accept(File dir, String name) { - return (name.endsWith(".png")); - } + +} + +/*** Helper classes **/ +import java.io.FilenameFilter; +import java.io.File; +class PngFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return (name.endsWith(".png")); + } } diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/ConversionUpdateMessage.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/ConversionUpdateMessage.java index f1dbdd0a15..c7b1c758ca 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/ConversionUpdateMessage.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/ConversionUpdateMessage.java @@ -41,6 +41,13 @@ public class ConversionUpdateMessage { message.put("room", pres.getRoom()); message.put("returnCode", "CONVERT"); message.put("presentationName", pres.getName()); + + + + if(pres.isDownloadable()) + message.put("fileName",pres.getFileNameToDownload()); + else + message.put("fileName",""); } public MessageBuilder entry(String key, Object value) { diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/UploadedPresentation.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/UploadedPresentation.java index 9a7b118fe6..a8517a3180 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/UploadedPresentation.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/UploadedPresentation.java @@ -29,11 +29,30 @@ public final class UploadedPresentation { private String fileType = "unknown"; private int numberOfPages = 0; private boolean lastStepSuccessful = false; + private boolean isDownloadable = false; + private String fileNameToDownload = ""; public UploadedPresentation(String conference, String room, String name) { this.conference = conference; this.room = room; this.name = name; + this.isDownloadable = false; + } + + public boolean isDownloadable() { + return isDownloadable; + } + + public void setDownloadable() { + this.isDownloadable = true; + } + + public void setFileNameToDownload(String name) { + this.fileNameToDownload = name; + } + + public String getFileNameToDownload() { + return fileNameToDownload; } public File getUploadedFile() { From 24d27d33259a36d8023f6eb0533222471d8a0086 Mon Sep 17 00:00:00 2001 From: alexandrekreis Date: Thu, 28 Nov 2013 17:05:05 -0200 Subject: [PATCH 2/4] refs #930 Interface improvements --- .../src/org/bigbluebutton/common/Images.as | 5 +++- .../common/assets/images/disk_grayscale.png | Bin 0 -> 398 bytes .../present/managers/PresentManager.as | 23 ++++++++++++++++-- .../present/ui/views/FileDownloadWindow.mxml | 4 +-- .../present/ui/views/FileUploadWindow.mxml | 9 ++++--- .../present/ui/views/PresentationWindow.mxml | 2 +- 6 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 bigbluebutton-client/src/org/bigbluebutton/common/assets/images/disk_grayscale.png diff --git a/bigbluebutton-client/src/org/bigbluebutton/common/Images.as b/bigbluebutton-client/src/org/bigbluebutton/common/Images.as index 7174c82160..85ad0b75ef 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/common/Images.as +++ b/bigbluebutton-client/src/org/bigbluebutton/common/Images.as @@ -268,7 +268,10 @@ package org.bigbluebutton.common public var pollIcon:Class; [Embed(source="assets/images/disk.png")] - public var disk:Class; + public var disk:Class; + + [Embed(source="assets/images/disk_grayscale.png")] + public var disk_grayscale:Class; [Embed(source="assets/images/folder.png")] public var folder:Class; diff --git a/bigbluebutton-client/src/org/bigbluebutton/common/assets/images/disk_grayscale.png b/bigbluebutton-client/src/org/bigbluebutton/common/assets/images/disk_grayscale.png new file mode 100644 index 0000000000000000000000000000000000000000..30056e2734a4077a030755f5de3d9db5c6804276 GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf67>k44ofy`glX(f`FeQ1ryDThUI#~+>j<$t{_Hez+p*s$wBS!mKGWH*US_w7tK#+m*>JOEXw7OLG=?b4kY8M{b3?A2KP5 zeh~}uQa9?FbgAKb*UVQjmwWcD?9i$eb#gS8C@dFQa>Yi#V@cYa);gOg^`;BU?3Uk{ zoX}ZVT#~87>RXj6I{%n_(ygC$z4yY`b5-nn6!2AJrtX95rd7eAsncxU&ClV|50|+X p`tR86=9)D1_pxo!(@Lb=|1&yX?mo^kLktw+44$rjF6*2Ung9tNp>O~I literal 0 HcmV?d00001 diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as index aea8794c32..ce5fadb3cc 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as @@ -22,6 +22,9 @@ package org.bigbluebutton.modules.present.managers import mx.collections.ArrayCollection; import mx.managers.PopUpManager; + import mx.managers.SystemManager; + import mx.core.Application; + import mx.core.FlexGlobals; import org.bigbluebutton.common.IBbbModuleWindow; import org.bigbluebutton.common.LogUtil; @@ -79,8 +82,16 @@ package org.bigbluebutton.modules.present.managers globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); - downloadWindow = new FileDownloadWindow(); - downloadWindow.fileNamesToDownload = fileNamesToDownload; + downloadWindow = new FileDownloadWindow(); + + var width:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.width; + var height:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.height; + + downloadWindow.x = (width - downloadWindow.width) / 2; + downloadWindow.y = (height - downloadWindow.height) / 2; + + downloadWindow.fileNamesToDownload = fileNamesToDownload; + mx.managers.PopUpManager.addPopUp(downloadWindow, presentWindow, true); } @@ -93,8 +104,16 @@ package org.bigbluebutton.modules.present.managers if (uploadWindow != null) return; uploadWindow = new FileUploadWindow(); + + var width:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.width; + var height:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.height; + + uploadWindow.x = (width - uploadWindow.width) / 2; + uploadWindow.y = (height - uploadWindow.height) / 2; + uploadWindow.presentationNamesAC = presentationNames; uploadWindow.maxFileSize = e.maxFileSize; + mx.managers.PopUpManager.addPopUp(uploadWindow, presentWindow, true); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml index 51915404f5..d43798c682 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml @@ -68,9 +68,9 @@ with BigBlueButton; if not, see . - + - diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml index a44c874760..8662e90355 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml @@ -167,6 +167,8 @@ with BigBlueButton; if not, see . uploadBtn.enabled = false; fileTxtInput.enabled = false; + letUserDownload.visible = false; + presentationNamesLb.visible = false; } @@ -246,7 +248,8 @@ with BigBlueButton; if not, see . okCancelBtn.visible = true; selectBtn.enabled = true; uploadBtn.enabled = true; - fileTxtInput.enabled = true; + fileTxtInput.enabled = true; + letUserDownload.visible = true; } private function convertUpdate(e:UploadEvent):void{ @@ -297,11 +300,12 @@ with BigBlueButton; if not, see . enabled="false" icon="{bulletGoIcon}"/> - + + @@ -312,7 +316,6 @@ with BigBlueButton; if not, see . styleName="presentationUploadProgressBarStyle" labelPlacement="center" width="460" visible="false"/> - diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml index 629f56f1c0..4010eca7ce 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml @@ -166,7 +166,7 @@ with BigBlueButton; if not, see . closeBtn.tabIndex = baseIndex+3; var images:Images = new Images(); - downloadPres.setStyle("icon", images.disk); + downloadPres.setStyle("icon", images.disk_grayscale); slideView.slideLoader.tabIndex = baseIndex+4; hotkeyCapture(); From d9f1672b6460ec41a036c18ae3b11f88d62346cf Mon Sep 17 00:00:00 2001 From: alexandrekreis Date: Fri, 20 Dec 2013 17:21:07 -0200 Subject: [PATCH 3/4] refs #930 Upload Window now indicates which presentations are downloadable --- .../locale/en_US/bbbResources.properties | 1 + .../present/managers/PresentManager.as | 68 +++++++++++++++---- .../views/DownloadPresentationRenderer.mxml | 2 +- .../present/ui/views/FileUploadWindow.mxml | 8 +-- .../views/UploadedPresentationRenderer.mxml | 33 ++++++--- 5 files changed, 84 insertions(+), 28 deletions(-) diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties index 7ec60f226e..b691018ed1 100755 --- a/bigbluebutton-client/locale/en_US/bbbResources.properties +++ b/bigbluebutton-client/locale/en_US/bbbResources.properties @@ -132,6 +132,7 @@ bbb.filedownload.title = Download the Presentations bbb.filedownload.fileLbl = Choose File to Download: bbb.filedownload.downloadBtn = Download bbb.filedownload.downloadBtn.toolTip = Download Presentation +bbb.filedownload.thisFileIsDownloadable = File is downloadable bbb.chat.title = Chat bbb.chat.quickLink.label = Chat Window bbb.chat.cmpColorPicker.toolTip = Text Color diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as index ce5fadb3cc..4afed95711 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as @@ -49,8 +49,8 @@ package org.bigbluebutton.modules.present.managers private var uploadWindow:FileUploadWindow; private var presentWindow:PresentationWindow; - //format: presentationNames = [{label:"00"}, {label:"11"}, {label:"22"} ]; - [Bindable] public var presentationNames:ArrayCollection = new ArrayCollection(); + //format: presentationInfos = [{label:"00"}, {label:"11"}, {label:"22"} ]; + [Bindable] public var presentationInfos:ArrayCollection = new ArrayCollection(); [Bindable] public var fileNamesToDownload:ArrayCollection = new ArrayCollection(); public function PresentManager() { @@ -80,8 +80,6 @@ package org.bigbluebutton.modules.present.managers public function handleOpenDownloadWindow():void{ if (downloadWindow != null) return; - globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); - downloadWindow = new FileDownloadWindow(); var width:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.width; @@ -110,32 +108,44 @@ package org.bigbluebutton.modules.present.managers uploadWindow.x = (width - uploadWindow.width) / 2; uploadWindow.y = (height - uploadWindow.height) / 2; + + uploadWindow.presentationInfosAC = presentationInfos; - uploadWindow.presentationNamesAC = presentationNames; uploadWindow.maxFileSize = e.maxFileSize; - + mx.managers.PopUpManager.addPopUp(uploadWindow, presentWindow, true); + } public function handleCloseUploadWindow():void{ PopUpManager.removePopUp(uploadWindow); uploadWindow = null; + globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); } public function updatePresentationNames(e:UploadEvent):void{ - LogUtil.debug("Adding presentation NAME " + e.presentationName); - for (var i:int = 0; i < presentationNames.length; i++) { - if (presentationNames[i] == e.presentationName) return; + for (var i:int = 0; i < presentationInfos.length; i++) { + if (presentationInfos[i].presentationName == e.presentationName) return; } - presentationNames.addItem(e.presentationName); + + var newPresentationInfo:Object = new Object(); + newPresentationInfo.presentationName = e.presentationName; + newPresentationInfo.isDownloadable = false; + + LogUtil.debug("Presentation Info: name = " + newPresentationInfo.presentationName); + LogUtil.debug("Presentation Info: downloadable? " + newPresentationInfo.isDownloadable); + presentationInfos.addItem(newPresentationInfo); } public function updateFileNamesToDownload(e:DownloadEvent):void{ - LogUtil.debug("Adding file to download NAME " + e.fileNameToDownload); + LogUtil.debug("Adding file NAME " + e.fileNameToDownload); for (var i:int = 0; i < fileNamesToDownload.length; i++) { if (fileNamesToDownload[i] == e.fileNameToDownload) return; } + fileNamesToDownload.addItem(e.fileNameToDownload); + updateDownloadablePresentations(e.fileNameToDownload); + } @@ -143,10 +153,10 @@ package org.bigbluebutton.modules.present.managers LogUtil.debug("Removing presentation " + e.presentationName); var p:String; - for (var i:int = 0; i < presentationNames.length; i++) { - p = presentationNames.getItemAt(i) as String; + for (var i:int = 0; i < presentationInfos.length; i++) { + p = presentationInfos.getItemAt(i).presentationName as String; if (p == e.presentationName) { - presentationNames.removeItemAt(i); + presentationInfos.removeItemAt(i); } } @@ -167,6 +177,24 @@ package org.bigbluebutton.modules.present.managers } + private function updateDownloadablePresentations(fileName:String):void + { + LogUtil.debug("Updating isDownloadable field "); + + var info:Object; + + for (var i:int = 0; i < presentationInfos.length; i++) { + info = presentationInfos.getItemAt(i) as Object; + if(info.presentationName == getPresentationName(fileName)) { + LogUtil.debug("Now we check the downloadable mark on the user interface (" + info.presentationName + ")"); + info.isDownloadable = true; + presentationInfos.setItemAt(info,i); + } + } + + } + + private function getPresentationName(fileName:String):String { var filenamePattern:RegExp = /(.+)(\..+)/i; @@ -177,7 +205,17 @@ package org.bigbluebutton.modules.present.managers public function queryPresentations():void { var pArray:Array = new Array(); - pArray = presentationNames.toArray(); + var pName:String; + + // here make a new array with the presentationNames only + //pArray = presentationInfos.toArray(); + + for (var i:int = 0; i < presentationInfos.length; i++) { + pName = presentationInfos.getItemAt(i).presentationName as String; + pArray.push(pName); + } + + LogUtil.debug("$ending... " + pArray); var qEvent:QueryListOfPresentationsReplyEvent = new QueryListOfPresentationsReplyEvent(); qEvent.presentations = pArray; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml index 4181ad4acb..b01699bd5d 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/DownloadPresentationRenderer.mxml @@ -1,5 +1,5 @@ - + . import org.bigbluebutton.util.i18n.ResourceUtil; - [Bindable] public var presentationNamesAC:ArrayCollection; + [Bindable] public var presentationInfosAC:ArrayCollection; [BIndable] public var maxFileSize:Number; private var images:Images = new Images(); @@ -78,7 +78,7 @@ with BigBlueButton; if not, see . } private function initData():void { - if (presentationNamesAC.length <= 0) { + if (presentationInfosAC.length <= 0) { selectFile(); } } @@ -289,7 +289,7 @@ with BigBlueButton; if not, see . - + . + dragEnabled="false" dataProvider="{presentationInfosAC}"> diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/UploadedPresentationRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/UploadedPresentationRenderer.mxml index 1a775a0a00..c79373b38e 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/UploadedPresentationRenderer.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/UploadedPresentationRenderer.mxml @@ -1,39 +1,56 @@ - + - + + + + + click="showPresentation()" enabled="true" + verticalCenter="0" /> + + click="deletePresentation()" enabled="true" + verticalCenter="0" /> From 6a66fc5db6637c4d7315ed6a309fec806279b11e Mon Sep 17 00:00:00 2001 From: Alexandre Kreismann Date: Wed, 30 Apr 2014 15:42:50 -0300 Subject: [PATCH 4/4] Correcting logic of getting the list of files in the download window --- .../bigbluebutton/modules/present/managers/PresentManager.as | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as index 4afed95711..837b4ab506 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/managers/PresentManager.as @@ -79,6 +79,8 @@ package org.bigbluebutton.modules.present.managers public function handleOpenDownloadWindow():void{ if (downloadWindow != null) return; + + globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); downloadWindow = new FileDownloadWindow(); @@ -119,8 +121,7 @@ package org.bigbluebutton.modules.present.managers public function handleCloseUploadWindow():void{ PopUpManager.removePopUp(uploadWindow); - uploadWindow = null; - globalDispatcher.dispatchEvent(new DownloadEvent(DownloadEvent.UPDATE_FILE_NAMES)); + uploadWindow = null; } public function updatePresentationNames(e:UploadEvent):void{