FTP server is no longer used for thumbnails. Everything is stored on the storage service. Waiting for ticket #5799 to be completed to speed up the generic thumbnails retrieval
git-svn-id: https://svn.research-infrastructures.eu/d4science/gcube/trunk/portlets/user/share-updates@134370 82a268e6-3cf1-43bd-a215-b396298e98cf
|
@ -1,9 +1,16 @@
|
||||||
<ReleaseNotes>
|
<ReleaseNotes>
|
||||||
<Changeset component="org.gcube.portlets-user.shareupdates.2-1-0"
|
<Changeset component="org.gcube.portlets-user.shareupdates.2-2-0"
|
||||||
date="2016-09-29">
|
date="2016-12-02">
|
||||||
<Change>updated opengraph checkURL for getting images in case of HTTP redirect permanently is encountered</Change>
|
<Change>Removed asl session dependency</Change>
|
||||||
|
<Change>Thumbnails are no longer stored on the FTP server. Storage
|
||||||
|
service is used</Change>
|
||||||
|
</Changeset>
|
||||||
|
<Changeset component="org.gcube.portlets-user.shareupdates.2-1-0"
|
||||||
|
date="2016-09-29">
|
||||||
|
<Change>updated opengraph checkURL for getting images in case of HTTP
|
||||||
|
redirect permanently is encountered
|
||||||
|
</Change>
|
||||||
</Changeset>
|
</Changeset>
|
||||||
|
|
||||||
<Changeset component="org.gcube.portlets-user.shareupdates.2-0-0"
|
<Changeset component="org.gcube.portlets-user.shareupdates.2-0-0"
|
||||||
date="2016-06-29">
|
date="2016-06-29">
|
||||||
<Change>Updated to Liferay 6.2.5</Change>
|
<Change>Updated to Liferay 6.2.5</Change>
|
||||||
|
@ -24,7 +31,8 @@
|
||||||
<Changeset component="org.gcube.portlets-user.shareupdates.1-8-0"
|
<Changeset component="org.gcube.portlets-user.shareupdates.1-8-0"
|
||||||
date="2015-07-06">
|
date="2015-07-06">
|
||||||
<Change>made notification to members option configurable as default,
|
<Change>made notification to members option configurable as default,
|
||||||
see Feature #121</Change>
|
see Feature #121
|
||||||
|
</Change>
|
||||||
</Changeset>
|
</Changeset>
|
||||||
<Changeset component="org.gcube.portlets-user.shareupdates.1-7-0"
|
<Changeset component="org.gcube.portlets-user.shareupdates.1-7-0"
|
||||||
date="2015-05-27">
|
date="2015-05-27">
|
||||||
|
|
4
pom.xml
|
@ -97,7 +97,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.core</groupId>
|
<groupId>org.gcube.core</groupId>
|
||||||
<artifactId>common-scope-maps</artifactId>
|
<artifactId>common-scope-maps</artifactId>
|
||||||
<scope>compile</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.portlets.widgets</groupId>
|
<groupId>org.gcube.portlets.widgets</groupId>
|
||||||
|
@ -232,10 +232,12 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -8,20 +8,27 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import net.coobird.thumbnailator.Thumbnails;
|
import net.coobird.thumbnailator.Thumbnails;
|
||||||
|
|
||||||
|
import org.apache.commons.fileupload.util.Streams;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.util.PDFTextStripper;
|
import org.apache.pdfbox.util.PDFTextStripper;
|
||||||
import org.apache.tika.config.TikaConfig;
|
import org.apache.tika.config.TikaConfig;
|
||||||
|
@ -29,8 +36,7 @@ import org.apache.tika.detect.Detector;
|
||||||
import org.apache.tika.io.TikaInputStream;
|
import org.apache.tika.io.TikaInputStream;
|
||||||
import org.apache.tika.metadata.Metadata;
|
import org.apache.tika.metadata.Metadata;
|
||||||
import org.apache.tika.mime.MediaType;
|
import org.apache.tika.mime.MediaType;
|
||||||
import org.gcube.applicationsupportlayer.social.storage.FTPManager;
|
import org.gcube.contentmanagement.blobstorage.service.IClient;
|
||||||
import org.gcube.portal.databook.shared.ImageType;
|
|
||||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -39,35 +45,36 @@ import com.sun.pdfview.PDFFile;
|
||||||
import com.sun.pdfview.PDFPage;
|
import com.sun.pdfview.PDFPage;
|
||||||
import com.sun.pdfview.PDFParseException;
|
import com.sun.pdfview.PDFParseException;
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Massimiliano Assante, ISTI-CNR
|
|
||||||
*
|
|
||||||
* Parse files and returns an image preview plus description
|
* Parse files and returns an image preview plus description
|
||||||
*
|
* @author Massimiliano Assante, ISTI-CNR
|
||||||
*/
|
*/
|
||||||
public class FilePreviewer {
|
public class FilePreviewer {
|
||||||
private static Logger _log = LoggerFactory.getLogger(FilePreviewer.class);
|
|
||||||
|
|
||||||
private static final String PDF_DEFAULT_IMAGE = "default/pdf.png";
|
private static final Logger _log = LoggerFactory.getLogger(FilePreviewer.class);
|
||||||
private static final String GENERICFILE_DEFAULT_IMAGE = "default/default_generic.png";
|
private static final String UPLOAD_LOCATION_LOCAL = System.getProperty("java.io.tmpdir");
|
||||||
|
public static final String DIR_STORAGE_DEFAULT_ICONS = "default-icons-directory"; // to be append to UPLOAD_DIR
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* these are the extension for which I have an icon image preview
|
* these are the extension for which I have an icon image preview
|
||||||
*/
|
*/
|
||||||
private static final String[] handledextensionImages = {"css", "csv", "doc", "docx", "java", "mdb", "mp3", "pdf", "ppt", "pptx", "psd", "rar", "tex", "txt", "xls", "xlsx", "zip"};
|
private static final String[] handledextensionImages = {"css", "csv", "doc", "docx", "java", "mdb", "mp3", "pdf", "ppt", "pptx", "psd", "rar", "tex", "txt", "xls", "xlsx", "zip"};
|
||||||
|
|
||||||
private static FTPManager getFTPManager() {
|
|
||||||
return FTPManager.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param fileNameLabel thename of the file
|
* @param fileNameLabel thename of the file
|
||||||
* @param path2Pdf the path of the pdf file
|
* @param path2Pdf the path of the pdf file
|
||||||
* @param httpUrl the http url where the file is reachable at
|
* @param httpUrl the http url where the file is reachable at
|
||||||
|
* @param storageClient
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected static LinkPreview getPdfPreview(String fileName, String path2Pdf, String httpUrl, String mimeType) throws Exception {
|
protected static LinkPreview getPdfPreview(
|
||||||
|
String fileName,
|
||||||
|
String path2Pdf,
|
||||||
|
String httpUrl,
|
||||||
|
String mimeType,
|
||||||
|
IClient sClient,
|
||||||
|
ServletContext sContext) throws Exception {
|
||||||
ArrayList<String> imagesUrl = new ArrayList<String>();
|
ArrayList<String> imagesUrl = new ArrayList<String>();
|
||||||
//description
|
//description
|
||||||
String desc = null;
|
String desc = null;
|
||||||
|
@ -90,8 +97,7 @@ public class FilePreviewer {
|
||||||
} catch (PDFParseException ex) {
|
} catch (PDFParseException ex) {
|
||||||
raf.close();
|
raf.close();
|
||||||
_log.error("PDF Parse exception, returning default pdf image");
|
_log.error("PDF Parse exception, returning default pdf image");
|
||||||
|
imagesUrl.add(getDefaultIconUrl(sClient, IconFileNames.PDF.getFileName(), sContext));
|
||||||
imagesUrl.add(getFTPManager().getBaseURL()+PDF_DEFAULT_IMAGE);
|
|
||||||
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
||||||
}
|
}
|
||||||
PDFPage page = pdf.getPage(0);
|
PDFPage page = pdf.getPage(0);
|
||||||
|
@ -104,11 +110,8 @@ public class FilePreviewer {
|
||||||
|
|
||||||
// create the image
|
// create the image
|
||||||
Rectangle rect = new Rectangle(0, 0, width, height);
|
Rectangle rect = new Rectangle(0, 0, width, height);
|
||||||
|
|
||||||
BufferedImage bufferedImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
|
BufferedImage bufferedImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
Image image = page.getImage(scaledWidth, scaledHeight, rect, null, true, true);
|
Image image = page.getImage(scaledWidth, scaledHeight, rect, null, true, true);
|
||||||
|
|
||||||
Graphics2D bufImageGraphics = bufferedImage.createGraphics();
|
Graphics2D bufImageGraphics = bufferedImage.createGraphics();
|
||||||
bufImageGraphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
|
bufImageGraphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
|
||||||
|
|
||||||
|
@ -118,9 +121,14 @@ public class FilePreviewer {
|
||||||
raf.close();
|
raf.close();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
String httpLink = getFTPManager().uploadImageOnFTPServer(new ByteArrayInputStream(out.toByteArray()), ImageType.JPG);
|
try{
|
||||||
_log.debug("PDF thumbnail available at: " + httpLink);
|
String storagehttpLink = syncUploadThumbnailStorage(new ByteArrayInputStream(out.toByteArray()), sClient, "thumbnail_" + fileName);
|
||||||
imagesUrl.add(httpLink);
|
imagesUrl.add(storagehttpLink);
|
||||||
|
_log.debug("PDF thumbnail available at: " + storagehttpLink);
|
||||||
|
}catch(Exception e){
|
||||||
|
_log.error("Failed to create a thumbnail for the preview ...");
|
||||||
|
imagesUrl.add(getDefaultIconUrl(sClient, IconFileNames.PDF.getFileName(), sContext));
|
||||||
|
}
|
||||||
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -134,7 +142,7 @@ public class FilePreviewer {
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected static LinkPreview getImagePreview(String fileName, String path2Image, String httpUrl, String mimeType) {
|
protected static LinkPreview getImagePreview(String fileName, String path2Image, String httpUrl, String mimeType, IClient sClient, ServletContext sContext) {
|
||||||
ArrayList<String> imagesUrl = new ArrayList<String>();
|
ArrayList<String> imagesUrl = new ArrayList<String>();
|
||||||
|
|
||||||
Dimension dim;
|
Dimension dim;
|
||||||
|
@ -152,13 +160,15 @@ public class FilePreviewer {
|
||||||
.width(80)
|
.width(80)
|
||||||
.outputFormat("jpg")
|
.outputFormat("jpg")
|
||||||
.toOutputStream(out);
|
.toOutputStream(out);
|
||||||
|
|
||||||
|
String storagehttpLink = syncUploadThumbnailStorage(new ByteArrayInputStream(out.toByteArray()), sClient, "thumbnail_" + fileName);
|
||||||
|
_log.debug("Image thumbnail available at: " + storagehttpLink);
|
||||||
|
imagesUrl.add(storagehttpLink);
|
||||||
|
}catch (IOException e) {
|
||||||
|
_log.error("Failed to get a preview... Using generic image");
|
||||||
|
imagesUrl.add(getDefaultIconUrl(sClient, IconFileNames.IMAGE_GENERIC.getFileName(), sContext));
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
String httpLink = getFTPManager().uploadImageOnFTPServer(new ByteArrayInputStream(out.toByteArray()), ImageType.JPG);
|
|
||||||
_log.debug("\nFlushed, Image thumbnail available at: " + httpLink);
|
|
||||||
imagesUrl.add(httpLink);
|
|
||||||
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,20 +180,26 @@ public class FilePreviewer {
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected static LinkPreview getUnhandledTypePreview(String fileName, String path2Pdf, String httpUrl, String mimeType) throws Exception {
|
protected static LinkPreview getUnhandledTypePreview(
|
||||||
|
String fileName,
|
||||||
|
String path2Pdf,
|
||||||
|
String httpUrl,
|
||||||
|
String mimeType,
|
||||||
|
IClient sClient,
|
||||||
|
ServletContext sContext) throws Exception {
|
||||||
|
|
||||||
ArrayList<String> imagesUrl = new ArrayList<String>();
|
ArrayList<String> imagesUrl = new ArrayList<String>();
|
||||||
String extension = getExtension(fileName);
|
String extension = getExtension(fileName);
|
||||||
//no description
|
//no description
|
||||||
String desc = "";
|
String desc = "";
|
||||||
if (extension == null)
|
if (extension == null)
|
||||||
imagesUrl.add(getFTPManager().getBaseURL()+GENERICFILE_DEFAULT_IMAGE);
|
imagesUrl.add(getDefaultIconUrl(sClient, IconFileNames.GENERIC.getFileName(), sContext));
|
||||||
else {
|
else {
|
||||||
int foundIndex = Arrays.binarySearch(handledextensionImages, extension);
|
int foundIndex = Arrays.binarySearch(handledextensionImages, extension);
|
||||||
if (foundIndex < 0)
|
if (foundIndex < 0)
|
||||||
imagesUrl.add(getFTPManager().getBaseURL()+GENERICFILE_DEFAULT_IMAGE);
|
imagesUrl.add(getDefaultIconUrl(sClient, IconFileNames.GENERIC.getFileName(), sContext));
|
||||||
else
|
else
|
||||||
imagesUrl.add(getFTPManager().getBaseURL()+"default/"+extension+".png");
|
imagesUrl.add(getDefaultIconUrl(sClient, extension+".png", sContext));
|
||||||
}
|
}
|
||||||
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
return new LinkPreview(fileName, desc, httpUrl, mimeType, imagesUrl);
|
||||||
}
|
}
|
||||||
|
@ -254,4 +270,148 @@ public class FilePreviewer {
|
||||||
MediaType mediaType = detector.detect(stream, metadata);
|
MediaType mediaType = detector.detect(stream, metadata);
|
||||||
return mediaType.getBaseType().toString();
|
return mediaType.getBaseType().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but having as input an inputstream object
|
||||||
|
* @param is
|
||||||
|
* @param filenameWithExtension
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected static String getMimeType(InputStream is, String filenameWithExtension) throws IOException {
|
||||||
|
TikaConfig config = TikaConfig.getDefaultConfig();
|
||||||
|
Detector detector = config.getDetector();
|
||||||
|
TikaInputStream stream = TikaInputStream.get(is);
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.add(Metadata.RESOURCE_NAME_KEY, filenameWithExtension);
|
||||||
|
MediaType mediaType = detector.detect(stream, metadata);
|
||||||
|
return mediaType.getBaseType().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a thumbnail on the storage and returns the http url. The operation is synchronous
|
||||||
|
* @param sClient
|
||||||
|
* @param byteArrayInputStream
|
||||||
|
* @return http url of the thumbnail
|
||||||
|
*/
|
||||||
|
protected static String syncUploadThumbnailStorage(ByteArrayInputStream byteArrayInputStream, IClient sClient, String thumbnailFileName){
|
||||||
|
try{
|
||||||
|
// a random remote folder/file on the storage for the thumbnail
|
||||||
|
String randomUploadFolderName = UUID.randomUUID().toString();
|
||||||
|
String remoteFilePath = ShareUpdateServiceImpl.UPLOAD_DIR + "/" + randomUploadFolderName + "/" + thumbnailFileName;
|
||||||
|
String thumbnailMime = getMimeType(byteArrayInputStream, null);
|
||||||
|
sClient.put(true, thumbnailMime).LFile(byteArrayInputStream).RFile(remoteFilePath);
|
||||||
|
return sClient.getHttpUrl(true).RFile(remoteFilePath);
|
||||||
|
}catch(Exception e){
|
||||||
|
_log.error("Failed to upload thumbnail on storage...");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a resource at a given url exists or not. If it exists, create a file in the temp dir
|
||||||
|
* of the tomcat. Files and folers are deleted on exit.
|
||||||
|
* @param urlThumbnail
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static File storeAndGetFile(String urlThumbnail){
|
||||||
|
try {
|
||||||
|
HttpURLConnection.setFollowRedirects(true);
|
||||||
|
HttpURLConnection con =
|
||||||
|
(HttpURLConnection) new URL(urlThumbnail).openConnection();
|
||||||
|
con.setRequestMethod("HEAD"); // body is not needed yet
|
||||||
|
if(con.getResponseCode() == HttpURLConnection.HTTP_OK){
|
||||||
|
|
||||||
|
//generate the random dir
|
||||||
|
File theRandomDir = new File(UPLOAD_LOCATION_LOCAL + File.separator + UUID.randomUUID().toString());
|
||||||
|
theRandomDir.mkdir();
|
||||||
|
theRandomDir.deleteOnExit();
|
||||||
|
_log.debug("Created temp upload directory in: " + theRandomDir);
|
||||||
|
|
||||||
|
// generate a random file name and create it under the randomDir
|
||||||
|
File file = new File(theRandomDir, UUID.randomUUID().toString().substring(0, 10));
|
||||||
|
file.deleteOnExit();
|
||||||
|
|
||||||
|
//Get the inputstream and copy there
|
||||||
|
URL url = new URL(urlThumbnail);
|
||||||
|
Streams.copy(url.openStream(), new FileOutputStream(file), true);
|
||||||
|
_log.debug("File is at " + file.getAbsolutePath());
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
_log.error("The resource at url " + urlThumbnail + " doesn't exist");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a link preview needs to be saved, the method save the thumbnail on the storage no longer using the external url
|
||||||
|
* @param urlThumbnail
|
||||||
|
* @return the url of the thumbnail saved on the storage or null in case of error
|
||||||
|
*/
|
||||||
|
public static String getThumbnailFromUrl(String urlThumbnail, IClient sClient, ServletContext sContext) {
|
||||||
|
File localFile;
|
||||||
|
if((localFile = storeAndGetFile(urlThumbnail)) != null){
|
||||||
|
String mimeType = null;
|
||||||
|
try {
|
||||||
|
mimeType = FilePreviewer.getMimeType(localFile, localFile.getName());
|
||||||
|
String thumbnailUrlStorage = null;
|
||||||
|
switch(mimeType){
|
||||||
|
case "image/png":
|
||||||
|
case "image/gif":
|
||||||
|
case "image/tiff":
|
||||||
|
case "image/jpg":
|
||||||
|
case "image/jpeg":
|
||||||
|
case "image/bmp":
|
||||||
|
thumbnailUrlStorage = getImagePreview(localFile.getName(), localFile.getAbsolutePath(), null, mimeType, sClient, sContext).getImageUrls().get(0);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return thumbnailUrlStorage;
|
||||||
|
} catch (IOException e) {
|
||||||
|
_log.error("Error while saving thumbnail on ftp", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else
|
||||||
|
_log.warn("the file at url " + urlThumbnail + " doesn't exist");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the preview methods fail to create a thumbnail and one of the "default icons" needs to be used,
|
||||||
|
* the method retrieve the url of these files from the storage. In case the icon is missing, it upload the file too on the storage
|
||||||
|
* before returning.
|
||||||
|
* @param storage
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String getDefaultIconUrl(IClient sClient, String iconFile, ServletContext sContext){
|
||||||
|
|
||||||
|
try{
|
||||||
|
//TODO do I need to download the whole stream?!
|
||||||
|
String iconPathOnStorage = ShareUpdateServiceImpl.UPLOAD_DIR + "/" + FilePreviewer.DIR_STORAGE_DEFAULT_ICONS + "/" + iconFile;
|
||||||
|
_log.debug("looking for remote file at relative url " + iconPathOnStorage);
|
||||||
|
|
||||||
|
InputStream inputStream = sClient.get().RFileAsInputStream(iconPathOnStorage);
|
||||||
|
if(inputStream == null){
|
||||||
|
_log.info("Ok, the default icon was not on the storage.. going to put it there");
|
||||||
|
InputStream localInputStream = sContext.getResourceAsStream("/images/default/" + iconFile);
|
||||||
|
if(localInputStream != null){
|
||||||
|
sClient.put(true).LFile(localInputStream).RFile(iconPathOnStorage);
|
||||||
|
_log.info("Request for upload started for file " + iconPathOnStorage + ", trying to get the http url");
|
||||||
|
return sClient.getHttpUrl(true).RFile(iconPathOnStorage);
|
||||||
|
}else{
|
||||||
|
_log.warn("Failed to get the inputstream of the icon " + iconFile + " form the subpath /images/default/");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
return sClient.getHttpUrl(true).RFile(iconPathOnStorage);
|
||||||
|
}catch(Exception e){
|
||||||
|
_log.error("Something went wrong with the storage for the default image.. returning null", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.gcube.portlets.user.shareupdates.server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icons type
|
||||||
|
* @author Costantino Perciante at ISTI-CNR
|
||||||
|
* (costantino.perciante@isti.cnr.it)
|
||||||
|
*/
|
||||||
|
public enum IconFileNames {
|
||||||
|
|
||||||
|
GENERIC("default_generic.png"),
|
||||||
|
IMAGE_GENERIC("default_image.png"),
|
||||||
|
DOCX("docx.png"),
|
||||||
|
PPTX("pptx.png"),
|
||||||
|
PDF("pdf.png"),
|
||||||
|
RAR("rar.png"),
|
||||||
|
ZIP("zip.png"),
|
||||||
|
XLS("xls.png"),
|
||||||
|
CSS("css.png"),
|
||||||
|
CSV("csv.png"),
|
||||||
|
DOC("doc.png"),
|
||||||
|
JAVA("java.png"),
|
||||||
|
MDB("mdb.png"),
|
||||||
|
MP3("mp3.png"),
|
||||||
|
PSD("psd.png"),
|
||||||
|
TEX("tex.png"),
|
||||||
|
PPT("ppt.png"),
|
||||||
|
XLSX("xlsx.png");
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
IconFileNames(String fileName){
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName(){
|
||||||
|
return this.fileName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package org.gcube.portlets.user.shareupdates.server;
|
package org.gcube.portlets.user.shareupdates.server;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
@ -19,7 +18,6 @@ import java.util.UUID;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
import org.apache.commons.fileupload.util.Streams;
|
|
||||||
import org.apache.commons.validator.routines.UrlValidator;
|
import org.apache.commons.validator.routines.UrlValidator;
|
||||||
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
|
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
|
||||||
import org.gcube.applicationsupportlayer.social.NotificationsManager;
|
import org.gcube.applicationsupportlayer.social.NotificationsManager;
|
||||||
|
@ -84,12 +82,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
private static final String STORAGE_OWNER = "gCubeSocialFramework";
|
private static final String STORAGE_OWNER = "gCubeSocialFramework";
|
||||||
public static final String UPLOAD_DIR = "/social-framework-uploads";
|
public static final String UPLOAD_DIR = "/social-framework-uploads";
|
||||||
private static final String NEWS_FEED_PORTLET_CLASSNAME = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl";
|
private static final String NEWS_FEED_PORTLET_CLASSNAME = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl";
|
||||||
private static String UPLOAD_LOCATION_LOCAL = System.getProperty("java.io.tmpdir");
|
private static final Logger _log = LoggerFactory.getLogger(ShareUpdateServiceImpl.class);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static Logger _log = LoggerFactory.getLogger(ShareUpdateServiceImpl.class);
|
|
||||||
private DatabookStore store;
|
private DatabookStore store;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,7 +139,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
String username = currUser.getUsername();
|
String username = currUser.getUsername();
|
||||||
String email = currUser.getEmail();
|
String email = currUser.getEmail();
|
||||||
String fullName = currUser.getFullname();
|
String fullName = currUser.getFullname();
|
||||||
String thumbnailAvatarURL = currUser.getUserAvatarId();
|
String thumbnailAvatarURL = currUser.getUserAvatarURL();
|
||||||
|
|
||||||
// get data from the preview of the link
|
// get data from the preview of the link
|
||||||
String linkTitle = preview.getTitle();
|
String linkTitle = preview.getTitle();
|
||||||
|
@ -156,7 +149,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
if (urlThumbnail == null)
|
if (urlThumbnail == null)
|
||||||
urlThumbnail = "null";
|
urlThumbnail = "null";
|
||||||
else
|
else
|
||||||
urlThumbnail = saveThumbnailOnFTPAndGetUrl(urlThumbnail);
|
urlThumbnail = FilePreviewer.getThumbnailFromUrl(urlThumbnail, getStorage(), getServletContext());
|
||||||
|
|
||||||
Date feedDate = new Date();
|
Date feedDate = new Date();
|
||||||
|
|
||||||
|
@ -192,7 +185,6 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
}//save the feed
|
}//save the feed
|
||||||
_log.trace("Success writing onto " + vreScope);
|
_log.trace("Success writing onto " + vreScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//share on a single VRE Timeline
|
//share on a single VRE Timeline
|
||||||
//receives a VreId(groupId) get the scope from the groupId
|
//receives a VreId(groupId) get the scope from the groupId
|
||||||
|
@ -228,80 +220,6 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a resource at a given url exists or not. If it exists, create a file in the temp dir
|
|
||||||
* of the tomcat
|
|
||||||
* @param urlThumbnail
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private File storeAndGetFile(String urlThumbnail){
|
|
||||||
try {
|
|
||||||
HttpURLConnection.setFollowRedirects(true);
|
|
||||||
HttpURLConnection con =
|
|
||||||
(HttpURLConnection) new URL(urlThumbnail).openConnection();
|
|
||||||
con.setRequestMethod("HEAD"); // body is not needed yet
|
|
||||||
if(con.getResponseCode() == HttpURLConnection.HTTP_OK){
|
|
||||||
|
|
||||||
//generate the random dir
|
|
||||||
File theRandomDir = new File(UPLOAD_LOCATION_LOCAL + File.separator + UUID.randomUUID().toString());
|
|
||||||
theRandomDir.mkdir();
|
|
||||||
theRandomDir.deleteOnExit();
|
|
||||||
_log.debug("Created temp upload directory in: " + theRandomDir);
|
|
||||||
|
|
||||||
// generate a random file name and create it under the randomDir
|
|
||||||
File file = new File(theRandomDir, UUID.randomUUID().toString().substring(0, 10));
|
|
||||||
file.deleteOnExit();
|
|
||||||
|
|
||||||
//Get the inputstream and copy there
|
|
||||||
URL url = new URL(urlThumbnail);
|
|
||||||
Streams.copy(url.openStream(), new FileOutputStream(file), true);
|
|
||||||
_log.debug("File is at " + file.getAbsolutePath());
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
_log.error("The resource at url " + urlThumbnail + " doesn't exist");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When a link preview needs to be saved, the method save the thumbnail on the storage no longer using the external url
|
|
||||||
* @param urlThumbnail
|
|
||||||
* @return the url of the thumbnail saved on the storage or null in case of error
|
|
||||||
*/
|
|
||||||
private String saveThumbnailOnFTPAndGetUrl(String urlThumbnail) {
|
|
||||||
File localFile;
|
|
||||||
if((localFile = storeAndGetFile(urlThumbnail)) != null){
|
|
||||||
String mimeType = null;
|
|
||||||
if (isWithinPortal()) {
|
|
||||||
try {
|
|
||||||
mimeType = FilePreviewer.getMimeType(localFile, localFile.getName());
|
|
||||||
String thumbnailUrlFTP = null;
|
|
||||||
switch(mimeType){
|
|
||||||
case "image/png":
|
|
||||||
case "image/gif":
|
|
||||||
case "image/tiff":
|
|
||||||
case "image/jpg":
|
|
||||||
case "image/jpeg":
|
|
||||||
case "image/bmp":
|
|
||||||
thumbnailUrlFTP = FilePreviewer.getImagePreview(localFile.getName(), localFile.getAbsolutePath(), null, mimeType).getImageUrls().get(0);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return thumbnailUrlFTP;
|
|
||||||
} catch (IOException e) {
|
|
||||||
_log.error("Error while saving thumbnail on ftp", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
_log.warn("the file at url " + urlThumbnail + " doesn't exist");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share a post with at least one attachment.
|
* Share a post with at least one attachment.
|
||||||
*/
|
*/
|
||||||
|
@ -331,7 +249,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
String username = currUser.getUsername();
|
String username = currUser.getUsername();
|
||||||
String email = currUser.getEmail();
|
String email = currUser.getEmail();
|
||||||
String fullName = currUser.getFullname();
|
String fullName = currUser.getFullname();
|
||||||
String thumbnailAvatarURL = currUser.getUserAvatarId();
|
String thumbnailAvatarURL = currUser.getUserAvatarURL();
|
||||||
|
|
||||||
// Managing attachments: the first one will use the same fields of a link preview.
|
// Managing attachments: the first one will use the same fields of a link preview.
|
||||||
// If more than one attachments are present, they will be saved as Attachment objects.
|
// If more than one attachments are present, they will be saved as Attachment objects.
|
||||||
|
@ -664,17 +582,14 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
@Override
|
@Override
|
||||||
public LinkPreview checkUploadedFile(String fileName, String fileabsolutePathOnServer) {
|
public LinkPreview checkUploadedFile(String fileName, String fileabsolutePathOnServer) {
|
||||||
|
|
||||||
PortalContext context = PortalContext.getConfiguration();
|
|
||||||
|
|
||||||
LinkPreview toReturn = null;
|
LinkPreview toReturn = null;
|
||||||
|
|
||||||
|
// a random remote folder/file on the storage for the payload
|
||||||
String randomUploadFolderName = UUID.randomUUID().toString();
|
String randomUploadFolderName = UUID.randomUUID().toString();
|
||||||
String remoteFilePath = UPLOAD_DIR + "/" + randomUploadFolderName + "/" + fileName;
|
String remoteFilePath = UPLOAD_DIR + "/" + randomUploadFolderName + "/" + fileName;
|
||||||
|
|
||||||
//get the Storage Client
|
//get the Storage Client
|
||||||
String currScope = ScopeProvider.instance.get();
|
IClient storageClient = getStorage();
|
||||||
ScopeProvider.instance.set(context.getCurrentScope(getThreadLocalRequest()));
|
|
||||||
IClient storageClient = new StorageClient(STORAGE_OWNER, AccessType.SHARED, MemoryType.PERSISTENT).getClient();
|
|
||||||
ScopeProvider.instance.set(currScope);
|
|
||||||
|
|
||||||
String httpURL = "";
|
String httpURL = "";
|
||||||
String smpURI = "";
|
String smpURI = "";
|
||||||
|
@ -692,7 +607,6 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
}
|
}
|
||||||
Thread thread = new Thread(new UploadToStorageThread(storageClient, fileName, fileabsolutePathOnServer, remoteFilePath, mimeType));
|
Thread thread = new Thread(new UploadToStorageThread(storageClient, fileName, fileabsolutePathOnServer, remoteFilePath, mimeType));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//get the url to show (though it could not be ready for download at this stage)
|
//get the url to show (though it could not be ready for download at this stage)
|
||||||
|
@ -700,41 +614,37 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
|
|
||||||
switch (mimeType) {
|
switch (mimeType) {
|
||||||
case "application/pdf":
|
case "application/pdf":
|
||||||
toReturn = FilePreviewer.getPdfPreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
toReturn = FilePreviewer.getPdfPreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
break;
|
break;
|
||||||
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
||||||
mimeType = "application/wordprocessor";
|
mimeType = "application/wordprocessor";
|
||||||
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||||
mimeType = "application/spreadsheet";
|
mimeType = "application/spreadsheet";
|
||||||
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
||||||
mimeType = "application/presentation";
|
mimeType = "application/presentation";
|
||||||
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
case "image/png":
|
case "image/png":
|
||||||
case "image/gif":
|
case "image/gif":
|
||||||
case "image/tiff":
|
case "image/tiff":
|
||||||
case "image/jpg":
|
case "image/jpg":
|
||||||
case "image/jpeg":
|
case "image/jpeg":
|
||||||
case "image/bmp":
|
case "image/bmp":
|
||||||
toReturn = FilePreviewer.getImagePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
toReturn = FilePreviewer.getImagePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType);
|
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, mimeType, storageClient, getServletContext());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
_log.error("Error while resolving or previewing file");
|
_log.error("Error while resolving or previewing file", e);
|
||||||
e.printStackTrace();
|
|
||||||
try {
|
try {
|
||||||
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, "Error During upload on Server!");
|
return FilePreviewer.getUnhandledTypePreview(fileName, fileabsolutePathOnServer, httpURL, "Error During upload on Server!", storageClient, getServletContext());
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
e1.printStackTrace();
|
_log.error("Unable to extract a preview ...", e1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_log.debug("smpURI=" + smpURI);
|
_log.debug("smpURI=" + smpURI);
|
||||||
_log.debug("Returning httpURL=" + httpURL);
|
_log.debug("Returning httpURL=" + httpURL);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
|
@ -944,4 +854,20 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the storage client object
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private IClient getStorage(){
|
||||||
|
|
||||||
|
String currScope = ScopeProvider.instance.get();
|
||||||
|
PortalContext context = PortalContext.getConfiguration();
|
||||||
|
ScopeProvider.instance.set(context.getCurrentScope(getThreadLocalRequest()));
|
||||||
|
IClient storageClient = new StorageClient(STORAGE_OWNER, AccessType.SHARED, MemoryType.PERSISTENT).getClient();
|
||||||
|
ScopeProvider.instance.set(currScope);
|
||||||
|
return storageClient;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 820 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 6.8 KiB |