Author: kmorin Date: 2014-06-29 19:42:07 +0200 (Sun, 29 Jun 2014) New Revision: 286 Url: http://forge.codelutin.com/projects/faxtomail/repository/revisions/286 Log: - am?\195?\169lioration de la g?\195?\169n?\195?\169ration des mail en pj - am?\195?\169lioration de l'?\195?\169dition des pj Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/FaxToMailServiceUtils.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/EditAttachmentAction.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/GenerateAnnotatedAttachmentAction.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeUIModel.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIModel.java trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java trunk/faxtomail-ui-web/pom.xml trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/job/MailFilterJob.java trunk/pom.xml Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo =================================================================== (Binary files differ) Modified: trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/FaxToMailServiceUtils.java =================================================================== --- trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/FaxToMailServiceUtils.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-service/src/main/java/com/franciaflex/faxtomail/services/FaxToMailServiceUtils.java 2014-06-29 17:42:07 UTC (rev 286) @@ -25,7 +25,13 @@ */ import com.franciaflex.faxtomail.persistence.entities.MailFolder; +import org.apache.commons.io.Charsets; +import javax.mail.MessagingException; +import javax.mail.Part; +import javax.mail.internet.ContentType; +import java.nio.charset.Charset; + /** * @author Kevin Morin (Code Lutin) * @since x.x @@ -44,4 +50,11 @@ faxNumber += "@" + folder.getFaxDomain(); return faxNumber; } + + public static Charset getCharset(Part part) throws MessagingException { + ContentType contentType = new ContentType(part.getContentType()); + String charsetName = contentType.getParameter("charset"); + Charset charset = Charsets.toCharset(charsetName); + return charset; + } } Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/EditAttachmentAction.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/EditAttachmentAction.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/EditAttachmentAction.java 2014-06-29 17:42:07 UTC (rev 286) @@ -58,10 +58,16 @@ @Override public void doAction() throws Exception { + FaxToMailUIUtil.forceAttachmentFileLoading(getContext(), attachment); + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); + MainUI mainUI = getContext().getMainUI(); PDFEditorUI dialogContent = new PDFEditorUI(getUI()); - FaxToMailUIUtil.forceAttachmentFileLoading(getContext(), attachment); /*boolean editedNull = attachment.getEditedFileName() == null; AttachmentFile attachmentFile = editedNull ? attachment.getOriginalFile() : attachment.getEditedFile(); if (attachmentFile == null) { @@ -77,4 +83,5 @@ getHandler().openDialog(dialogContent, attachment.getOriginalFileName(), mainUI.getSize()); dialogContent.getModel().toEntity(attachment); } + } \ No newline at end of file Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/GenerateAnnotatedAttachmentAction.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/GenerateAnnotatedAttachmentAction.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/GenerateAnnotatedAttachmentAction.java 2014-06-29 17:42:07 UTC (rev 286) @@ -116,13 +116,14 @@ float zoom = model.getZoom(); int rotation = model.getRotation(); + for (int i = 0 ; i < pageNb ; i++) { PdfContentByte cb = pdfStamper.getOverContent(i + 1); - PdfDictionary pageDict; - pageDict = pdfReader.getPageN(i + 1); - int pageRotation = pdfReader.getPageRotation(i + 1); - pageDict.put(PdfName.ROTATE, new PdfNumber((360 + pageRotation + rotation) % 360)); +// PdfDictionary pageDict; +// pageDict = pdfReader.getPageN(i + 1); +// int pageRotation = pdfReader.getPageRotation(i + 1); +// pageDict.put(PdfName.ROTATE, new PdfNumber((360 + pageRotation + rotation) % 360)); for (PDFEditorNoteUI note : model.getPages()[i].getNotes()) { @@ -240,6 +241,7 @@ // convert content to blob InputStream is = new BufferedInputStream(new FileInputStream(target)); AttachmentFile attachmentFileNew = getContext().getEmailService().getAttachmentFileFromStream(is); + attachmentFileNew.setRotation(rotation); String fileName = getModel().getNotNullFile().getFilename(); attachmentFileNew.setFilename(FaxToMailUIUtil.getEditedFileName(fileName)); getModel().setEditedFile(attachmentFileNew); Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeUIModel.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeUIModel.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeUIModel.java 2014-06-29 17:42:07 UTC (rev 286) @@ -39,6 +39,7 @@ import com.franciaflex.faxtomail.persistence.entities.Priority; import com.franciaflex.faxtomail.persistence.entities.RangeRow; import com.franciaflex.faxtomail.persistence.entities.Reply; +import com.franciaflex.faxtomail.services.FaxToMailServiceUtils; import com.franciaflex.faxtomail.ui.swing.util.AbstractFaxToMailBeanUIModel; import com.franciaflex.faxtomail.ui.swing.content.attachment.AttachmentModelAware; import com.google.common.base.Function; @@ -967,7 +968,7 @@ // if it is a text part, the,n this is the email content String disposition = bp.getDisposition(); if (bp.isMimeType("text/*") && !Part.ATTACHMENT.equals(disposition)) { - Charset charset = getCharset(bp); + Charset charset = FaxToMailServiceUtils.getCharset(bp); String content = IOUtils.toString(bp.getInputStream(), charset); if (bp.isMimeType("text/plain")) { plainContent = content; @@ -982,13 +983,6 @@ } } - protected Charset getCharset(Part part) throws MessagingException { - ContentType contentType = new ContentType(part.getContentType()); - String charsetName = contentType.getParameter("charset"); - Charset charset = Charsets.toCharset(charsetName); - return charset; - } - @Override public boolean isEmpty() { return false; Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java 2014-06-29 17:42:07 UTC (rev 286) @@ -233,7 +233,7 @@ @Override public void onCloseUI() { - +// getModel() } public void addNote() { @@ -515,6 +515,7 @@ // convert content to blob AttachmentFile attachmentFileNew = getContext().getEmailService().getAttachmentFileFromStream(new FileInputStream(target)); attachmentFileNew.setFilename(attachmentFile.getFilename() + ".pdf"); + attachmentFileNew.setRotation(0); getModel().setEditedFile(attachmentFileNew); return target; Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIModel.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIModel.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIModel.java 2014-06-29 17:42:07 UTC (rev 286) @@ -138,6 +138,7 @@ Object oldValue = getEditedFile(); editObject.setEditedFile(file); firePropertyChange(Attachment.PROPERTY_EDITED_FILE, oldValue, file); + setRotation(file != null ? file.getRotation() : 0); } public AttachmentFile getEditedFile() { Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java 2014-06-29 17:42:07 UTC (rev 286) @@ -171,7 +171,7 @@ || context.getCurrentUser().isAffectedFoldersEmpty() || context.getCurrentUser().containsAffectedFolders(node.getMailFolder())) { - foreground = hasFocus ? Color.WHITE : Color.BLACK; + foreground = sel ? Color.WHITE : Color.BLACK; } else { foreground = Color.LIGHT_GRAY; Modified: trunk/faxtomail-ui-web/pom.xml =================================================================== --- trunk/faxtomail-ui-web/pom.xml 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-web/pom.xml 2014-06-29 17:42:07 UTC (rev 286) @@ -293,6 +293,11 @@ <artifactId>itextpdf</artifactId> </dependency> + <dependency> + <groupId>gui.ava</groupId> + <artifactId>html2image</artifactId> + </dependency> + </dependencies> <build> Modified: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/job/MailFilterJob.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/job/MailFilterJob.java 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/job/MailFilterJob.java 2014-06-29 17:42:07 UTC (rev 286) @@ -28,11 +28,13 @@ import java.awt.image.RenderedImage; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; +import java.io.StringBufferInputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.nio.ByteBuffer; @@ -46,6 +48,7 @@ import java.util.Enumeration; import java.util.List; import java.util.Properties; +import java.util.regex.Pattern; import javax.activation.DataHandler; import javax.activation.DataSource; @@ -62,6 +65,9 @@ import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import com.franciaflex.faxtomail.persistence.entities.FaxToMailUser; import com.franciaflex.faxtomail.persistence.entities.MailFilter; @@ -72,6 +78,7 @@ import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfWriter; +import gui.ava.html.image.generator.HtmlImageGenerator; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.Charsets; import org.apache.commons.io.FileUtils; @@ -80,6 +87,10 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.htmlcleaner.CleanerProperties; +import org.htmlcleaner.HtmlCleaner; +import org.htmlcleaner.PrettyXmlSerializer; +import org.htmlcleaner.TagNode; import org.nuiton.decorator.Decorator; import org.nuiton.util.StringUtil; import org.quartz.JobExecutionContext; @@ -102,6 +113,10 @@ import com.franciaflex.faxtomail.services.service.ConfigurationService; import com.franciaflex.faxtomail.services.service.EmailService; import com.franciaflex.faxtomail.services.service.MailFolderService; +import org.xhtmlrenderer.pdf.ITextRenderer; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; /** * @author Kevin Morin (Code Lutin) @@ -221,7 +236,7 @@ int messageNumber = count - i; Message message = folder.getMessage(messageNumber); - Charset charset = getCharset(message); + Charset charset = FaxToMailServiceUtils.getCharset(message); List<String> modifiedProperties = new ArrayList<>(); @@ -352,10 +367,7 @@ } - Date receivedDate = message.getReceivedDate(); - if (receivedDate == null) { - receivedDate = message.getSentDate(); - } + Date receivedDate = new Date(); email.setReceptionDate(receivedDate); modifiedProperties.add(Email.PROPERTY_RECEPTION_DATE); @@ -380,19 +392,25 @@ emailSource.append("\n").append(originalContent); email.setOriginalEmail(emailSource.toString()); - List<Attachment> attachements = new ArrayList<>(); - Attachment attachment = convertTextToPdf(emailSource.toString(), t("faxtomail.email.content.attachment.fileName")); - attachements.add(attachment); + List<Attachment> attachments = new ArrayList<>(); + if (message.isMimeType("multipart/*")) { + String htmlContent = decomposeMultipartEmail(attachments, message, email, emailService); + if (htmlContent != null) { + Attachment attachment = convertHTMLToPdf(attachments, htmlContent, t("faxtomail.email.content.attachment.fileName")); + attachments.add(attachment); + } - if (message.isMimeType("multipart/*")) { - decomposeMultipartEmail(attachements, message, email, emailService); - // } else { + } else { // String content = IOUtils.toString(message.getInputStream(), charset); // email.setPlainContent(content); +// Charset charset = FaxToMailServiceUtils.getCharset(bp); + String content = IOUtils.toString(message.getInputStream(), charset); + Attachment attachment = convertTextToPdf(content, t("faxtomail.email.content.attachment.fileName")); + attachments.add(0, attachment); } emailService.saveEmail(email, - attachements, + attachments, email.getClient() != null ? email.getClient().getCode() : null, null, modifiedProperties.toArray(new String[modifiedProperties.size()])); @@ -428,28 +446,36 @@ * @param emailService email service * @throws Exception */ - protected void decomposeMultipartEmail(List<Attachment> attachments, Part part, Email email, EmailService emailService) throws Exception { + protected String decomposeMultipartEmail(List<Attachment> attachments, Part part, Email email, EmailService emailService) throws Exception { + String result = null; + DataSource dataSource = part.getDataHandler().getDataSource(); MimeMultipart mimeMultipart = new MimeMultipart(dataSource); int multiPartCount = mimeMultipart.getCount(); for (int j = 0; j < multiPartCount; j++) { MimeBodyPart bp = (MimeBodyPart) mimeMultipart.getBodyPart(j); - Charset charset = getCharset(bp); - // if it is a text part, the,n this is the email content + // if it is a text part, then this is the email content String disposition = bp.getDisposition(); if (bp.isMimeType("text/*") && !Part.ATTACHMENT.equals(disposition)) { -// String content = IOUtils.toString(bp.getInputStream(), charset); -// if (bp.isMimeType("text/plain")) { -// email.setPlainContent(content); -// } else { -// email.setHtmlContent(content); -// } + Charset charset = FaxToMailServiceUtils.getCharset(bp); + String content = IOUtils.toString(bp.getInputStream(), charset); + if (bp.isMimeType("text/plain")) { + Attachment attachment = convertTextToPdf(content, t("faxtomail.email.content.attachment.fileName")); + attachments.add(attachment); + + } else { + result = content; + } + // if it is multipart part, decompose it } else if (bp.isMimeType("multipart/*")) { - decomposeMultipartEmail(attachments, bp, email, emailService); + String htmlContent = decomposeMultipartEmail(attachments, bp, email, emailService); + if (htmlContent != null) { + result = htmlContent; + } // else, this is an attachment } else { @@ -465,7 +491,6 @@ // remove the guillemets between the id - if (fileName == null && contentID == null) { break; } else if (fileName == null) { @@ -501,15 +526,9 @@ attachments.add(attachment); } } + return result; } - protected Charset getCharset(Part part) throws MessagingException { - ContentType contentType = new ContentType(part.getContentType()); - String charsetName = contentType.getParameter("charset"); - Charset charset = Charsets.toCharset(charsetName); - return charset; - } - /** * Retourne un input stream sur une piece jointe convertie ou pas. * @@ -601,7 +620,6 @@ } public Attachment convertTextToPdf(String content, String name) throws IOException, DocumentException { - File target = File.createTempFile("faxtomail-", ".tmp"); target.deleteOnExit(); @@ -630,4 +648,60 @@ return attachment; } + + public Attachment convertHTMLToPdf(List<Attachment> attachments, String content, String name) throws IOException, ParserConfigurationException, SAXException, DocumentException { + + File source = File.createTempFile("faxtomail-", ".html"); + source.deleteOnExit(); + File target = File.createTempFile("faxtomail-", ".png"); + target.deleteOnExit(); + + content = content.replaceAll("<meta (.*?)>(</meta>)?", ""); + for (Attachment attachment : attachments) { + String key = attachment.getContentId(); + if (key == null) { + key = attachment.getOriginalFileName(); + } + + // get file content + AttachmentFile attachmentFile = attachment.getOriginalFile(); + File file = attachmentFile.getFile(); + + // replace the inline attachments with the extracted attachment file url + // match les patterns: + // <td background="cid:bg.gif" height="52"> + // <img border=0 src="cid:bg.gif" /> + // <img src='cid:5e9ef859-ea65-4f9b-a9fa-30d4a2c5837c' + content = content.replaceAll("(\\w+)=([\"'])cid:" + Pattern.quote(key) + "([\"'])", "$1=$2file://" + file.getAbsolutePath() + "$3"); + + if (log.isDebugEnabled()) { + log.debug("Mapping attachment id " + key + " to file " + file.getAbsolutePath()); + } + } + +// CleanerProperties props = new CleanerProperties(); + +// do parsing +// TagNode tagNode = new HtmlCleaner(props).clean(content); + +// serialize to xml file +// new PrettyXmlSerializer(props).writeToFile(tagNode, source.getAbsolutePath(), "utf-8"); + + HtmlImageGenerator imageGenerator = new HtmlImageGenerator(); +// imageGenerator.loadUrl(source.toURI().toURL()); + imageGenerator.loadHtml(content); + imageGenerator.saveAsImage(target); + + // convert content to blob + EmailService emailService = serviceContext.newService(EmailService.class); + AttachmentFile attachmentFileNew = emailService.getAttachmentFileFromStream(new FileInputStream(target)); + attachmentFileNew.setFilename(name + ".png"); + + Attachment attachment = new AttachmentImpl(); + attachment.setOriginalFile(attachmentFileNew); + attachment.setOriginalFileName(name); + attachment.setAddedByUser(false); + + return attachment; + } } Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2014-06-29 16:50:40 UTC (rev 285) +++ trunk/pom.xml 2014-06-29 17:42:07 UTC (rev 286) @@ -151,7 +151,15 @@ <checksumPolicy>fail</checksumPolicy> </releases> </repository> + + <repository> + <id>yoava</id> + <name>AOL yoava</name> + <url>http://evgenyg.artifactoryonline.com/evgenyg/repo</url> + </repository> + </repositories> + <pluginRepositories> <pluginRepository> <id>faxtomail-public-group</id> @@ -631,13 +639,19 @@ <artifactId>pdfbox</artifactId> <version>${pdfboxVersion}</version> </dependency> + + <dependency> + <groupId>gui.ava</groupId> + <artifactId>html2image</artifactId> + <version>0.9</version> + </dependency> + </dependencies> </dependencyManagement> <build> - <pluginManagement> <plugins>