Skip to content

Commit

Permalink
feature (api): Add preUploadedPresentation param to API's /create via…
Browse files Browse the repository at this point in the history
… GET
  • Loading branch information
Scroody committed Nov 13, 2023
1 parent 6a10a27 commit 3555e16
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 6 deletions.
17 changes: 16 additions & 1 deletion bbb-common-web/src/main/java/org/bigbluebutton/api/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;

public final class Util {
Expand All @@ -20,6 +23,14 @@ private Util() {
throw new IllegalStateException("Utility class");
}

public static String extractFilenameFromUrl(String preUploadedPresentation) throws MalformedURLException {
URL url = new URL(preUploadedPresentation);
String filename = FilenameUtils.getName(url.getPath());
String extension = FilenameUtils.getExtension(url.getPath());
if (extension == null || extension.isEmpty()) return null;
return filename;
}

public static boolean isMeetingIdValidFormat(String id) {
Matcher matcher = MEETING_ID_PATTERN.matcher(id);
if (matcher.matches()) {
Expand Down Expand Up @@ -51,7 +62,11 @@ public static String generatePresentationId(String presFilename) {
}

public static String createNewFilename(String presId, String fileExt) {
return presId + "." + fileExt;
if (!fileExt.isEmpty()) {
return presId + "." + fileExt;
} else {
return presId;
}
}

public static File createPresentationDir(String meetingId, String presentationDir, String presentationId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.bigbluebutton.presentation;

import org.bigbluebutton.api.domain.Extension;

import java.util.*;

import static org.bigbluebutton.presentation.FileTypeConstants.*;
Expand Down Expand Up @@ -43,6 +45,15 @@ public class MimeTypeUtils {
put(FileTypeConstants.SVG, Arrays.asList(SVG));
}
};

public String getExtensionBasedOnMimeType(String mimeType) {
return EXTENSIONS_MIME.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(mimeType))
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
}

public Boolean extensionMatchMimeType(String mimeType, String finalExtension) {
finalExtension = finalExtension.toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,19 @@ public static String detectMimeType(File pres) {
return "";
}

public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) {
String mimeType = detectMimeType(pres);

public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) {
String mimeType = detectMimeType(pres);

if (mimeType.equals("")) {
log.error("Not able to detect mimeType.");
return false;
}

if (!mimeTypeUtils.getValidMimeTypes().contains(mimeType)) {
log.error("MimeType is not valid for this meeting, [{}]", mimeType);
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,38 @@ class ApiController {
def listOfPresentation = []
def presentationListHasCurrent = false

Boolean hasPresentationUrlInParameter = false


String[] pu = request.getParameterMap().get("preUploadedPresentation")
String[] puName = request.getParameterMap().get("preUploadedPresentationName")
if (pu != null) {
String preUploadedPresentation = pu[0]
hasPresentationUrlInParameter = true
def xmlString = new StringWriter()
def xml = new MarkupBuilder(xmlString)
String filename
if (puName == null) {
filename = Util.extractFilenameFromUrl(preUploadedPresentation)
if (filename == null) {
filename = "untitled"
}
} else {
filename = puName[0]
}
xml.document (
removable: "true",
downloadable: "false",
url: preUploadedPresentation,
filename: filename,
isPreUploadedPresentationFromParameter: "true"
)

def parsedXml = new XmlSlurper().parseText(xmlString.toString())

listOfPresentation << parsedXml
}

// This part of the code is responsible for organize the presentations in a certain order
// It selects the one that has the current=true, and put it in the 0th place.
// Afterwards, the 0th presentation is going to be uploaded first, which spares processing time
Expand All @@ -1397,9 +1429,16 @@ class ApiController {
log.warn("Insert Document API called without a payload - ignoring")
return;
}
listOfPresentation << [name: "default", current: true];

if (hasPresentationUrlInParameter) {
if (!preUploadedPresentationOverrideDefault) {
listOfPresentation << [name: "default", current: true]
}
} else {
listOfPresentation << [name: "default", current: true]
}
} else {
Boolean hasCurrent = false;
Boolean hasCurrent = hasPresentationUrlInParameter;
Boolean hasPresentationModule = false;
if (xmlModules.containsKey("presentation")) {
def modulePresentation = xmlModules.get("presentation")
Expand Down Expand Up @@ -1438,6 +1477,7 @@ class ApiController {
def Boolean isRemovable = true;
def Boolean isDownloadable = false;
def Boolean isDefaultPresentation = false;
def Boolean isPreUploadedPresentationFromParameter = false;

if (document.name != null && "default".equals(document.name)) {
if (presentationService.defaultUploadedPresentation) {
Expand All @@ -1446,11 +1486,15 @@ class ApiController {
}
downloadAndProcessDocument(presentationService.defaultUploadedPresentation, conf.getInternalId(),
document.current /* default presentation */, '', false,
true, isDefaultPresentation);
true, isDefaultPresentation, isPreUploadedPresentationFromParameter);
} else {
log.error "Default presentation could not be read, it is (" + presentationService.defaultUploadedPresentation + ")", "error"
}
} else {
if (!StringUtils.isEmpty(document.@isPreUploadedPresentationFromParameter.toString())) {
isPreUploadedPresentationFromParameter = java.lang.Boolean.parseBoolean(
document.@isPreUploadedPresentationFromParameter.toString());
}
// Extracting all properties inside the xml
if (!StringUtils.isEmpty(document.@removable.toString())) {
isRemovable = java.lang.Boolean.parseBoolean(document.@removable.toString());
Expand Down Expand Up @@ -1517,8 +1561,8 @@ class ApiController {
def pres = null
def presId = null

if (presFilename == "" || filenameExt == "") {
log.debug("Upload failed. Invalid filename " + presOrigFilename)
if (presFilename == "" || (filenameExt == "" && !isPreUploadedPresentationFromParameter)) {
log.debug("Upload failed. Invalid filename " + presOrigFilename)
uploadFailReasons.add("invalid_filename")
uploadFailed = true
} else {
Expand All @@ -1539,6 +1583,21 @@ class ApiController {
uploadFailReasons.add("failed_to_download_file")
uploadFailed = true
}
if (isPreUploadedPresentationFromParameter && filenameExt.isEmpty()) {
String fileExtension = SupportedFileTypes.detectFileExtensionBasedOnMimeType(pres)
newFilename = Util.createNewFilename(presId, fileExtension)
newFilePath = uploadDir.absolutePath + File.separatorChar + newFilename
File destination = new File(newFilePath)
filenameExt = fileExtension
presFilename = Util.createNewFilename(presFilename, fileExtension)
if (pres.renameTo(destination)) {
log.info("Presentation coming from URL parameter is at ${destination.getAbsolutePath()}")
pres = destination
} else {
log.error("Error while renaming presentation from URL parameter to ${destination.getAbsolutePath()}, " +
"consider sending it through `/insertDocument`")
}
}
}

// Hardcode pre-uploaded presentation to the default presentation window
Expand Down

0 comments on commit 3555e16

Please sign in to comment.