r910 - in trunk: . src/main/java/org/ourproject/kune/platf/client/ui/download src/main/java/org/ourproject/kune/platf/server/manager/impl src/main/java/org/ourproject/kune/platf/server/properties src/main/resources src/test/java/org/ourproject/kune/platf/server/manager/impl
Author: vjrj Date: 2008-10-15 05:14:33 +0200 (Wed, 15 Oct 2008) New Revision: 910 Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/download/FileConstants.java Modified: trunk/INSTALL trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/FileUploadManager.java trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefault.java trunk/src/main/java/org/ourproject/kune/platf/server/properties/KuneProperties.java trunk/src/main/resources/kune.properties trunk/src/test/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefaultTest.java Log: Complete - task Images server utilities Modified: trunk/INSTALL =================================================================== --- trunk/INSTALL 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/INSTALL 2008-10-15 03:14:33 UTC (rev 910) @@ -57,6 +57,13 @@ - Install and run a openfire jabber server (see Appendix B for proper configuration of openfire) or ejabberd. +- Install jmagick-jni. In debian: apt-get install libjmagick6-jni (version 6.2.6-0) also you need or: + sudo ln -s /usr/lib/jni/libJMagick.so /usr/lib/libJMagick.so +or + set LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jni in your test and in your webserver. + +in Windows maybe (not checked) you need to do something similar (copy the jmagick .dll of the same version in the Windows directory) + - Run jetty: mvn jetty:run -Dliquibase.should.run=false once started (and initialized the db), you can stop a run jetty with de db migrator to insert initial data and migrate: Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/download/FileConstants.java =================================================================== --- trunk/src/main/java/org/ourproject/kune/platf/client/ui/download/FileConstants.java 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/download/FileConstants.java 2008-10-15 03:14:33 UTC (rev 910) @@ -0,0 +1,7 @@ +package org.ourproject.kune.platf.client.ui.download; + +public interface FileConstants { + final String ICON_SUFFIX = ".ico."; + final String SIZED_SUFFIX = ".sized."; + final String THUMB_SUFFIX = ".thumb."; +} Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/FileUploadManager.java =================================================================== --- trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/FileUploadManager.java 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/FileUploadManager.java 2008-10-15 03:14:33 UTC (rev 910) @@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import magick.MagickException; import net.sf.json.JSONObject; import org.apache.commons.fileupload.FileItem; @@ -23,6 +24,7 @@ import org.ourproject.kune.docs.server.DocumentServerTool; import org.ourproject.kune.platf.client.dto.StateToken; import org.ourproject.kune.platf.client.services.I18nTranslationService; +import org.ourproject.kune.platf.client.ui.download.FileConstants; import org.ourproject.kune.platf.client.ui.upload.FileUploader; import org.ourproject.kune.platf.server.UserSession; import org.ourproject.kune.platf.server.access.AccessRol; @@ -47,12 +49,12 @@ @RequestScoped public class FileUploadManager extends HttpServlet { + private static final long serialVersionUID = 1L; + public static final Log log = LogFactory.getLog(FileUploadManager.class); private static final String UTF8 = "UTF-8"; - private static final long serialVersionUID = 1L; - @Inject KuneProperties kuneProperties; @Inject @@ -69,126 +71,158 @@ @Override @SuppressWarnings( { "unchecked", "deprecation" }) protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, - IOException { + IOException { - JSONObject jsonResponse = createSuccessResponse(); + JSONObject jsonResponse = createSuccessResponse(); - final DiskFileItemFactory factory = new DiskFileItemFactory(); - // maximum size that will be stored in memory - factory.setSizeThreshold(4096); - // the location for saving data that is larger than getSizeThreshold() - factory.setRepository(new File("/tmp")); + final DiskFileItemFactory factory = new DiskFileItemFactory(); + // maximum size that will be stored in memory + factory.setSizeThreshold(4096); + // the location for saving data that is larger than getSizeThreshold() + factory.setRepository(new File("/tmp")); - if (!ServletFileUpload.isMultipartContent(req)) { - log.warn("Not a multipart upload"); - } + if (!ServletFileUpload.isMultipartContent(req)) { + log.warn("Not a multipart upload"); + } - final ServletFileUpload upload = new ServletFileUpload(factory); - // maximum size before a FileUploadException will be thrown - upload.setSizeMax(new Integer(kuneProperties.get(KuneProperties.UPLOAD_MAX_FILE_SIZE)) * 1024 * 1024); + final ServletFileUpload upload = new ServletFileUpload(factory); + // maximum size before a FileUploadException will be thrown + upload.setSizeMax(new Integer(kuneProperties.get(KuneProperties.UPLOAD_MAX_FILE_SIZE)) * 1024 * 1024); - try { - final List fileItems = upload.parseRequest(req); - String userHash = null; - StateToken stateToken = null; - String fileName = null; - FileItem file = null; - for (final Iterator iterator = fileItems.iterator(); iterator.hasNext();) { - final FileItem item = (FileItem) iterator.next(); - if (item.isFormField()) { - final String name = item.getFieldName(); - final String value = item.getString(); - log.info("name: " + name + " value: " + value); - if (name.equals(FileUploader.USERHASH)) { - userHash = value; - } - if (name.equals(FileUploader.CURRENT_STATE_TOKEN)) { - stateToken = new StateToken(value); - } - } else { - fileName = item.getName(); - log.info("file: " + fileName + " fieldName: " + item.getFieldName() + " size: " + item.getSize()); - file = item; - } - } - createUploadedFile(userHash, stateToken, fileName, file); - } catch (final FileUploadException e) { - jsonResponse = createJsonResponse(false, i18n.t("Error: File too large")); - } catch (final Exception e) { - jsonResponse = createJsonResponse(false, i18n.t("Error uploading file")); - log.info("Exception: " + e.getCause()); - e.printStackTrace(); - } + try { + final List fileItems = upload.parseRequest(req); + String userHash = null; + StateToken stateToken = null; + String fileName = null; + FileItem file = null; + for (final Iterator iterator = fileItems.iterator(); iterator.hasNext();) { + final FileItem item = (FileItem) iterator.next(); + if (item.isFormField()) { + final String name = item.getFieldName(); + final String value = item.getString(); + log.info("name: " + name + " value: " + value); + if (name.equals(FileUploader.USERHASH)) { + userHash = value; + } + if (name.equals(FileUploader.CURRENT_STATE_TOKEN)) { + stateToken = new StateToken(value); + } + } else { + fileName = item.getName(); + log.info("file: " + fileName + " fieldName: " + item.getFieldName() + " size: " + item.getSize()); + file = item; + } + } + createUploadedFile(userHash, stateToken, fileName, file); + } catch (final FileUploadException e) { + jsonResponse = createJsonResponse(false, i18n.t("Error: File too large")); + } catch (final Exception e) { + jsonResponse = createJsonResponse(false, i18n.t("Error uploading file")); + log.info("Exception: " + e.getCause()); + e.printStackTrace(); + } - final Writer w = new OutputStreamWriter(resp.getOutputStream()); - w.write(jsonResponse.toString()); - w.close(); - resp.setStatus(HttpServletResponse.SC_OK); + final Writer w = new OutputStreamWriter(resp.getOutputStream()); + w.write(jsonResponse.toString()); + w.close(); + resp.setStatus(HttpServletResponse.SC_OK); } @Authenticated @Authorizated(accessRolRequired = AccessRol.Editor, actionLevel = ActionLevel.container) @Transactional(type = TransactionType.READ_WRITE) Content createUploadedFile(final String userHash, final StateToken stateToken, final String fileName, - final FileItem fileUploadItem) throws Exception { - final String relDir = FileUtils.toDir(stateToken); - final String absDir = kuneProperties.get(KuneProperties.UPLOAD_LOCATION) + relDir; - fileManager.mkdir(absDir); + final FileItem fileUploadItem) throws Exception { + final String relDir = FileUtils.toDir(stateToken); + final String absDir = kuneProperties.get(KuneProperties.UPLOAD_LOCATION) + relDir; + fileManager.mkdir(absDir); - File file = null; - try { - final String filenameUTF8 = new String(fileName.getBytes(), UTF8); - file = fileManager.createFileWithSequentialName(absDir, filenameUTF8); - fileUploadItem.write(file); + File file = null; + try { + final String filenameUTF8 = new String(fileName.getBytes(), UTF8); + file = fileManager.createFileWithSequentialName(absDir, filenameUTF8); + fileUploadItem.write(file); - final String mimetype = fileUploadItem.getContentType(); - final String extension = FileUtils.getFileNameExtension(filenameUTF8, false); + final String mimetype = fileUploadItem.getContentType(); + BasicMimeType basicMimeType = new BasicMimeType(mimetype); + log.info("Mimetype: " + basicMimeType); + final String extension = FileUtils.getFileNameExtension(file.getName(), false); - // Persist - final User user = userSession.getUser(); - final Container container = accessService.accessToContainer(ContentUtils.parseId(stateToken.getFolder()), - user, AccessRol.Editor); - final String preview = "Preview of this file (in development)"; - final Content content = contentManager.createContent(FileUtils.getFileNameWithoutExtension(file.getName(), - extension), preview, user, container); - content.setTypeId(DocumentServerTool.TYPE_UPLOADEDFILE); - content.setMimeType(new BasicMimeType(mimetype)); - content.setFilename(filenameUTF8); - return content; - } catch (final Exception e) { - if (file != null && file.exists()) { - file.delete(); - } - throw e; - } + if (basicMimeType.getType().equals("image")) { + generateThumbs(absDir, file.getName(), extension); + } + + // Persist + final User user = userSession.getUser(); + final Container container = accessService.accessToContainer(ContentUtils.parseId(stateToken.getFolder()), + user, AccessRol.Editor); + final String preview = "Preview of this file (in development)"; + final Content content = contentManager.createContent(FileUtils.getFileNameWithoutExtension(file.getName(), + extension), preview, user, container); + content.setTypeId(DocumentServerTool.TYPE_UPLOADEDFILE); + content.setMimeType(basicMimeType); + content.setFilename(file.getName()); + return content; + } catch (final Exception e) { + if (file != null && file.exists()) { + file.delete(); + } + throw e; + } } private JSONObject createJsonResponse(final boolean success, final String message) { - /** - * - * http://max-bazhenov.com/dev/upload-dialog-2.0/index.php - * - * Server side handler. - * - * The files in the queue are posted one at a time, the file field name - * is 'file'. The handler should return json encoded object with - * following properties: { success: true|false, // required error: - * 'Error or success message' // optional, also can be named 'message' } - */ + /** + * + * http://max-bazhenov.com/dev/upload-dialog-2.0/index.php + * + * Server side handler. + * + * The files in the queue are posted one at a time, the file field name + * is 'file'. The handler should return json encoded object with + * following properties: { success: true|false, // required error: + * 'Error or success message' // optional, also can be named 'message' } + */ - JSONObject response = null; - try { - response = new JSONObject(); - response.put("success", success); - response.put("error", message); - response.put("code", "232"); - } catch (final Exception e) { - log.error("Error building response"); - } - return response; + JSONObject response = null; + try { + response = new JSONObject(); + response.put("success", success); + response.put("error", message); + response.put("code", "232"); + } catch (final Exception e) { + log.error("Error building response"); + } + return response; } private JSONObject createSuccessResponse() { - return createJsonResponse(true, i18n.t("Success uploading")); + return createJsonResponse(true, i18n.t("Success uploading")); } + + private void generateThumbs(String absDir, String filename, String extension) { + try { + String fileOrig = absDir + filename; + String withoutExtension = FileUtils.getFileNameWithoutExtension(filename, extension); + + String resizeName = absDir + withoutExtension + FileConstants.SIZED_SUFFIX + extension; + String thumbName = absDir + withoutExtension + FileConstants.THUMB_SUFFIX + extension; + String iconName = absDir + withoutExtension + FileConstants.ICON_SUFFIX + extension; + + int resizeWidth = Integer.parseInt(kuneProperties.get(KuneProperties.IMAGES_RESIZEWIDTH)); + int thumbSize = Integer.parseInt(kuneProperties.get(KuneProperties.IMAGES_THUMBSIZE)); + int cropSize = Integer.parseInt(kuneProperties.get(KuneProperties.IMAGES_CROPSIZE)); + int iconSize = Integer.parseInt(kuneProperties.get(KuneProperties.IMAGES_ICONSIZE)); + + ImageUtilsDefault.scaleImageToMax(fileOrig, resizeName, resizeWidth); + ImageUtilsDefault.createThumb(fileOrig, thumbName, thumbSize, cropSize); + ImageUtilsDefault.createThumb(fileOrig, iconName, iconSize); + + } catch (NumberFormatException e) { + log.error("Image sizes in kune.properties are not integers"); + e.printStackTrace(); + } catch (MagickException e) { + log.info("Problem generating image thumb for " + filename); + } + } } Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefault.java =================================================================== --- trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefault.java 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefault.java 2008-10-15 03:14:33 UTC (rev 910) @@ -11,7 +11,12 @@ /** * http://en.wikipedia.org/wiki/Thumbnail + * */ + public static void createThumb(String fileOrig, String fileDest, int cropDimension) throws MagickException { + createThumb(fileOrig, fileDest, cropDimension, cropDimension); + } + public static void createThumb(String fileOrig, String fileDest, int thumbDimension, int cropDimension) throws MagickException { if (thumbDimension < cropDimension) { @@ -21,10 +26,10 @@ Dimension origDimension = imageOrig.getDimension(); int origHeight = origDimension.height; int origWidth = origDimension.width; - Dimension proportionalDim = calculateProportionalDim(origWidth, origHeight, thumbDimension); + Dimension proportionalDim = calculatePropDim(origWidth, origHeight, thumbDimension, true); + MagickImage scaled = scaleImage(imageOrig, proportionalDim.width, proportionalDim.height); int x = calculateCenteredCoordinate(proportionalDim.width, cropDimension); int y = calculateCenteredCoordinate(proportionalDim.height, cropDimension); - MagickImage scaled = scaleImage(imageOrig, proportionalDim.width, proportionalDim.height); cropImage(scaled, fileDest, x, y, cropDimension, cropDimension); } @@ -53,15 +58,32 @@ return scaleImage(imageOrig, fileDest, width, height); } + public static boolean scaleImageToMax(String fileOrig, String fileDest, int maxSize) throws MagickException { + MagickImage imageOrig = createImage(fileOrig); + Dimension origDimension = imageOrig.getDimension(); + int origHeight = origDimension.height; + int origWidth = origDimension.width; + Dimension proportionalDim = calculatePropDim(origWidth, origHeight, maxSize, false); + MagickImage scaled = scaleImage(imageOrig, proportionalDim.width, proportionalDim.height); + + return writeImage(scaled, fileDest); + } + static int calculateCenteredCoordinate(int size, int crop) { int i = (size - crop) / 2; return i < 0 ? 0 : i; } - static Dimension calculateProportionalDim(int origWidth, int origHeight, int maxSize) { + static Dimension calculatePropDim(int origWidth, int origHeight, int maxSize) { + return calculatePropDim(origWidth, origHeight, maxSize, true); + } + + static Dimension calculatePropDim(int origWidth, int origHeight, int maxSize, boolean toShortest) { boolean higher = origHeight > origWidth; - double height = higher ? (origHeight * maxSize / origWidth) : maxSize; - double width = !higher ? (origWidth * maxSize / origHeight) : maxSize; + int propHeight = origHeight * maxSize / origWidth; + int propWidth = origWidth * maxSize / origHeight; + double height = toShortest ? (higher ? propHeight : maxSize) : (higher ? maxSize : propHeight); + double width = toShortest ? (!higher ? propWidth : maxSize) : (!higher ? maxSize : propWidth); if ((higher && origHeight <= maxSize) || (!higher && origWidth <= maxSize)) { return new Dimension(origWidth, origHeight); } Modified: trunk/src/main/java/org/ourproject/kune/platf/server/properties/KuneProperties.java =================================================================== --- trunk/src/main/java/org/ourproject/kune/platf/server/properties/KuneProperties.java 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/main/java/org/ourproject/kune/platf/server/properties/KuneProperties.java 2008-10-15 03:14:33 UTC (rev 910) @@ -32,6 +32,10 @@ public String UPLOAD_GALLERY_PERMITTED_EXTS = "kune.upload.gallerypermittedextensions"; public String UPLOAD_MAX_FILE_SIZE = "kune.upload.maxfilesizeinmegas"; public String UPLOAD_LOCATION = "kune.upload.location"; + public String IMAGES_RESIZEWIDTH = "kune.images.resizewidth"; + public String IMAGES_THUMBSIZE = "kune.images.thumbsize"; + public String IMAGES_CROPSIZE = "kune.images.cropsize"; + public String IMAGES_ICONSIZE = "kune.images.iconsize"; public String get(String key); Modified: trunk/src/main/resources/kune.properties =================================================================== --- trunk/src/main/resources/kune.properties 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/main/resources/kune.properties 2008-10-15 03:14:33 UTC (rev 910) @@ -25,5 +25,13 @@ kune.sitelogourl = images/kune-logo-16px.png kune.upload.location = /var/lib/kune/uploads/ + +# Gallery options kune.upload.gallerypermittedextensions = jpg,jpeg,png,gif,bmp,svg,avi,mpg,mpeg,ogg,mov,tif,tiff,mp3,wav kune.upload.maxfilesizeinmegas = 10 +# Images are resized to thumbsize pixels and later cropped (centered) to cropsize +kune.images.resizewidth = 400 +kune.images.thumbsize = 100 +kune.images.cropsize = 85 + +kune.images.iconsize = 16 Modified: trunk/src/test/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefaultTest.java =================================================================== --- trunk/src/test/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefaultTest.java 2008-10-14 13:39:30 UTC (rev 909) +++ trunk/src/test/java/org/ourproject/kune/platf/server/manager/impl/ImageUtilsDefaultTest.java 2008-10-15 03:14:33 UTC (rev 910) @@ -13,9 +13,14 @@ import org.junit.Test; /** - * UnsatisfiedLinkError: problem with jmagick installation (in debian, apt-get - * install libjmagick6-jni, and add LD_LIBRARY_PATH=/usr/lib/jni/ to this test - * environment params + * If you get a UnsatisfiedLinkError this is a problem with jmagick installation + * (in debian, apt-get install libjmagick6-jni, and add + * LD_LIBRARY_PATH=/usr/lib/jni/ to this test environment params or sudo ln -s + * /usr/lib/jni/libJMagick.so /usr/lib/libJMagick.so) + * + * See the output of: + * System.out.println(System.getProperty("java.library.path")); to see when is + * expecting the .so/.dll */ public class ImageUtilsDefaultTest { @@ -56,7 +61,7 @@ @Test public void testProportionalHigher() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(500, 1000, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(500, 1000, 100); assertEquals(100, proportionalDim.width); assertEquals(200, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -65,7 +70,7 @@ @Test public void testProportionalHigherLikeSamples() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(1200, 1600, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(1200, 1600, 100); assertEquals(100, proportionalDim.width); assertEquals(133, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -74,7 +79,7 @@ @Test public void testProportionalHigherSame() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(20, 100, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(20, 100, 100); assertEquals(20, proportionalDim.width); assertEquals(100, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -83,7 +88,7 @@ @Test public void testProportionalHigherSmaller() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(20, 10, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(20, 10, 100); assertEquals(20, proportionalDim.width); assertEquals(10, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -91,8 +96,36 @@ } @Test + public void testProportionalToBiggerNormal() { + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(600, 300, 300, false); + assertEquals(300, proportionalDim.width); + assertEquals(150, proportionalDim.height); + } + + @Test + public void testProportionalToBiggerSame() { + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(600, 300, 600, false); + assertEquals(600, proportionalDim.width); + assertEquals(300, proportionalDim.height); + } + + @Test + public void testProportionalToBiggerSmaller() { + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(600, 300, 700, false); + assertEquals(600, proportionalDim.width); + assertEquals(300, proportionalDim.height); + } + + @Test + public void testProportionalToBiggerWider() { + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(300, 600, 200, false); + assertEquals(100, proportionalDim.width); + assertEquals(200, proportionalDim.height); + } + + @Test public void testProportionalWider() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(1000, 500, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(1000, 500, 100); assertEquals(200, proportionalDim.width); assertEquals(100, proportionalDim.height); assertEquals(50, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -101,7 +134,7 @@ @Test public void testProportionalWiderSame() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(100, 20, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(100, 20, 100); assertEquals(100, proportionalDim.width); assertEquals(20, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100)); @@ -110,7 +143,7 @@ @Test public void testProportionalWiderSmaller() { - Dimension proportionalDim = ImageUtilsDefault.calculateProportionalDim(5, 10, 100); + Dimension proportionalDim = ImageUtilsDefault.calculatePropDim(5, 10, 100); assertEquals(5, proportionalDim.width); assertEquals(10, proportionalDim.height); assertEquals(0, ImageUtilsDefault.calculateCenteredCoordinate(proportionalDim.width, 100));
participants (1)
-
vjrj