Rework presentation download and upload
- verify presentation and meeting id formats - construct presentation file path making sure that they are valid - add "downloadable" flag to check if presentation can be downloaded or not - collect presentation upload errors so we can send to the client in the future
This commit is contained in:
parent
1297819518
commit
f876ce01c2
@ -32,7 +32,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -70,54 +69,42 @@ public class RecordingService {
|
||||
}
|
||||
|
||||
public void processMakePresentationDownloadableMsg(MakePresentationDownloadableMsg msg) {
|
||||
File presDir = Util.getPresentationDir(presentationBaseDir, msg.meetingId, msg.presId);
|
||||
File downloadableFile = new File(presDir.getAbsolutePath() + File.separatorChar + msg.presFilename);
|
||||
|
||||
if (presDir != null) {
|
||||
if (msg.downloadable) {
|
||||
String fileExt = FilenameUtils.getExtension(msg.presFilename);
|
||||
File presFile = new File(presDir.getAbsolutePath() + File.separatorChar + msg.presId + "." + fileExt);
|
||||
log.info("Make file downloadable. {}", downloadableFile.getAbsolutePath());
|
||||
copyPresentationFile(presFile, downloadableFile);
|
||||
} else {
|
||||
if (downloadableFile.exists()) {
|
||||
if(downloadableFile.delete()) {
|
||||
log.info("File deleted. {}", downloadableFile.getAbsolutePath());
|
||||
} else {
|
||||
log.warn("Failed to delete. {}", downloadableFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
Util.makePresentationDownloadable(presentationBaseDir, msg.meetingId, msg.presId, msg.downloadable);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to make presentation downloadable: {}", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public File getDownloadablePresentationFile(String meetingId, String presId, String presFilename) {
|
||||
log.info("Find downloadable presentation for meetingId={} presId={} filename={}", meetingId, presId,
|
||||
presFilename);
|
||||
Matcher metaMatcher = PRESENTATION_ID_PATTERN.matcher(presFilename);
|
||||
if (metaMatcher.matches()) {
|
||||
File presDir = Util.getPresentationDir(presentationBaseDir, meetingId, presId);
|
||||
// Build file to presFilename
|
||||
// Get canonicalPath and make sure it starts with
|
||||
// /var/bigbluebutton/<meetingid-pattern>
|
||||
// If so return file, if not return null
|
||||
try {
|
||||
File presFile = new File(presDir.getAbsolutePath() + File.separatorChar + presFilename);
|
||||
String presFileCanonical = presFile.getCanonicalPath();
|
||||
log.debug("Requested presentation name file full path {}",presFileCanonical);
|
||||
if (presFileCanonical.startsWith(presentationBaseDir)) {
|
||||
return presFile;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Exception getting canonical path for {}.\n{}", presFilename, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
log.error("Cannot find file for {}.", presFilename);
|
||||
log.info("Find downloadable presentation for meetingId={} presId={} filename={}", meetingId, presId,
|
||||
presFilename);
|
||||
|
||||
if (! Util.isPresFileIdValidFormat(presFilename)) {
|
||||
log.error("Invalid presentation filename for meetingId={} presId={} filename={}", meetingId, presId,
|
||||
presFilename);
|
||||
return null;
|
||||
}
|
||||
|
||||
String presFilenameExt = FilenameUtils.getExtension(presFilename);
|
||||
File presDir = Util.getPresentationDir(presentationBaseDir, meetingId, presId);
|
||||
File downloadMarker = Util.getPresFileDownloadMarker(presentationBaseDir, meetingId, presId);
|
||||
if (presDir != null && downloadMarker != null && downloadMarker.exists()) {
|
||||
String safePresFilename = presId.concat(".").concat(presFilenameExt);
|
||||
File presFile = new File(presDir.getAbsolutePath() + File.separatorChar + safePresFilename);
|
||||
if (presFile.exists()) {
|
||||
return presFile;
|
||||
}
|
||||
|
||||
log.error("Presentation file missing for meetingId={} presId={} filename={}", meetingId, presId,
|
||||
presFilename);
|
||||
return null;
|
||||
}
|
||||
|
||||
log.error("Invalid presentation directory for meetingId={} presId={} filename={}", meetingId, presId,
|
||||
presFilename);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public void kickOffRecordingChapterBreak(String meetingId, Long timestamp) {
|
||||
|
@ -1,49 +1,132 @@
|
||||
package org.bigbluebutton.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public final class Util {
|
||||
|
||||
private Util() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static String generatePresentationId(String name) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
return DigestUtils.sha1Hex(name) + "-" + timestamp;
|
||||
|
||||
private static final Pattern MEETING_ID_PATTERN = Pattern.compile("^[a-z0-9-]+$");
|
||||
private static final Pattern PRES_ID_PATTERN = Pattern.compile("^[a-z0-9-]+$");
|
||||
private static final Pattern PRES_FILE_ID_PATTERN = Pattern.compile("^[a-z0-9-]+.[a-zA-Z]{3,4}$");
|
||||
|
||||
private Util() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static boolean isMeetingIdValidFormat(String id) {
|
||||
Matcher matcher = MEETING_ID_PATTERN.matcher(id);
|
||||
if (matcher.matches()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPresIdValidFormat(String id) {
|
||||
Matcher matcher = PRES_ID_PATTERN.matcher(id);
|
||||
if (matcher.matches()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPresFileIdValidFormat(String id) {
|
||||
Matcher matcher = PRES_FILE_ID_PATTERN.matcher(id);
|
||||
if (matcher.matches()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String generatePresentationId(String presFilename) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
return DigestUtils.sha1Hex(presFilename) + "-" + timestamp;
|
||||
}
|
||||
|
||||
public static String createNewFilename(String presId, String fileExt) {
|
||||
return presId + "." + fileExt;
|
||||
}
|
||||
|
||||
public static String createNewFilename(String presId, String fileExt) {
|
||||
return presId + "." + fileExt;
|
||||
}
|
||||
|
||||
public static File createPresentationDir(String meetingId, String presentationDir, String presentationId) {
|
||||
String meetingPath = presentationDir + File.separatorChar + meetingId + File.separatorChar + meetingId;
|
||||
String presPath = meetingPath + File.separatorChar + presentationId;
|
||||
File dir = new File(presPath);
|
||||
if (dir.mkdirs()) {
|
||||
return dir;
|
||||
if (Util.isMeetingIdValidFormat(meetingId) && Util.isPresIdValidFormat(presentationId)) {
|
||||
String meetingPath = presentationDir + File.separatorChar + meetingId + File.separatorChar + meetingId;
|
||||
String presPath = meetingPath + File.separatorChar + presentationId;
|
||||
File dir = new File(presPath);
|
||||
if (dir.mkdirs()) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static File getMeetingDirPath(String presentationBaseDir, String meetingId) {
|
||||
if (Util.isMeetingIdValidFormat(meetingId)) {
|
||||
String meetingPath = presentationBaseDir + File.separatorChar + meetingId + File.separatorChar + meetingId;
|
||||
File dir = new File(meetingPath);
|
||||
if (dir.isDirectory() && dir.exists()) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static File getPresentationDir(String presentationBaseDir, String meetingId, String presentationId) {
|
||||
String meetingPath = presentationBaseDir + File.separatorChar + meetingId + File.separatorChar + meetingId;
|
||||
String presPath = meetingPath + File.separatorChar + presentationId;
|
||||
File dir = new File(presPath);
|
||||
if (dir.isDirectory() && dir.exists()) {
|
||||
return dir;
|
||||
if (Util.isMeetingIdValidFormat(meetingId) && Util.isPresIdValidFormat(presentationId)) {
|
||||
String meetingPath = presentationBaseDir + File.separatorChar + meetingId + File.separatorChar + meetingId;
|
||||
String presPath = meetingPath + File.separatorChar + presentationId;
|
||||
File dir = new File(presPath);
|
||||
if (dir.isDirectory() && dir.exists()) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String stripPresBaseDirFromPath(String presentationBaseDir, String path) {
|
||||
if (path.startsWith(presentationBaseDir)) {
|
||||
String presBaseDir = presentationBaseDir;
|
||||
if (! presBaseDir.endsWith("/")) {
|
||||
presBaseDir = presBaseDir.concat("/");
|
||||
return StringUtils.removeStart(path, presBaseDir);
|
||||
} else {
|
||||
return StringUtils.removeStart(path, presBaseDir);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public static File getPresFileDownloadMarker(String presBaseDir, String meetingId, String presId) {
|
||||
File presDir = Util.getPresentationDir(presBaseDir, meetingId, presId);
|
||||
|
||||
if (presDir != null) {
|
||||
String downloadMarker = presId.concat(".downloadable");
|
||||
return new File(presDir.getAbsolutePath() + File.separatorChar + downloadMarker);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static File downloadPresentationDirectory(String uploadDirectory) {
|
||||
File dir = new File(uploadDirectory + File.separatorChar + "download");
|
||||
if (dir.mkdirs()) {
|
||||
return dir;
|
||||
public static void makePresentationDownloadable(
|
||||
String presBaseDir,
|
||||
String meetingId,
|
||||
String presId,
|
||||
boolean downloadable
|
||||
) throws IOException {
|
||||
File downloadMarker = Util.getPresFileDownloadMarker(presBaseDir, meetingId, presId);
|
||||
if (downloadable) {
|
||||
if (downloadMarker != null && ! downloadMarker.exists()) {
|
||||
downloadMarker.createNewFile();
|
||||
}
|
||||
} else {
|
||||
if (downloadMarker != null && downloadMarker.exists()) {
|
||||
downloadMarker.delete();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,14 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
|
||||
|
||||
public void processDocument(UploadedPresentation pres) {
|
||||
|
||||
if (pres.isUploadFailed()) {
|
||||
// We should send a message to the client in the future.
|
||||
// ralam may 1, 2020
|
||||
log.error("Presentation upload failed for meetingId={} presId={}", pres.getMeetingId(), pres.getId());
|
||||
log.error("Presentation upload fail reasons {}", pres.getUploadFailReason());
|
||||
return;
|
||||
}
|
||||
|
||||
SupportedDocumentFilter sdf = new SupportedDocumentFilter(gw);
|
||||
|
||||
sendDocConversionRequestReceived(pres);
|
||||
|
@ -6,12 +6,14 @@ import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
@ -59,10 +61,19 @@ public class PresentationUrlDownloadService {
|
||||
}
|
||||
|
||||
public void processUploadedFile(String podId, String meetingId, String presId,
|
||||
String filename, File presFile, Boolean current, String authzToken) {
|
||||
String filename, File presFile, Boolean current, String authzToken,
|
||||
Boolean uploadFailed, ArrayList<String> uploadFailReasons) {
|
||||
// TODO add podId
|
||||
UploadedPresentation uploadedPres = new UploadedPresentation(podId, meetingId,
|
||||
presId, filename, presentationBaseURL, current, authzToken);
|
||||
UploadedPresentation uploadedPres = new UploadedPresentation(
|
||||
podId,
|
||||
meetingId,
|
||||
presId,
|
||||
filename,
|
||||
presentationBaseURL,
|
||||
current,
|
||||
authzToken,
|
||||
uploadFailed,
|
||||
uploadFailReasons);
|
||||
uploadedPres.setUploadedFile(presFile);
|
||||
processUploadedPresentation(uploadedPres);
|
||||
}
|
||||
@ -84,6 +95,9 @@ public class PresentationUrlDownloadService {
|
||||
private void extractPage(final String sourceMeetingId, final String presentationId,
|
||||
final Integer presentationSlide, final String destinationMeetingId) {
|
||||
|
||||
Boolean uploadFailed = false;
|
||||
ArrayList<String> uploadFailedReasons = new ArrayList<String>();
|
||||
|
||||
// Build the source meeting path
|
||||
File sourceMeetingPath = new File(presentationDir + File.separatorChar
|
||||
+ sourceMeetingId + File.separatorChar + sourceMeetingId
|
||||
@ -118,13 +132,13 @@ public class PresentationUrlDownloadService {
|
||||
} else {
|
||||
sourcePresentationFile = matches[0];
|
||||
}
|
||||
|
||||
// Build the target meeting path
|
||||
String filenameExt = FilenameUtils.getExtension(sourcePresentationFile
|
||||
.getName());
|
||||
String presId = generatePresentationId(presentationId);
|
||||
String filenameExt = FilenameUtils.getExtension(sourcePresentationFile.getName());
|
||||
String presId = Util.generatePresentationId(presentationId);
|
||||
String newFilename = Util.createNewFilename(presId, filenameExt);
|
||||
|
||||
File uploadDir = createPresentationDirectory(destinationMeetingId,
|
||||
File uploadDir = Util.createPresentationDir(destinationMeetingId,
|
||||
presentationDir, presId);
|
||||
String newFilePath = uploadDir.getAbsolutePath() + File.separatorChar
|
||||
+ newFilename;
|
||||
@ -143,27 +157,15 @@ 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, "breakout-authz-token");
|
||||
}
|
||||
|
||||
public String generatePresentationId(String name) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
return DigestUtils.sha1Hex(name) + "-" + timestamp;
|
||||
}
|
||||
|
||||
public File createPresentationDirectory(String meetingId,
|
||||
String presentationDir, String presentationId) {
|
||||
String meetingPath = presentationDir + File.separatorChar + meetingId
|
||||
+ File.separatorChar + meetingId;
|
||||
String presPath = meetingPath + File.separatorChar + presentationId;
|
||||
File dir = new File(presPath);
|
||||
log.debug("Creating dir [{}]", presPath);
|
||||
if (dir.mkdirs()) {
|
||||
return dir;
|
||||
}
|
||||
return null;
|
||||
processUploadedFile("DEFAULT_PRESENTATION_POD",
|
||||
destinationMeetingId,
|
||||
presId,
|
||||
"default-" + presentationSlide.toString() + "." + filenameExt,
|
||||
newPresentation,
|
||||
true,
|
||||
"breakout-authz-token",
|
||||
uploadFailed,
|
||||
uploadFailedReasons);
|
||||
}
|
||||
|
||||
private String followRedirect(String meetingId, String redirectUrl,
|
||||
|
@ -20,12 +20,15 @@
|
||||
package org.bigbluebutton.presentation;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class UploadedPresentation {
|
||||
private final String podId;
|
||||
private final String meetingId;
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final boolean uploadFailed;
|
||||
private final ArrayList<String> uploadFailReason;
|
||||
private File uploadedFile;
|
||||
private String fileType = "unknown";
|
||||
private int numberOfPages = 0;
|
||||
@ -36,13 +39,16 @@ public final class UploadedPresentation {
|
||||
private String authzToken;
|
||||
private boolean conversionStarted = false;
|
||||
|
||||
|
||||
public UploadedPresentation(String podId,
|
||||
String meetingId,
|
||||
String id,
|
||||
String name,
|
||||
String baseUrl,
|
||||
Boolean current,
|
||||
String authzToken) {
|
||||
String authzToken,
|
||||
Boolean uploadFailed,
|
||||
ArrayList<String> uploadFailReason) {
|
||||
this.podId = podId;
|
||||
this.meetingId = meetingId;
|
||||
this.id = id;
|
||||
@ -51,6 +57,8 @@ public final class UploadedPresentation {
|
||||
this.isDownloadable = false;
|
||||
this.current = current;
|
||||
this.authzToken = authzToken;
|
||||
this.uploadFailed = uploadFailed;
|
||||
this.uploadFailReason = uploadFailReason;
|
||||
}
|
||||
|
||||
public File getUploadedFile() {
|
||||
@ -132,4 +140,12 @@ public final class UploadedPresentation {
|
||||
public boolean isConversionStarted() {
|
||||
return conversionStarted;
|
||||
}
|
||||
|
||||
public boolean isUploadFailed() {
|
||||
return uploadFailed;
|
||||
}
|
||||
|
||||
public ArrayList<String> getUploadFailReason() {
|
||||
return uploadFailReason;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bigbluebutton.presentation.imp;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.bigbluebutton.api.Util;
|
||||
import org.bigbluebutton.presentation.*;
|
||||
import org.bigbluebutton.presentation.messages.DocPageConversionStarted;
|
||||
import org.bigbluebutton.presentation.messages.DocPageCountExceeded;
|
||||
@ -10,6 +11,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@ -53,6 +55,19 @@ public class PresentationFileProcessor {
|
||||
}
|
||||
|
||||
public synchronized void process(UploadedPresentation pres) {
|
||||
if (pres.isDownloadable()) {
|
||||
try {
|
||||
Util.makePresentationDownloadable(
|
||||
pres.getUploadedFile().getParent(),
|
||||
pres.getMeetingId(),
|
||||
pres.getId(),
|
||||
pres.isDownloadable()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to make presentation downloadable: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Runnable messageProcessor = new Runnable() {
|
||||
public void run() {
|
||||
processUploadedPresentation(pres);
|
||||
|
@ -2017,68 +2017,110 @@ class ApiController {
|
||||
}
|
||||
}
|
||||
|
||||
def processDocumentFromRawBytes(bytes, presFilename, meetingId, current) {
|
||||
def filenameExt = FilenameUtils.getExtension(presFilename);
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
def presId = Util.generatePresentationId(presFilename)
|
||||
File uploadDir = presDownloadService.createPresentationDirectory(meetingId, presentationDir, presId)
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
def pres = new File(uploadDir.absolutePath + File.separatorChar + newFilename);
|
||||
def processDocumentFromRawBytes(bytes, presOrigFilename, meetingId, current) {
|
||||
def uploadFailed = false
|
||||
def uploadFailReasons = new ArrayList<String>()
|
||||
|
||||
FileOutputStream fos = new java.io.FileOutputStream(pres)
|
||||
fos.write(bytes)
|
||||
fos.flush()
|
||||
fos.close()
|
||||
// Gets the name minus the path from a full fileName.
|
||||
// a/b/c.txt --> c.txt
|
||||
def presFilename = FilenameUtils.getName(presOrigFilename)
|
||||
def filenameExt = FilenameUtils.getExtension(presOrigFilename)
|
||||
def pres = null
|
||||
def presId = null
|
||||
|
||||
// Hardcode pre-uploaded presentation to the default presentation window
|
||||
processUploadedFile("DEFAULT_PRESENTATION_POD",
|
||||
if (presFilename == "" || filenameExt == "") {
|
||||
log.debug("Upload failed. Invalid filename " + presOrigFilename)
|
||||
uploadFailReasons.add("invalid_filename")
|
||||
uploadFailed = true
|
||||
} else {
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
presId = Util.generatePresentationId(presFilename)
|
||||
|
||||
File uploadDir = Util.createPresentationDir(meetingId, presentationDir, presId)
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
pres = new File(uploadDir.absolutePath + File.separatorChar + newFilename);
|
||||
|
||||
FileOutputStream fos = new java.io.FileOutputStream(pres)
|
||||
fos.write(bytes)
|
||||
fos.flush()
|
||||
fos.close()
|
||||
} else {
|
||||
log.warn "Upload failed. File Empty."
|
||||
uploadFailReasons.add("failed_to_download_file")
|
||||
uploadFailed = true
|
||||
}
|
||||
}
|
||||
|
||||
// Hardcode pre-uploaded presentation to the default presentation window
|
||||
processUploadedFile("DEFAULT_PRESENTATION_POD",
|
||||
meetingId,
|
||||
presId,
|
||||
presFilename,
|
||||
pres,
|
||||
current,
|
||||
"preupload-raw-authz-token");
|
||||
}
|
||||
|
||||
"preupload-raw-authz-token",
|
||||
uploadFailed,
|
||||
uploadFailReasons)
|
||||
}
|
||||
|
||||
def downloadAndProcessDocument(address, meetingId, current, fileName) {
|
||||
log.debug("ApiController#downloadAndProcessDocument(${address}, ${meetingId}, ${fileName})");
|
||||
String presFilename;
|
||||
String presOrigFilename;
|
||||
if (StringUtils.isEmpty(fileName)) {
|
||||
presFilename = address.tokenize("/")[-1];
|
||||
presOrigFilename = address.tokenize("/")[-1];
|
||||
} else {
|
||||
presFilename = fileName;
|
||||
presOrigFilename = fileName;
|
||||
}
|
||||
|
||||
def filenameExt = FilenameUtils.getExtension(presFilename);
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
def uploadFailed = false
|
||||
def uploadFailReasons = new ArrayList<String>()
|
||||
|
||||
def presId = presDownloadService.generatePresentationId(presFilename)
|
||||
File uploadDir = presDownloadService.createPresentationDirectory(meetingId, presentationDir, presId)
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
def newFilePath = uploadDir.absolutePath + File.separatorChar + newFilename
|
||||
// Gets the name minus the path from a full fileName.
|
||||
// a/b/c.txt --> c.txt
|
||||
def presFilename = FilenameUtils.getName(presOrigFilename)
|
||||
def filenameExt = FilenameUtils.getExtension(presOrigFilename)
|
||||
def pres = null
|
||||
def presId
|
||||
|
||||
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,
|
||||
"preupload-download-authz-token");
|
||||
} else {
|
||||
log.error("Failed to download presentation=[${address}], meeting=[${meetingId}], fileName=[${fileName}]")
|
||||
if (presFilename == "" || filenameExt == "") {
|
||||
log.debug("Upload failed. Invalid filename " + presOrigFilename)
|
||||
uploadFailReasons.add("invalid_filename")
|
||||
uploadFailed = true
|
||||
} else {
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
presId = Util.generatePresentationId(presFilename)
|
||||
File uploadDir = Util.createPresentationDir(meetingId, presentationDir, presId)
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
def newFilePath = uploadDir.absolutePath + File.separatorChar + newFilename
|
||||
|
||||
if (presDownloadService.savePresentation(meetingId, newFilePath, address)) {
|
||||
pres = new File(newFilePath)
|
||||
} else {
|
||||
log.error("Failed to download presentation=[${address}], meeting=[${meetingId}], fileName=[${fileName}]")
|
||||
uploadFailReasons.add("failed_to_download_file")
|
||||
uploadFailed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hardcode pre-uploaded presentation to the default presentation window
|
||||
processUploadedFile(
|
||||
"DEFAULT_PRESENTATION_POD",
|
||||
meetingId,
|
||||
presId,
|
||||
presFilename,
|
||||
pres,
|
||||
current,
|
||||
"preupload-download-authz-token",
|
||||
uploadFailed,
|
||||
uploadFailReasons
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def processUploadedFile(podId, meetingId, presId, filename, presFile, current, authzToken) {
|
||||
def processUploadedFile(podId, meetingId, presId, filename, presFile, current, authzToken, uploadFailed, uploadFailReasons ) {
|
||||
def presentationBaseUrl = presentationService.presentationBaseUrl
|
||||
// TODO add podId
|
||||
UploadedPresentation uploadedPres = new UploadedPresentation(podId,
|
||||
@ -2087,7 +2129,9 @@ class ApiController {
|
||||
filename,
|
||||
presentationBaseUrl,
|
||||
current,
|
||||
authzToken);
|
||||
authzToken,
|
||||
uploadFailed,
|
||||
uploadFailReasons)
|
||||
uploadedPres.setUploadedFile(presFile);
|
||||
presentationService.processUploadedPresentation(uploadedPres);
|
||||
}
|
||||
|
@ -76,73 +76,95 @@ class PresentationController {
|
||||
// check if the authorization token provided is valid
|
||||
if (null == params.authzToken || !meetingService.authzTokenIsValidAndExpired(params.authzToken)) {
|
||||
log.debug "WARNING! AuthzToken=" + params.authzToken + " was not valid in meetingId=" + params.conference
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'invalid auth token'
|
||||
return
|
||||
}
|
||||
|
||||
def meetingId = params.conference
|
||||
def meeting = meetingService.getNotEndedMeetingWithId(meetingId);
|
||||
if (meeting == null) {
|
||||
flash.message = 'meeting is not running'
|
||||
log.debug("Upload failed. No meeting running " + meetingId)
|
||||
if (Util.isMeetingIdValidFormat(meetingId)) {
|
||||
def meeting = meetingService.getNotEndedMeetingWithId(meetingId)
|
||||
if (meeting == null) {
|
||||
log.debug("Upload failed. No meeting running " + meetingId)
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'no-meeting'
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.debug("Upload failed. Invalid meeting id format " + meetingId)
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'no-meeting';
|
||||
return
|
||||
}
|
||||
|
||||
def isDownloadable = params.boolean('is_downloadable') //instead of params.is_downloadable
|
||||
def podId = params.pod_id
|
||||
log.debug "@Default presentation pod" + podId
|
||||
|
||||
def uploadFailed = false
|
||||
def uploadFailReasons = new ArrayList<String>()
|
||||
def presOrigFilename = ""
|
||||
def presFilename = ""
|
||||
def filenameExt = ""
|
||||
def presId = ""
|
||||
def pres = null
|
||||
|
||||
def file = request.getFile('fileUpload')
|
||||
if (file && !file.empty) {
|
||||
flash.message = 'Your file has been uploaded'
|
||||
def presFilename = file.getOriginalFilename()
|
||||
def filenameExt = FilenameUtils.getExtension(presFilename);
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
def presId = Util.generatePresentationId(presFilename)
|
||||
File uploadDir = Util.createPresentationDir(meetingId, presentationDir, presId)
|
||||
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
def pres = new File(uploadDir.absolutePath + File.separatorChar + newFilename)
|
||||
file.transferTo(pres)
|
||||
|
||||
def isDownloadable = params.boolean('is_downloadable') //instead of params.is_downloadable
|
||||
def podId = params.pod_id
|
||||
log.debug "@Default presentation pod" + podId
|
||||
|
||||
if (isDownloadable) {
|
||||
log.debug "@Creating download directory..."
|
||||
File downloadDir = Util.downloadPresentationDirectory(uploadDir.absolutePath)
|
||||
if (downloadDir != null) {
|
||||
def notValidCharsRegExp = /[^0-9a-zA-Z_\.]/
|
||||
def downloadableFileName = presFilename.replaceAll(notValidCharsRegExp, '-')
|
||||
def downloadableFile = new File(downloadDir.absolutePath + File.separatorChar + downloadableFileName)
|
||||
downloadableFile << pres.newInputStream()
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("processing file upload " + presFilename)
|
||||
def presentationBaseUrl = presentationService.presentationBaseUrl
|
||||
UploadedPresentation uploadedPres = new UploadedPresentation(podId, meetingId, presId,
|
||||
presFilename, presentationBaseUrl, false /* default presentation */,
|
||||
params.authzToken);
|
||||
|
||||
if (isDownloadable) {
|
||||
log.debug "@Setting file to be downloadable..."
|
||||
uploadedPres.setDownloadable();
|
||||
}
|
||||
|
||||
uploadedPres.setUploadedFile(pres);
|
||||
presentationService.processUploadedPresentation(uploadedPres)
|
||||
log.debug("file upload success " + presFilename)
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'upload-success'
|
||||
}
|
||||
presOrigFilename = file.getOriginalFilename()
|
||||
// Gets the name minus the path from a full fileName.
|
||||
// a/b/c.txt --> c.txt
|
||||
presFilename = FilenameUtils.getName(presOrigFilename)
|
||||
filenameExt = FilenameUtils.getExtension(presFilename)
|
||||
} else {
|
||||
log.warn "Upload failed. File Empty."
|
||||
flash.message = 'file cannot be empty'
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'file-empty'
|
||||
uploadFailReasons.add("uploaded_file_empty")
|
||||
uploadFailed = true
|
||||
}
|
||||
|
||||
if (presFilename == "" || filenameExt == "") {
|
||||
log.debug("Upload failed. Invalid filename " + presOrigFilename)
|
||||
uploadFailReasons.add("invalid_filename")
|
||||
uploadFailed = true
|
||||
} else {
|
||||
String presentationDir = presentationService.getPresentationDir()
|
||||
presId = Util.generatePresentationId(presFilename)
|
||||
File uploadDir = Util.createPresentationDir(meetingId, presentationDir, presId)
|
||||
if (uploadDir != null) {
|
||||
def newFilename = Util.createNewFilename(presId, filenameExt)
|
||||
pres = new File(uploadDir.absolutePath + File.separatorChar + newFilename)
|
||||
file.transferTo(pres)
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("processing file upload " + presFilename)
|
||||
def presentationBaseUrl = presentationService.presentationBaseUrl
|
||||
UploadedPresentation uploadedPres = new UploadedPresentation(
|
||||
podId,
|
||||
meetingId,
|
||||
presId,
|
||||
presFilename,
|
||||
presentationBaseUrl,
|
||||
false /* default presentation */,
|
||||
params.authzToken,
|
||||
uploadFailed,
|
||||
uploadFailReasons
|
||||
)
|
||||
|
||||
if (isDownloadable) {
|
||||
log.debug "@Setting file to be downloadable..."
|
||||
uploadedPres.setDownloadable();
|
||||
}
|
||||
|
||||
uploadedPres.setUploadedFile(pres);
|
||||
presentationService.processUploadedPresentation(uploadedPres)
|
||||
log.debug("file upload success " + presFilename)
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
response.contentType = 'plain/text'
|
||||
response.outputStream << 'upload-success'
|
||||
}
|
||||
|
||||
def testConversion = {
|
||||
|
Loading…
Reference in New Issue
Block a user