2012-04-21 08:27:10 +02:00
|
|
|
/*
|
2013-03-30 10:32:07 +01:00
|
|
|
** Copyright (C) 2012-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
2012-04-21 08:27:10 +02:00
|
|
|
**
|
|
|
|
** This program is free software; you can redistribute it and/or modify it
|
|
|
|
** under the terms of the GNU General Public License as published by the
|
|
|
|
** Free Software Foundation; either version 3, or (at your option) any
|
|
|
|
** later version.
|
|
|
|
**
|
|
|
|
** This program is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with this program; if not, write to the Free Software Foundation,
|
|
|
|
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <mu-msg.h>
|
|
|
|
#include <mu-date.h>
|
|
|
|
#include <mu-msg-part.h>
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <webkit/webkitwebview.h>
|
2012-04-21 18:21:06 +02:00
|
|
|
#include <webkit/webkitwebresource.h>
|
2012-04-21 08:27:10 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2012-04-29 16:31:54 +02:00
|
|
|
static gboolean
|
|
|
|
print_to_pdf (WebKitWebFrame *frame, GError **err)
|
2012-04-21 08:27:10 +02:00
|
|
|
{
|
2012-04-29 16:31:54 +02:00
|
|
|
GtkPrintOperation *op;
|
|
|
|
GtkPrintOperationResult res;
|
|
|
|
char *path;
|
|
|
|
gboolean rv;
|
|
|
|
|
|
|
|
path = g_strdup_printf ("%s%c%x.pdf",mu_util_cache_dir(),
|
|
|
|
G_DIR_SEPARATOR, (unsigned)random());
|
|
|
|
if (!mu_util_create_dir_maybe (mu_util_cache_dir(),0700,FALSE)) {
|
|
|
|
g_warning ("Couldn't create tempdir");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
|
2012-04-29 16:31:54 +02:00
|
|
|
op = gtk_print_operation_new ();
|
2012-04-21 08:27:10 +02:00
|
|
|
gtk_print_operation_set_export_filename
|
2012-04-29 16:31:54 +02:00
|
|
|
(GTK_PRINT_OPERATION(op), path);
|
|
|
|
|
|
|
|
res = webkit_web_frame_print_full (frame, op,
|
|
|
|
GTK_PRINT_OPERATION_ACTION_EXPORT,
|
|
|
|
err);
|
|
|
|
g_object_unref (op);
|
|
|
|
rv = (res != GTK_PRINT_OPERATION_RESULT_ERROR);
|
|
|
|
if (rv)
|
|
|
|
g_print ("%s\n", path);
|
|
|
|
|
|
|
|
g_free (path);
|
|
|
|
return rv;
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-21 18:21:06 +02:00
|
|
|
static char*
|
|
|
|
save_file_for_cid (MuMsg *msg, const char* cid)
|
|
|
|
{
|
|
|
|
gint idx;
|
|
|
|
gchar *filepath;
|
|
|
|
GError *err;
|
|
|
|
|
|
|
|
g_return_val_if_fail (msg, NULL);
|
|
|
|
g_return_val_if_fail (cid, NULL);
|
|
|
|
|
2012-08-01 09:49:41 +02:00
|
|
|
idx = mu_msg_find_index_for_cid (msg, MU_MSG_OPTION_NONE, cid);
|
2012-04-21 18:21:06 +02:00
|
|
|
if (idx < 0) {
|
2015-04-22 20:06:31 +02:00
|
|
|
g_warning ("%s: cannot find %s", __func__, cid);
|
2012-04-21 18:21:06 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = NULL;
|
2012-08-01 09:49:41 +02:00
|
|
|
filepath = mu_msg_part_get_cache_path (msg, MU_MSG_OPTION_NONE, idx, NULL);
|
|
|
|
if (!filepath)
|
|
|
|
goto errexit;
|
|
|
|
|
|
|
|
if (!mu_msg_part_save (msg, MU_MSG_OPTION_USE_EXISTING, filepath, idx,
|
|
|
|
&err))
|
|
|
|
goto errexit;
|
2012-04-21 18:21:06 +02:00
|
|
|
|
|
|
|
return filepath;
|
2012-08-01 09:49:41 +02:00
|
|
|
|
|
|
|
errexit:
|
2015-04-22 20:06:31 +02:00
|
|
|
g_warning ("%s: failed to save %s: %s", __func__,
|
2012-08-01 09:49:41 +02:00
|
|
|
filepath,
|
|
|
|
err&&err->message?err->message:"error");
|
|
|
|
g_clear_error (&err);
|
|
|
|
g_free (filepath);
|
|
|
|
|
|
|
|
return NULL;
|
2012-04-21 18:21:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_resource_request_starting (WebKitWebView *self, WebKitWebFrame *frame,
|
|
|
|
WebKitWebResource *resource,
|
|
|
|
WebKitNetworkRequest *request,
|
|
|
|
WebKitNetworkResponse *response, MuMsg *msg)
|
|
|
|
{
|
|
|
|
const char* uri;
|
|
|
|
uri = webkit_network_request_get_uri (request);
|
|
|
|
|
|
|
|
if (g_ascii_strncasecmp (uri, "cid:", 4) == 0) {
|
|
|
|
gchar *filepath;
|
|
|
|
filepath = save_file_for_cid (msg, uri);
|
|
|
|
if (filepath) {
|
|
|
|
gchar *fileuri;
|
|
|
|
fileuri = g_strdup_printf ("file://%s", filepath);
|
|
|
|
webkit_network_request_set_uri (request, fileuri);
|
|
|
|
g_free (fileuri);
|
|
|
|
g_free (filepath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-21 08:27:10 +02:00
|
|
|
/* return the path to the output file, or NULL in case of error */
|
2012-04-29 16:31:54 +02:00
|
|
|
static gboolean
|
2012-04-21 08:27:10 +02:00
|
|
|
generate_pdf (MuMsg *msg, const char *str, GError **err)
|
|
|
|
{
|
|
|
|
GtkWidget *view;
|
|
|
|
WebKitWebFrame *frame;
|
|
|
|
WebKitWebSettings *settings;
|
2012-04-21 18:21:06 +02:00
|
|
|
WebKitLoadStatus status;
|
2012-04-29 16:31:54 +02:00
|
|
|
time_t started;
|
2012-11-08 20:35:01 +01:00
|
|
|
const int max_time = 3; /* max 3 seconds to download stuff */
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
settings = webkit_web_settings_new ();
|
|
|
|
g_object_set (G_OBJECT(settings),
|
|
|
|
"enable-scripts", FALSE,
|
|
|
|
"auto-load-images", TRUE,
|
2012-04-30 16:32:34 +02:00
|
|
|
"enable-plugins", FALSE, NULL);
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
view = webkit_web_view_new ();
|
2012-04-21 18:21:06 +02:00
|
|
|
|
|
|
|
/* to support cid: */
|
|
|
|
g_signal_connect (G_OBJECT(view), "resource-request-starting",
|
2012-04-30 16:32:34 +02:00
|
|
|
G_CALLBACK (on_resource_request_starting), msg);
|
2012-04-21 18:21:06 +02:00
|
|
|
|
2012-04-21 08:27:10 +02:00
|
|
|
webkit_web_view_set_settings (WEBKIT_WEB_VIEW(view), settings);
|
|
|
|
webkit_web_view_load_string (WEBKIT_WEB_VIEW(view),
|
|
|
|
str, "text/html", "utf-8", "");
|
|
|
|
g_object_unref (settings);
|
2012-04-21 18:21:06 +02:00
|
|
|
|
2012-04-21 08:27:10 +02:00
|
|
|
frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(view));
|
|
|
|
if (!frame) {
|
|
|
|
g_set_error (err, 0, MU_ERROR, "cannot get web frame");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-04-29 16:31:54 +02:00
|
|
|
started = time (NULL);
|
2012-04-21 18:21:06 +02:00
|
|
|
do {
|
|
|
|
status = webkit_web_view_get_load_status (WEBKIT_WEB_VIEW(view));
|
2012-04-29 16:31:54 +02:00
|
|
|
gtk_main_iteration_do (FALSE);
|
|
|
|
} while (status != WEBKIT_LOAD_FINISHED &&
|
|
|
|
(time(NULL) - started) <= max_time);
|
|
|
|
|
|
|
|
return print_to_pdf (frame, err);
|
2012-04-21 08:27:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_header (GString *gstr, const char* header, const char *val)
|
|
|
|
{
|
|
|
|
char *esc;
|
|
|
|
|
|
|
|
if (!val)
|
|
|
|
return;
|
|
|
|
|
|
|
|
esc = g_markup_escape_text (val, -1);
|
|
|
|
g_string_append_printf (gstr, "<b>%s</b>: %s<br>", header, esc);
|
|
|
|
g_free (esc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return the path to the output file, or NULL in case of error */
|
2012-04-29 16:31:54 +02:00
|
|
|
static gboolean
|
2012-04-21 08:27:10 +02:00
|
|
|
convert_to_pdf (MuMsg *msg, GError **err)
|
|
|
|
{
|
|
|
|
GString *gstr;
|
|
|
|
const char *body;
|
2012-04-29 16:31:54 +02:00
|
|
|
gchar *data;
|
|
|
|
gboolean rv;
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
gstr = g_string_sized_new (4096);
|
|
|
|
|
|
|
|
add_header (gstr, "From", mu_msg_get_from (msg));
|
|
|
|
add_header (gstr, "To", mu_msg_get_to (msg));
|
|
|
|
add_header (gstr, "Cc", mu_msg_get_cc (msg));
|
|
|
|
add_header (gstr, "Subject", mu_msg_get_subject (msg));
|
2012-04-22 10:33:25 +02:00
|
|
|
add_header (gstr, "Date", mu_date_str_s
|
|
|
|
("%c", mu_msg_get_date(msg)));
|
2012-04-21 08:27:10 +02:00
|
|
|
|
|
|
|
gstr = g_string_append (gstr, "<hr>\n");
|
|
|
|
|
2012-08-09 08:38:58 +02:00
|
|
|
body = mu_msg_get_body_html (msg, MU_MSG_OPTION_NONE);
|
2012-04-21 08:27:10 +02:00
|
|
|
if (body)
|
|
|
|
g_string_append_printf (gstr, "%s", body);
|
|
|
|
else {
|
2012-08-09 08:38:58 +02:00
|
|
|
body = mu_msg_get_body_text (msg, MU_MSG_OPTION_NONE);
|
2012-04-21 08:27:10 +02:00
|
|
|
if (body) {
|
|
|
|
gchar *esc;
|
|
|
|
esc = g_markup_escape_text (body, -1);
|
|
|
|
g_string_append_printf (gstr, "<pre>\n%s\n</pre>",
|
|
|
|
esc);
|
|
|
|
g_free (esc);
|
|
|
|
} else
|
|
|
|
gstr = g_string_append
|
|
|
|
(gstr, "<i>No body</i>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
data = g_string_free (gstr, FALSE);
|
2012-04-29 16:31:54 +02:00
|
|
|
rv = generate_pdf (msg, data, err);
|
2012-04-21 08:27:10 +02:00
|
|
|
g_free (data);
|
|
|
|
|
2012-04-29 16:31:54 +02:00
|
|
|
return rv;
|
2012-04-21 08:27:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
MuMsg *msg;
|
|
|
|
GError *err;
|
|
|
|
|
|
|
|
if (argc != 2) {
|
|
|
|
g_print ("msg2pdf: generate pdf files from e-mail messages\n"
|
|
|
|
"usage: msg2pdf <msgfile>\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_init (&argc, &argv);
|
|
|
|
|
|
|
|
if (access (argv[1], R_OK) != 0) {
|
|
|
|
g_printerr ("%s is not a readable file\n", argv[1]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = NULL;
|
|
|
|
msg = mu_msg_new_from_file (argv[1], NULL, &err);
|
|
|
|
if (!msg) {
|
2012-04-30 16:32:34 +02:00
|
|
|
g_printerr ("failed to create msg for %s\n", argv[1]);
|
|
|
|
goto err;
|
2012-04-21 08:27:10 +02:00
|
|
|
}
|
|
|
|
|
2012-04-29 16:31:54 +02:00
|
|
|
if (!convert_to_pdf (msg, &err)) {
|
2012-04-30 16:32:34 +02:00
|
|
|
g_printerr ("failed to create pdf from %s\n", argv[1]);
|
|
|
|
goto err;
|
2012-04-21 08:27:10 +02:00
|
|
|
}
|
|
|
|
|
2012-04-30 16:32:34 +02:00
|
|
|
/* it worked! */
|
|
|
|
mu_msg_unref (msg);
|
2012-04-21 08:27:10 +02:00
|
|
|
return 0;
|
2012-04-30 16:32:34 +02:00
|
|
|
|
|
|
|
err:
|
|
|
|
/* some error occured */
|
|
|
|
mu_msg_unref (msg);
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
g_printerr ("error: %s", err->message);
|
|
|
|
|
|
|
|
g_clear_error (&err);
|
|
|
|
return 1;
|
|
|
|
|
2012-04-21 08:27:10 +02:00
|
|
|
}
|