diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PdfConversionInvalidErrorSysPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PdfConversionInvalidErrorSysPubMsgHdlr.scala index c625dbde7747b49928fe689c0863177cdc315c06..2577dc3bd0f5821d510e00a87798d64f63d704de 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PdfConversionInvalidErrorSysPubMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PdfConversionInvalidErrorSysPubMsgHdlr.scala @@ -6,7 +6,7 @@ import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.running.LiveMeeting trait PdfConversionInvalidErrorSysPubMsgHdlr { - this: PresentationPodHdlrs => + this: PresentationPodHdlrs => def handle( msg: PdfConversionInvalidErrorSysPubMsg, state: MeetingState2x, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPageConvertedSysMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPageConvertedSysMsgHdlr.scala new file mode 100755 index 0000000000000000000000000000000000000000..f53324260ab5a24295d3e5e09b8091a8e1b3d818 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPageConvertedSysMsgHdlr.scala @@ -0,0 +1,43 @@ +package org.bigbluebutton.core.apps.presentationpod + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.bus.MessageBus +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.running.LiveMeeting + +trait PresentationPageConvertedSysMsgHdlr { + this: PresentationPodHdlrs => + + def handle(msg: PresentationPageConvertedSysMsg, state: MeetingState2x, + liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { + + def broadcastEvent(msg: PresentationPageConvertedSysMsg): Unit = { + val routing = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + liveMeeting.props.meetingProp.intId, msg.header.userId + ) + val envelope = BbbCoreEnvelope(PresentationPageConvertedEventMsg.NAME, routing) + val header = BbbClientMsgHeader( + PresentationPageConvertedEventMsg.NAME, + liveMeeting.props.meetingProp.intId, msg.header.userId + ) + + val body = PresentationPageConvertedEventMsgBody( + msg.body.podId, + msg.body.messageKey, + msg.body.code, + msg.body.presentationId, + msg.body.numberOfPages, + msg.body.pagesCompleted, + msg.body.presName, + msg.body.page + ) + val event = PresentationPageConvertedEventMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + bus.outGW.send(msgEvent) + } + + broadcastEvent(msg) + state + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala index bcb6bb2895c6d2acfc096398a3067f0e5d8885e2..00c18af24d9659c983e61a773b5c9bdd5646d1b5 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala @@ -20,7 +20,8 @@ class PresentationPodHdlrs(implicit val context: ActorContext) with PresentationUploadTokenReqMsgHdlr with ResizeAndMovePagePubMsgHdlr with SyncGetPresentationPodsMsgHdlr - with RemovePresentationPodPubMsgHdlr { + with RemovePresentationPodPubMsgHdlr + with PresentationPageConvertedSysMsgHdlr { val log = Logging(context.system, getClass) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index 2db88ad68a864743cf8573346cc29b3a23f8a8a3..a4dd6ee3a3dfda086542840efc3fc4fe1f65f5c3 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -219,6 +219,10 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[PresentationPageCountErrorSysPubMsg](envelope, jsonNode) case PresentationPageGeneratedSysPubMsg.NAME => routeGenericMsg[PresentationPageGeneratedSysPubMsg](envelope, jsonNode) + case PresentationPageConvertedSysMsg.NAME => + routeGenericMsg[PresentationPageConvertedSysMsg](envelope, jsonNode) + case PresentationConversionStartedSysMsg.NAME => + routeGenericMsg[PresentationConversionStartedSysMsg](envelope, jsonNode) case PresentationConversionCompletedSysPubMsg.NAME => routeGenericMsg[PresentationConversionCompletedSysPubMsg](envelope, jsonNode) case PdfConversionInvalidErrorSysPubMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 5ea402cddedb021d0cbdde7cdbd8b7cfb38a1173..707217d7c0278f854163b5eb76649e737cd0a33a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -438,6 +438,7 @@ class MeetingActor( case m: PresentationPageCountErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: PresentationUploadTokenReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: ResizeAndMovePagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationPageConvertedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) // Caption case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala index f65e7bf7276f5d7050fccbb073220b95c23edf5d..5a0c5dddfbfcafa2f49b6f31bf96fb9e8786677a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala @@ -106,6 +106,9 @@ class AnalyticsActor extends Actor with ActorLogging { case m: SetCurrentPresentationEvtMsg => logMessage(msg) case m: SetPresentationDownloadablePubMsg => logMessage(msg) case m: SetPresentationDownloadableEvtMsg => logMessage(msg) + case m: PresentationPageConvertedSysMsg => logMessage(msg) + case m: PresentationPageConvertedEventMsg => logMessage(msg) + case m: PresentationConversionStartedSysMsg => logMessage(msg) // Group Chats case m: SendGroupChatMessageMsg => logMessage(msg) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala index 2d36a93c848ad68ed3366cbb725c46c0c6696200..65d131066927a3d453ec76814b9cf68cc9b1fe42 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala @@ -1,6 +1,6 @@ package org.bigbluebutton.common2.msgs -import org.bigbluebutton.common2.domain.{ PresentationPodVO, PresentationVO } +import org.bigbluebutton.common2.domain.{ PageVO, PresentationPodVO, PresentationVO } // ------------ client to akka-apps ------------ object CreateNewPresentationPodPubMsg { val NAME = "CreateNewPresentationPodPubMsg" } @@ -73,8 +73,8 @@ case class PdfConversionInvalidErrorSysPubMsg( body: PdfConversionInvalidErrorSysPubMsgBody ) extends StandardMsg case class PdfConversionInvalidErrorSysPubMsgBody(podId: String, messageKey: String, code: String, presentationId: String, - bigPageNumber: Int, bigPageSize: Int, presName: String) - + bigPageNumber: Int, bigPageSize: Int, presName: String) + object PresentationPageGeneratedSysPubMsg { val NAME = "PresentationPageGeneratedSysPubMsg" } case class PresentationPageGeneratedSysPubMsg( header: BbbClientMsgHeader, @@ -90,6 +90,47 @@ case class PresentationConversionCompletedSysPubMsg( ) extends StandardMsg case class PresentationConversionCompletedSysPubMsgBody(podId: String, messageKey: String, code: String, presentation: PresentationVO) + +object PresentationPageConvertedSysMsg { val NAME = "PresentationPageConvertedSysMsg" } +case class PresentationPageConvertedSysMsg( + header: BbbClientMsgHeader, + body: PresentationPageConvertedSysMsgBody +) extends StandardMsg +case class PresentationPageConvertedSysMsgBody( + podId: String, + messageKey: String, + code: String, + presentationId: String, + numberOfPages: Int, + pagesCompleted: Int, + presName: String, + page: PageVO +) + +object PresentationConversionStartedSysMsg { val NAME = "PresentationConversionStartedSysMsg" } +case class PresentationConversionStartedSysMsg( + header: BbbClientMsgHeader, + body: PresentationConversionStartedSysMsgBody +) extends StandardMsg +case class PresentationConversionStartedSysMsgBody( + podId: String, + presentationId: String, + current: Boolean, + presName: String, + downloadable: Boolean +) + +object PresentationConversionEndedSysMsg { val NAME = "PresentationConversionEndedSysMsg" } +case class PresentationConversionEndedSysMsg( + header: BbbClientMsgHeader, + body: PresentationConversionEndedSysMsgBody +) extends StandardMsg +case class PresentationConversionEndedSysMsgBody( + podId: String, + presentationId: String, + presName: String +) + // ------------ bbb-common-web to akka-apps ------------ // ------------ akka-apps to client ------------ @@ -125,6 +166,22 @@ object PresentationPageGeneratedEvtMsg { val NAME = "PresentationPageGeneratedEv case class PresentationPageGeneratedEvtMsg(header: BbbClientMsgHeader, body: PresentationPageGeneratedEvtMsgBody) extends BbbCoreMsg case class PresentationPageGeneratedEvtMsgBody(podId: String, messageKey: String, code: String, presentationId: String, numberOfPages: Int, pagesCompleted: Int, presName: String) +object PresentationPageConvertedEventMsg { val NAME = "PresentationPageConvertedEventMsg" } +case class PresentationPageConvertedEventMsg( + header: BbbClientMsgHeader, + body: PresentationPageConvertedEventMsgBody +) extends BbbCoreMsg +case class PresentationPageConvertedEventMsgBody( + podId: String, + messageKey: String, + code: String, + presentationId: String, + numberOfPages: Int, + pagesCompleted: Int, + presName: String, + page: PageVO +) + object PresentationConversionCompletedEvtMsg { val NAME = "PresentationConversionCompletedEvtMsg" } case class PresentationConversionCompletedEvtMsg(header: BbbClientMsgHeader, body: PresentationConversionCompletedEvtMsgBody) extends BbbCoreMsg case class PresentationConversionCompletedEvtMsgBody(podId: String, messageKey: String, code: String, presentation: PresentationVO) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java index e585a4000ad5fbc11490c76d4d4e7d237f370221..5c4618a982f42404332c4d6ea6c299c2969d0a3c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java @@ -35,6 +35,7 @@ public class ConversionMessageConstants { public static final String GENERATED_TEXTFILES_KEY = "GENERATED_TEXTFILES"; public static final String GENERATING_SVGIMAGES_KEY = "GENERATING_SVGIMAGES"; public static final String GENERATED_SVGIMAGES_KEY = "GENERATED_SVGIMAGES"; + public static final String CONVERSION_STARTED_KEY = "CONVERSION_STARTED_KEY"; public static final String CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED"; private ConversionMessageConstants() { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java index 3f979ef8b7250ab93df382278a189f7bec7af7b8..4c5af192ee4b056ea06f8ab6dd80cd02d2707efb 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java @@ -26,6 +26,7 @@ import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.presentation.imp.ImageToSwfSlidesGenerationService; import org.bigbluebutton.presentation.imp.OfficeToPdfConversionService; import org.bigbluebutton.presentation.imp.PdfToSwfSlidesGenerationService; +import org.bigbluebutton.presentation.messages.DocConversionStarted; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,21 +41,46 @@ public class DocumentConversionServiceImp implements DocumentConversionService { private PdfToSwfSlidesGenerationService pdfToSwfSlidesGenerationService; private ImageToSwfSlidesGenerationService imageToSwfSlidesGenerationService; + private void sendDocConversionStartedProgress(UploadedPresentation pres) { + DocConversionStarted progress = new DocConversionStarted( + pres.getPodId(), + pres.getMeetingId(), + pres.getId(), + pres.getName(), + pres.getAuthzToken(), + pres.isDownloadable(), + pres.isDownloadable()); + gw.sendDocConversionMsg(progress); + } + public void processDocument(UploadedPresentation pres) { SupportedDocumentFilter sdf = new SupportedDocumentFilter(gw); - Map<String, Object> logData = new HashMap<String, Object>(); - logData.put("podId", pres.getPodId()); - logData.put("meetingId", pres.getMeetingId()); - logData.put("presId", pres.getId()); - logData.put("filename", pres.getName()); - logData.put("current", pres.isCurrent()); - logData.put("logCode", "presentation_conversion_start"); - logData.put("message", "Start presentation conversion."); - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - log.info(" --analytics-- data={}", logStr); + + if (! pres.isConversionStarted()) { + Map<String, Object> logData = new HashMap<String, Object>(); + + logData.put("podId", pres.getPodId()); + logData.put("meetingId", pres.getMeetingId()); + logData.put("presId", pres.getId()); + logData.put("filename", pres.getName()); + logData.put("current", pres.isCurrent()); + logData.put("authzToken", pres.getAuthzToken()); + logData.put("logCode", "presentation_conversion_start"); + logData.put("message", "Start presentation conversion."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + log.info(" --analytics-- data={}", logStr); + + pres.startConversion(); + sendDocConversionStartedProgress(pres); + } + + + + if (sdf.isSupported(pres)) { String fileType = pres.getFileType(); @@ -79,6 +105,7 @@ public class DocumentConversionServiceImp implements DocumentConversionService { } else if (SupportedFileTypes.isImageFile(fileType)) { imageToSwfSlidesGenerationService.generateSlides(pres); } else { + Map<String, Object> logData = new HashMap<String, Object>(); logData = new HashMap<String, Object>(); logData.put("podId", pres.getPodId()); logData.put("meetingId", pres.getMeetingId()); @@ -87,12 +114,14 @@ public class DocumentConversionServiceImp implements DocumentConversionService { logData.put("current", pres.isCurrent()); logData.put("logCode", "supported_file_not_handled"); logData.put("message", "Supported file not handled."); - gson = new Gson(); - logStr = gson.toJson(logData); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); log.warn(" --analytics-- data={}", logStr); } } else { + Map<String, Object> logData = new HashMap<String, Object>(); logData = new HashMap<String, Object>(); logData.put("podId", pres.getPodId()); logData.put("meetingId", pres.getMeetingId()); @@ -101,11 +130,13 @@ public class DocumentConversionServiceImp implements DocumentConversionService { logData.put("current", pres.isCurrent()); logData.put("logCode", "unsupported_file_format"); logData.put("message", "Unsupported file format"); - gson = new Gson(); - logStr = gson.toJson(logData); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); log.error(" --analytics-- data={}", logStr); } + Map<String, Object> logData = new HashMap<String, Object>(); logData = new HashMap<String, Object>(); logData.put("podId", pres.getPodId()); logData.put("meetingId", pres.getMeetingId()); @@ -114,8 +145,9 @@ public class DocumentConversionServiceImp implements DocumentConversionService { logData.put("current", pres.isCurrent()); logData.put("logCode", "presentation_conversion_end"); logData.put("message", "End presentation conversion."); - gson = new Gson(); - logStr = gson.toJson(logData); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); log.info(" --analytics-- data={}", logStr); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java index de3e16c3a7eb0c8b566416e1b0830645229f744c..a4b217756f51af3e40b640ece5b66297e6099a00 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java @@ -59,10 +59,10 @@ public class PresentationUrlDownloadService { } public void processUploadedFile(String podId, String meetingId, String presId, - String filename, File presFile, Boolean current) { + String filename, File presFile, Boolean current, String authzToken) { // TODO add podId UploadedPresentation uploadedPres = new UploadedPresentation(podId, meetingId, - presId, filename, presentationBaseURL, current); + presId, filename, presentationBaseURL, current, authzToken); uploadedPres.setUploadedFile(presFile); processUploadedPresentation(uploadedPres); } @@ -145,7 +145,7 @@ public class PresentationUrlDownloadService { // Hardcode pre-uploaded presentation for breakout room to the default presentation window processUploadedFile("DEFAULT_PRESENTATION_POD", destinationMeetingId, presId, "default-" + presentationSlide.toString() + "." + filenameExt, - newPresentation, true); + newPresentation, true, "breakout-authz-token"); } public String generatePresentationId(String name) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/UploadedPresentation.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/UploadedPresentation.java index 867982abe822aaf5015041579aa64501f0edc8cc..0bbb49eec26f8957751a6567178c176087d2d64b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/UploadedPresentation.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/UploadedPresentation.java @@ -33,8 +33,16 @@ public final class UploadedPresentation { private final String baseUrl; private boolean isDownloadable = false; private boolean current = false; - - public UploadedPresentation(String podId, String meetingId, String id, String name, String baseUrl, Boolean current) { + private String authzToken; + private boolean conversionStarted = false; + + public UploadedPresentation(String podId, + String meetingId, + String id, + String name, + String baseUrl, + Boolean current, + String authzToken) { this.podId = podId; this.meetingId = meetingId; this.id = id; @@ -42,6 +50,7 @@ public final class UploadedPresentation { this.baseUrl = baseUrl; this.isDownloadable = false; this.current = current; + this.authzToken = authzToken; } public File getUploadedFile() { @@ -111,4 +120,16 @@ public final class UploadedPresentation { public void setCurrent(Boolean value) { this.current = value; } + + public String getAuthzToken() { + return authzToken; + } + + public void startConversion() { + conversionStarted = true; + } + + public boolean isConversionStarted() { + return conversionStarted; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ImageToSwfSlidesGenerationService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ImageToSwfSlidesGenerationService.java index 85c80db1f2895492287bc0536fe0236e5e021437..ae3b21d7d9e8c22f4a6c5f87c387a8118b1eb13c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ImageToSwfSlidesGenerationService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ImageToSwfSlidesGenerationService.java @@ -166,8 +166,8 @@ public class ImageToSwfSlidesGenerationService { slide.generateBlankSlide(); } } - slideGenerated++; - notifier.sendConversionUpdateMessage(slideGenerated, pres); + slideGenerated++; + notifier.sendConversionUpdateMessage(slideGenerated, pres, slide.getPageNumber()); } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java index a54c27b14cc61524b45ce32067964eb4c707d219..80a22899c1486a9284b77e64864322bdbe8f5b68 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java @@ -83,21 +83,27 @@ public class PdfToSwfSlidesGenerationService { return; } } - + + System.out.println("****** CREATING SWFs"); // Only create SWF files if the configuration requires it if (swfSlidesRequired) { - convertPdfToSwf(pres); + convertPdfToSwf(pres); } + System.out.println("****** CREATING THM"); /* adding accessibility */ createThumbnails(pres); + + System.out.println("****** CREATING TXTs"); createTextFiles(pres); + System.out.println("****** CREATING SVGs"); // only create SVG images if the configuration requires it if (svgImagesRequired) { createSvgImages(pres); } + System.out.println("****** CREATING PNGs"); // only create PNG images if the configuration requires it if (generatePngs) { createPngImages(pres); @@ -284,7 +290,7 @@ public class PdfToSwfSlidesGenerationService { long timeLeft = endNanos - System.nanoTime(); PdfToSwfSlide s = f.get(timeLeft, TimeUnit.NANOSECONDS); slidesCompleted++; - notifier.sendConversionUpdateMessage(slidesCompleted, pres); + notifier.sendConversionUpdateMessage(slidesCompleted, pres, s.getPageNumber()); } catch (ExecutionException e) { Map<String, Object> logData = new HashMap<>(); logData.put("podId", pres.getPodId()); @@ -360,7 +366,7 @@ public class PdfToSwfSlidesGenerationService { String logStr = gson.toJson(logData); log.warn(" --analytics-- data={}", logStr); - notifier.sendConversionUpdateMessage(slidesCompleted++, pres); + notifier.sendConversionUpdateMessage(slidesCompleted++, pres, slide.getPageNumber()); } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PngCreatorImp.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PngCreatorImp.java index a0bcd56f169d7ddd5f3a2f32f152aa307f1bd388..e100519b562d9320ed07176b14b960bd4820cd97 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PngCreatorImp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PngCreatorImp.java @@ -52,16 +52,25 @@ public class PngCreatorImp implements PngCreator { cleanDirectory(pngDir); try { + long start = System.currentTimeMillis(); success = generatePngs(pngDir, pres); + long end = System.currentTimeMillis(); + System.out.println("*** GENERATE PNG " + (end - start)); } catch (InterruptedException e) { log.warn("Interrupted Exception while generating png."); success = false; } + long start = System.currentTimeMillis(); // Create blank thumbnails for pages that failed to generate a thumbnail. createBlankPngs(pngDir, pres.getNumberOfPages()); + long end = System.currentTimeMillis(); + System.out.println("*** GENERATE BLANK PNG " + (end - start)); + start = System.currentTimeMillis(); renamePng(pngDir); + end = System.currentTimeMillis(); + System.out.println("*** RENAME PNG " + (end - start)); return success; } @@ -74,6 +83,8 @@ public class PngCreatorImp implements PngCreator { dest = pngsDir.getAbsolutePath() + File.separator + TEMP_PNG_NAME; COMMAND = "pdftocairo -png -scale-to " + slideWidth + " " + source + " " + dest; + System.out.println("********* CREATING PNGs " + COMMAND); + boolean done = new ExternalProcessExecutor().exec(COMMAND, 60000); if (done) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java index cafeb3835d1177c0c56559c1c1a789182a2070a8..df054e1bd5021b801ebfcb17c30a3a30d0d5f1ca 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java @@ -85,6 +85,8 @@ public class SvgImageCreatorImp implements SvgImageCreator { // Continue image processing for (int i = 1; i <= numSlides; i++) { + System.out.println("******** CREATING SVG page " + i); + File destsvg = new File(imagePresentationDir.getAbsolutePath() + File.separatorChar + "slide" + i + ".svg"); NuProcessBuilder convertPdfToSvg = createConversionProcess("-svg", i, source, destsvg.getAbsolutePath(), @@ -198,7 +200,7 @@ public class SvgImageCreatorImp implements SvgImageCreator { } slidesCompleted++; - notifier.sendConversionUpdateMessage(slidesCompleted, pres); + notifier.sendConversionUpdateMessage(slidesCompleted, pres, i); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java index 3039d37e0a6aa80ec2de18aed8aa021188829e9b..0759a80c5cde342a8cf918bc0f1ddc64950177d4 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java @@ -42,12 +42,21 @@ public class SwfSlidesGenerationProgressNotifier { } - public void sendConversionUpdateMessage(int slidesCompleted, UploadedPresentation pres) { - DocPageGeneratedProgress progress = new DocPageGeneratedProgress(pres.getPodId(), pres.getMeetingId(), - pres.getId(), pres.getId(), - pres.getName(), "notUsedYet", "notUsedYet", - pres.isDownloadable(), ConversionMessageConstants.GENERATED_SLIDE_KEY, - pres.getNumberOfPages(), slidesCompleted); + public void sendConversionUpdateMessage(int slidesCompleted, UploadedPresentation pres, int pageGenerated) { + DocPageGeneratedProgress progress = new DocPageGeneratedProgress(pres.getPodId(), + pres.getMeetingId(), + pres.getId(), + pres.getId(), + pres.getName(), + "notUsedYet", + "notUsedYet", + pres.isDownloadable(), + ConversionMessageConstants.GENERATED_SLIDE_KEY, + pres.getNumberOfPages(), + slidesCompleted, + pres.getBaseUrl(), + pageGenerated, + (pageGenerated == 1)); messagingService.sendDocConversionMsg(progress); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocConversionStarted.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocConversionStarted.java new file mode 100755 index 0000000000000000000000000000000000000000..728c73e7ba96a8af2c8b9d8f8f8ae3fb924d4628 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocConversionStarted.java @@ -0,0 +1,27 @@ +package org.bigbluebutton.presentation.messages; + +public class DocConversionStarted implements IDocConversionMsg { + public final String podId; + public final String meetingId; + public final String presId; + public final String filename; + public final String authzToken; + public final Boolean downloadable; + public final Boolean current; + + public DocConversionStarted(String podId, + String meetingId, + String presId, + String filename, + String authzToken, + Boolean downloadable, + Boolean current) { + this.podId = podId; + this.meetingId = meetingId; + this.presId = presId; + this.filename = filename; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.current = current; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java index a67249da85c819cd9ac08e537d66269da04c794a..8a8fbe4119f3370df9565101de86ebc4ea85d227 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java @@ -12,11 +12,24 @@ public class DocPageGeneratedProgress implements IDocConversionMsg { public final String key; public final Integer numPages; public final Integer pagesCompleted; + public final String presBaseUrl; + public final Boolean current; + public final Integer page; - public DocPageGeneratedProgress(String podId, String meetingId, String presId, String presInstance, - String filename, String uploaderId, String authzToken, - Boolean downloadable, String key, - Integer numPages, Integer pagesCompleted) { + public DocPageGeneratedProgress(String podId, + String meetingId, + String presId, + String presInstance, + String filename, + String uploaderId, + String authzToken, + Boolean downloadable, + String key, + Integer numPages, + Integer pagesCompleted, + String presBaseUrl, + Integer page, + Boolean current) { this.podId = podId; this.meetingId = meetingId; this.presId = presId; @@ -28,5 +41,8 @@ public class DocPageGeneratedProgress implements IDocConversionMsg { this.key = key; this.numPages = numPages; this.pagesCompleted = pagesCompleted; + this.presBaseUrl = presBaseUrl; + this.page = page; + this.current = current; } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala index 112fe63c71682d07dffc43fd9adcac9d47a0ad7c..546afe88106f0691ef69cbe5cb6ad6ab7783c9f4 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala @@ -274,6 +274,10 @@ class BbbWebApiGWApp( if (msg.isInstanceOf[DocPageGeneratedProgress]) { val event = MsgBuilder.buildPresentationPageGeneratedPubMsg(msg.asInstanceOf[DocPageGeneratedProgress]) msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) + + // Send new event with page urls + val newEvent = MsgBuilder.buildPresentationPageConvertedSysMsg(msg.asInstanceOf[DocPageGeneratedProgress]) + msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, newEvent)) } else if (msg.isInstanceOf[OfficeDocConversionProgress]) { val event = MsgBuilder.buildPresentationConversionUpdateSysPubMsg(msg.asInstanceOf[OfficeDocConversionProgress]) msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) @@ -289,6 +293,9 @@ class BbbWebApiGWApp( } else if (msg.isInstanceOf[PdfConversionInvalid]) { val event = MsgBuilder.buildPdfConversionInvalidErrorSysPubMsg(msg.asInstanceOf[PdfConversionInvalid]) msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) + } else if (msg.isInstanceOf[DocConversionStarted]) { + val event = MsgBuilder.buildPresentationConversionStartedSysMsg(msg.asInstanceOf[DocConversionStarted]) + msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala index c5ead9b5d930cf5de21f4a2bc0a3a7dc0d720a28..e696df3dc4ee27152f62787ae2cf7646d14d22aa 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala @@ -64,10 +64,48 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, req) } + def generatePresentationPage(presId: String, numPages: Int, presBaseUrl: String, page: Int): PageVO = { + val id = presId + "/" + page + val current = if (page == 1) true else false + val thumbnail = presBaseUrl + "/thumbnail/" + page + val swfUri = presBaseUrl + "/slide/" + page + + val txtUri = presBaseUrl + "/textfiles/" + page + val svgUri = presBaseUrl + "/svg/" + page + + PageVO(id = id, num = page, thumbUri = thumbnail, swfUri = swfUri, + txtUri = txtUri, svgUri = svgUri, + current = current) + } + + def buildPresentationPageConvertedSysMsg(msg: DocPageGeneratedProgress): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-web") + val envelope = BbbCoreEnvelope(PresentationPageConvertedSysMsg.NAME, routing) + val header = BbbClientMsgHeader(PresentationPageConvertedSysMsg.NAME, msg.meetingId, msg.authzToken) + + val page = generatePresentationPage(msg.presId, msg.numPages.intValue(), msg.presBaseUrl, msg.page.intValue()) + + println("Converted page " + page) + + val body = PresentationPageConvertedSysMsgBody( + podId = msg.podId, + messageKey = msg.key, + code = msg.key, + presentationId = msg.presId, + numberOfPages = msg.numPages.intValue(), + pagesCompleted = msg.pagesCompleted.intValue(), + presName = msg.filename, + page + ) + val req = PresentationPageConvertedSysMsg(header, body) + BbbCommonEnvCoreMsg(envelope, req) + } + def buildPresentationPageGeneratedPubMsg(msg: DocPageGeneratedProgress): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-web") val envelope = BbbCoreEnvelope(PresentationPageGeneratedSysPubMsg.NAME, routing) val header = BbbClientMsgHeader(PresentationPageGeneratedSysPubMsg.NAME, msg.meetingId, msg.authzToken) + val body = PresentationPageGeneratedSysPubMsgBody(podId = msg.podId, messageKey = msg.key, code = msg.key, presentationId = msg.presId, numberOfPages = msg.numPages.intValue(), pagesCompleted = msg.pagesCompleted.intValue(), presName = msg.filename) @@ -143,7 +181,7 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, req) } - def buildPdfConversionInvalidErrorSysPubMsg(msg: PdfConversionInvalid): BbbCommonEnvCoreMsg ={ + def buildPdfConversionInvalidErrorSysPubMsg(msg: PdfConversionInvalid): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-web") val envelope = BbbCoreEnvelope(PdfConversionInvalidErrorSysPubMsg.NAME, routing) val header = BbbClientMsgHeader(PdfConversionInvalidErrorSysPubMsg.NAME, msg.meetingId, msg.authzToken) @@ -153,7 +191,23 @@ object MsgBuilder { val req = PdfConversionInvalidErrorSysPubMsg(header, body) BbbCommonEnvCoreMsg(envelope, req) } - + + def buildPresentationConversionStartedSysMsg(msg: DocConversionStarted): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-web") + val envelope = BbbCoreEnvelope(PresentationConversionStartedSysMsg.NAME, routing) + val header = BbbClientMsgHeader(PresentationConversionStartedSysMsg.NAME, msg.meetingId, msg.authzToken) + + val body = PresentationConversionStartedSysMsgBody( + podId = msg.podId, + presentationId = msg.presId, + current = msg.current, + presName = msg.filename, + downloadable = msg.downloadable + ) + val req = PresentationConversionStartedSysMsg(header, body) + BbbCommonEnvCoreMsg(envelope, req) + } + def buildPublishedRecordingSysMsg(msg: PublishedRecordingMessage): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-web") val envelope = BbbCoreEnvelope(PublishedRecordingSysMsg.NAME, routing) diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index 4c9005b289cb1cc8a6033fd41a1188c64754e64b..b13d5249578e07ea40b084fc3fe91a061ab294ed 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -2031,7 +2031,13 @@ class ApiController { fos.close() // Hardcode pre-uploaded presentation to the default presentation window - processUploadedFile("DEFAULT_PRESENTATION_POD", meetingId, presId, presFilename, pres, current); + processUploadedFile("DEFAULT_PRESENTATION_POD", + meetingId, + presId, + presFilename, + pres, + current, + "preupload-raw-authz-token"); } } @@ -2057,7 +2063,13 @@ class ApiController { if (presDownloadService.savePresentation(meetingId, newFilePath, address)) { def pres = new File(newFilePath) // Hardcode pre-uploaded presentation to the default presentation window - processUploadedFile("DEFAULT_PRESENTATION_POD", meetingId, presId, presFilename, pres, current); + processUploadedFile("DEFAULT_PRESENTATION_POD", + meetingId, + presId, + presFilename, + pres, + current, + "preupload-download-authz-token"); } else { log.error("Failed to download presentation=[${address}], meeting=[${meetingId}], fileName=[${fileName}]") } @@ -2065,10 +2077,16 @@ class ApiController { } - def processUploadedFile(podId, meetingId, presId, filename, presFile, current) { + def processUploadedFile(podId, meetingId, presId, filename, presFile, current, authzToken) { def presentationBaseUrl = presentationService.presentationBaseUrl // TODO add podId - UploadedPresentation uploadedPres = new UploadedPresentation(podId, meetingId, presId, filename, presentationBaseUrl, current); + UploadedPresentation uploadedPres = new UploadedPresentation(podId, + meetingId, + presId, + filename, + presentationBaseUrl, + current, + authzToken); uploadedPres.setUploadedFile(presFile); presentationService.processUploadedPresentation(uploadedPres); } 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 6c7f79b5d37b8c5cb28b065850b40285546772d0..edce746e1419a0dd82328109326718aac9ff93bb 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 @@ -119,7 +119,8 @@ class PresentationController { log.debug("processing file upload " + presFilename) def presentationBaseUrl = presentationService.presentationBaseUrl UploadedPresentation uploadedPres = new UploadedPresentation(podId, meetingId, presId, - presFilename, presentationBaseUrl, false /* default presentation */); + presFilename, presentationBaseUrl, false /* default presentation */, + params.authzToken); if (isDownloadable) { log.debug "@Setting file to be downloadable..."