Skip to content
Snippets Groups Projects
Commit ed72e731 authored by srosse's avatar srosse
Browse files

Merge remote-tracking branch 'origin/OpenOLAT_15.2' into OpenOLAT_15.3

parents 369ef660 029f9313
No related branches found
No related tags found
No related merge requests found
...@@ -22,12 +22,14 @@ package org.olat.course.nodes.pf.manager; ...@@ -22,12 +22,14 @@ package org.olat.course.nodes.pf.manager;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor; import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -44,12 +46,15 @@ import org.olat.core.gui.media.ServletUtil; ...@@ -44,12 +46,15 @@ import org.olat.core.gui.media.ServletUtil;
import org.olat.core.gui.translator.Translator; import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.core.logging.Tracing; import org.olat.core.logging.Tracing;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper; import org.olat.core.util.StringHelper;
import org.olat.core.util.Util; import org.olat.core.util.Util;
import org.olat.core.util.io.ShieldOutputStream;
import org.olat.core.util.io.SystemFileFilter; import org.olat.core.util.io.SystemFileFilter;
import org.olat.course.nodes.PFCourseNode; import org.olat.course.nodes.PFCourseNode;
import org.olat.course.nodes.pf.ui.PFParticipantController; import org.olat.course.nodes.pf.ui.PFParticipantController;
import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.environment.CourseEnvironment;
import org.olat.repository.RepositoryEntry;
import org.olat.user.UserManager; import org.olat.user.UserManager;
/** /**
* *
...@@ -107,6 +112,14 @@ public class FileSystemExport implements MediaResource { ...@@ -107,6 +112,14 @@ public class FileSystemExport implements MediaResource {
@Override @Override
public void prepare(HttpServletResponse hres) { public void prepare(HttpServletResponse hres) {
RepositoryEntry entry = courseEnv.getCourseGroupManager().getCourseEntry();
String label = StringHelper.transformDisplayNameToFileSystemName(pfNode.getShortName() + "_" + entry.getDisplayname())
+ "_" + Formatter.formatDatetimeWithMinutes(new Date())
+ ".zip";
String urlEncodedLabel = StringHelper.urlEncodeUTF8(label);
hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + urlEncodedLabel);
hres.setHeader("Content-Description", urlEncodedLabel);
try (ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) { try (ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) {
zout.setLevel(9); zout.setLevel(9);
Path relPath = Paths.get(courseEnv.getCourseBaseContainer().getBasefile().getAbsolutePath(), Path relPath = Paths.get(courseEnv.getCourseBaseContainer().getBasefile().getAbsolutePath(),
...@@ -132,8 +145,8 @@ public class FileSystemExport implements MediaResource { ...@@ -132,8 +145,8 @@ public class FileSystemExport implements MediaResource {
* @param translator * @param translator
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
public static boolean fsToZip(ZipOutputStream zout, String zipPath, final Path sourceFolder, PFCourseNode pfNode, public static boolean fsToZip(final ZipOutputStream zout, String zipPath, final Path sourceFolder, PFCourseNode pfNode,
List<Identity> identities, Translator translator) { List<Identity> identities, final Translator translator) {
if(StringHelper.containsNonWhitespace(zipPath)) { if(StringHelper.containsNonWhitespace(zipPath)) {
if(!zipPath.endsWith("/")) { if(!zipPath.endsWith("/")) {
...@@ -143,7 +156,7 @@ public class FileSystemExport implements MediaResource { ...@@ -143,7 +156,7 @@ public class FileSystemExport implements MediaResource {
zipPath = ""; zipPath = "";
} }
final String targetPath = zipPath + translator.translate("participant.folder") + "/"; final String targetPath = zipPath;
final UserManager userManager = CoreSpringFactory.getImpl(UserManager.class); final UserManager userManager = CoreSpringFactory.getImpl(UserManager.class);
Set<String> idKeys = new HashSet<>(); Set<String> idKeys = new HashSet<>();
if (identities != null) { if (identities != null) {
...@@ -188,7 +201,7 @@ public class FileSystemExport implements MediaResource { ...@@ -188,7 +201,7 @@ public class FileSystemExport implements MediaResource {
String relPath = sourceFolder.relativize(file).toString(); String relPath = sourceFolder.relativize(file).toString();
if ((relPath = containsID(relPath)) != null && (relPath = boxesEnabled(relPath)) != null) { if ((relPath = containsID(relPath)) != null && (relPath = boxesEnabled(relPath)) != null) {
zout.putNextEntry(new ZipEntry(targetPath + relPath)); zout.putNextEntry(new ZipEntry(targetPath + relPath));
Files.copy(file, zout); copyFile(file, zout);
zout.closeEntry(); zout.closeEntry();
} }
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
...@@ -204,7 +217,6 @@ public class FileSystemExport implements MediaResource { ...@@ -204,7 +217,6 @@ public class FileSystemExport implements MediaResource {
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
}); });
zout.close();
return true; return true;
} catch (IOException e) { } catch (IOException e) {
log.error("Unable to export zip",e); log.error("Unable to export zip",e);
...@@ -212,4 +224,12 @@ public class FileSystemExport implements MediaResource { ...@@ -212,4 +224,12 @@ public class FileSystemExport implements MediaResource {
} }
} }
private static void copyFile(Path file, ZipOutputStream zout) {
try(OutputStream out= new ShieldOutputStream(zout)) {
Files.copy(file, zout);
} catch(Exception e) {
log.error("Cannot zip {}", file, e);
}
}
} }
\ No newline at end of file
...@@ -63,7 +63,6 @@ import org.olat.core.gui.util.SyntheticUserRequest; ...@@ -63,7 +63,6 @@ import org.olat.core.gui.util.SyntheticUserRequest;
import org.olat.core.gui.util.WindowControlMocker; import org.olat.core.gui.util.WindowControlMocker;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.core.id.Roles; import org.olat.core.id.Roles;
import org.olat.core.id.UserConstants;
import org.olat.core.logging.Tracing; import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils; import org.olat.core.util.FileUtils;
import org.olat.core.util.Formatter; import org.olat.core.util.Formatter;
...@@ -300,12 +299,24 @@ public class QTI21ResultsExportMediaResource implements MediaResource { ...@@ -300,12 +299,24 @@ public class QTI21ResultsExportMediaResource implements MediaResource {
if(identity == null || identity.getStatus() == null || identity.getStatus().equals(Identity.STATUS_DELETED)) { if(identity == null || identity.getStatus() == null || identity.getStatus().equals(Identity.STATUS_DELETED)) {
continue; continue;
} }
String lastNameOrAnoymous = identity.getUser().getLastName(); String nickname = identity.getUser().getNickName();
if(!StringHelper.containsNonWhitespace(lastNameOrAnoymous)) { String firstName = identity.getUser().getFirstName();
lastNameOrAnoymous = "anonym"; String lastNameOrAnonymous = identity.getUser().getLastName();
if(!StringHelper.containsNonWhitespace(lastNameOrAnonymous)) {
lastNameOrAnonymous = "anonym";
} }
String lastname = StringHelper.transformDisplayNameToFileSystemName(lastNameOrAnoymous); String nameOrAnonymous = lastNameOrAnonymous;
String idDir = exportFolderName + "/" + DATA + lastname + "_" + identity.getKey(); if(StringHelper.containsNonWhitespace(firstName)) {
nameOrAnonymous += "_" + firstName;
}
if(StringHelper.containsNonWhitespace(nickname)) {
nameOrAnonymous += "_" + nickname;
} else {
nameOrAnonymous += "_" + identity.getKey();
}
String names = StringHelper.transformDisplayNameToFileSystemName(nameOrAnonymous);
String idDir = exportFolderName + "/" + DATA + names;
idDir = idDir.endsWith(SEP) ? idDir : idDir + SEP; idDir = idDir.endsWith(SEP) ? idDir : idDir + SEP;
createZipDirectory(zout, idDir); createZipDirectory(zout, idDir);
...@@ -323,8 +334,7 @@ public class QTI21ResultsExportMediaResource implements MediaResource { ...@@ -323,8 +334,7 @@ public class QTI21ResultsExportMediaResource implements MediaResource {
String linkToUser = idDir.replace(exportFolderName + "/", "") + "index.html"; String linkToUser = idDir.replace(exportFolderName + "/", "") + "index.html";
String memberEmail = userManager.getUserDisplayEmail(identity, ureq.getLocale()); String memberEmail = userManager.getUserDisplayEmail(identity, ureq.getLocale());
AssessedMember member = new AssessedMember(identity.getUser().getProperty(UserConstants.NICKNAME, null), AssessedMember member = new AssessedMember(nickname, lastNameOrAnonymous, firstName,
lastNameOrAnoymous, identity.getUser().getFirstName(),
memberEmail, assessments.size(), passed, score, linkToUser); memberEmail, assessments.size(), passed, score, linkToUser);
String singleUserInfoHTML = createResultListingHTML(assessments, assessmentDocuments, member); String singleUserInfoHTML = createResultListingHTML(assessments, assessmentDocuments, member);
......
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
<table id='oneUser' class='table table-striped table-hover'> <table id='oneUser' class='table table-striped table-hover'>
<thead> <thead>
<tr> <tr>
<th>$t.translate("table.all.username")</th> <th scope="col">$t.translate("table.all.username")</th>
<th>$t.translate("table.all.lastname")</th> <th scope="col">$t.translate("table.all.lastname")</th>
<th>$t.translate("table.all.firstname")</th> <th scope="col">$t.translate("table.all.firstname")</th>
<th>$t.translate("table.user.email")</th> <th scope="col">$t.translate("table.user.email")</th>
<th>$t.translate("table.all.node.score")</th> <th scope="col">$t.translate("table.all.node.score")</th>
<th>$t.translate("table.all.node.passed")</th> <th scope="col">$t.translate("table.all.node.passed")</th>
<th>$t.translate("table.all.tries")</th> <th scope="col">$t.translate("table.all.tries")</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -48,17 +48,17 @@ ...@@ -48,17 +48,17 @@
<table id='results' class='table table-striped table-hover'> <table id='results' class='table table-striped table-hover'>
<thead> <thead>
<tr> <tr>
<th colspan="8">$t.translate("table.test.sessions")</th> <th colspan="8" scope="col">$t.translate("table.test.sessions")</th>
</tr> </tr>
<tr> <tr>
<th>$t.translate("table.user.id")</th> <th scope="col">$t.translate("table.user.id")</th>
<th>$t.translate("table.user.date")</th> <th scope="col">$t.translate("table.user.date")</th>
<th>$t.translate("table.user.duration")</th> <th scope="col">$t.translate("table.user.duration")</th>
<th>$t.translate("table.user.score")</th> <th scope="col">$t.translate("table.user.score")</th>
<th>$t.translate("table.user.manualScore")</th> <th scope="col">$t.translate("table.user.manualScore")</th>
<th>$t.translate("table.user.finalScore")</th> <th scope="col">$t.translate("table.user.finalScore")</th>
<th>$t.translate("table.all.passed")</th> <th scope="col">$t.translate("table.all.passed")</th>
<th>$t.translate("button.show")</th> <th scope="col">$t.translate("button.show")</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
<table id='assessmentDocuments' class='table table-striped table-hover'> <table id='assessmentDocuments' class='table table-striped table-hover'>
<thead> <thead>
<tr> <tr>
<th>$t.translate("assessment.docs")</th> <th scope="col">$t.translate("assessment.docs")</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
<table id='allUsers' class='table table-striped table-hover'> <table id='allUsers' class='table table-striped table-hover'>
<thead> <thead>
<tr> <tr>
<th>$t.translate("table.all.username")</th> <th scope="col">$t.translate("table.all.username")</th>
<th>$t.translate("table.all.lastname")</th> <th scope="col">$t.translate("table.all.lastname")</th>
<th>$t.translate("table.all.firstname")</th> <th scope="col">$t.translate("table.all.firstname")</th>
<th>$t.translate("table.all.score")</th> <th scope="col">$t.translate("table.all.score")</th>
<th>$t.translate("table.all.passed")</th> <th scope="col">$t.translate("table.all.passed")</th>
<th>$t.translate("table.all.tries")</th> <th scope="col">$t.translate("table.all.tries")</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment