file preview works for pdf
git-svn-id: https://svn.research-infrastructures.eu/d4science/gcube/trunk/portlets/user/share-updates@90348 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
aca1ae6aa9
commit
e99f65e9f5
5
pom.xml
5
pom.xml
|
@ -107,6 +107,11 @@
|
|||
<artifactId>pdf-renderer</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>1.8.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
|
|
|
@ -180,8 +180,7 @@ public class ShareUpdateForm extends Composite {
|
|||
FileUpload up = uploadProgress.initialize();
|
||||
up.setVisible(false);
|
||||
fileBrowse(up.getElement());
|
||||
uploadProgress.setVisible(true);
|
||||
attachButton.getElement().getStyle().setVisibility(Visibility.HIDDEN); //beacuse otherwise it looses the other properties setting
|
||||
uploadProgress.setVisible(true);
|
||||
} else {
|
||||
Window.alert("You cannot post two files, please remove the previous one first.");
|
||||
}
|
||||
|
@ -196,7 +195,8 @@ public class ShareUpdateForm extends Composite {
|
|||
|
||||
|
||||
@UiHandler("submitButton")
|
||||
void onClick(ClickEvent e) {
|
||||
void onClick(ClickEvent e) {
|
||||
attachButton.getElement().getStyle().setVisibility(Visibility.VISIBLE); //beacuse otherwise it looses the other properties setting
|
||||
shareupdateService.getUserSettings(new AsyncCallback<UserSettings>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
Window.alert("Ops! we encountered some problems delivering your message, server is not responding, please try again in a short while.");
|
||||
|
@ -366,7 +366,8 @@ public class ShareUpdateForm extends Composite {
|
|||
preview.clear();
|
||||
uploadProgress.setVisible(false);
|
||||
if (result != null)
|
||||
addPreview(result, true);
|
||||
addPreview(result, true);
|
||||
attachButton.getElement().getStyle().setVisibility(Visibility.HIDDEN); //beacuse otherwise it looses the other properties setting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,129 @@
|
|||
package org.gcube.portlets.user.shareupdates.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.util.PDFTextStripper;
|
||||
import org.gcube.applicationsupportlayer.social.storage.FTPManager;
|
||||
import org.gcube.portal.databook.shared.ImageType;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.pdfview.PDFFile;
|
||||
import com.sun.pdfview.PDFPage;
|
||||
import com.sun.pdfview.PDFParseException;
|
||||
/**
|
||||
*
|
||||
* @author Massimiliano Assante, ISTI-CNR
|
||||
*
|
||||
* Parse files and returns an image preview plus description
|
||||
*
|
||||
*/
|
||||
public class FilePreviewer {
|
||||
private static Logger _log = LoggerFactory.getLogger(FilePreviewer.class);
|
||||
|
||||
private static final String PDF_DEFAULT_IMAGE = "default_pdf.png";
|
||||
|
||||
private static FTPManager getFTPManager() {
|
||||
return FTPManager.getInstance();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param fileName thename of the file
|
||||
* @param path2Pdf the path of the pdf file
|
||||
* @param httpUrl the http url where the file is reachable at
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected static LinkPreview getPdfPreview(String fileName, String path2Pdf, String httpUrl) throws Exception {
|
||||
ArrayList<String> imagesUrl = new ArrayList<String>();
|
||||
//description
|
||||
String desc = null;
|
||||
try {
|
||||
desc = getPDFDescription(path2Pdf);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_log.warn("PDF Parse exception, returning no description");
|
||||
desc = "";
|
||||
}
|
||||
//thumbnail preview
|
||||
File pdfFile = new File(path2Pdf);
|
||||
RandomAccessFile raf = new RandomAccessFile(pdfFile, "r");
|
||||
FileChannel channel = raf.getChannel();
|
||||
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
|
||||
PDFFile pdf = null;
|
||||
try {
|
||||
pdf = new PDFFile(buf);
|
||||
} catch (PDFParseException ex) {
|
||||
raf.close();
|
||||
_log.error("PDF Parse exception, returning default pdf image");
|
||||
|
||||
imagesUrl.add(getFTPManager().getBaseURL()+PDF_DEFAULT_IMAGE);
|
||||
return new LinkPreview(fileName, desc, httpUrl, "d4science.org", imagesUrl);
|
||||
}
|
||||
PDFPage page = pdf.getPage(0);
|
||||
|
||||
int width = (int) page.getBBox().getWidth();
|
||||
int height = (int) page.getBBox().getHeight();
|
||||
|
||||
int scaledWidth = width/8;
|
||||
int scaledHeight = height/8;
|
||||
|
||||
// create the image
|
||||
Rectangle rect = new Rectangle(0, 0, width, height);
|
||||
|
||||
BufferedImage bufferedImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
Image image = page.getImage(scaledWidth, scaledHeight, rect, null, true, true);
|
||||
|
||||
Graphics2D bufImageGraphics = bufferedImage.createGraphics();
|
||||
bufImageGraphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
|
||||
|
||||
//thumbnail previes are very small in this case we can use in-memory streams
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
boolean result = ImageIO.write(bufferedImage, "JPG", out);
|
||||
raf.close();
|
||||
|
||||
if (result) {
|
||||
String httpLink = getFTPManager().uploadImageOnFTPServer(new ByteArrayInputStream(out.toByteArray()), ImageType.JPG);
|
||||
_log.debug("PDF thumbnail available at: " + httpLink);
|
||||
imagesUrl.add(httpLink);
|
||||
return new LinkPreview(fileName, desc, httpUrl, "d4science.org", imagesUrl);
|
||||
}
|
||||
else
|
||||
throw new IOException("Could not process pdf file");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path2File
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String getPDFDescription(String path2File) throws Exception {
|
||||
PDDocument doc = PDDocument.load(path2File);
|
||||
PDFTextStripper stripper = new PDFTextStripper();
|
||||
//only first page text
|
||||
stripper.setStartPage(1);
|
||||
stripper.setEndPage(1);
|
||||
String text = stripper.getText(doc);
|
||||
String toReturn = (text.length() > 300) ? text.substring(0, 295) + " ... " : text;
|
||||
doc.close();
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,17 @@
|
|||
package org.gcube.portlets.user.shareupdates.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
@ -33,14 +22,21 @@ import org.gcube.application.framework.core.session.ASLSession;
|
|||
import org.gcube.application.framework.core.session.SessionManager;
|
||||
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
|
||||
import org.gcube.applicationsupportlayer.social.NotificationsManager;
|
||||
import org.gcube.applicationsupportlayer.social.ftp.FTPManager;
|
||||
import org.gcube.applicationsupportlayer.social.storage.FTPManager;
|
||||
import org.gcube.applicationsupportlayer.social.storage.UriResolverReaderParameter;
|
||||
import org.gcube.common.homelibrary.home.HomeLibrary;
|
||||
import org.gcube.common.homelibrary.home.exceptions.HomeNotFoundException;
|
||||
import org.gcube.common.homelibrary.home.exceptions.InternalErrorException;
|
||||
import org.gcube.common.homelibrary.home.workspace.Workspace;
|
||||
import org.gcube.common.homelibrary.home.workspace.exceptions.WorkspaceFolderNotFoundException;
|
||||
import org.gcube.common.portal.PortalContext;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.common.scope.impl.ScopeBean;
|
||||
import org.gcube.common.scope.impl.ScopeBean.Type;
|
||||
import org.gcube.contentmanagement.blobstorage.service.IClient;
|
||||
import org.gcube.contentmanager.storageclient.wrapper.AccessType;
|
||||
import org.gcube.contentmanager.storageclient.wrapper.MemoryType;
|
||||
import org.gcube.contentmanager.storageclient.wrapper.StorageClient;
|
||||
import org.gcube.portal.custom.communitymanager.OrganizationsUtil;
|
||||
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
|
||||
import org.gcube.portal.databook.client.GCubeSocialNetworking;
|
||||
|
@ -49,16 +45,15 @@ import org.gcube.portal.databook.server.DatabookStore;
|
|||
import org.gcube.portal.databook.shared.ClientFeed;
|
||||
import org.gcube.portal.databook.shared.Feed;
|
||||
import org.gcube.portal.databook.shared.FeedType;
|
||||
import org.gcube.portal.databook.shared.ImageType;
|
||||
import org.gcube.portal.databook.shared.PrivacyLevel;
|
||||
import org.gcube.portal.databook.shared.UserInfo;
|
||||
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
|
||||
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
|
||||
import org.gcube.portlets.user.shareupdates.client.ShareUpdateService;
|
||||
import org.gcube.portlets.user.shareupdates.server.metaseeker.MetaSeeker;
|
||||
import org.gcube.portlets.user.shareupdates.server.opengraph.OpenGraph;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
import org.gcube.portlets.user.shareupdates.shared.UserSettings;
|
||||
import org.gcube.portlets.widgets.pickuser.shared.PickingUser;
|
||||
import org.gcube.vomanagement.usermanagement.GroupManager;
|
||||
import org.gcube.vomanagement.usermanagement.UserManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.liferay.LiferayGroupManager;
|
||||
|
@ -82,9 +77,6 @@ import com.liferay.portal.service.OrganizationLocalServiceUtil;
|
|||
import com.liferay.portal.service.UserLocalServiceUtil;
|
||||
import com.liferay.portal.theme.ThemeDisplay;
|
||||
import com.sun.net.ssl.HttpsURLConnection;
|
||||
import com.sun.pdfview.PDFFile;
|
||||
import com.sun.pdfview.PDFPage;
|
||||
import com.sun.pdfview.PDFParseException;
|
||||
|
||||
/**
|
||||
* The server side implementation of the RPC service.
|
||||
|
@ -98,16 +90,20 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final String PDF_DEFAULT_IMAGE = "default_pdf.png";
|
||||
|
||||
private static final String STORAGE_OWNER = "gCubeSocialFramework";
|
||||
public static final String UPLOAD_DIR = "/social-framework-uploads";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static Logger _log = LoggerFactory.getLogger(ShareUpdateServiceImpl.class);
|
||||
/**
|
||||
* The store interface
|
||||
* The Cassandra store interface
|
||||
*/
|
||||
private DatabookStore store;
|
||||
|
||||
/**
|
||||
* the FTP Storage
|
||||
*/
|
||||
private FTPManager ftpStore;
|
||||
/**
|
||||
* used for debugging in eclipse
|
||||
|
@ -118,7 +114,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
|||
*/
|
||||
public void init() {
|
||||
store = new DBCassandraAstyanaxImpl();
|
||||
ftpStore = FTPManager.getManager();
|
||||
ftpStore = FTPManager.getInstance();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
@ -337,66 +333,45 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
|||
*/
|
||||
@Override
|
||||
public LinkPreview checkUploadedFile(String fileName, String fileabsolutePathOnServer) {
|
||||
String imageUrl = null;
|
||||
LinkPreview toReturn = null;
|
||||
|
||||
String randomUploadFolderName = UUID.randomUUID().toString();
|
||||
String remoteFilePath = UPLOAD_DIR + "/" + randomUploadFolderName + "/" + fileName;
|
||||
|
||||
String currScope = ScopeProvider.instance.get();
|
||||
ScopeProvider.instance.set("/"+PortalContext.getConfiguration().getInfrastructureName());
|
||||
IClient storageClient = new StorageClient(STORAGE_OWNER, AccessType.SHARED, MemoryType.PERSISTENT).getClient();
|
||||
ScopeProvider.instance.set(currScope);
|
||||
|
||||
|
||||
|
||||
String httpURL = "";
|
||||
|
||||
String smpURI = storageClient.getUrl().RFile(remoteFilePath);
|
||||
|
||||
//The uploader Thread starts here asyncronously
|
||||
Thread thread = new Thread(new UploadToStorageThread(storageClient, fileName, fileabsolutePathOnServer, remoteFilePath));
|
||||
thread.start();
|
||||
|
||||
try {
|
||||
imageUrl = getPdfPreviewImage(fileabsolutePathOnServer);
|
||||
UriResolverReaderParameter resolver = new UriResolverReaderParameter();
|
||||
//get the url to show (though it could not be ready for download at this stage)
|
||||
httpURL = resolver.resolveAsUriRequest(smpURI, fileName, "application/pdf", true);
|
||||
|
||||
//TODO: switch
|
||||
toReturn = FilePreviewer.getPdfPreview(fileName, fileabsolutePathOnServer, httpURL);
|
||||
} catch (Exception e) {
|
||||
_log.error("Error while resolving or previewing file");
|
||||
e.printStackTrace();
|
||||
}
|
||||
ArrayList<String> imagesUrl = new ArrayList<String>();
|
||||
imagesUrl.add(imageUrl);
|
||||
return new LinkPreview(fileName, "the Desc", "http://www.lalala.com", "d4science.org", imagesUrl);
|
||||
}
|
||||
|
||||
|
||||
private String getPdfPreviewImage(String path2Pdf) throws Exception {
|
||||
File pdfFile = new File(path2Pdf);
|
||||
RandomAccessFile raf = new RandomAccessFile(pdfFile, "r");
|
||||
FileChannel channel = raf.getChannel();
|
||||
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
|
||||
PDFFile pdf = null;
|
||||
try {
|
||||
pdf = new PDFFile(buf);
|
||||
} catch (PDFParseException ex) {
|
||||
raf.close();
|
||||
_log.error("PDF Parse exception, returning default pdf image");
|
||||
return ftpStore.getBaseURL()+PDF_DEFAULT_IMAGE;
|
||||
}
|
||||
PDFPage page = pdf.getPage(0);
|
||||
}
|
||||
|
||||
int width = (int) page.getBBox().getWidth();
|
||||
int height = (int) page.getBBox().getHeight();
|
||||
|
||||
int scaledWidth = width/8;
|
||||
int scaledHeight = height/8;
|
||||
|
||||
// create the image
|
||||
Rectangle rect = new Rectangle(0, 0, width, height);
|
||||
|
||||
BufferedImage bufferedImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
Image image = page.getImage(scaledWidth, scaledHeight, // width & height
|
||||
rect, // clip rect
|
||||
null, // null for the ImageObserver
|
||||
true, // fill background with white
|
||||
true // block until drawing is done
|
||||
);
|
||||
Graphics2D bufImageGraphics = bufferedImage.createGraphics();
|
||||
bufImageGraphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
|
||||
|
||||
//images are very small in this case we can use in-memory streams
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
boolean result = ImageIO.write(bufferedImage, "JPG", out);
|
||||
raf.close();
|
||||
|
||||
if (result) {
|
||||
String httpLink = ftpStore.uploadImageOnFTPServer(new ByteArrayInputStream(out.toByteArray()), ImageType.JPG);
|
||||
_log.debug("PDF thumbnail available at: " + httpLink);
|
||||
return httpLink;
|
||||
}
|
||||
else
|
||||
throw new IOException("Could not process pdf file");
|
||||
_log.debug("smpURI=" + smpURI);
|
||||
_log.debug("Returning httpURL=" + httpURL);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* return the id as key and the names as value of the vre a user is subscribed to
|
||||
|
@ -804,5 +779,5 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar
|
|||
return workspace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package org.gcube.portlets.user.shareupdates.server;
|
||||
|
||||
import org.gcube.contentmanagement.blobstorage.service.IClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Massimiliano Assante ISTI-CNR
|
||||
*
|
||||
*/
|
||||
public class UploadToStorageThread implements Runnable {
|
||||
private static Logger _log = LoggerFactory.getLogger(UploadToStorageThread.class);
|
||||
|
||||
/**
|
||||
* remote path (with file name) in which you want to put the file
|
||||
*/
|
||||
private String remoteFilePath;
|
||||
/**
|
||||
* the name of the file you are putting
|
||||
*/
|
||||
private String fileName;
|
||||
/**
|
||||
* the path (with name) of the file you are putting
|
||||
*/
|
||||
private String fileabsolutePathOnServer;
|
||||
|
||||
private IClient sClient;
|
||||
/**
|
||||
*
|
||||
* @param sClient the instance of the storage client
|
||||
* @param fileToUpload the absolute path of the file
|
||||
*/
|
||||
public UploadToStorageThread(IClient sClient, String fileName, String fileabsolutePathOnServer, String remoteFilePath) {
|
||||
super();
|
||||
this.sClient = sClient;
|
||||
this.remoteFilePath = remoteFilePath;
|
||||
this.fileName = fileName;
|
||||
this.fileabsolutePathOnServer = fileabsolutePathOnServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String theID = sClient.put(true).LFile(fileabsolutePathOnServer).RFile(remoteFilePath);
|
||||
_log.debug("Uploaded " + fileName + " - Returned Storage id=" + theID);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,3 +15,4 @@ log4j.logger.org.gcube.resources.discovery.icclient=ERROR
|
|||
log4j.logger.org.gcube.common.clients=ERROR
|
||||
log4j.logger.org.gcube.common.homelibrary.jcr=ERROR
|
||||
log4j.logger.org.gcube.application.framework.accesslogger=ERROR
|
||||
log4j.logger.org.apache.pdfbox.util.PDFStreamEngine=ERROR
|
||||
|
|
Loading…
Reference in New Issue