diff --git a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java index a74eac51a8b63d4a74b749c63bfe5c09d0b84181..bec8188c4c68fe4d0623381246810e0c0d1c74b5 100644 --- a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java +++ b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java @@ -20,10 +20,17 @@ */ package org.olat.course.assessment.portfolio; +import java.io.File; +import java.util.List; +import java.util.Locale; +import java.util.Map; + import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.util.SyntheticUserRequest; +import org.olat.core.gui.util.WindowControlMocker; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -31,7 +38,10 @@ import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.xml.XStreamHelper; +import org.olat.course.assessment.AssessmentHelper; import org.olat.course.assessment.EfficiencyStatement; +import org.olat.course.assessment.model.AssessmentNodeData; +import org.olat.course.assessment.ui.tool.IdentityAssessmentOverviewController; import org.olat.course.certificate.ui.CertificateAndEfficiencyStatementController; import org.olat.modules.portfolio.Media; import org.olat.modules.portfolio.MediaInformations; @@ -42,6 +52,7 @@ import org.olat.modules.portfolio.handler.AbstractMediaHandler; import org.olat.modules.portfolio.manager.MediaDAO; import org.olat.modules.portfolio.ui.media.StandardEditMediaController; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -141,4 +152,23 @@ public class EfficiencyStatementMediaHandler extends AbstractMediaHandler { public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { return new StandardEditMediaController(ureq, wControl, media); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + EfficiencyStatement statement = null; + if(StringHelper.containsNonWhitespace(media.getContent())) { + try { + statement = (EfficiencyStatement)myXStream.fromXML(media.getContent()); + } catch (Exception e) { + log.error("Cannot load efficiency statement from artefact", e); + } + } + if(statement != null) { + List<Map<String,Object>> assessmentNodes = statement.getAssessmentNodes(); + List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.assessmentNodeDataMapToList(assessmentNodes); + SyntheticUserRequest ureq = new SyntheticUserRequest(media.getAuthor(), locale); + IdentityAssessmentOverviewController details = new IdentityAssessmentOverviewController(ureq, new WindowControlMocker(), assessmentNodeList); + super.exportContent(media, details.getInitialComponent(), null, mediaArchiveDirectory, locale); + } + } } diff --git a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java index ef47808a23cf8cb58310dd8e8607776d8edd63f9..5c068e2d629f0c54bb15a7de8e36c4bb31eabfbc 100644 --- a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java +++ b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java @@ -21,7 +21,10 @@ package org.olat.modules.fo.portfolio; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Locale; import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; @@ -30,6 +33,8 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.FileUtils; +import org.olat.core.util.StringHelper; +import org.olat.core.util.io.SystemFileFilter; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; @@ -51,6 +56,7 @@ import org.olat.modules.portfolio.manager.PortfolioFileStorage; import org.olat.modules.portfolio.ui.media.StandardEditMediaController; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -170,4 +176,17 @@ public class ForumMediaHandler extends AbstractMediaHandler { public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { return new StandardEditMediaController(ureq, wControl, media); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + List<File> attachments = new ArrayList<>(); + if(StringHelper.containsNonWhitespace(media.getStoragePath())) { + File mediaDir = fileStorage.getMediaDirectory(media); + if(mediaDir != null && mediaDir.exists()) { + File[] attachmentArr = mediaDir.listFiles(new SystemFileFilter(true, false)); + attachments = Arrays.asList(attachmentArr); + } + } + super.exportContent(media, null, attachments, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/portfolio/MediaHandler.java b/src/main/java/org/olat/modules/portfolio/MediaHandler.java index 8f6f4c9569f34b08755c7d71ff06677a2fc3f6e4..32200a10842d4bc380e371a0446b3bd9f2cfbf2b 100644 --- a/src/main/java/org/olat/modules/portfolio/MediaHandler.java +++ b/src/main/java/org/olat/modules/portfolio/MediaHandler.java @@ -20,6 +20,9 @@ */ package org.olat.modules.portfolio; +import java.io.File; +import java.util.Locale; + import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; @@ -27,6 +30,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSLeaf; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; /** * @@ -57,5 +61,15 @@ public interface MediaHandler { public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media, MediaRenderingHints hints); public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media); + + /** + * Export the user data. + * + * @param identity The identity + * @param manifest A manifest for all the files added to the archive + * @param archiveDirectory The directory where the files can be safely saved. + * @param locale The language + */ + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale); } diff --git a/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java b/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java index 382328b871439baa5f34a447b0fa1aded8e03ffe..cee0e8ab9ed618fbea99b4f7817462e60fb857ef 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java @@ -19,9 +19,32 @@ */ package org.olat.modules.portfolio.handler; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Locale; + +import org.olat.core.gui.DefaultGlobalSettings; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.render.EmptyURLBuilder; +import org.olat.core.gui.render.RenderResult; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.velocity.VelocityRenderDecorator; +import org.olat.core.gui.translator.Translator; +import org.olat.core.gui.util.SyntheticUserRequest; +import org.olat.core.gui.util.WindowControlMocker; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.FileUtils; +import org.olat.core.util.StringHelper; +import org.olat.core.util.Util; import org.olat.modules.portfolio.Media; import org.olat.modules.portfolio.MediaHandler; import org.olat.modules.portfolio.MediaInformations; @@ -29,6 +52,8 @@ import org.olat.modules.portfolio.MediaLight; import org.olat.modules.portfolio.MediaRenderingHints; import org.olat.modules.portfolio.model.MediaPart; import org.olat.modules.portfolio.model.StandardMediaRenderingHints; +import org.olat.modules.portfolio.ui.MediaCenterController; +import org.olat.modules.portfolio.ui.MediaMetadataController; import org.olat.modules.portfolio.ui.editor.PageElement; import org.olat.modules.portfolio.ui.editor.PageElementHandler; import org.olat.modules.portfolio.ui.editor.PageElementRenderingHints; @@ -43,6 +68,8 @@ import org.olat.modules.portfolio.ui.editor.PageRunElement; */ public abstract class AbstractMediaHandler implements MediaHandler, PageElementHandler { + private static final OLog log = Tracing.createLoggerFor(AbstractMediaHandler.class); + private final String type; public AbstractMediaHandler(String type) { @@ -83,6 +110,64 @@ public abstract class AbstractMediaHandler implements MediaHandler, PageElementH return null; } + /** + * A utility method to export media with content or a content component. The + * attached files are added to the output as a list of links. + * + * + * @param media The media to export + * @param contentCmp Optional, if not present with simply print the content of the media + * @param attachments Optional, a list of document to be attached to the media + * @param mediaArchiveDirectory The directory where all the medias are exported + * @param locale The language + */ + protected void exportContent(Media media, Component contentCmp, List<File> attachments, File mediaArchiveDirectory, Locale locale) { + String title = StringHelper.transformDisplayNameToFileSystemName(media.getTitle()); + File mediaFile = new File(mediaArchiveDirectory, media.getKey() + "_" + title + ".html"); + try(OutputStream out = new FileOutputStream(mediaFile)) { + String content = exportContent(media, contentCmp, attachments, locale); + out.write(content.getBytes("UTF-8")); + out.flush(); + } catch(IOException e) { + log.error("", e); + } + + if(attachments != null && !attachments.isEmpty()) { + File attachmentsDir = new File(mediaArchiveDirectory, media.getKey().toString()); + attachmentsDir.mkdir(); + for(File attachment:attachments) { + FileUtils.copyFileToDir(attachment, attachmentsDir, false, "Copy media artfacts"); + } + } + } + + private String exportContent(Media media, Component contentCmp, List<File> attachments, Locale locale) { + StringOutput sb = new StringOutput(10000); + Translator translator = Util.createPackageTranslator(MediaCenterController.class, locale); + String pagePath = Util.getPackageVelocityRoot(AbstractMediaHandler.class) + "/export_content.html"; + VelocityContainer component = new VelocityContainer("html", pagePath, translator, null); + component.contextPut("media", media); + if(contentCmp != null) { + component.put("contentCmp", contentCmp); + } else { + component.contextPut("content", media.getContent()); + } + component.contextPut("attachments", attachments); + + SyntheticUserRequest ureq = new SyntheticUserRequest(null, locale); + MediaMetadataController metadata = new MediaMetadataController(ureq, new WindowControlMocker(), media); + component.put("metadata", metadata.getInitialComponent()); + + Renderer renderer = Renderer.getInstance(component, translator, new EmptyURLBuilder(), new RenderResult(), new DefaultGlobalSettings()); + try(VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, component, sb)) { + component.contextPut("r", vrdec); + renderer.render(sb, component, null); + } catch(IOException e) { + log.error("", e); + } + return sb.toString(); + } + public final class Informations implements MediaInformations { private final String title; diff --git a/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java b/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java index 34915d42b7a6d41f542a24b0a5d581b1e453396e..ddc214ddab2f3ecde0649a7ae88fd8a51f8d76b8 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java @@ -19,6 +19,9 @@ */ package org.olat.modules.portfolio.handler; +import java.io.File; +import java.util.Locale; + import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; @@ -37,6 +40,7 @@ import org.olat.modules.portfolio.ui.editor.PageElementAddController; import org.olat.modules.portfolio.ui.media.CitationMediaController; import org.olat.modules.portfolio.ui.media.CollectCitationMediaController; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -106,4 +110,9 @@ public class CitationHandler extends AbstractMediaHandler implements Interactive public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) { return new CollectCitationMediaController(ureq, wControl); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + super.exportContent(media, null, null, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java index b34adbd5d7323d80570fd41d4a75a48e5c875037..35542bea2c056cc18555dfd47cbb886d90be0c07 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java @@ -20,6 +20,9 @@ package org.olat.modules.portfolio.handler; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; import org.olat.core.commons.modules.bc.meta.MetaInfo; import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged; @@ -51,6 +54,7 @@ import org.olat.modules.portfolio.ui.media.UploadMedia; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.artefacts.FileArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -198,4 +202,14 @@ public class FileHandler extends AbstractMediaHandler implements InteractiveAddP public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) { return new CollectFileMediaController(ureq, wControl); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + List<File> files = new ArrayList<>(); + if(StringHelper.containsNonWhitespace(media.getStoragePath()) && StringHelper.containsNonWhitespace(media.getRootFilename())) { + File mediaDir = fileStorage.getMediaDirectory(media); + files.add(new File(mediaDir, media.getRootFilename())); + } + super.exportContent(media, null, files, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java index 242f8b146ec6d81b73de968d431faaf12824c622..d1153c681544ec8727557b6eafb702a7d014d067 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java @@ -20,7 +20,10 @@ package org.olat.modules.portfolio.handler; import java.io.File; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; +import java.util.Locale; import java.util.Set; import org.olat.core.commons.modules.bc.meta.MetaInfo; @@ -50,6 +53,7 @@ import org.olat.modules.portfolio.ui.media.CollectImageMediaController; import org.olat.modules.portfolio.ui.media.ImageMediaController; import org.olat.modules.portfolio.ui.media.UploadMedia; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -176,4 +180,12 @@ public class ImageHandler extends AbstractMediaHandler implements InteractiveAdd public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) { return new CollectImageMediaController(ureq, wControl); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + List<File> images = new ArrayList<>(); + File mediaDir = fileStorage.getMediaDirectory(media); + images.add(new File(mediaDir, media.getRootFilename())); + super.exportContent(media, null, images, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java index 4905cea59761c9ad754b89b01a3202975d34f620..9f4608b6889dfec5a2d4024950c1fff4348144bf 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java @@ -19,6 +19,9 @@ */ package org.olat.modules.portfolio.handler; +import java.io.File; +import java.util.Locale; + import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; @@ -37,6 +40,7 @@ import org.olat.modules.portfolio.ui.media.CollectTextMediaController; import org.olat.modules.portfolio.ui.media.TextMediaController; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -117,6 +121,11 @@ public class TextHandler extends AbstractMediaHandler { public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { return new CollectTextMediaController(ureq, wControl, media); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + super.exportContent(media, null, null, mediaArchiveDirectory, locale); + } /*@Override public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) { diff --git a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java index 39a4b58bf78790251d086928f74eecd1d9cd1d84..dff7b8d01c46921ae08e03b8c2378713ca00d829 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java @@ -20,7 +20,10 @@ package org.olat.modules.portfolio.handler; import java.io.File; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; +import java.util.Locale; import java.util.Set; import org.olat.core.commons.modules.bc.meta.MetaInfo; @@ -50,6 +53,7 @@ import org.olat.modules.portfolio.ui.media.CollectVideoMediaController; import org.olat.modules.portfolio.ui.media.UploadMedia; import org.olat.modules.portfolio.ui.media.VideoMediaController; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -173,4 +177,12 @@ public class VideoHandler extends AbstractMediaHandler implements InteractiveAdd public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) { return new CollectVideoMediaController(ureq, wControl); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + List<File> videos = new ArrayList<>(); + File mediaDir = fileStorage.getMediaDirectory(media); + videos.add(new File(mediaDir, media.getRootFilename())); + super.exportContent(media, null, videos, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html b/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html new file mode 100644 index 0000000000000000000000000000000000000000..00ba3ddcb97ef481a9804adf3484acd5e14ead50 --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html @@ -0,0 +1,33 @@ +<html> + <head> + <title>$r.escapeHtml($media.title)</title> + <meta http-equiv="Content-type" content="text/html; charset=utf-8"> + </head> + <body> + <fieldset> + <legend>$r.translate("metadata.title")</legend> + $r.render("metadata") + </fieldset> + <fieldset> + <legend>$r.translate("content.title")</legend> + #if($r.available("contentCmp")) + <div>$r.render("contentCmp")</div> + #else + <div>$media.content</div> + #end + #if($r.isNotEmpty($attachments)) + <div class="o_attachments"> + <h5>$r.translate("attachments"):</h5> + <ul class="list-inline"> + #foreach($attachment in $attachments) + #set($fname = $attachment.getName()) + <li class="o_attachment"> + <a href="${media.key}/${fname}" target="_blank"><span class="o_filename">$r.escapeHtml($fname)</span></a> + </li> + #end + </ul> + </div> + #end + </fieldset> + </body> +</html> \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java index 845c4fc286bc7c1e31a4f50dbb20043bf28253ed..77930423ffca5ede45022228d3ea5fa6fab5daf5 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java @@ -149,6 +149,10 @@ public class PortfolioFileStorage implements InitializingBean { return null; } + public File getMediaDirectory(MediaLight media) { + return new File(FolderConfig.getCanonicalRoot(), media.getStoragePath()); + } + public VFSContainer getMediaContainer(MediaLight media) { return new OlatRootFolderImpl("/" + media.getStoragePath(), null); } diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java index 9e533458874b307f627aaf96b3f7d5bed6de9405..5e36df4bb2c036c1b3f77d120d89cef0f96e0281 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java @@ -21,6 +21,7 @@ import org.olat.group.BusinessGroup; import org.olat.group.DeletableGroupData; import org.olat.modules.portfolio.Binder; import org.olat.modules.portfolio.Media; +import org.olat.modules.portfolio.MediaHandler; import org.olat.modules.portfolio.PortfolioRoles; import org.olat.modules.portfolio.PortfolioService; import org.olat.modules.portfolio.model.BinderImpl; @@ -111,10 +112,29 @@ public class PortfolioUserDataManager implements DeletableGroupData, UserDataDel @Override public void export(Identity identity, ManifestBuilder manifest, File archiveDirectory, Locale locale) { File portfolioArchive = new File(archiveDirectory, "Portfolios"); - portfolioArchive.mkdirs(); + portfolioArchive.mkdir(); + exportBinders(identity, portfolioArchive, locale); + exportMedias(identity, manifest, portfolioArchive, locale); + } + + private void exportMedias(Identity identity, ManifestBuilder manifest, File portfolioArchive, Locale locale) { + File mediasArchive = new File(portfolioArchive, "Media"); + mediasArchive.mkdir(); + + List<Media> medias = mediaDao.load(identity); + dbInstance.commitAndCloseSession(); + for(Media media:medias) { + MediaHandler handler = portfolioService.getMediaHandler(media.getType()); + handler.export(media, manifest, mediasArchive, locale); + } + } + + private void exportBinders(Identity identity, File portfolioArchive, Locale locale) { + File bindersArchive = new File(portfolioArchive, "Binders"); + bindersArchive.mkdir(); List<Binder> binders = binderDao.getOwnedBinders(identity); for(Binder binder:binders) { - exportBinder(binder, identity, portfolioArchive, locale); + exportBinder(binder, identity, bindersArchive, locale); } } diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties index 8f7634c770b8c1c245a518bfddefc3a10a99ec99..802a952a5c9a6df5bd47838842bc596fa54c62bd 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties @@ -58,6 +58,7 @@ assignment.type=Typ assignment.type.document=Dokument assignment.type.essay=Freitext assignment.type.form=Fragebogen +attachments=Dokumenten attachments.error.file.exists=Diese Datei existiert bereits und kann nicht erneut hochgeladen werden. attachments.upload.successful=Die Datei {0} wurde erfolgreich hochgeladen. Bei Bedarf k\u00F6nnen noch weitere Dateien angeh\u00E4ngt werden. author=Autor @@ -95,6 +96,7 @@ compare.evaluations=Auswertung confirmation=Best\u00E4tigung confirm.close.page=Wollen Sie diesen Eintrag abschliessen? Der Eintrag wird f\u00FCr den Lernenden anschliessend als abgeschlossen angezeigt. confirm.close.page.other.coaches=Die folgende Personen haben auch Zugriff auf diesen Eintrag: +content.title=Inhalt create.binder=Mappe erstellen create.empty.binder=Leere Mappe erstellen create.empty.binder.from.course=Mappe f\u00FCr Portfolioaufgabe aus Kurs erstellen @@ -222,6 +224,7 @@ meta.page.assignment=Hier ist eine Aufgabe. meta.page.assignment.type=Typ meta.section.assignments=<strong>Aufgabe</strong> in diesem Bereich meta.section.categories=<strong>Kategorien</strong> in diesem Bereich +metadata.title=Metadaten mf.creator=Autor mf.edition=Auflage mf.editor=Verlag diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties index 285340b6eefe4a8b9c351152b3b54aa457449647..410a41eaf058c61a862363733e74a3897a1c9a0a 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties @@ -58,6 +58,7 @@ assignment.type=Type assignment.type.document=Document assignment.type.essay=Essay assignment.type.form=Survey +attachments=Documents attachments.error.file.exists=This file already exists and can therefore not be uploaded again. attachments.upload.successful=File {0} successfully uploaded. Other files can still be attached if needed. author=Author @@ -95,6 +96,7 @@ compare.evaluations=Evaluation confirm.close.page=Do you really want to close this entry? The entry will be marked as closed for the trainee. confirm.close.page.other.coaches=The following persons also have access to this entry\: confirmation=Confirmation +content.title=Content create.binder=Create binder create.empty.binder=New empty binder create.empty.binder.from.course=New binder from course portfolio task @@ -222,6 +224,7 @@ meta.page.assignment=This is an assignment meta.page.assignment.type=Type meta.section.assignments=<strong>Assignments</strong> in this section meta.section.categories=<strong>Categories</strong> in this section +metadata.title=Metadata mf.creator=Author mf.edition=Edition mf.editor=Editor diff --git a/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java b/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java index 818cf51486458c978734bb22977ea1090adcd1e7..256626beb33d2ebe13bf311cf548584a0a75c9a8 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java @@ -128,8 +128,12 @@ public class CollectArtefactController extends FormBasicController { //TODO } - List<String> updatedCategories = categoriesEl.getValueList(); - portfolioService.updateCategories(mediaReference, updatedCategories); + if(mediaReference != null) { + List<String> updatedCategories = categoriesEl.getValueList(); + portfolioService.updateCategories(mediaReference, updatedCategories); + } else { + showError("ERROR"); + } fireEvent(ureq, Event.DONE_EVENT); } diff --git a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java index 10d1a8983219d2cdc8945c97a29042af00121493..be3c2b7fbb9ed18094acb343ab89435055a1f95b 100644 --- a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java +++ b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java @@ -20,6 +20,10 @@ package org.olat.modules.webFeed.portfolio; import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; @@ -27,6 +31,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.util.io.SystemFileFilter; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; @@ -44,6 +49,7 @@ import org.olat.modules.webFeed.Item; import org.olat.modules.webFeed.manager.FeedManager; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -148,4 +154,12 @@ public class BlogEntryMediaHandler extends AbstractMediaHandler { public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { return new StandardEditMediaController(ureq, wControl, media); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + File mediaDir = fileStorage.getMediaDirectory(media); + File[] files = mediaDir.listFiles(new SystemFileFilter(true, false)); + List<File> attachments = files == null ? Collections.emptyList() : Arrays.asList(files); + super.exportContent(media, null, attachments, mediaArchiveDirectory, locale); + } } diff --git a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java index b2cdead0e0b48b14565fd202177e8d4bd373bfb2..b0ec4c86ae89ee95addbdc06e6fb54024b09e5b5 100644 --- a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java +++ b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java @@ -21,6 +21,9 @@ */ package org.olat.modules.wiki.portfolio; +import java.io.File; +import java.util.Locale; + import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; @@ -39,6 +42,7 @@ import org.olat.modules.portfolio.manager.MediaDAO; import org.olat.modules.portfolio.ui.media.StandardEditMediaController; import org.olat.modules.wiki.WikiPage; import org.olat.portfolio.model.artefacts.AbstractArtefact; +import org.olat.user.manager.ManifestBuilder; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -124,4 +128,9 @@ public class WikiMediaHandler extends AbstractMediaHandler { public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { return new StandardEditMediaController(ureq, wControl, media); } + + @Override + public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) { + super.exportContent(media, null, null, mediaArchiveDirectory, locale); + } }