mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Add file upload support
This commit is contained in:
parent
458d3f43f8
commit
fb55e99f7b
@ -35,8 +35,13 @@
|
||||
<artifactId>commons.wicket</artifactId>
|
||||
<version>1.0.29</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.pmease</groupId>
|
||||
<artifactId>commons.jersey</artifactId>
|
||||
<version>1.0.30</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- WICKET -->
|
||||
<dependency>
|
||||
<groupId>com.vaynberg.wicket.select2</groupId>
|
||||
@ -54,7 +59,31 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-multipart</artifactId>
|
||||
<version>1.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.imgscalr</groupId>
|
||||
<artifactId>imgscalr-lib</artifactId>
|
||||
<version>4.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.codahale.dropwizard</groupId>
|
||||
<artifactId>dropwizard-jackson</artifactId>
|
||||
<version>0.7.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
@ -73,6 +102,18 @@
|
||||
</snapshots>
|
||||
<url>http://artifact.pmease.com/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.pmease.gitop.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
@ -17,13 +16,9 @@ import org.apache.wicket.request.Response;
|
||||
import org.apache.wicket.util.time.Duration;
|
||||
import org.apache.wicket.util.time.Time;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.pmease.commons.loader.AppLoader;
|
||||
import com.pmease.commons.wicket.AbstractWicketConfig;
|
||||
import com.pmease.gitop.core.manager.ConfigManager;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.web.assets.AssetLocator;
|
||||
import com.pmease.gitop.web.common.component.avatar.AvatarImageResource;
|
||||
import com.pmease.gitop.web.common.component.avatar.AvatarImageResourceReference;
|
||||
@ -135,8 +130,8 @@ public class GitopWebApp extends AbstractWicketConfig {
|
||||
getSharedResources().add(AvatarImageResourceReference.AVATAR_RESOURCE, new AvatarImageResource());
|
||||
mountResource("avatars/${type}/${id}", new AvatarImageResourceReference());
|
||||
|
||||
mountResource("fileManager", new FileManagerResourceReference(getUploadsDir().getAbsolutePath()));
|
||||
mountResource("fileUpload", new FileUploadResourceReference(getUploadsDir().getAbsolutePath()));
|
||||
mountResource("fileManager", new FileManagerResourceReference(SitePaths.get().uploadsDir().getAbsolutePath()));
|
||||
mountResource("fileUpload", new FileUploadResourceReference(SitePaths.get().uploadsDir().getAbsolutePath()));
|
||||
}
|
||||
|
||||
public boolean isGravatarEnabled() {
|
||||
@ -146,27 +141,4 @@ public class GitopWebApp extends AbstractWicketConfig {
|
||||
public boolean isPublicSignupEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public File getDataDir() {
|
||||
String str = AppLoader.getInstance(ConfigManager.class).getStorageSetting().getRepoStorageDir();
|
||||
return new File(str);
|
||||
}
|
||||
|
||||
public File getSystemAvatarDir() {
|
||||
return new File(getDataDir(), "avatars");
|
||||
}
|
||||
|
||||
public File getUserAvatarDir(Long id) {
|
||||
Preconditions.checkNotNull(id, "user id");
|
||||
return new File(getSystemAvatarDir(), "users/" + id.toString());
|
||||
}
|
||||
|
||||
public File getUserAvatarDir(User user) {
|
||||
return getUserAvatarDir(user.getId());
|
||||
}
|
||||
|
||||
public File getUploadsDir() {
|
||||
return new File(getDataDir(), "uploads");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
56
gitop.web/src/main/java/com/pmease/gitop/web/SitePaths.java
Normal file
56
gitop.web/src/main/java/com/pmease/gitop/web/SitePaths.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.pmease.gitop.web;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.pmease.commons.bootstrap.Bootstrap;
|
||||
import com.pmease.commons.loader.AppLoader;
|
||||
import com.pmease.gitop.core.manager.ConfigManager;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
|
||||
@Singleton
|
||||
public class SitePaths {
|
||||
private final ConfigManager configManager;
|
||||
|
||||
public static SitePaths get() {
|
||||
return AppLoader.getInstance(SitePaths.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
SitePaths(ConfigManager configManager) {
|
||||
this.configManager = configManager;
|
||||
}
|
||||
|
||||
public File installDir() {
|
||||
return Bootstrap.installDir;
|
||||
}
|
||||
|
||||
public File dataDir() {
|
||||
// TODO: this is not correct, should change repo storage dir to data dir
|
||||
return new File(configManager.getStorageSetting().getRepoStorageDir());
|
||||
}
|
||||
|
||||
public File avatarsDir() {
|
||||
return new File(dataDir(), "avatars");
|
||||
}
|
||||
|
||||
public File userAvatarDir(Long id) {
|
||||
return new File(avatarsDir(), "users/" + checkNotNull(id));
|
||||
}
|
||||
|
||||
public File userAvatarDir(User user) {
|
||||
return userAvatarDir(checkNotNull(user));
|
||||
}
|
||||
|
||||
public File tempDir() {
|
||||
return new File(installDir(), "temp");
|
||||
}
|
||||
|
||||
public File uploadsDir() {
|
||||
return new File(dataDir(), "uploads");
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.pmease.gitop.web;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
@ -11,6 +12,8 @@ import com.pmease.commons.jetty.ServletContextConfigurator;
|
||||
import com.pmease.commons.loader.AbstractPluginModule;
|
||||
import com.pmease.commons.wicket.AbstractWicketConfig;
|
||||
import com.pmease.gitop.web.assets.AssetLocator;
|
||||
import com.pmease.gitop.web.common.component.fileupload.FileUploadServlet;
|
||||
import com.pmease.gitop.web.resource.RestResourceModule;
|
||||
|
||||
/**
|
||||
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
|
||||
@ -24,6 +27,7 @@ public class WebModule extends AbstractPluginModule {
|
||||
|
||||
// put your guice bindings here
|
||||
bind(AbstractWicketConfig.class).to(GitopWebApp.class);
|
||||
bind(SitePaths.class).in(Singleton.class);
|
||||
|
||||
contribute(ServletContextConfigurator.class, new ServletContextConfigurator() {
|
||||
|
||||
@ -35,10 +39,13 @@ public class WebModule extends AbstractPluginModule {
|
||||
|
||||
ErrorPageErrorHandler errorHandler = (ErrorPageErrorHandler) context.getErrorHandler();
|
||||
errorHandler.addErrorPage(HttpServletResponse.SC_NOT_FOUND, "/assets/404.html");
|
||||
|
||||
servletHolder = context.addServlet(FileUploadServlet.class, "/uploads/*");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
install(new RestResourceModule());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import com.pmease.commons.loader.AppLoader;
|
||||
import com.pmease.gitop.core.manager.UserManager;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.web.GitopWebApp;
|
||||
import com.pmease.gitop.web.SitePaths;
|
||||
import com.pmease.gitop.web.common.component.avatar.AvatarImage.AvatarImageType;
|
||||
|
||||
public class AvatarImageResource extends DynamicImageResource {
|
||||
@ -30,7 +31,7 @@ public class AvatarImageResource extends DynamicImageResource {
|
||||
User user = AppLoader.getInstance(UserManager.class).get(id);
|
||||
|
||||
if (!Strings.isNullOrEmpty(user.getAvatarUrl())) {
|
||||
avatarFile = new File(GitopWebApp.get().getUserAvatarDir(id), user.getAvatarUrl());
|
||||
avatarFile = new File(SitePaths.get().userAvatarDir(id), user.getAvatarUrl());
|
||||
}
|
||||
} else {
|
||||
// Repository project = AppLoader.getInstance(RepositoryManager.class).get(id);
|
||||
|
||||
@ -1,43 +1,125 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:wicket="http://wicket.apache.org">
|
||||
<wicket:panel>
|
||||
<div class="row fileupload-buttonbar">
|
||||
<div class="span7">
|
||||
<!-- The fileinput-button span is used to style the file input field as button -->
|
||||
<span class="btn btn-success fileinput-button">
|
||||
<i class="icon-plus icon-white"></i>
|
||||
<span>Add files...</span>
|
||||
<input type="file" multiple="true"/>
|
||||
</span>
|
||||
<button type="submit" class="btn btn-primary start">
|
||||
<i class="icon-upload icon-white"></i>
|
||||
<span>Start upload</span>
|
||||
<wicket:panel>
|
||||
<form wicket:id="form" action="/rest/file/upload" method="POST" enctype="multipart/form-data">
|
||||
<!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
|
||||
<div class="row fileupload-buttonbar">
|
||||
<div class="col-lg-7">
|
||||
<!-- The fileinput-button span is used to style the file input field as button -->
|
||||
<span class="btn btn-success fileinput-button"> <i
|
||||
class="glyphicon glyphicon-plus"></i> <span>Add files...</span> <input
|
||||
type="file" name="files" />
|
||||
</span>
|
||||
<button type="submit" class="btn btn-primary start">
|
||||
<i class="glyphicon glyphicon-upload"></i> <span>Start
|
||||
upload</span>
|
||||
</button>
|
||||
<button type="reset" class="btn btn-warning cancel">
|
||||
<i class="glyphicon glyphicon-ban-circle"></i> <span>Cancel
|
||||
upload</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger delete">
|
||||
<i class="glyphicon glyphicon-trash"></i> <span>Delete</span>
|
||||
</button>
|
||||
<input type="checkbox" class="toggle">
|
||||
<!-- The loading indicator is shown during file processing -->
|
||||
<span class="fileupload-loading"></span>
|
||||
</div>
|
||||
<!-- The global progress information -->
|
||||
<div class="col-lg-5 fileupload-progress fade">
|
||||
<!-- The global progress bar -->
|
||||
<div class="progress progress-striped active" role="progressbar"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar progress-bar-success" style="width: 0%;"></div>
|
||||
</div>
|
||||
<!-- The extended global progress information -->
|
||||
<div class="progress-extended"> </div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- The table listing the files available for upload/download -->
|
||||
<table role="presentation" class="table table-striped">
|
||||
<tbody class="files"></tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<!-- The template to display files available for upload -->
|
||||
<script id="template-upload" type="text/x-tmpl">
|
||||
{% for (var i=0, file; file=o.files[i]; i++) { %}
|
||||
<tr class="template-upload fade">
|
||||
<td>
|
||||
<span class="preview"></span>
|
||||
</td>
|
||||
<td>
|
||||
<p class="name">{%=file.name%}</p>
|
||||
{% if (file.error) { %}
|
||||
<div><span class="label label-danger">Error</span> {%=file.error%}</div>
|
||||
{% } %}
|
||||
</td>
|
||||
<td>
|
||||
<p class="size">{%=o.formatFileSize(file.size)%}</p>
|
||||
{% if (!o.files.error) { %}
|
||||
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
|
||||
{% } %}
|
||||
</td>
|
||||
<td>
|
||||
{% if (!o.files.error && !i && !o.options.autoUpload) { %}
|
||||
<button class="btn btn-primary start">
|
||||
<i class="glyphicon glyphicon-upload"></i>
|
||||
<span>Start</span>
|
||||
</button>
|
||||
<button type="reset" class="btn btn-warning cancel">
|
||||
<i class="icon-ban-circle icon-white"></i>
|
||||
<span>Cancel upload</span>
|
||||
{% } %}
|
||||
{% if (!i) { %}
|
||||
<button class="btn btn-warning cancel">
|
||||
<i class="glyphicon glyphicon-ban-circle"></i>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger delete">
|
||||
<i class="icon-trash icon-white"></i>
|
||||
{% } %}
|
||||
</td>
|
||||
</tr>
|
||||
{% } %}
|
||||
</script>
|
||||
<!-- The template to display files available for download -->
|
||||
<script id="template-download" type="text/x-tmpl">
|
||||
{% for (var i=0, file; file=o.files[i]; i++) { %}
|
||||
<tr class="template-download fade">
|
||||
<td>
|
||||
<span class="preview">
|
||||
{% if (file.thumbnailUrl) { %}
|
||||
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
|
||||
{% } %}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<p class="name">
|
||||
{% if (file.url) { %}
|
||||
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
|
||||
{% } else { %}
|
||||
<span>{%=file.name%}</span>
|
||||
{% } %}
|
||||
</p>
|
||||
{% if (file.error) { %}
|
||||
<div><span class="label label-danger">Error</span> {%=file.error%}</div>
|
||||
{% } %}
|
||||
</td>
|
||||
<td>
|
||||
<span class="size">{%=o.formatFileSize(file.size)%}</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if (file.deleteUrl) { %}
|
||||
<button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
|
||||
<i class="glyphicon glyphicon-trash"></i>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
<input type="checkbox" class="toggle"/>
|
||||
</div>
|
||||
<!-- The global progress information -->
|
||||
<div class="span5 fileupload-progress fade">
|
||||
<!-- The global progress bar -->
|
||||
<div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="bar" style="width:0%;"></div>
|
||||
</div>
|
||||
<!-- The extended global progress information -->
|
||||
<div class="progress-extended">©</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- The loading indicator is shown during file processing -->
|
||||
<div class="fileupload-loading"></div>
|
||||
<br/>
|
||||
<!-- The table listing the files available for upload/download -->
|
||||
<table role="presentation" class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
|
||||
|
||||
</wicket:panel>
|
||||
<input type="checkbox" name="delete" value="1" class="toggle">
|
||||
{% } else { %}
|
||||
<button class="btn btn-warning cancel">
|
||||
<i class="glyphicon glyphicon-ban-circle"></i>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
{% } %}
|
||||
</td>
|
||||
</tr>
|
||||
{% } %}
|
||||
</script>
|
||||
</wicket:panel>
|
||||
</html>
|
||||
@ -1,5 +1,6 @@
|
||||
package com.pmease.gitop.web.common.component.fileupload;
|
||||
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
|
||||
/**
|
||||
@ -13,6 +14,8 @@ public class FileUploadBar extends Panel {
|
||||
public FileUploadBar(String id) {
|
||||
super(id);
|
||||
|
||||
add(new FileUploadResourceBehavior());
|
||||
WebMarkupContainer form = new WebMarkupContainer("form");
|
||||
add(form);
|
||||
form.add(new FileUploadResourceBehavior());
|
||||
}
|
||||
}
|
||||
@ -5,14 +5,15 @@ import java.util.Map;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.behavior.Behavior;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.resource.CssResourceReference;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
import org.apache.wicket.request.resource.ResourceReference;
|
||||
import org.apache.wicket.util.io.IOUtils;
|
||||
import org.apache.wicket.util.template.PackageTextTemplate;
|
||||
|
||||
import com.pmease.gitop.web.GitopWebApp;
|
||||
import com.pmease.gitop.web.assets.AssetLocator;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@ -20,17 +21,17 @@ public class FileUploadResourceBehavior extends Behavior {
|
||||
|
||||
private static final ResourceReference FILEUPLOAD_JS =
|
||||
new JavaScriptResourceReference(
|
||||
AssetLocator.class,
|
||||
"res/js/jquery.file.upload.js");
|
||||
FileUploadResourceBehavior.class,
|
||||
"res/js/jquery.fileupload.js");
|
||||
|
||||
private static final ResourceReference IFRAME_TRANSPORT_JS =
|
||||
new JavaScriptResourceReference(
|
||||
AssetLocator.class,
|
||||
FileUploadResourceBehavior.class,
|
||||
"res/js/jquery.iframe-transport.js");
|
||||
|
||||
private static final ResourceReference FILEUPLOAD_UI_JS =
|
||||
new JavaScriptResourceReference(
|
||||
AssetLocator.class,
|
||||
FileUploadResourceBehavior.class,
|
||||
"res/js/jquery.fileupload-ui.js");
|
||||
|
||||
/**
|
||||
@ -55,17 +56,31 @@ public class FileUploadResourceBehavior extends Behavior {
|
||||
public void renderHead(Component component, IHeaderResponse response) {
|
||||
super.renderHead(component, response);
|
||||
|
||||
response.render(CssHeaderItem.forReference(new CssResourceReference(FileUploadResourceBehavior.class, "res/css/jquery.fileupload-ui.css")));
|
||||
|
||||
response.render(JavaScriptHeaderItem.forReference(AssetLocator.JQUERY_UI_WIDGET_JS));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/tmpl.min.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/load-image.min.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.blueimp-gallery.min.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/canvas-to-blob.min.js")));
|
||||
|
||||
response.render(JavaScriptHeaderItem.forReference(IFRAME_TRANSPORT_JS));
|
||||
response.render(JavaScriptHeaderItem.forReference(FILEUPLOAD_JS));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.fileupload-process.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.fileupload-audio.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.fileupload-video.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.fileupload-image.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(FileUploadResourceBehavior.class, "res/js/jquery.fileupload-validate.js")));
|
||||
response.render(JavaScriptHeaderItem.forReference(FILEUPLOAD_UI_JS));
|
||||
|
||||
PackageTextTemplate jsTmpl = new PackageTextTemplate(AssetLocator.class, "js/vendor/jquery-file-upload/main.js");
|
||||
|
||||
PackageTextTemplate jsTmpl = new PackageTextTemplate(FileUploadResourceBehavior.class,
|
||||
"res/js/main.js");
|
||||
try {
|
||||
Map<String, Object> variables = new HashMap<String, Object>();
|
||||
|
||||
variables.put("componentMarkupId", component.getMarkupId());
|
||||
variables.put("url", component.urlFor(new FileUploadResourceReference(GitopWebApp.get().getUploadsDir().getAbsolutePath()), null));
|
||||
variables.put("componentId", component.getMarkupId());
|
||||
variables.put("url", "/rest/file/upload");
|
||||
variables.put("paramName", PARAM_NAME);
|
||||
|
||||
String s = jsTmpl.asString(variables);
|
||||
|
||||
@ -13,7 +13,7 @@ import org.apache.wicket.request.resource.IResource;
|
||||
import org.apache.wicket.request.resource.ResourceReference;
|
||||
import org.apache.wicket.util.upload.FileItem;
|
||||
|
||||
import com.pmease.gitop.web.GitopWebApp;
|
||||
import com.pmease.gitop.web.SitePaths;
|
||||
|
||||
/**
|
||||
* A resource reference provides default implementation of
|
||||
@ -81,7 +81,7 @@ public class FileUploadResourceReference extends ResourceReference {
|
||||
PageParameters params = new PageParameters();
|
||||
params.set("filename", fileItem.getName());
|
||||
CharSequence url = RequestCycle.get().urlFor(
|
||||
new FileManagerResourceReference(GitopWebApp.get().getUploadsDir().getAbsolutePath()),
|
||||
new FileManagerResourceReference(SitePaths.get().uploadsDir().getAbsolutePath()),
|
||||
params);
|
||||
return url;
|
||||
}
|
||||
@ -91,7 +91,7 @@ public class FileUploadResourceReference extends ResourceReference {
|
||||
params.set("filename", fileItem.getName());
|
||||
params.set("delete", true);
|
||||
CharSequence url = RequestCycle.get().urlFor(
|
||||
new FileManagerResourceReference(GitopWebApp.get().getUploadsDir().getAbsolutePath()),
|
||||
new FileManagerResourceReference(SitePaths.get().uploadsDir().getAbsolutePath()),
|
||||
params);
|
||||
return url;
|
||||
}
|
||||
|
||||
@ -0,0 +1,182 @@
|
||||
package com.pmease.gitop.web.common.component.fileupload;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.imgscalr.Scalr;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class FileUploadServlet extends HttpServlet {
|
||||
static File imgDir = new File("/Users/zhenyu/temp/");
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
if (request.getParameter("getfile") != null
|
||||
&& !request.getParameter("getfile").isEmpty()) {
|
||||
File file = new File(imgDir, request.getParameter("getfile"));
|
||||
if (file.exists()) {
|
||||
int bytes = 0;
|
||||
ServletOutputStream op = response.getOutputStream();
|
||||
|
||||
response.setContentType(getMimeType(file));
|
||||
response.setContentLength((int) file.length());
|
||||
response.setHeader("Content-Disposition", "inline; filename=\""
|
||||
+ file.getName() + "\"");
|
||||
|
||||
byte[] bbuf = new byte[1024];
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(
|
||||
file));
|
||||
|
||||
while ((in != null) && ((bytes = in.read(bbuf)) != -1)) {
|
||||
op.write(bbuf, 0, bytes);
|
||||
}
|
||||
|
||||
in.close();
|
||||
op.flush();
|
||||
op.close();
|
||||
}
|
||||
} else if (request.getParameter("delfile") != null
|
||||
&& !request.getParameter("delfile").isEmpty()) {
|
||||
File file = new File(imgDir, request.getParameter("delfile"));
|
||||
if (file.exists()) {
|
||||
file.delete(); // TODO:check and report success
|
||||
}
|
||||
} else if (request.getParameter("getthumb") != null
|
||||
&& !request.getParameter("getthumb").isEmpty()) {
|
||||
File file = new File(imgDir, request.getParameter("getthumb"));
|
||||
if (file.exists()) {
|
||||
System.out.println(file.getAbsolutePath());
|
||||
String mimetype = getMimeType(file);
|
||||
if (mimetype.endsWith("png") || mimetype.endsWith("jpeg")
|
||||
|| mimetype.endsWith("jpg") || mimetype.endsWith("gif")) {
|
||||
BufferedImage im = ImageIO.read(file);
|
||||
if (im != null) {
|
||||
BufferedImage thumb = Scalr.resize(im, 75);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
if (mimetype.endsWith("png")) {
|
||||
ImageIO.write(thumb, "PNG", os);
|
||||
response.setContentType("image/png");
|
||||
} else if (mimetype.endsWith("jpeg")) {
|
||||
ImageIO.write(thumb, "jpg", os);
|
||||
response.setContentType("image/jpeg");
|
||||
} else if (mimetype.endsWith("jpg")) {
|
||||
ImageIO.write(thumb, "jpg", os);
|
||||
response.setContentType("image/jpeg");
|
||||
} else {
|
||||
ImageIO.write(thumb, "GIF", os);
|
||||
response.setContentType("image/gif");
|
||||
}
|
||||
ServletOutputStream srvos = response.getOutputStream();
|
||||
response.setContentLength(os.size());
|
||||
response.setHeader("Content-Disposition",
|
||||
"inline; filename=\"" + file.getName() + "\"");
|
||||
os.writeTo(srvos);
|
||||
srvos.flush();
|
||||
srvos.close();
|
||||
}
|
||||
}
|
||||
} // TODO: check and report success
|
||||
} else {
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.write("call POST with multipart form data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
|
||||
* response)
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
if (!ServletFileUpload.isMultipartContent(request)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Request is not multipart, please 'multipart/form-data' enctype for your form.");
|
||||
}
|
||||
|
||||
ServletFileUpload uploadHandler = new ServletFileUpload(new DiskFileItemFactory());
|
||||
|
||||
PrintWriter writer = response.getWriter();
|
||||
response.setContentType("application/json");
|
||||
JSONArray json = new JSONArray();
|
||||
try {
|
||||
List<FileItem> items = uploadHandler.parseRequest(request);
|
||||
for (FileItem item : items) {
|
||||
if (!item.isFormField()) {
|
||||
File file = new File(imgDir, item.getName());
|
||||
item.write(file);
|
||||
JSONObject jsono = new JSONObject();
|
||||
jsono.put("name", item.getName());
|
||||
jsono.put("size", item.getSize());
|
||||
jsono.put("url", "UploadServlet?getfile=" + item.getName());
|
||||
jsono.put("thumbnail_url",
|
||||
"UploadServlet?getthumb=" + item.getName());
|
||||
jsono.put("delete_url",
|
||||
"UploadServlet?delfile=" + item.getName());
|
||||
jsono.put("delete_type", "GET");
|
||||
json.put(jsono);
|
||||
System.out.println(json.toString());
|
||||
}
|
||||
}
|
||||
} catch (FileUploadException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
writer.write(json.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getMimeType(File file) {
|
||||
String mimetype = "";
|
||||
if (file.exists()) {
|
||||
if (getSuffix(file.getName()).equalsIgnoreCase("png")) {
|
||||
mimetype = "image/png";
|
||||
} else if (getSuffix(file.getName()).equalsIgnoreCase("jpg")) {
|
||||
mimetype = "image/jpg";
|
||||
} else if (getSuffix(file.getName()).equalsIgnoreCase("jpeg")) {
|
||||
mimetype = "image/jpeg";
|
||||
} else if (getSuffix(file.getName()).equalsIgnoreCase("gif")) {
|
||||
mimetype = "image/gif";
|
||||
} else {
|
||||
javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap();
|
||||
mimetype = mtMap.getContentType(file);
|
||||
}
|
||||
}
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
private String getSuffix(String filename) {
|
||||
String suffix = "";
|
||||
int pos = filename.lastIndexOf('.');
|
||||
if (pos > 0 && pos < filename.length() - 1) {
|
||||
suffix = filename.substring(pos + 1);
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,68 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload UI Plugin CSS 8.8.1
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.fileinput-button input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
transform: translate(-300px, 0) scale(4);
|
||||
font-size: 23px;
|
||||
direction: ltr;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fileupload-buttonbar .btn,
|
||||
.fileupload-buttonbar .toggle {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.progress-animated .progress-bar,
|
||||
.progress-animated .bar {
|
||||
background: url(../img/progressbar.gif) !important;
|
||||
filter: none;
|
||||
}
|
||||
.fileupload-loading {
|
||||
float: right;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(../img/loading.gif) center no-repeat;
|
||||
background-size: contain;
|
||||
display: none;
|
||||
}
|
||||
.fileupload-processing .fileupload-loading {
|
||||
display: block;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.fileupload-buttonbar .toggle,
|
||||
.files .toggle,
|
||||
.files .btn span {
|
||||
display: none;
|
||||
}
|
||||
.files .name {
|
||||
width: 80px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 80px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
!function(t){"use strict";var e=t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype,n=t.Blob&&function(){try{return Boolean(new Blob)}catch(t){return!1}}(),o=n&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(t){return!1}}(),r=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,i=(n||r)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(t){var e,i,a,l,u,B;for(e=t.split(",")[0].indexOf("base64")>=0?atob(t.split(",")[1]):decodeURIComponent(t.split(",")[1]),i=new ArrayBuffer(e.length),a=new Uint8Array(i),l=0;l<e.length;l+=1)a[l]=e.charCodeAt(l);return u=t.split(",")[0].split(":")[1].split(";")[0],n?new Blob([o?a:i],{type:u}):(B=new r,B.append(i),B.getBlob(u))};t.HTMLCanvasElement&&!e.toBlob&&(e.mozGetAsFile?e.toBlob=function(t,n,o){o&&e.toDataURL&&i?t(i(this.toDataURL(n,o))):t(this.mozGetAsFile("blob",n))}:e.toDataURL&&i&&(e.toBlob=function(t,e,n){t(i(this.toDataURL(e,n)))})),"function"==typeof define&&define.amd?define(function(){return i}):t.dataURLtoBlob=i}(this);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,26 +1,41 @@
|
||||
/*
|
||||
* jQuery File Upload Plugin JS Example 8.8.2
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/*jslint nomen: true, regexp: true */
|
||||
/*global $, window, blueimp */
|
||||
|
||||
$(function () {
|
||||
'use strict';
|
||||
|
||||
$('#${componentMarkupId}').fileupload({
|
||||
url: '${url}',
|
||||
paramName: '${paramName}',
|
||||
singleFileUploads: true,
|
||||
maxFileSize: 5000000,
|
||||
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
|
||||
process: [
|
||||
{
|
||||
action: 'load',
|
||||
fileTypes: /^image\/(gif|jpeg|png)$/,
|
||||
maxFileSize: 20000000 // 20MB
|
||||
},
|
||||
{
|
||||
action: 'resize',
|
||||
maxWidth: 1440,
|
||||
maxHeight: 900
|
||||
},
|
||||
{
|
||||
action: 'save'
|
||||
}
|
||||
]
|
||||
// Initialize the jQuery File Upload widget:
|
||||
$('#${componentId}').fileupload({
|
||||
// Uncomment the following to send cross-domain cookies:
|
||||
//xhrFields: {withCredentials: true},
|
||||
url: '${url}'
|
||||
});
|
||||
});
|
||||
|
||||
// Load existing files:
|
||||
$('#${componentId}').addClass('fileupload-processing');
|
||||
$.ajax({
|
||||
// Uncomment the following to send cross-domain cookies:
|
||||
//xhrFields: {withCredentials: true},
|
||||
url: $('#${componentId}').fileupload('option', 'url'),
|
||||
dataType: 'json',
|
||||
context: $('#${componentId}')[0]
|
||||
}).always(function () {
|
||||
$(this).removeClass('fileupload-processing');
|
||||
}).done(function (result) {
|
||||
console.log('done');
|
||||
$(this).fileupload('option', 'done')
|
||||
.call(this, null, {result: result});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -1 +1 @@
|
||||
(function(a){"use strict";var b=function(a,c){var d=/[^\w\-\.:]/.test(a)?new Function(b.arg+",tmpl","var _e=tmpl.encode"+b.helper+",_s='"+a.replace(b.regexp,b.func)+"';return _s;"):b.cache[a]=b.cache[a]||b(b.load(a));return c?d(c,b):function(a){return d(a,b)}};b.cache={},b.load=function(a){return document.getElementById(a).innerHTML},b.regexp=/([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,b.func=function(a,b,c,d,e,f){if(b)return{"\n":"\\n","\r":"\\r","\t":"\\t"," ":" "}[a]||"\\"+a;if(c)return c==="="?"'+_e("+d+")+'":"'+("+d+"||'')+'";if(e)return"';";if(f)return"_s+='"},b.encReg=/[<>&"'\x00]/g,b.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},b.encode=function(a){return String(a||"").replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}",typeof define=="function"&&define.amd?define(function(){return b}):a.tmpl=b})(this);
|
||||
!function(e){"use strict";var n=function(e,t){var c=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?c(t,n):function(e){return c(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,c,r,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+c+")+'":"'+("+c+"==null?'':"+c+")+'":r?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},n.encode=function(e){return(null==e?"":""+e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):e.tmpl=n}(this);
|
||||
@ -2,7 +2,6 @@
|
||||
<wicket:extend>
|
||||
<div class="container">
|
||||
<h1>Hello, Gitop!</h1>
|
||||
|
||||
<h3>Upload Test</h3>
|
||||
<div wicket:id="upload"></div>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.gitop.web.resource;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class RestResourceModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(TestResource.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package com.pmease.gitop.web.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
|
||||
import com.codahale.dropwizard.jackson.Jackson;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.pmease.gitop.web.SitePaths;
|
||||
|
||||
@Path("/file")
|
||||
public class TestResource {
|
||||
|
||||
private static final String SUCCESS_RESPONSE = "Successful";
|
||||
private static final String FAILED_RESPONSE = "Failed";
|
||||
|
||||
@POST
|
||||
@Path("/upload")
|
||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
public Response uploadFile(@Context HttpServletRequest request) throws JsonProcessingException {
|
||||
String candidateName = null;
|
||||
File uploadDir = SitePaths.get().uploadsDir();
|
||||
|
||||
Result result = new Result();
|
||||
|
||||
// checks whether there is a file upload request or not
|
||||
if (ServletFileUpload.isMultipartContent(request)) {
|
||||
final FileItemFactory factory = new DiskFileItemFactory();
|
||||
final ServletFileUpload fileUpload = new ServletFileUpload(factory);
|
||||
|
||||
try {
|
||||
/*
|
||||
* parseRequest returns a list of FileItem but in old
|
||||
* (pre-java5) style
|
||||
*/
|
||||
final List<FileItem> items = fileUpload.parseRequest(request);
|
||||
|
||||
if (items != null) {
|
||||
final Iterator<FileItem> iter = items.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final FileItem item = iter.next();
|
||||
final String itemName = item.getName();
|
||||
final String fieldName = item.getFieldName();
|
||||
final String fieldValue = item.getString();
|
||||
|
||||
if (item.isFormField()) {
|
||||
candidateName = fieldValue;
|
||||
System.out.println("Field Name: " + fieldName
|
||||
+ ", Field Value: " + fieldValue);
|
||||
System.out.println("Candidate Name: "
|
||||
+ candidateName);
|
||||
} else {
|
||||
final File savedFile = new File(uploadDir, itemName);
|
||||
System.out.println("Saving the file: "
|
||||
+ savedFile.getName());
|
||||
item.write(savedFile);
|
||||
|
||||
UploadFile f = new UploadFile();
|
||||
f.name = savedFile.getName();
|
||||
f.size = savedFile.length();
|
||||
result.files.add(f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (FileUploadException fue) {
|
||||
fue.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
ObjectMapper mapper = Jackson.newObjectMapper();
|
||||
String str = mapper.writeValueAsString(result);
|
||||
|
||||
System.out.println("Returned Response Status: " + str);
|
||||
return Response.ok().entity(str).build();
|
||||
}
|
||||
|
||||
static class Result {
|
||||
@JsonProperty
|
||||
List<UploadFile> files = Lists.newArrayList();
|
||||
}
|
||||
|
||||
static class UploadFile {
|
||||
@JsonProperty
|
||||
String name;
|
||||
@JsonProperty
|
||||
long size;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user