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:
Massimiliano Assante 2014-01-21 17:43:03 +00:00
parent aca1ae6aa9
commit e99f65e9f5
6 changed files with 235 additions and 81 deletions

View File

@ -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>

View File

@ -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
}
});
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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