Commit 0efa2385 authored by Martin Lowe's avatar Martin Lowe 🇨🇦
Browse files

#445 - Fix EPS compression, save source of compressed images

parent 95e8c912
...@@ -13,7 +13,7 @@ public interface ImageStoreFormat { ...@@ -13,7 +13,7 @@ public interface ImageStoreFormat {
String getName(); String getName();
public enum ImageStoreFormats implements ImageStoreFormat { public enum ImageStoreFormats implements ImageStoreFormat {
SMALL, LARGE, PRINT, WEB; SMALL, LARGE, PRINT, WEB, WEB_SRC;
@Override @Override
public String getName() { public String getName() {
......
...@@ -49,7 +49,8 @@ public interface ImageStoreService { ...@@ -49,7 +49,8 @@ public interface ImageStoreService {
* @param format the name of the format to write the image for * @param format the name of the format to write the image for
* @return absolute path to access the live image * @return absolute path to access the live image
*/ */
String writeImage(Supplier<byte[]> imageBytes, String organization, String mimeType, Optional<ImageStoreFormat> format); String writeImage(Supplier<byte[]> imageBytes, String organization, String mimeType,
Optional<ImageStoreFormat> format);
/** /**
* Remove images associated with the given organization. This should clear all images that exist for the * Remove images associated with the given organization. This should clear all images that exist for the
...@@ -73,17 +74,33 @@ public interface ImageStoreService { ...@@ -73,17 +74,33 @@ public interface ImageStoreService {
String webRoot(); String webRoot();
@WithDefault("1000000")
long maxSizeInBytes();
@WithDefault("") @WithDefault("")
String defaultImageUrl(); String defaultImageUrl();
MaxSizeInBytes maxSizeInBytes();
Compression compression(); Compression compression();
@WithDefault("false") @WithDefault("false")
boolean persistToDb(); boolean persistToDb();
/**
* Contains the properties regarding max size of saved assets
*
* @author Martin Lowe
*
*/
interface MaxSizeInBytes {
@WithDefault("1000000")
long web();
@WithDefault("64000")
long webPostCompression();
@WithDefault("10000000")
long print();
}
/** /**
* Represents compression configuration settings. * Represents compression configuration settings.
* *
......
...@@ -51,6 +51,7 @@ import org.eclipsefoundation.persistence.model.RDBMSQuery; ...@@ -51,6 +51,7 @@ import org.eclipsefoundation.persistence.model.RDBMSQuery;
import org.eclipsefoundation.persistence.service.FilterService; import org.eclipsefoundation.persistence.service.FilterService;
import org.eclipsefoundation.react.helper.ImageFileHelper; import org.eclipsefoundation.react.helper.ImageFileHelper;
import org.eclipsefoundation.react.namespace.ImageStoreFormat; import org.eclipsefoundation.react.namespace.ImageStoreFormat;
import org.eclipsefoundation.react.namespace.ImageStoreFormat.ImageStoreFormats;
import org.eclipsefoundation.react.service.ImageStoreService; import org.eclipsefoundation.react.service.ImageStoreService;
import org.imgscalr.Scalr; import org.imgscalr.Scalr;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl; import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
...@@ -153,20 +154,39 @@ public class DefaultImageStoreService implements ImageStoreService { ...@@ -153,20 +154,39 @@ public class DefaultImageStoreService implements ImageStoreService {
// cannot provide image, return null // cannot provide image, return null
return null; return null;
} }
if (format.isPresent() && format.get().equals(ImageStoreFormats.PRINT)) {
if (bytes.length > config.maxSizeInBytes().print()) {
throw new BadRequestException("Passed image is larger than allowed size of '"
+ config.maxSizeInBytes().print() + "' bytes");
}
// Any print files should not attempt compression (as they are meant to be big)
return getWebUrl(Files.write(p, bytes));
} else {
if (bytes.length > config.maxSizeInBytes().web()) {
throw new BadRequestException("Passed image is larger than allowed size of '"
+ config.maxSizeInBytes().web() + "' bytes");
}
// compress image and then compare max size // compress image and then compare max size
byte[] compressedImage = compress(bytes, mimeType); byte[] compressedImage = compress(bytes, mimeType);
if (compressedImage.length > config.maxSizeInBytes() && (!Files.exists(p) if (compressedImage.length > config.maxSizeInBytes().webPostCompression()
|| !approximatelyMatch((long) compressedImage.length, attrView.readAttributes().size(), 1000))) { && (!Files.exists(p) || !approximatelyMatch((long) compressedImage.length,
throw new BadRequestException( attrView.readAttributes().size(), 1000))) {
"Passed image is larger than allowed size of '" + config.maxSizeInBytes() + "' bytes"); throw new BadRequestException("Passed image is larger than allowed size of '"
+ config.maxSizeInBytes().webPostCompression() + "' bytes");
} }
// if enabled, update the EclipseDB on logo update when image name is numeric // if enabled, update the EclipseDB on logo update when image name is numeric
// max size check is related to max blob size of 64kb // max size check is related to max blob size of 64kb
// TODO remove once the Drupal API references this API as this will no longer be needed then // TODO remove once the Drupal API references this API as this will no longer be needed then
handleDBPersist(fileName, compressedImage, mimeType, format); handleDBPersist(fileName, compressedImage, mimeType, format);
// write the orginal bytes to preserve source file in case of emergency
Files.write(imageStoreRoot.resolve(ImageFileHelper.getFileNameWithExtension(fileName,
Optional.of(ImageStoreFormats.WEB_SRC), mimeType)), bytes);
// write will create and overwrite file by default if it exists // write will create and overwrite file by default if it exists
return getWebUrl(Files.write(p, compress(bytes, mimeType))); return getWebUrl(Files.write(p, compressedImage));
}
} catch (IOException e) { } catch (IOException e) {
throw new ServerErrorException("Could not write image for organization " + fileName, throw new ServerErrorException("Could not write image for organization " + fileName,
Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e); Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e);
...@@ -229,8 +249,8 @@ public class DefaultImageStoreService implements ImageStoreService { ...@@ -229,8 +249,8 @@ public class DefaultImageStoreService implements ImageStoreService {
// get a ref to the given organization information object // get a ref to the given organization information object
MultivaluedMap<String, String> params = new MultivaluedMapImpl<>(); MultivaluedMap<String, String> params = new MultivaluedMapImpl<>();
params.add(DefaultUrlParameterNames.ID.getName(), fileName); params.add(DefaultUrlParameterNames.ID.getName(), fileName);
List<OrganizationInformation> infoRefs = dao List<OrganizationInformation> infoRefs = dao.get(
.get(new RDBMSQuery<>(new RequestWrapper(), filters.get(OrganizationInformation.class), params)); new RDBMSQuery<>(new RequestWrapper(), filters.get(OrganizationInformation.class), params));
// if ref doesn't exist, create one // if ref doesn't exist, create one
OrganizationInformation oi; OrganizationInformation oi;
if (infoRefs.isEmpty()) { if (infoRefs.isEmpty()) {
......
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