package controllers; import managers.FolderManager; import managers.MediaManager; import models.Folder; import models.Media; import models.services.NotificationService; import play.Configuration; import play.Logger; import play.db.jpa.Transactional; import play.mvc.Http.MultipartFormData; import play.mvc.Result; import play.mvc.Security; import javax.inject.Inject; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import views.html.Media.list; @Security.Authenticated(Secured.class) public class MediaController extends BaseController { final Logger.ALogger LOG = Logger.of(MediaController.class); MediaManager mediaManager; FolderManager folderManager; Configuration configuration; NotificationService notificationService; @Inject public MediaController(MediaManager mediaManager, FolderManager folderManager, Configuration configuration, NotificationService notificationService) { this.mediaManager = mediaManager; this.folderManager = folderManager; this.configuration = configuration; this.notificationService = notificationService; this.MAX_FILESIZE = configuration.getInt("media.maxSize.file"); } final static String tempPrefix = "htwplus_temp"; int MAX_FILESIZE; @Transactional(readOnly = true) public Result view(Long mediaId, String action) { Media media = mediaManager.findById(mediaId); if (media == null) { return notFound(); } if (Secured.viewMedia(media)) { switch (action) { case "show": response().setHeader("Content-Disposition", "inline; filename=\"" + media.fileName + "\""); break; case "download": response().setHeader("Content-Disposition", "attachment; filename=\"" + media.fileName + "\""); break; } return ok(media.file); } else { flash("error", "Dazu hast du keine Berechtigung!"); return Secured.nullRedirect(request()); } } public Result mediaList(Long folderId) { Folder folder = folderManager.findById(folderId); if (!Secured.viewFolder(folder)) { return forbidden("Dazu hast du keine Berechtigung"); } Folder rootFolder = FolderManager.findRoot(folder); List<Media> mediaSet = folder.files; List<Folder> folderList = folder.folders; for (Media media : mediaSet) { media.sizeInByte = mediaManager.bytesToString(media.size, false); } return ok(list.render(mediaSet, folderList, rootFolder.group.id)); } @Transactional public Result delete(Long id) { Media media = mediaManager.findById(id); if (media == null) { return notFound(); } if (!Secured.deleteMedia(media)) { return redirect(controllers.routes.Application.index()); } mediaManager.delete(media); flash("success", "Datei " + media.title + " erfolgreich gelöscht!"); return Secured.nullRedirect(request()); } @Transactional(readOnly = true) public Result multiView() { String[] action = request().body().asFormUrlEncoded().get("action"); Result ret = Secured.nullRedirect(request()); Media media; Folder folder; String[] mediaselection = request().body().asFormUrlEncoded().get("mediaSelection"); String[] folderSelection = request().body().asFormUrlEncoded().get("folderSelection"); if (mediaselection == null && folderSelection == null) { flash("error", "Bitte wähle mindestens eine Datei aus."); return ret; } if (action[0].equals("delete")) { // delete media files if (mediaselection != null) { for (String s : mediaselection) { try { media = mediaManager.findById(Long.parseLong(s)); } catch (NumberFormatException nfe) { Logger.error("Unable to parse media id: " + s, nfe); return ret; } if (Secured.deleteMedia(media)) { mediaManager.delete(media); } } } // delete folder and files if (folderSelection != null) { for (String folderId : folderSelection) { try { folder = folderManager.findById(Long.parseLong(folderId)); } catch (NumberFormatException nfe) { Logger.error("Unable to parse folder id: " + folderId, nfe); return ret; } if (Secured.deleteFolder(folder)) { folderManager.delete(folder); } } } flash("success", "Datei(en) erfolgreich gelöscht!"); } if (action[0].equals("download")) { String filename = createFileName("HTWplus"); List<Media> mediaList = new ArrayList<>(); // grab media files if (mediaselection != null) { for (String s : mediaselection) { try { media = mediaManager.findById(Long.parseLong(s)); } catch (NumberFormatException nfe) { Logger.error("Unable to parse media id: " + s, nfe); return ret; } if (Secured.viewMedia(media)) { mediaList.add(media); } } } // grab folder files if (folderSelection != null) { for (String folderId : folderSelection) { try { folder = folderManager.findById(Long.parseLong(folderId)); } catch (NumberFormatException nfe) { Logger.error("Unable to parse folder id: " + folderId, nfe); return ret; } if (Secured.viewFolder(folder)) { mediaList.addAll(folderManager.getAllMedia(folder)); } } } try { File file = createZIP(mediaList); response().setHeader("Content-disposition", "attachment; filename=\"" + filename + "\""); return ok(file); } catch (IOException e) { flash("error", "Etwas ist schiefgegangen. Bitte probiere es noch einmal!"); return ret; } } return ret; } private String createFileName(String prefix) { return prefix + "-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".zip"; } private File createZIP(List<Media> media) throws IOException { //cleanUpTemp(); // JUST FOR DEVELOPMENT, DO NOT USE IN PRODUCTION String tmpPath = configuration.getString("media.tempPath"); File file = File.createTempFile(tempPrefix, ".tmp", new File(tmpPath)); ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(file)); zipOut.setLevel(Deflater.NO_COMPRESSION); byte[] buffer = new byte[4092]; int byteCount = 0; for (Media m : media) { zipOut.putNextEntry(new ZipEntry(m.fileName)); FileInputStream fis = new FileInputStream(m.file); byteCount = 0; while ((byteCount = fis.read(buffer)) != -1) { zipOut.write(buffer, 0, byteCount); } fis.close(); zipOut.closeEntry(); } zipOut.flush(); zipOut.close(); return file; } /** * Upload some media. * * @param folderId Folder to upload. * @return Result */ @Transactional @SuppressWarnings("unchecked") public Result upload(Long folderId) { // Get the data MultipartFormData body = request().body().asMultipartFormData(); MultipartFormData.FilePart<File> upload = body.getFile("file"); Folder folder = folderManager.findById(folderId); if (!Secured.viewFolder(folder)) { return forbidden("Dazu hast du keine Berechtigung"); } if (upload != null) { // Create the Media models and perform some checks // File too big? if (mediaManager.byteAsMB(upload.getFile().length()) > MAX_FILESIZE) { return status(REQUEST_ENTITY_TOO_LARGE, "Es sind maximal "+ MAX_FILESIZE + " MByte pro Datei möglich."); } // File already exists? if (mediaManager.existsInFolder(upload.getFilename(), folder)) { return status(CONFLICT, "Eine Datei mit diesem Namen existiert bereits."); } // Everything is fine Media med = new Media(); med.title = upload.getFilename(); med.mimetype = upload.getContentType(); med.fileName = upload.getFilename(); med.file = upload.getFile(); med.owner = Component.currentAccount(); med.folder = folder; med.temporarySender = Component.currentAccount(); // Persist medialist and create notification(s) try { mediaManager.create(med); notificationService.createNotification(med, Media.MEDIA_NEW_MEDIA); LOG.info("New media " + med.fileName + " from " + med.owner.id + " in folder " + med.folder.id); } catch (Exception e) { return internalServerError("Während des Uploads ist etwas schiefgegangen!"); } return created("/media/" + med.id); } else { return internalServerError("Es konnte keine Datei gefunden werden!"); } } }