Skip to content

Commit

Permalink
Add option to keep converted HTML files
Browse files Browse the repository at this point in the history
  • Loading branch information
alextretyak committed Oct 7, 2015
1 parent 2990422 commit d0055ad
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 52 deletions.
29 changes: 18 additions & 11 deletions README.md
@@ -1,14 +1,11 @@
##EML to PDF Converter

### Homepage
<a href="https://eml-to-pdf.com">eml-to-pdf.com</a>
##EML to PDF/HTML Converter

### Screenshot
<img src="https://www.whitebyte.info/wp-content/uploads/2015/02/scr1.png" />
![Screenshot](screenshot.png?raw=true)

### Commandline Interface
```
Usage: EMLtoPDFConverter [options]
Usage: emailconverter [options] <EML-File>
Options:
-d, --debug
Debug mode
Expand All @@ -24,17 +21,20 @@ Usage: EMLtoPDFConverter [options]
Default: false
-ad, --extract-attachments-directory
Extract Attachments to this Directory, if this option is not present the
directory is besides the pdf as "-attachments".
-?, --help
directory is besides the output file as "<output-filename>-attachments".
-h, --help
Print this help.
Default: false
-hh, --hide-headers
Do not add email headers (subject, from, etc.) at the beginning of the
PDF document.
PDF/HTML document.
Default: false
--html
Produce HTML document instead of PDF.
Default: false
-o, --output-filepath
Filepath of the produced PDF document. If this option is ommited the PDF
will be placed alongside the EML File.
Filepath of the produced PDF/HTML document. If this option is ommited the
PDF/HTML will be placed alongside the EML File.
-p, --proxy
Proxy (e.g. "http://10.64.1.74:81"). If "auto" is supplied the default
system proxy will be used.
Expand Down Expand Up @@ -65,3 +65,10 @@ Executes the unit tests and generates various reports (jacoco, checkstyle, findb

### License
The code available under the terms of the GNU Affero General Public License (AGPL). This means you have to release the source code of applications that use this software. If you can't do so you can <a target="_blank" href="https://eml-to-pdf.com">buy a commercial license</a>.

### Download
A Java installation is required. If you haven't installed Java yet get it [here](https://www.java.com/download) completely free.

Win32 binaries and compiled jar for non-windows Systems (MacOs, Linux, etc) can be found in [Releases](../../releases) section.

*Note: If you have another system than Windows you need to install the free [wkhtmltopdf](http://wkhtmltopdf.org/downloads.html) and add it's binary to your PATH variable.*
Binary file added screenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 11 additions & 4 deletions src/main/java/cli/CommandLineParameters.java
Expand Up @@ -31,7 +31,7 @@ public class CommandLineParameters {
@Parameter(description = "<EML-File>", arity = 1)
private List<String> files = new ArrayList<String>();

@Parameter(names = {"-o", "--output-filepath"}, description = "Filepath of the produced PDF document. If this option is ommited the PDF will be placed alongside the EML File.")
@Parameter(names = {"-o", "--output-filepath"}, description = "Filepath of the produced PDF/HTML document. If this option is ommited the PDF/HTML will be placed alongside the EML File.")
private String output;

@Parameter(names = {"-p", "--proxy"}, description = "Proxy (e.g. \"http://10.64.1.74:81\"). If \"auto\" is supplied the default system proxy will be used.")
Expand All @@ -46,13 +46,16 @@ public class CommandLineParameters {
@Parameter(names = {"-q", "--quiet"}, description = "Do not display any messages at all.")
private boolean quiet = false;

@Parameter(names = {"-?", "--help"}, description = "Print this help.", help = true)
@Parameter(names = {"-h", "--help"}, description = "Print this help.", help = true)
private boolean help;

@Parameter(names = {"-v", "--version"}, description = "Print the version number.")
private boolean version;

@Parameter(names = {"-hh", "--hide-headers"}, description = "Do not add email headers (subject, from, etc.) at the beginning of the PDF document.")
@Parameter(names = {"--html"}, description = "Produce HTML document instead of PDF.")
private boolean outputHTML = false;

@Parameter(names = {"-hh", "--hide-headers"}, description = "Do not add email headers (subject, from, etc.) at the beginning of the PDF/HTML document.")
private boolean hideHeaders = false;

@Parameter(names = {"-a", "--extract-attachments"}, description = "Extract Attachments.")
Expand All @@ -61,7 +64,7 @@ public class CommandLineParameters {
@Parameter(names = {"-dc", "--disable-crashreports"}, description = "Do not send crash reports to the developer.")
private boolean disableCrashreports = false;

@Parameter(names = {"-ad", "--extract-attachments-directory"}, description = "Extract Attachments to this Directory, if this option is not present the directory is besides the pdf as \"<pdf-name>-attachments\".")
@Parameter(names = {"-ad", "--extract-attachments-directory"}, description = "Extract Attachments to this Directory, if this option is not present the directory is besides the output file as \"<output-filename>-attachments\".")
private String extractAttachmentsDir;

@Parameter(names = {"-gui", "--show-graphical-user-interface"}, description = "Show graphical user interface (other parameters are ignored when using this switch).")
Expand Down Expand Up @@ -123,6 +126,10 @@ public void setProxy(String proxy) {
this.proxy = proxy;
}

public boolean isOutputHTML() {
return outputHTML;
}

public boolean isHideHeaders() {
return hideHeaders;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/cli/Main.java
Expand Up @@ -49,7 +49,7 @@ public class Main {
public static void main(String[] args) throws IOException {
CommandLineParameters cli = new CommandLineParameters();
JCommander jCmd = new JCommander(cli, args);
jCmd.setProgramName("EMLtoPDFConverter");
jCmd.setProgramName("emailconverter");

if (cli.isGui()) {
MainWindow.main(new String[0]);
Expand Down Expand Up @@ -120,7 +120,7 @@ public static void main(String[] args) throws IOException {
}

try {
MimeMessageConverter.convertToPdf(in, out, cli.isHideHeaders(), cli.isExtractAttachments(), cli.getExtractAttachmentsDir(), extParams);
MimeMessageConverter.convertToPdf(in, out, cli.isOutputHTML(), cli.isHideHeaders(), cli.isExtractAttachments(), cli.getExtractAttachmentsDir(), extParams);
} catch (Exception e) {
Logger.error("The eml could not be converted. Error: %s", Throwables.getStackTraceAsString(e));

Expand Down
27 changes: 22 additions & 5 deletions src/main/java/gui/MainWindow.java
Expand Up @@ -110,7 +110,7 @@ private void initialize() {
frmEmlToPdf = new JFrame();
frmEmlToPdf.setIconImage(Toolkit.getDefaultToolkit().getImage(MainWindow.class.getResource("/icons/logo_emlconverter-482_16x16.png")));
frmEmlToPdf.setResizable(false);
frmEmlToPdf.setTitle("EML to PDF Converter");
frmEmlToPdf.setTitle("EML to PDF/HTML Converter");
frmEmlToPdf.getContentPane().setBackground(Color.WHITE);
frmEmlToPdf.setBackground(Color.WHITE);
frmEmlToPdf.setBounds(100, 100, 700, 703);
Expand Down Expand Up @@ -218,12 +218,25 @@ public void actionPerformed(ActionEvent e) {
frmEmlToPdf.getContentPane().add(panel);
panel.setLayout(null);

final JCheckBox chckbxAddEmailHeaders = new JCheckBox("Add Email headers to the PDF document");
final JCheckBox chckbxAddEmailHeaders = new JCheckBox("Add Email headers to the PDF/HTML document");
chckbxAddEmailHeaders.setSelected(true);
chckbxAddEmailHeaders.setBackground(Color.WHITE);
chckbxAddEmailHeaders.setBounds(10, 17, 632, 23);
chckbxAddEmailHeaders.setBounds(10, 17, 270, 23);
panel.add(chckbxAddEmailHeaders);

final JRadioButton rdbtnOutputPDF = new JRadioButton("Output PDF");
rdbtnOutputPDF.setSelected(true);
rdbtnOutputPDF.setBackground(Color.WHITE);
rdbtnOutputPDF.setBounds(280, 17, 100, 23);
panel.add(rdbtnOutputPDF);
final JRadioButton rdbtnOutputHTML = new JRadioButton("Output HTML");
rdbtnOutputHTML.setBackground(Color.WHITE);
rdbtnOutputHTML.setBounds(380, 17, 100, 23);
panel.add(rdbtnOutputHTML);
{ButtonGroup bg = new ButtonGroup();
bg.add(rdbtnOutputPDF);
bg.add(rdbtnOutputHTML);}

final JRadioButton rdbtnAutomaticProxySelection = new JRadioButton("Automatic Proxy Selection");
rdbtnAutomaticProxySelection.setSelected(true);
rdbtnAutomaticProxySelection.setEnabled(false);
Expand Down Expand Up @@ -303,7 +316,7 @@ public void actionPerformed(ActionEvent e) {
new Thread(new Runnable() {
@Override
public void run() {
startConversion(Collections.list(listModel.elements()), chckbxAddEmailHeaders.isSelected(), proxy, chckbxExtractAttachments.isSelected());
startConversion(Collections.list(listModel.elements()), rdbtnOutputHTML.isSelected(), chckbxAddEmailHeaders.isSelected(), proxy, chckbxExtractAttachments.isSelected());
}
}).start();
}
Expand Down Expand Up @@ -362,10 +375,14 @@ public void actionPerformed(ActionEvent e) {
*
* @param enumeration
*/
private void startConversion(List<String> l, boolean showHeaders, String proxy, boolean extractAttachments) {
private void startConversion(List<String> l, boolean outputHTML, boolean showHeaders, String proxy, boolean extractAttachments) {
try {
ArrayList<String> argsOptions = new ArrayList<String>();

if (outputHTML) {
argsOptions.add("--html");
}

if (!showHeaders) {
argsOptions.add("--hide-headers");
}
Expand Down
70 changes: 40 additions & 30 deletions src/main/java/mimeparser/MimeMessageConverter.java
Expand Up @@ -79,6 +79,7 @@ public class MimeMessageConverter {

// html wrapper template for text/plain messages
private static final String HTML_WRAPPER_TEMPLATE = "<!DOCTYPE html><html><head><style>body{font-size: 0.5cm;}</style><meta charset=\"%s\"><title>title</title></head><body>%s</body></html>";
private static final String HTML_CHARSET_TEMPLATE = "<!DOCTYPE html><html><head><meta charset=\"%s\"><title>title</title></head><body>%s</body></html>";
private static final String ADD_HEADER_IFRAME_JS_TAG_TEMPLATE = "<script id=\"header-v6a8oxpf48xfzy0rhjra\" data-file=\"%s\" type=\"text/javascript\">%s</script>";
private static final String HEADER_FIELD_TEMPLATE = "<tr><td class=\"header-name\">%s</td><td class=\"header-value\">%s</td></tr>";

Expand Down Expand Up @@ -108,7 +109,7 @@ private static void execCommand(List<String> command) {
* Convert an EML file to PDF.
* @throws Exception
*/
public static void convertToPdf(String emlPath, String pdfOutputPath, boolean hideHeaders, boolean extractAttachments, String attachmentsdir, List<String> extParams) throws Exception {
public static void convertToPdf(String emlPath, String pdfOutputPath, boolean outputHTML, boolean hideHeaders, boolean extractAttachments, String attachmentsdir, List<String> extParams) throws Exception {
Logger.info("Start converting %s to %s", emlPath, pdfOutputPath);

Logger.debug("Read eml file from %s", emlPath);
Expand Down Expand Up @@ -158,6 +159,8 @@ public static void convertToPdf(String emlPath, String pdfOutputPath, boolean hi
/* ######### Embed images in the html ######### */
String htmlBody = bodyEntry.getEntry();
if (bodyEntry.getContentType().match("text/html")) {
htmlBody = String.format(HTML_CHARSET_TEMPLATE, charsetName, htmlBody.replaceAll("(?i)</?(html|body)>", ""));

if (inlineImageMap.size() > 0) {
Logger.debug("Embed the referenced images (cid) using <img src=\"data:image ...> syntax");

Expand Down Expand Up @@ -222,12 +225,11 @@ public String replace(Matcher m) throws Exception {
Logger.debug("Body (excerpt): %s", bodyExcerpt);
Logger.debug("----------------------------------");

Logger.info("Start conversion to pdf");
Logger.info("Start conversion to " + (outputHTML ? "html" : "pdf"));
File pdf = new File(pdfOutputPath);

File tmpHtmlHeader = null;
if (!hideHeaders) {
tmpHtmlHeader = File.createTempFile("emailtopdf", ".html");
String tmpHtmlHeaderStr = Resources.toString(Resources.getResource("header.html"), StandardCharsets.UTF_8);
String headers = "";

if (!Strings.isNullOrEmpty(from)) {
Expand All @@ -246,38 +248,46 @@ public String replace(Matcher m) throws Exception {
headers += String.format(HEADER_FIELD_TEMPLATE, "Date", HtmlEscapers.htmlEscaper().escape(sentDateStr));
}

Files.write(String.format(tmpHtmlHeaderStr, headers), tmpHtmlHeader, StandardCharsets.UTF_8);
if (outputHTML)
htmlBody = htmlBody.replace("</head><body>", "<style>.header-name {color:#9E9E9E; text-align:right;}</style></head><body><table style='border:1px solid #DDD; margin: 8px'>" + headers + "</table>");
else {
tmpHtmlHeader = new File(pdf.getParentFile(), Files.getNameWithoutExtension(pdfOutputPath) + "_h.html");
String tmpHtmlHeaderStr = Resources.toString(Resources.getResource("header.html"), StandardCharsets.UTF_8);

Files.write(String.format(tmpHtmlHeaderStr, headers), tmpHtmlHeader, StandardCharsets.UTF_8);

// Append this script tag dirty to the bottom
htmlBody += String.format(ADD_HEADER_IFRAME_JS_TAG_TEMPLATE, tmpHtmlHeader.toURI(), Resources.toString(Resources.getResource("contentScript.js"), StandardCharsets.UTF_8));
// Append this script tag dirty to the bottom
htmlBody += String.format(ADD_HEADER_IFRAME_JS_TAG_TEMPLATE, tmpHtmlHeader.toURI(), Resources.toString(Resources.getResource("contentScript.js"), StandardCharsets.UTF_8));
}
}

File tmpHtml = File.createTempFile("emailtopdf", ".html");
Logger.debug("Write html to temporary file %s", tmpHtml.getAbsolutePath());
File tmpHtml = new File(pdf.getParentFile(), Files.getNameWithoutExtension(pdfOutputPath) + ".html");
Logger.debug("Write html to file %s", tmpHtml.getAbsolutePath());
Files.write(htmlBody, tmpHtml, Charset.forName(charsetName));

File pdf = new File(pdfOutputPath);
Logger.debug("Write pdf to %s", pdf.getAbsolutePath());

List<String> cmd = new ArrayList<String>(Arrays.asList("wkhtmltopdf",
"--viewport-size", "2480x3508",
// "--disable-smart-shrinking",
"--image-quality", "100",
"--encoding", charsetName));
cmd.addAll(extParams);
cmd.add(tmpHtml.getAbsolutePath());
cmd.add(pdf.getAbsolutePath());

Logger.debug("Execute: %s", Joiner.on(' ').join(cmd));
execCommand(cmd);

if (!tmpHtml.delete()) {
tmpHtml.deleteOnExit();
}
if (!outputHTML) {
Logger.debug("Write pdf to %s", pdf.getAbsolutePath());

if (tmpHtmlHeader != null) {
if (!tmpHtmlHeader.delete()) {
tmpHtmlHeader.deleteOnExit();
List<String> cmd = new ArrayList<String>(Arrays.asList("wkhtmltopdf",
"--viewport-size", "2480x3508",
// "--disable-smart-shrinking",
"--image-quality", "100",
"--encoding", charsetName));
cmd.addAll(extParams);
cmd.add(tmpHtml.getAbsolutePath());
cmd.add(pdf.getAbsolutePath());

Logger.debug("Execute: %s", Joiner.on(' ').join(cmd));
execCommand(cmd);

if (!tmpHtml.delete()) {
tmpHtml.deleteOnExit();
}

if (tmpHtmlHeader != null) {
if (!tmpHtmlHeader.delete()) {
tmpHtmlHeader.deleteOnExit();
}
}
}

Expand Down

0 comments on commit d0055ad

Please sign in to comment.