[issue-18924] - changes in review, and added possibility to insert a name along with URL
This commit is contained in:
parent
a22068be18
commit
d6670a4145
@ -2,11 +2,14 @@ package org.bigbluebutton.api;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public final class Util {
|
public final class Util {
|
||||||
@ -50,8 +53,19 @@ public final class Util {
|
|||||||
return DigestUtils.sha1Hex(presFilename + uuid) + "-" + timestamp;
|
return DigestUtils.sha1Hex(presFilename + uuid) + "-" + timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 String createNewFilename(String presId, String fileExt) {
|
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) {
|
public static File createPresentationDir(String meetingId, String presentationDir, String presentationId) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.bigbluebutton.presentation;
|
package org.bigbluebutton.presentation;
|
||||||
|
|
||||||
|
import org.bigbluebutton.api.domain.Extension;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.bigbluebutton.presentation.FileTypeConstants.*;
|
import static org.bigbluebutton.presentation.FileTypeConstants.*;
|
||||||
@ -44,6 +46,15 @@ public class MimeTypeUtils {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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) {
|
public Boolean extensionMatchMimeType(String mimeType, String finalExtension) {
|
||||||
finalExtension = finalExtension.toLowerCase();
|
finalExtension = finalExtension.toLowerCase();
|
||||||
|
|
||||||
|
@ -108,14 +108,21 @@ public final class SupportedFileTypes {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String detectFileExtensionBasedOnMimeType(File pres) {
|
||||||
|
String mimeType = detectMimeType(pres);
|
||||||
|
return mimeTypeUtils.getExtensionBasedOnMimeType(mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) {
|
public static Boolean isPresentationMimeTypeValid(File pres, String fileExtension) {
|
||||||
String mimeType = detectMimeType(pres);
|
String mimeType = detectMimeType(pres);
|
||||||
|
|
||||||
if (mimeType.equals("")) {
|
if (mimeType.equals("")) {
|
||||||
|
log.error("Not able to detect mimeType.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mimeTypeUtils.getValidMimeTypes().contains(mimeType)) {
|
if (!mimeTypeUtils.getValidMimeTypes().contains(mimeType)) {
|
||||||
|
log.error("MimeType is not valid for this meeting, [{}]", mimeType);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ import org.bigbluebutton.web.services.turn.TurnEntry
|
|||||||
import org.bigbluebutton.web.services.turn.StunServer
|
import org.bigbluebutton.web.services.turn.StunServer
|
||||||
import org.bigbluebutton.web.services.turn.RemoteIceCandidate
|
import org.bigbluebutton.web.services.turn.RemoteIceCandidate
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
|
import org.apache.commons.io.FilenameUtils
|
||||||
import javax.servlet.ServletRequest
|
import javax.servlet.ServletRequest
|
||||||
|
|
||||||
class ApiController {
|
class ApiController {
|
||||||
@ -1383,17 +1383,27 @@ class ApiController {
|
|||||||
|
|
||||||
|
|
||||||
String[] pu = request.getParameterMap().get("preUploadedPresentation")
|
String[] pu = request.getParameterMap().get("preUploadedPresentation")
|
||||||
|
String[] puName = request.getParameterMap().get("preUploadedPresentationName")
|
||||||
if (pu != null) {
|
if (pu != null) {
|
||||||
String preUploadedPresentation = pu[0]
|
String preUploadedPresentation = pu[0]
|
||||||
hasPresentationUrlInParameter = true
|
hasPresentationUrlInParameter = true
|
||||||
def xmlString = new StringWriter()
|
def xmlString = new StringWriter()
|
||||||
def xml = new MarkupBuilder(xmlString)
|
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 (
|
xml.document (
|
||||||
removable: "true",
|
removable: "true",
|
||||||
downloadable: "false",
|
downloadable: "false",
|
||||||
url: preUploadedPresentation,
|
url: preUploadedPresentation,
|
||||||
filename: extractFilenameFromUrl(preUploadedPresentation),
|
filename: filename,
|
||||||
name: extractFilenameFromUrl(preUploadedPresentation)
|
isPreUploadedPresentationFromParameter: "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
def parsedXml = new XmlSlurper().parseText(xmlString.toString())
|
def parsedXml = new XmlSlurper().parseText(xmlString.toString())
|
||||||
@ -1454,6 +1464,7 @@ class ApiController {
|
|||||||
def Boolean isRemovable = true;
|
def Boolean isRemovable = true;
|
||||||
def Boolean isDownloadable = false;
|
def Boolean isDownloadable = false;
|
||||||
def Boolean isInitialPresentation = false;
|
def Boolean isInitialPresentation = false;
|
||||||
|
def Boolean isPreUploadedPresentationFromParameter = false
|
||||||
|
|
||||||
if (document.name != null && "default".equals(document.name)) {
|
if (document.name != null && "default".equals(document.name)) {
|
||||||
if (presentationService.defaultUploadedPresentation) {
|
if (presentationService.defaultUploadedPresentation) {
|
||||||
@ -1462,11 +1473,15 @@ class ApiController {
|
|||||||
}
|
}
|
||||||
downloadAndProcessDocument(presentationService.defaultUploadedPresentation, conf.getInternalId(),
|
downloadAndProcessDocument(presentationService.defaultUploadedPresentation, conf.getInternalId(),
|
||||||
document.current /* default presentation */, '', false,
|
document.current /* default presentation */, '', false,
|
||||||
true, isInitialPresentation);
|
true, isInitialPresentation, isPreUploadedPresentationFromParameter);
|
||||||
} else {
|
} else {
|
||||||
log.error "Default presentation could not be read, it is (" + presentationService.defaultUploadedPresentation + ")", "error"
|
log.error "Default presentation could not be read, it is (" + presentationService.defaultUploadedPresentation + ")", "error"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!StringUtils.isEmpty(document.@isPreUploadedPresentationFromParameter.toString())) {
|
||||||
|
isPreUploadedPresentationFromParameter = java.lang.Boolean.parseBoolean(
|
||||||
|
document.@isPreUploadedPresentationFromParameter.toString());
|
||||||
|
}
|
||||||
// Extracting all properties inside the xml
|
// Extracting all properties inside the xml
|
||||||
if (!StringUtils.isEmpty(document.@removable.toString())) {
|
if (!StringUtils.isEmpty(document.@removable.toString())) {
|
||||||
isRemovable = java.lang.Boolean.parseBoolean(document.@removable.toString());
|
isRemovable = java.lang.Boolean.parseBoolean(document.@removable.toString());
|
||||||
@ -1493,7 +1508,7 @@ class ApiController {
|
|||||||
fileName = document.@filename.toString();
|
fileName = document.@filename.toString();
|
||||||
}
|
}
|
||||||
downloadAndProcessDocument(document.@url.toString(), conf.getInternalId(), isCurrent /* default presentation */,
|
downloadAndProcessDocument(document.@url.toString(), conf.getInternalId(), isCurrent /* default presentation */,
|
||||||
fileName, isDownloadable, isRemovable, isInitialPresentation);
|
fileName, isDownloadable, isRemovable, isInitialPresentation, isPreUploadedPresentationFromParameter);
|
||||||
} else if (!StringUtils.isEmpty(document.@name.toString())) {
|
} else if (!StringUtils.isEmpty(document.@name.toString())) {
|
||||||
def b64 = new Base64()
|
def b64 = new Base64()
|
||||||
def decodedBytes = b64.decode(document.text().getBytes())
|
def decodedBytes = b64.decode(document.text().getBytes())
|
||||||
@ -1507,10 +1522,6 @@ class ApiController {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
def extractFilenameFromUrl(String url) {
|
|
||||||
return url.split('/')[-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
def processDocumentFromRawBytes(bytes, presOrigFilename, meetingId, current, isDownloadable, isRemovable,
|
def processDocumentFromRawBytes(bytes, presOrigFilename, meetingId, current, isDownloadable, isRemovable,
|
||||||
isInitialPresentation) {
|
isInitialPresentation) {
|
||||||
def uploadFailed = false
|
def uploadFailed = false
|
||||||
@ -1567,7 +1578,8 @@ class ApiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def downloadAndProcessDocument(address, meetingId, current, fileName, isDownloadable, isRemovable, isInitialPresentation) {
|
def downloadAndProcessDocument(address, meetingId, current, fileName, isDownloadable, isRemovable,
|
||||||
|
isInitialPresentation, isPreUploadedPresentationFromParameter) {
|
||||||
log.debug("ApiController#downloadAndProcessDocument(${address}, ${meetingId}, ${fileName})");
|
log.debug("ApiController#downloadAndProcessDocument(${address}, ${meetingId}, ${fileName})");
|
||||||
String presOrigFilename;
|
String presOrigFilename;
|
||||||
if (StringUtils.isEmpty(fileName)) {
|
if (StringUtils.isEmpty(fileName)) {
|
||||||
@ -1592,7 +1604,7 @@ class ApiController {
|
|||||||
def pres = null
|
def pres = null
|
||||||
def presId
|
def presId
|
||||||
|
|
||||||
if (presFilename == "" || filenameExt == "") {
|
if (presFilename == "" || (filenameExt == "" && !isPreUploadedPresentationFromParameter)) {
|
||||||
log.debug("presentation is null by default")
|
log.debug("presentation is null by default")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
@ -1609,6 +1621,22 @@ class ApiController {
|
|||||||
uploadFailReasons.add("failed_to_download_file")
|
uploadFailReasons.add("failed_to_download_file")
|
||||||
uploadFailed = true
|
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`")
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("Null presentation directory meeting=[${meetingId}], presentationDir=[${presentationDir}], presId=[${presId}]")
|
log.error("Null presentation directory meeting=[${meetingId}], presentationDir=[${presentationDir}], presId=[${presId}]")
|
||||||
uploadFailReasons.add("null_presentation_dir")
|
uploadFailReasons.add("null_presentation_dir")
|
||||||
|
Loading…
Reference in New Issue
Block a user