diff --git a/configure.ac b/configure.ac index 249a417d..85ab8438 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ ## along with this program; if not, write to the Free Software Foundation, ## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -AC_INIT([mu],[0.9.8.4-dev1],[http://code.google.com/p/mu0/issues/list],[mu]) +AC_INIT([mu],[0.9.8.4-dev2],[http://code.google.com/p/mu0/issues/list],[mu]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([src/mu.cc]) # libtoolize wants to put some stuff in here; if you have an old @@ -203,15 +203,27 @@ AS_IF([test "x$have_gtk2" = "xyes" -o "x$have_gtk3" = "xyes"],[buildgui=yes], AS_IF([test "x$have_gtk3" = "xyes"], [AC_DEFINE_UNQUOTED([HAVE_GTK3],1,[Whether we have GTK+ 3.x])]) - # webkit? needed for the fancy web widget -AS_IF([test "x$buildgui" = "xyes"],[ + +# note; gtk2 and gtk3 imply different webkit versions +AS_IF([test "x$have_gtk2" = "xyes"],[ PKG_CHECK_MODULES(WEBKIT,webkit-1.0 >= 1.0.3,[have_webkit=yes],[have_webkit=no]) AS_IF([test "x$have_webkit" = "xyes"],[ webkit_version="`$PKG_CONFIG --modversion webkit-1.0`"]) AC_SUBST(WEBKIT_CFLAGS) AC_SUBST(WEBKIT_LIBS) ]) + +AS_IF([test "x$have_gtk3" = "xyes"],[ + PKG_CHECK_MODULES(WEBKIT,webkitgtk-3.0 >= 1.8.0, [have_webkit=yes],[have_webkit=no]) + AS_IF([test "x$have_webkit" = "xyes"],[ + webkit_version="`$PKG_CONFIG --modversion webkitgtk-3.0`"]) + AC_SUBST(WEBKIT_CFLAGS) + AC_SUBST(WEBKIT_LIBS) +]) + + + AM_CONDITIONAL(HAVE_WEBKIT, [test "x$have_webkit" = "xyes"]) # gio is needed for some widget/ things @@ -283,7 +295,7 @@ src/Makefile src/tests/Makefile widgets/Makefile emacs/Makefile -emacs/mu4e-version.el +emacs/mu4e-meta.el emacs/version.texi guile/Makefile guile/mu/Makefile @@ -291,6 +303,7 @@ guile/examples/Makefile toys/Makefile toys/mug/Makefile toys/mug2/Makefile +toys/msg2pdf/Makefile man/Makefile m4/Makefile contrib/Makefile diff --git a/toys/Makefile.am b/toys/Makefile.am index cfbaf8c5..8a020549 100644 --- a/toys/Makefile.am +++ b/toys/Makefile.am @@ -23,7 +23,7 @@ if HAVE_GTK SUBDIRS += mug endif -# for mug2, we need webkit +# for mug2 and msg2pdf, we need webkit if BUILD_WIDGETS -SUBDIRS += mug2 +SUBDIRS += mug2 msg2pdf endif diff --git a/toys/msg2pdf/Makefile.am b/toys/msg2pdf/Makefile.am new file mode 100644 index 00000000..13b90bd7 --- /dev/null +++ b/toys/msg2pdf/Makefile.am @@ -0,0 +1,55 @@ +## Copyright (C) 2012 Dirk-Jan C. Binnema +## +## 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 of the License, 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 $(top_srcdir)/gtest.mk + +# enforce compiling this dir first before decending into tests/ +SUBDIRS= . + + +INCLUDES=-I${top_srcdir}/src $(GTK_CFLAGS) $(WEBKIT_CFLAGS) -DICONDIR='"$(icondir)"' + +# don't use -Werror, as it might break on other compilers +# use -Wno-unused-parameters, because some callbacks may not +# really need all the params they get +AM_CFLAGS=-Wall -Wextra -Wno-unused-parameter -Wdeclaration-after-statement +AM_CXXFLAGS=-Wall -Wextra -Wno-unused-parameter + + +noinst_PROGRAMS= \ + msg2pdf + +# note, mug.cc is '.cc' only because libmu must explicitly +# be linked as c++, not c. +msg2pdf_SOURCES= \ + msg2pdf.c \ + dummy.cc + +# we need to use dummy.cc to enforce c++ linking... +BUILT_SOURCES= \ + dummy.cc + +dummy.cc: + touch dummy.cc + +DISTCLEANFILES= \ + $(BUILT_SOURCES) + + +msg2pdf_LDADD= \ + ${top_builddir}/src/libmu.la \ + $(GTK_LIBS) \ + ${WEBKIT_LIBS} diff --git a/toys/msg2pdf/msg2pdf.c b/toys/msg2pdf/msg2pdf.c new file mode 100644 index 00000000..94d19d99 --- /dev/null +++ b/toys/msg2pdf/msg2pdf.c @@ -0,0 +1,192 @@ +/* +** Copyright (C) 2012 Dirk-Jan C. Binnema +** +** 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 +#include +#include + +#include +#include +#include +#include +#include + +static GtkPrintOperation* +get_print_operation (const char *path) +{ + GtkPrintOperation *printop; + + printop = gtk_print_operation_new (); + + gtk_print_operation_set_export_filename + (GTK_PRINT_OPERATION(printop), path); + + return printop; +} + + +/* return the path to the output file, or NULL in case of error */ +static char* +generate_pdf (MuMsg *msg, const char *str, GError **err) +{ + GtkWidget *view; + WebKitWebFrame *frame; + WebKitWebSettings *settings; + + GtkPrintOperationResult printres; + GtkPrintOperation *printop; + char *path; + + settings = webkit_web_settings_new (); + g_object_set (G_OBJECT(settings), + "enable-scripts", FALSE, + "auto-load-images", TRUE, + "enable-plugins", FALSE, + NULL); + + view = webkit_web_view_new (); + 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); + 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; + } + + path = g_strdup_printf ("%s%c%x.pdf",mu_util_cache_dir(), + G_DIR_SEPARATOR, (unsigned)random()); + + printop = get_print_operation (path); + printres = webkit_web_frame_print_full + (frame, printop, GTK_PRINT_OPERATION_ACTION_EXPORT, + err); + g_object_unref (printop); + + if (printres != GTK_PRINT_OPERATION_RESULT_ERROR) + return path; + else { + g_free (path); + return NULL; + } +} + + +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, "%s: %s
", header, esc); + g_free (esc); +} + + /* return the path to the output file, or NULL in case of error */ +static char* +convert_to_pdf (MuMsg *msg, GError **err) +{ + GString *gstr; + const char *body; + gchar *data, *path; + + 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)); + add_header (gstr, "Date", mu_date_display_s (mu_msg_get_date(msg))); + + gstr = g_string_append (gstr, "
\n"); + + body = mu_msg_get_body_html (msg); + if (body) + g_string_append_printf (gstr, "%s", body); + else { + body = mu_msg_get_body_text (msg); + if (body) { + gchar *esc; + esc = g_markup_escape_text (body, -1); + g_string_append_printf (gstr, "
\n%s\n
", + esc); + g_free (esc); + } else + gstr = g_string_append + (gstr, "No body\n"); + } + + data = g_string_free (gstr, FALSE); + path = generate_pdf (msg, data, err); + g_free (data); + + return path; +} + + +int +main(int argc, char *argv[]) +{ + MuMsg *msg; + GError *err; + char *path; + + if (argc != 2) { + g_print ("msg2pdf: generate pdf files from e-mail messages\n" + "usage: msg2pdf \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) { + g_printerr ("failed to create msg for %s: %s\n", + argv[1], + err && err->message ? err->message : + "unknown error"); + g_clear_error (&err); + return 1; + } + + path = convert_to_pdf (msg, &err); + if (!path) { + g_printerr ("failed to create pdf from %s: %s\n", + argv[1], + err && err->message ? err->message : + "unknown error"); + g_clear_error (&err); + mu_msg_unref (msg); + return 1; + } + mu_msg_unref (msg); + + g_print ("%s\n", path); + return 0; +}