diff --git a/migration/i8.2z/oracle/202105241446_IDEMPIERE-4796.sql b/migration/i8.2z/oracle/202105241446_IDEMPIERE-4796.sql new file mode 100644 index 0000000000..6e082ccbe9 --- /dev/null +++ b/migration/i8.2z/oracle/202105241446_IDEMPIERE-4796.sql @@ -0,0 +1,26 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-4796 +-- May 24, 2021, 2:38:13 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203486,0,0,'Y',TO_DATE('2021-05-24 14:38:13','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2021-05-24 14:38:13','YYYY-MM-DD HH24:MI:SS'),0,'HTMLAttachmentType','HTML Attachment Type','Define html email body processing behaviour. HTML Email body can be converted as attachment *.html file or parse images into attachment.','HTML Attachment Type','D','419fec21-afb6-4f9a-b78f-48be3a1cbcaa') +; + +-- May 24, 2021, 2:40:51 PM CEST +INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU) VALUES (200186,'HTML Attachment Type List','L',0,0,'Y',TO_DATE('2021-05-24 14:40:51','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2021-05-24 14:40:51','YYYY-MM-DD HH24:MI:SS'),0,'D','N','d907e9e1-f51c-4d32-ac85-287be286962e') +; + +-- May 24, 2021, 2:41:41 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200505,'HTML as Attachment',200186,'H',0,0,'Y',TO_DATE('2021-05-24 14:41:40','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2021-05-24 14:41:40','YYYY-MM-DD HH24:MI:SS'),0,'D','6a1a33f0-0150-4061-9bb9-c3ced1ba507c') +; + +-- May 24, 2021, 2:42:34 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200506,'Parse Images to Attachments',200186,'I',0,0,'Y',TO_DATE('2021-05-24 14:42:34','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2021-05-24 14:42:34','YYYY-MM-DD HH24:MI:SS'),0,'D','13bf37a5-821f-45d2-9931-b64a6209904b') +; + +-- May 24, 2021, 2:43:33 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,IsAutocomplete) VALUES (200342,0,0,'Y',TO_DATE('2021-05-24 14:43:33','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2021-05-24 14:43:33','YYYY-MM-DD HH24:MI:SS'),0,'HTML Attachment Type','Define html email body processing behaviour. HTML Email body can be converted as attachment *.html file or parse images into attachment.',50012,140,17,200186,'N',1,'Y','H','HTMLAttachmentType','Y','D',203486,'b86cbb49-9fdf-47c8-af70-203e7354784c','N','N') +; + +SELECT Register_Migration_Script ('202105241446_IDEMPIERE-4796.sql') FROM DUAL +; diff --git a/migration/i8.2z/postgresql/202105241446_IDEMPIERE-4796.sql b/migration/i8.2z/postgresql/202105241446_IDEMPIERE-4796.sql new file mode 100644 index 0000000000..26aa565ca0 --- /dev/null +++ b/migration/i8.2z/postgresql/202105241446_IDEMPIERE-4796.sql @@ -0,0 +1,23 @@ +-- IDEMPIERE-4796 +-- May 24, 2021, 2:38:13 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203486,0,0,'Y',TO_TIMESTAMP('2021-05-24 14:38:13','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2021-05-24 14:38:13','YYYY-MM-DD HH24:MI:SS'),0,'HTMLAttachmentType','HTML Attachment Type','Define html email body processing behaviour. HTML Email body can be converted as attachment *.html file or parse images into attachment.','HTML Attachment Type','D','419fec21-afb6-4f9a-b78f-48be3a1cbcaa') +; + +-- May 24, 2021, 2:40:51 PM CEST +INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU) VALUES (200186,'HTML Attachment Type List','L',0,0,'Y',TO_TIMESTAMP('2021-05-24 14:40:51','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2021-05-24 14:40:51','YYYY-MM-DD HH24:MI:SS'),0,'D','N','d907e9e1-f51c-4d32-ac85-287be286962e') +; + +-- May 24, 2021, 2:41:41 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200505,'HTML as Attachment',200186,'H',0,0,'Y',TO_TIMESTAMP('2021-05-24 14:41:40','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2021-05-24 14:41:40','YYYY-MM-DD HH24:MI:SS'),0,'D','6a1a33f0-0150-4061-9bb9-c3ced1ba507c') +; + +-- May 24, 2021, 2:42:34 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200506,'Parse Images to Attachments',200186,'I',0,0,'Y',TO_TIMESTAMP('2021-05-24 14:42:34','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2021-05-24 14:42:34','YYYY-MM-DD HH24:MI:SS'),0,'D','13bf37a5-821f-45d2-9931-b64a6209904b') +; + +-- May 24, 2021, 2:43:33 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,IsAutocomplete) VALUES (200342,0,0,'Y',TO_TIMESTAMP('2021-05-24 14:43:33','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2021-05-24 14:43:33','YYYY-MM-DD HH24:MI:SS'),0,'HTML Attachment Type','Define html email body processing behaviour. HTML Email body can be converted as attachment *.html file or parse images into attachment.',50012,140,17,200186,'N',1,'Y','H','HTMLAttachmentType','Y','D',203486,'b86cbb49-9fdf-47c8-af70-203e7354784c','N','N') +; + +SELECT Register_Migration_Script ('202105241446_IDEMPIERE-4796.sql') FROM DUAL +; diff --git a/org.adempiere.base.process/src/org/compiere/process/RequestEMailProcessor.java b/org.adempiere.base.process/src/org/compiere/process/RequestEMailProcessor.java index de1cebc3aa..a2ed50a5d2 100644 --- a/org.adempiere.base.process/src/org/compiere/process/RequestEMailProcessor.java +++ b/org.adempiere.base.process/src/org/compiere/process/RequestEMailProcessor.java @@ -74,6 +74,7 @@ public class RequestEMailProcessor extends SvrProcess implements ProcessEmailHan protected int R_RequestType_ID = 0; protected String p_DefaultPriority = null; protected String p_DefaultConfidentiality = null; + protected String p_HTMLAttachmentType = "H"; protected int noProcessed = 0; protected int noRequest = 0; @@ -133,10 +134,15 @@ public class RequestEMailProcessor extends SvrProcess implements ProcessEmailHan p_DefaultConfidentiality = ((String)para[i].getParameter()); else if (name.equals("p_NestInbox")) p_NestInbox = "Y".equalsIgnoreCase(para[i].getParameter().toString()); + else if (name.equals("HTMLAttachmentType")) + p_HTMLAttachmentType = para[i].getParameterAsString(); else log.log(Level.SEVERE, "prepare - Unknown Parameter: " + name); } + if(p_HTMLAttachmentType == null) + p_HTMLAttachmentType = "H"; + } // prepare /** @@ -457,14 +463,26 @@ public class RequestEMailProcessor extends SvrProcess implements ProcessEmailHan if (log.isLoggable(Level.INFO)) log.info("created request " + req.getR_Request_ID() + " from msg -> " + emailContent.subject); - String htmlContent = emailContent.getHtmlContent(true); - if (htmlContent != null){ - MAttachment attach = req.createAttachment(); - - attach.addEntry(emailContent.subject + ".html", emailContent.getHtmlContent(true).getBytes(Charset.forName("UTF-8"))); - attach.saveEx(trxName); + if("H".equals(p_HTMLAttachmentType)) { + String htmlContent = emailContent.getHtmlContent(true); + if (htmlContent != null){ + MAttachment attach = req.createAttachment(); + + attach.addEntry(emailContent.subject + ".html", emailContent.getHtmlContent(true).getBytes(Charset.forName("UTF-8"))); + attach.saveEx(trxName); + } + } else if("I".equals(p_HTMLAttachmentType)) { + ArrayList imagesList = emailContent.getHTMLImageBodyParts(); + if(imagesList != null) { + for(BodyPart image: imagesList) { + MAttachment attach = req.createAttachment(); + + attach.addEntry(image.getFileName(), EmailSrv.getBinaryData(image)); + attach.saveEx(trxName); + } + } } - + for (BodyPart attachFile : emailContent.lsAttachPart){ MAttachment attach = req.createAttachment(); attach.addEntry(attachFile.getFileName(), EmailSrv.getBinaryData(attachFile)); diff --git a/org.adempiere.base/src/org/compiere/util/EmailSrv.java b/org.adempiere.base/src/org/compiere/util/EmailSrv.java index 9ea9c68654..34ea75ea8e 100644 --- a/org.adempiere.base/src/org/compiere/util/EmailSrv.java +++ b/org.adempiere.base/src/org/compiere/util/EmailSrv.java @@ -709,6 +709,45 @@ public class EmailSrv { return reconstructSign.toString(); } + + public static ArrayList getEmbededImages(String mailContent, ProvideBase64Data provideBase64Data, String embedPattern) throws MessagingException, IOException { + ArrayList bodyPartImagesList = new ArrayList(); + + String origonSign = mailContent; + + // pattern to get src value of attach image. + Pattern imgPattern = Pattern.compile(embedPattern); + // matcher object to anlysic image tab in sign + Matcher imgMatcher = imgPattern.matcher(origonSign); + // list image name in sign + List lsImgSrc = new ArrayList (); + + while (imgMatcher.find()){ + // get image name + lsImgSrc.add(imgMatcher.group(1).trim()); + } + // end string not include "cid:imageName" + + // no image in sign return origon + if (lsImgSrc.size() == 0){ + return bodyPartImagesList; + } + + // reconstruct with image source convert to embed image by base64 encode + for (int i = 0; i < lsImgSrc.size(); i++){ + + BodyPart image = provideBase64Data.getBodyPart(lsImgSrc.get(i)); + + if (image == null){ + log.warning("miss data of image has id is:" + lsImgSrc.get(i)); + }else{ + // convert image to base64 encode and embed to img tag + bodyPartImagesList.add(image); + } + } + + return bodyPartImagesList; + } public static boolean isBinaryPart (Part binaryPart) throws MessagingException{ return binaryPart.isMimeType("application/*") || binaryPart.isMimeType ("image/*"); @@ -786,6 +825,8 @@ public class EmailSrv { */ public static interface ProvideBase64Data { public String getBase64Data (String dataId) throws MessagingException, IOException; + + public BodyPart getBodyPart (String dataId) throws MessagingException, IOException; } /** @@ -862,6 +903,20 @@ public class EmailSrv { return null; } + + @Override + public BodyPart getBodyPart(String contentId) throws MessagingException, IOException { + if (contentId == null) + return null; + + for (BodyPart imageEmbed : emailContent.lsEmbedPart){ + if (contentId.equalsIgnoreCase(EmailSrv.getContentID(imageEmbed))){ + return imageEmbed; + } + } + + return null; + } } /** @@ -920,6 +975,15 @@ public class EmailSrv { return EmailSrv.embedImgToEmail(htmlContentBuild.toString(), provideBase64Data, "\\s+src\\s*=\\s*(?:3D)?\\s*\"cid:(.*?)\""); } + + public ArrayList getHTMLImageBodyParts() throws MessagingException, IOException{ + if (htmlContentBuild == null || htmlContentBuild.length() == 0) + return null; + + EmailEmbedProvideBase64Data provideBase64Data = new EmailEmbedProvideBase64Data(this); + + return EmailSrv.getEmbededImages(htmlContentBuild.toString(), provideBase64Data, "\\s+src\\s*=\\s*(?:3D)?\\s*\"cid:(.*?)\""); + } /** * get text content