aboutsummaryrefslogtreecommitdiff
path: root/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2012-07-02 21:24:02 -0700
committerScott Jackson <daneren2005@gmail.com>2012-07-02 21:24:02 -0700
commita1a18f77a50804e0127dfa4b0f5240c49c541184 (patch)
tree19a38880afe505beddb5590379a8134d7730a277 /subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
parentb61d787706979e7e20f4c3c4f93c1f129d92273f (diff)
downloaddsub-a1a18f77a50804e0127dfa4b0f5240c49c541184.tar.gz
dsub-a1a18f77a50804e0127dfa4b0f5240c49c541184.tar.bz2
dsub-a1a18f77a50804e0127dfa4b0f5240c49c541184.zip
Initial Commit
Diffstat (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java')
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java260
1 files changed, 260 insertions, 0 deletions
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
new file mode 100644
index 00000000..de7bf8dd
--- /dev/null
+++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
@@ -0,0 +1,260 @@
+/*
+ This file is part of Subsonic.
+
+ Subsonic is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Subsonic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright 2009 (C) Sindre Mehus
+ */
+package net.sourceforge.subsonic.controller;
+
+import net.sourceforge.subsonic.*;
+import net.sourceforge.subsonic.domain.*;
+import net.sourceforge.subsonic.upload.*;
+import net.sourceforge.subsonic.service.*;
+import net.sourceforge.subsonic.util.*;
+import org.apache.commons.fileupload.*;
+import org.apache.commons.fileupload.servlet.*;
+import org.apache.commons.io.*;
+import org.apache.tools.zip.*;
+import org.springframework.web.servlet.*;
+import org.springframework.web.servlet.mvc.*;
+
+import javax.servlet.http.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Controller which receives uploaded files.
+ *
+ * @author Sindre Mehus
+ */
+public class UploadController extends ParameterizableViewController {
+
+ private static final Logger LOG = Logger.getLogger(UploadController.class);
+
+ private SecurityService securityService;
+ private PlayerService playerService;
+ private StatusService statusService;
+ private SettingsService settingsService;
+ public static final String UPLOAD_STATUS = "uploadStatus";
+
+ @Override
+ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+ Map<String, Object> map = new HashMap<String, Object>();
+ List<File> uploadedFiles = new ArrayList<File>();
+ List<File> unzippedFiles = new ArrayList<File>();
+ TransferStatus status = null;
+
+ try {
+
+ status = statusService.createUploadStatus(playerService.getPlayer(request, response, false, false));
+ status.setBytesTotal(request.getContentLength());
+
+ request.getSession().setAttribute(UPLOAD_STATUS, status);
+
+ // Check that we have a file upload request
+ if (!ServletFileUpload.isMultipartContent(request)) {
+ throw new Exception("Illegal request.");
+ }
+
+ File dir = null;
+ boolean unzip = false;
+
+ UploadListener listener = new UploadListenerImpl(status);
+
+ FileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
+ ServletFileUpload upload = new ServletFileUpload(factory);
+
+ List<?> items = upload.parseRequest(request);
+
+ // First, look for "dir" and "unzip" parameters.
+ for (Object o : items) {
+ FileItem item = (FileItem) o;
+
+ if (item.isFormField() && "dir".equals(item.getFieldName())) {
+ dir = new File(item.getString());
+ } else if (item.isFormField() && "unzip".equals(item.getFieldName())) {
+ unzip = true;
+ }
+ }
+
+ if (dir == null) {
+ throw new Exception("Missing 'dir' parameter.");
+ }
+
+ // Look for file items.
+ for (Object o : items) {
+ FileItem item = (FileItem) o;
+
+ if (!item.isFormField()) {
+ String fileName = item.getName();
+ if (fileName.trim().length() > 0) {
+
+ File targetFile = new File(dir, new File(fileName).getName());
+
+ if (!securityService.isUploadAllowed(targetFile)) {
+ throw new Exception("Permission denied: " + StringUtil.toHtml(targetFile.getPath()));
+ }
+
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ item.write(targetFile);
+ uploadedFiles.add(targetFile);
+ LOG.info("Uploaded " + targetFile);
+
+ if (unzip && targetFile.getName().toLowerCase().endsWith(".zip")) {
+ unzip(targetFile, unzippedFiles);
+ }
+ }
+ }
+ }
+
+ } catch (Exception x) {
+ LOG.warn("Uploading failed.", x);
+ map.put("exception", x);
+ } finally {
+ if (status != null) {
+ statusService.removeUploadStatus(status);
+ request.getSession().removeAttribute(UPLOAD_STATUS);
+ User user = securityService.getCurrentUser(request);
+ securityService.updateUserByteCounts(user, 0L, 0L, status.getBytesTransfered());
+ }
+ }
+
+ map.put("uploadedFiles", uploadedFiles);
+ map.put("unzippedFiles", unzippedFiles);
+
+ ModelAndView result = super.handleRequestInternal(request, response);
+ result.addObject("model", map);
+ return result;
+ }
+
+ private void unzip(File file, List<File> unzippedFiles) throws Exception {
+ LOG.info("Unzipping " + file);
+
+ ZipFile zipFile = new ZipFile(file);
+
+ try {
+
+ Enumeration<?> entries = zipFile.getEntries();
+
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ File entryFile = new File(file.getParentFile(), entry.getName());
+
+ if (!entry.isDirectory()) {
+
+ if (!securityService.isUploadAllowed(entryFile)) {
+ throw new Exception("Permission denied: " + StringUtil.toHtml(entryFile.getPath()));
+ }
+
+ entryFile.getParentFile().mkdirs();
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ inputStream = zipFile.getInputStream(entry);
+ outputStream = new FileOutputStream(entryFile);
+
+ byte[] buf = new byte[8192];
+ while (true) {
+ int n = inputStream.read(buf);
+ if (n == -1) {
+ break;
+ }
+ outputStream.write(buf, 0, n);
+ }
+
+ LOG.info("Unzipped " + entryFile);
+ unzippedFiles.add(entryFile);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+ }
+
+ zipFile.close();
+ file.delete();
+
+ } finally {
+ zipFile.close();
+ }
+ }
+
+ public void setSecurityService(SecurityService securityService) {
+ this.securityService = securityService;
+ }
+
+ public void setPlayerService(PlayerService playerService) {
+ this.playerService = playerService;
+ }
+
+ public void setStatusService(StatusService statusService) {
+ this.statusService = statusService;
+ }
+
+ public void setSettingsService(SettingsService settingsService) {
+ this.settingsService = settingsService;
+ }
+
+ /**
+ * Receives callbacks as the file upload progresses.
+ */
+ private class UploadListenerImpl implements UploadListener {
+ private TransferStatus status;
+ private long start;
+
+ private UploadListenerImpl(TransferStatus status) {
+ this.status = status;
+ start = System.currentTimeMillis();
+ }
+
+ public void start(String fileName) {
+ status.setFile(new File(fileName));
+ }
+
+ public void bytesRead(long bytesRead) {
+
+ // Throttle bitrate.
+
+ long byteCount = status.getBytesTransfered() + bytesRead;
+ long bitCount = byteCount * 8L;
+
+ float elapsedMillis = Math.max(1, System.currentTimeMillis() - start);
+ float elapsedSeconds = elapsedMillis / 1000.0F;
+ long maxBitsPerSecond = getBitrateLimit();
+
+ status.setBytesTransfered(byteCount);
+
+ if (maxBitsPerSecond > 0) {
+ float sleepMillis = 1000.0F * (bitCount / maxBitsPerSecond - elapsedSeconds);
+ if (sleepMillis > 0) {
+ try {
+ Thread.sleep((long) sleepMillis);
+ } catch (InterruptedException x) {
+ LOG.warn("Failed to sleep.", x);
+ }
+ }
+ }
+ }
+
+ private long getBitrateLimit() {
+ return 1024L * settingsService.getUploadBitrateLimit() / Math.max(1, statusService.getAllUploadStatuses().size());
+ }
+ }
+
+} \ No newline at end of file