[evolution/gnome-3-38] I#1089 - Extend the iTIP formatter to show ATTACH and URL



commit d64bdd1423f897fd541f5250f5673bb91dde055c
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 14 16:06:09 2020 +0200

    I#1089 - Extend the iTIP formatter to show ATTACH and URL
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1089

 src/modules/itip-formatter/e-mail-formatter-itip.c |   1 -
 src/modules/itip-formatter/e-mail-parser-itip.c    | 127 +++++++++++++++++++++
 .../itip-formatter/itip-view-elements-defines.h    |   1 +
 src/modules/itip-formatter/itip-view.c             |  37 +++++-
 src/modules/itip-formatter/itip-view.h             |   3 +
 5 files changed, 167 insertions(+), 2 deletions(-)
---
diff --git a/src/modules/itip-formatter/e-mail-formatter-itip.c 
b/src/modules/itip-formatter/e-mail-formatter-itip.c
index fc3324d483..67146534c0 100644
--- a/src/modules/itip-formatter/e-mail-formatter-itip.c
+++ b/src/modules/itip-formatter/e-mail-formatter-itip.c
@@ -86,7 +86,6 @@ emfe_itip_format (EMailFormatterExtension *extension,
                buffer = g_string_sized_new (2048);
 
                itip_view_write (itip_part, formatter, buffer);
-
        } else {
                CamelFolder *folder, *old_folder;
                CamelMimeMessage *message, *old_message;
diff --git a/src/modules/itip-formatter/e-mail-parser-itip.c b/src/modules/itip-formatter/e-mail-parser-itip.c
index 7ef3325746..326d930b63 100644
--- a/src/modules/itip-formatter/e-mail-parser-itip.c
+++ b/src/modules/itip-formatter/e-mail-parser-itip.c
@@ -57,6 +57,130 @@ static const gchar *parser_mime_types[] = {
        NULL
 };
 
+static void
+empe_itip_wrap_attachment (EMailParser *parser,
+                          GString *part_id,
+                          ICalProperty *prop,
+                          const gchar *content,
+                          GQueue *queue)
+{
+       CamelMimePart *opart;
+       CamelDataWrapper *dw;
+       ICalParameter *param;
+       const gchar *mime_type = NULL, *tmp;
+
+       opart = camel_mime_part_new ();
+
+       param = i_cal_property_get_first_parameter (prop, I_CAL_FILENAME_PARAMETER);
+
+       if (param) {
+               tmp = i_cal_parameter_get_filename (param);
+
+               if (tmp && *tmp)
+                       camel_mime_part_set_filename (opart, tmp);
+
+               g_object_unref (param);
+       }
+
+       param = i_cal_property_get_first_parameter (prop, I_CAL_FMTTYPE_PARAMETER);
+
+       if (param)
+               mime_type = i_cal_parameter_get_fmttype (param);
+
+       if (!mime_type || !*mime_type)
+               mime_type = "application/octet-stream";
+
+       camel_mime_part_set_content (opart, content, strlen (content), mime_type);
+       camel_mime_part_set_encoding (opart, CAMEL_TRANSFER_ENCODING_BASE64);
+
+       dw = camel_medium_get_content (CAMEL_MEDIUM (opart));
+       camel_data_wrapper_set_encoding (dw, CAMEL_TRANSFER_ENCODING_BASE64);
+
+       e_mail_parser_wrap_as_attachment (parser, opart, part_id, queue);
+
+       g_clear_object (&param);
+       g_object_unref (opart);
+}
+
+static void
+empe_itip_extract_attachments (EMailParser *parser,
+                              const gchar *vcalendar_str,
+                              GString *part_id,
+                              GQueue *queue)
+{
+       ICalComponent *vcalendar, *ical_comp;
+       ICalCompIter *iter;
+
+       if (!vcalendar_str)
+               return;
+
+       vcalendar = i_cal_parser_parse_string (vcalendar_str);
+
+       if (!vcalendar)
+               return;
+
+       iter = i_cal_component_begin_component (vcalendar, I_CAL_ANY_COMPONENT);
+       ical_comp = i_cal_comp_iter_deref (iter);
+       if (ical_comp) {
+               ICalComponentKind kind;
+
+               kind = i_cal_component_isa (ical_comp);
+               if (kind != I_CAL_VEVENT_COMPONENT &&
+                   kind != I_CAL_VTODO_COMPONENT &&
+                   kind != I_CAL_VFREEBUSY_COMPONENT &&
+                   kind != I_CAL_VJOURNAL_COMPONENT) {
+                       do {
+                               g_clear_object (&ical_comp);
+                               ical_comp = i_cal_comp_iter_next (iter);
+                               if (!ical_comp)
+                                       break;
+                               kind = i_cal_component_isa (ical_comp);
+                       } while (ical_comp &&
+                                kind != I_CAL_VEVENT_COMPONENT &&
+                                kind != I_CAL_VTODO_COMPONENT &&
+                                kind != I_CAL_VFREEBUSY_COMPONENT &&
+                                kind != I_CAL_VJOURNAL_COMPONENT);
+               }
+       }
+
+       g_clear_object (&iter);
+
+       if (ical_comp) {
+               ICalProperty *prop;
+               gint len, index = 0;
+
+               len = part_id->len;
+
+               for (prop = i_cal_component_get_first_property (ical_comp, I_CAL_ATTACH_PROPERTY);
+                    prop;
+                    g_object_unref (prop), prop = i_cal_component_get_next_property (ical_comp, 
I_CAL_ATTACH_PROPERTY)) {
+                       ICalAttach *attach;
+
+                       attach = i_cal_property_get_attach (prop);
+
+                       if (attach && !i_cal_attach_get_is_url (attach)) {
+                               const gchar *content;
+
+                               content = (const gchar *) i_cal_attach_get_data (attach);
+
+                               if (content) {
+                                       g_string_append_printf (part_id, ".attachment.%d", index);
+
+                                       empe_itip_wrap_attachment (parser, part_id, prop, content, queue);
+
+                                       g_string_truncate (part_id, len);
+                                       index++;
+                               }
+                       }
+
+                       g_clear_object (&attach);
+               }
+       }
+
+       g_clear_object (&ical_comp);
+       g_clear_object (&vcalendar);
+}
+
 static gboolean
 empe_itip_parse (EMailParserExtension *extension,
                  EMailParser *parser,
@@ -105,6 +229,9 @@ empe_itip_parse (EMailParserExtension *extension,
 
        e_queue_transfer (&work_queue, out_mail_parts);
 
+       empe_itip_extract_attachments (parser, itip_part->vcalendar, part_id, &work_queue);
+       e_queue_transfer (&work_queue, out_mail_parts);
+
        g_string_truncate (part_id, len);
 
        return TRUE;
diff --git a/src/modules/itip-formatter/itip-view-elements-defines.h 
b/src/modules/itip-formatter/itip-view-elements-defines.h
index 35bf65313e..529102297e 100644
--- a/src/modules/itip-formatter/itip-view-elements-defines.h
+++ b/src/modules/itip-formatter/itip-view-elements-defines.h
@@ -22,6 +22,7 @@
 #define TEXT_ROW_SENDER "text_row_sender"
 #define TABLE_ROW_SUMMARY "table_row_summary"
 #define TABLE_ROW_LOCATION "table_row_location"
+#define TABLE_ROW_URL "table_row_url"
 #define TABLE_ROW_START_DATE "table_row_start_time"
 #define TABLE_ROW_END_DATE "table_row_end_time"
 #define TABLE_ROW_STATUS "table_row_status"
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index 72c3138e33..bbdcf9af72 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -82,6 +82,7 @@ struct _ItipViewPrivate {
        gchar *location;
         gchar *status;
        gchar *comment;
+       gchar *url;
 
        struct tm *start_tm;
        guint start_tm_is_date : 1;
@@ -686,7 +687,8 @@ htmlize_text (const gchar *id,
              gchar **out_tmp)
 {
        if (text && *text) {
-               if (g_strcmp0 (id, TABLE_ROW_LOCATION) == 0) {
+               if (g_strcmp0 (id, TABLE_ROW_LOCATION) == 0 ||
+                   g_strcmp0 (id, TABLE_ROW_URL) == 0) {
                        *out_tmp = camel_text_to_html (text, CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | 
CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, 0);
                } else {
                        *out_tmp = g_markup_escape_text (text, -1);
@@ -1485,6 +1487,7 @@ itip_view_finalize (GObject *object)
        g_free (priv->location);
        g_free (priv->status);
        g_free (priv->comment);
+       g_free (priv->url);
        g_free (priv->start_tm);
        g_free (priv->start_label);
        g_free (priv->end_tm);
@@ -1698,6 +1701,7 @@ itip_view_write (gpointer itip_part_ptr,
 
        append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL, NULL);
        append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_URL, _("URL:"), NULL);
        append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"), NULL);
        append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"), NULL);
        append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"), NULL);
@@ -1809,6 +1813,9 @@ itip_view_write_for_printing (ItipView *view,
        append_text_table_row_nonempty (
                buffer, TABLE_ROW_LOCATION,
                _("Location:"), view->priv->location);
+       append_text_table_row_nonempty (
+               buffer, TABLE_ROW_URL,
+               _("URL:"), view->priv->url);
        append_text_table_row_nonempty (
                buffer, TABLE_ROW_START_DATE,
                view->priv->start_header, view->priv->start_label);
@@ -2191,6 +2198,30 @@ itip_view_get_location (ItipView *view)
        return view->priv->location;
 }
 
+void
+itip_view_set_url (ItipView *view,
+                  const gchar *url)
+{
+       g_return_if_fail (ITIP_IS_VIEW (view));
+
+       if (view->priv->url == url)
+               return;
+
+       g_free (view->priv->url);
+
+       view->priv->url = url ? g_strstrip (e_utf8_ensure_valid (url)) : NULL;
+
+       set_area_text (view, TABLE_ROW_URL, view->priv->url);
+}
+
+const gchar *
+itip_view_get_url (ItipView *view)
+{
+       g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
+
+       return view->priv->url;
+}
+
 void
 itip_view_set_status (ItipView *view,
                       const gchar *status)
@@ -6483,6 +6514,10 @@ itip_view_init_view (ItipView *view)
        itip_view_set_location (view, string);
        g_free (string);
 
+       string = e_cal_component_get_url (view->priv->comp);
+       itip_view_set_url (view, string);
+       g_free (string);
+
         /* Status really only applies for REPLY */
        if (response_enabled && view->priv->method == I_CAL_METHOD_REPLY) {
                list = e_cal_component_get_attendees (view->priv->comp);
diff --git a/src/modules/itip-formatter/itip-view.h b/src/modules/itip-formatter/itip-view.h
index 05e26f84a6..b53b2b5624 100644
--- a/src/modules/itip-formatter/itip-view.h
+++ b/src/modules/itip-formatter/itip-view.h
@@ -158,6 +158,9 @@ void                itip_view_set_summary           (ItipView *view,
 const gchar *  itip_view_get_location          (ItipView *view);
 void           itip_view_set_location          (ItipView *view,
                                                 const gchar *location);
+const gchar *  itip_view_get_url               (ItipView *view);
+void           itip_view_set_url               (ItipView *view,
+                                                const gchar *url);
 const gchar *  itip_view_get_status            (ItipView *view);
 void           itip_view_set_status            (ItipView *view,
                                                 const gchar *status);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]