Commit f20853bd authored by Matija Obreza's avatar Matija Obreza

Image gallery displays metadata

HTTP headers for downloaded files set caching headers to (a-bit-more-)public
parent 3727a96f
......@@ -30,15 +30,18 @@ import org.genesys2.server.filerepository.model.RepositoryFile;
import org.genesys2.server.filerepository.service.BytesStorageService;
import org.genesys2.server.filerepository.service.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerMapping;
@Controller
public class FileRepositoryController extends BaseController {
public class RepositoryDownloadController extends BaseController {
public static final Log LOG = LogFactory.getLog(FileRepositoryController.class);
public static final Log LOG = LogFactory.getLog(RepositoryDownloadController.class);
@Autowired
private RepositoryService repositoryService;
......@@ -63,18 +66,13 @@ public class FileRepositoryController extends BaseController {
try {
final RepositoryFile repositoryFile = this.repositoryService.getFile(UUID.fromString(uuid));
if (repositoryFile == null) {
throw new ResourceNotFoundException("No such thing");
}
if (!repositoryFile.getPath().equals(path) || !repositoryFile.getExtension().equals(ext)) {
LOG.warn(repositoryFile.getPath() + "!=" + path);
LOG.warn(repositoryFile.getExtension() + "!=" + ext);
throw new ResourceNotFoundException("No such thing");
}
sanityCheck(path, ext, repositoryFile);
data = this.repositoryService.getFileBytes(repositoryFile.getPath(), repositoryFile.getFilename());
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
......@@ -87,11 +85,28 @@ public class FileRepositoryController extends BaseController {
}
}
response.setContentLength(data.length);
response.getOutputStream().write(data);
if (data != null) {
response.setContentLength(data.length);
response.getOutputStream().write(data);
}
response.flushBuffer();
}
private void sanityCheck(final String path, final String ext, final RepositoryFile repositoryFile) {
if (repositoryFile == null) {
throw new ResourceNotFoundException("No such thing");
}
if (!repositoryFile.getPath().equals(path) || !repositoryFile.getExtension().equals(ext)) {
LOG.warn(repositoryFile.getPath() + "!=" + path);
LOG.warn(repositoryFile.getExtension() + "!=" + ext);
throw new ResourceNotFoundException("No such thing");
}
}
/**
* Serve the bytes of the repository object
*/
@RequestMapping(value = "/repository/d/**", method = RequestMethod.GET)
public void downloadFile(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
......@@ -102,11 +117,39 @@ public class FileRepositoryController extends BaseController {
final String ext = fullpath.substring(fullpath.lastIndexOf("."));
final String uuid = fullpath.substring(fullpath.lastIndexOf("/") + 1, fullpath.lastIndexOf("."));
final String path = fullpath.substring("/repository/d".length(), fullpath.lastIndexOf("/") + 1);
// System.err.println(path + "- " + uuid + " -" + ext);
if (LOG.isDebugEnabled()) {
LOG.debug(path + " " + uuid + ext);
}
downloadFile(path, uuid, ext, response);
}
/**
* Return repository object metadata
*/
@RequestMapping(value = "/repository/d/**", method = RequestMethod.GET, params= { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody RepositoryFile getMetadata(final HttpServletRequest request)
throws IOException, NoSuchRepositoryFileException {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
if (LOG.isTraceEnabled()) {
LOG.trace("Fullname: " + fullpath);
}
final String ext = fullpath.substring(fullpath.lastIndexOf("."));
final String uuid = fullpath.substring(fullpath.lastIndexOf("/") + 1, fullpath.lastIndexOf("."));
final String path = fullpath.substring("/repository/d".length(), fullpath.lastIndexOf("/") + 1);
if (LOG.isDebugEnabled()) {
LOG.debug(path + " " + uuid + ext);
}
final RepositoryFile repositoryFile = this.repositoryService.getFile(UUID.fromString(uuid));
sanityCheck(path, ext, repositoryFile);
return repositoryFile;
}
}
......@@ -37,6 +37,7 @@ import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
......@@ -144,11 +145,12 @@ public class SpringServletConfig extends WebMvcConfigurerAdapter {
return cookieThemeResolver;
}
// @Override
// public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// configurer.favorPathExtension(false);
// }
//
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// Trying to be tooooo smart. Ignore path-based extension in content negotiation.
configurer.favorPathExtension(false);
}
// /**
// * http://stackoverflow.com/questions/16332092/spring-mvc-pathvariable-with-dot-is-getting-truncated
// */
......
......@@ -817,3 +817,4 @@ repository.gallery.successfully-updated=Image gallery successfully updated!
repository.gallery.removed=Image gallery was removed.
repository.gallery.create-here=Create image gallery!
repository.gallery.navigate=View image gallery!
repository.gallery.downloadImage=Download image
......@@ -2504,3 +2504,39 @@ div[x-href] {
color: Gray;
}
}
.imagegallery {
&.thumbs {
img {
width: 100%;
}
}
&.image-frame {
position: relative;
display: none;
&:hover .metadata {
background-color: $brand-primary;
opacity: 1.0;
}
.theimage {
width: 100%;
}
.metadata {
display: none;
position: absolute;
bottom: 0px;
background-color: Gray;
font-size: 10px;
opacity: 0.7;
.val {
font-weight: bold;
font-size: 120%;
}
}
}
}
......@@ -676,3 +676,39 @@ span.idx-col {
opacity: 0.5;
}
}
.imagegallery {
&.thumbs {
img {
width: 100%;
}
}
&.image-frame {
position: relative;
display: none;
&:hover .metadata {
background-color: $brand-primary;
opacity: 1.0;
}
.theimage {
width: 100%;
}
.metadata {
display: none;
position: absolute;
bottom: 0px;
background-color: Gray;
font-size: 10px;
opacity: 0.7;
.val {
font-weight: bold;
font-size: 120%;
}
}
}
}
......@@ -340,16 +340,31 @@
<h4>
<spring:message code="accession.imageGallery" />
</h4>
<div class="row" id="imagegallery-thumbs">
<div class="row imagegallery thumbs" id="accession-images-thumbs">
<c:forEach items="${imageGallery.images}" var="image">
<div x-src="<c:out value="${image.uuid}${image.extension}" />" style="cursor: pointer;" class="col-xs-6 col-sm-3 col-md-2 col-lg-2">
<img style="width: 100%;" src="<c:url value="/repository/d${image.path}_thumb/${thumbnailFormat}_${image.uuid}.png" />" alt="${image.title}" />
<div x-uuid="<c:out value="${image.uuid}" />" x-ext="<c:out value="${image.extension}" />" style="cursor: pointer;" class="col-xs-6 col-sm-3 col-md-2 col-lg-2">
<img src="<c:url value="/repository/d${image.path}_thumb/${thumbnailFormat}_${image.uuid}.png" />" alt="${image.title}" />
</div>
</c:forEach>
</div>
<div class="imagegallery-image-frame row text-center">
<img style="width: 100%;" id="imagegallery-image" />
<div class="imagegallery image-frame row" id="accession-image-view">
<img class="theimage" />
<div class="metadata">
<div class="title"><spring:message code="repository.file.title" /> <span class="val"></span></div>
<div class="subject"><spring:message code="repository.file.subject" /> <span class="val"></span></div>
<div class="description"><spring:message code="repository.file.description" /> <span class="val"></span></div>
<div class="creator"><spring:message code="repository.file.creator" /> <span class="val"></span></div>
<div class="created"><spring:message code="repository.file.created" /> <span class="val"></span></div>
<div class="rightsHolder"><spring:message code="repository.file.rightsHolder" /> <span class="val"></span></div>
<div class="accessRights"><spring:message code="repository.file.accessRights" /> <span class="val"></span></div>
<div class="license"><spring:message code="repository.file.license" /> <span class="val"></span></div>
<div class="extent"><spring:message code="repository.file.extent" /> <span class="val"></span></div>
<div class="bibliographicCitation"><spring:message code="repository.file.bibliographicCitation" /> <span class="val"></span></div>
<!-- Extras -->
<div class="downloadLink"><a href=""><spring:message code="repository.gallery.downloadImage" /></a></div>
</div>
</div>
</c:if>
......@@ -812,17 +827,61 @@
</c:if>
<c:if test="${imageGallery ne null}">
<script type="text/javascript">
$(document).ready(function() {
var imageViewer=$('#imagegallery-image')[0];
function fillMetadata(metadataBox, metadata) {
var box=$(metadataBox);
box.children().hide();
for (var i in metadata) {
// console.log(i);
var elem = box.find('.' + i)[0];
// console.log(elem);
if (elem !== undefined) {
$(elem).children().first().html('');
}
if (metadata[i] === null || metadata[i].length === 0) {
continue;
}
if (elem !== undefined) {
$(elem).children().first().text(metadata[i]);
$(elem).show();
}
}
var elem = box.find('.downloadLink').show().find('a').first().attr('href', box.parent().parent().find('.theimage').first().attr('src'));
}
function showImage(imagegalleryFrame, imageUuid, imageExt) {
var baseHref = '<c:url value="/repository/d${imageGallery.path}" />';
var galleryImages = $('#imagegallery-thumbs div');
if (galleryImages.length > 0) {
imageViewer.src = baseHref + $(galleryImages[0]).attr('x-src');
}
$('#imagegallery-thumbs div').click(function(ev) {
imageViewer.src = baseHref + $(this).attr('x-src');
var imageViewer = $(imagegalleryFrame).find('.theimage').first();
var metadataBox = $(imagegalleryFrame).find('.metadata').first();
imageViewer.attr('src', baseHref + imageUuid + imageExt);
// console.log('Image source: ' + imageViewer.src)
// console.log(imageViewer.attr('src'));
$(imagegalleryFrame).show();
$(metadataBox).hide();
// Load metadata
$.ajax(baseHref + imageUuid + imageExt + "?metadata", {
method: 'get',
dataType : 'json',
success : function(respObject) {
// console.log(respObject);
fillMetadata(metadataBox, respObject);
$(metadataBox).show();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
}
});
}
$(document).ready(function() {
var galleryView=$('#accession-image-view')[0];
var galleryThumbnails = $('#accession-images-thumbs div');
galleryThumbnails.click(function(ev) {
showImage(galleryView, $(this).attr('x-uuid'), $(this).attr('x-ext'));
});
if (galleryThumbnails.length > 0) {
// Show first image
showImage(galleryView, $(galleryThumbnails[0]).attr('x-uuid'), $(galleryThumbnails[0]).attr('x-ext'));
}
});
</script>
</c:if>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment