[evolution/wip-webkit2] Process various URI requests asynchronously.



commit 8a7ce6454dce71d164dbac9ae4b9dda49f25f4eb
Author: Tomas Popela <tpopela redhat com>
Date:   Tue Jan 14 14:51:36 2014 +0100

    Process various URI requests asynchronously.

 e-util/e-web-view.c   |   80 ++++++++++++++++----
 mail/e-mail-display.c |  196 ++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 248 insertions(+), 28 deletions(-)
---
diff --git a/e-util/e-web-view.c b/e-util/e-web-view.c
index 755a6a4..a7c5db0 100644
--- a/e-util/e-web-view.c
+++ b/e-util/e-web-view.c
@@ -1696,33 +1696,54 @@ e_web_view_selectable_init (ESelectableInterface *interface)
 }
 
 static void
+web_view_process_uri_scheme_finished_cb (EWebView *web_view,
+                                         GAsyncResult *result,
+                                         WebKitURISchemeRequest *request)
+{
+       GError *error = NULL;
+
+       if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+               if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                       g_warning ("URI %s cannot be processed: %s",
+                               webkit_uri_scheme_request_get_uri (request),
+                               error ? error->message : "Unknown error");
+               }
+               g_object_unref (request);
+               if (error)
+                       g_error_free (error);
+       }
+}
+
+static void
 web_view_cid_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                                      EWebView *web_view)
 {
 }
 
 static void
-web_view_file_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
-                                      EWebView *web_view)
+web_view_process_file_uri_scheme_request (GTask *task,
+                                          gpointer source_object,
+                                          gpointer task_data,
+                                          GCancellable *cancellable)
 {
-       GInputStream *stream;
+       gboolean ret_val = FALSE;
        const gchar *uri;
        gchar *content = NULL;
-       gchar *content_type;
-       gchar *filename;
+       gchar *content_type = NULL;
+       gchar *filename = NULL;
+       GInputStream *stream;
        gsize length = 0;
+       GError *error = NULL;
+       WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
 
-       g_warning ("%s", __FUNCTION__);
        uri = webkit_uri_scheme_request_get_uri (request);
 
-       filename = g_filename_from_uri (strstr (uri, "file"), NULL, NULL);
+       filename = g_filename_from_uri (strstr (uri, "file"), NULL, &error);
        if (!filename)
-               return;
+               goto out;
 
-       if (!g_file_get_contents (filename, &content, &length, NULL)) {
-               g_free (filename);
-               return;
-       }
+       if (!g_file_get_contents (filename, &content, &length, &error))
+               goto out;
 
        content_type = g_content_type_guess (filename, NULL, 0, NULL);
 
@@ -1730,23 +1751,50 @@ web_view_file_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
 
        webkit_uri_scheme_request_finish (request, stream, length, content_type);
 
+       ret_val = TRUE;
+ out:
        g_free (content_type);
        g_free (content);
        g_free (filename);
-/*     g_object_unref (stream); */
+
+       if (ret_val)
+               g_object_unref (request);
+
+       if (error)
+               g_task_return_error (task, error);
+       else
+               g_task_return_boolean (task, ret_val);
+}
+
+static void
+web_view_file_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+                                      EWebView *web_view)
+{
+       GTask *task;
+
+       g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+       task = g_task_new (
+               web_view, NULL,
+               (GAsyncReadyCallback) web_view_process_uri_scheme_finished_cb,
+               request);
+
+       g_task_set_task_data (task, g_object_ref (request), NULL);
+       g_task_run_in_thread (task, web_view_process_file_uri_scheme_request);
+
+       g_object_unref (task);
 }
+
 static void
 web_view_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                                       EWebView *web_view)
 {
-       g_warning ("%s", __FUNCTION__);
 }
 
 static void
 web_view_http_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                                       EWebView *web_view)
 {
-       g_warning ("%s", __FUNCTION__);
 }
 
 static void
@@ -1838,8 +1886,6 @@ web_view_gtk_stock_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
        if (!content_type)
                content_type = g_strdup ("image/png");
 
-       g_warning ("%s", content_type);
-
        if (buffer != NULL) {
                GInputStream *stream;
 
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 84f81dc..d486cf7 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -1374,6 +1374,25 @@ e_mail_display_class_init (EMailDisplayClass *class)
 }
 
 static void
+mail_display_process_uri_scheme_finished_cb (EMailDisplay *display,
+                                             GAsyncResult *result,
+                                             WebKitURISchemeRequest *request)
+{
+       GError *error = NULL;
+
+       if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+               if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                       g_warning ("URI %s cannot be processed: %s",
+                               webkit_uri_scheme_request_get_uri (request),
+                               error ? error->message : "Unknown error");
+               }
+               g_object_unref (request);
+               if (error)
+                       g_error_free (error);
+       }
+}
+
+static void
 mail_cid_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                                  EMailDisplay *display)
 {
@@ -1420,13 +1439,32 @@ static void
 mail_http_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                                   EMailDisplay *display)
 {
+       GTask *task;
+       GCancellable *cancellable;
+
+       g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+       cancellable = g_cancellable_new ();
+
+       task = g_task_new (
+               display, cancellable,
+               (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
+               request);
+
+       g_task_set_task_data (task, g_object_ref (request), NULL);
+       g_task_run_in_thread (task, web_view_process_http_uri_scheme_request);
+
+       g_object_unref (task);
+       g_object_unref (cancellable);
 }
 
 static void
-mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
-                                  EMailDisplay *display)
+mail_display_process_mail_uri_scheme_request (GTask *task,
+                                              gpointer source_object,
+                                              gpointer task_data,
+                                              GCancellable *cancellable)
 {
-       GInputStream *stream;
+       GInputStream *stream = NULL;
        EMailFormatter *formatter;
        EMailPartList *part_list;
        CamelStream *output_stream;
@@ -1435,10 +1473,9 @@ mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
        const gchar *val, *uri;
        const gchar *default_charset, *charset;
        SoupURI *soup_uri;
-
-       GCancellable *cancellable = NULL;
-
        EMailFormatterContext context = { 0 };
+       EMailDisplay *display = E_MAIL_DISPLAY (source_object);
+       WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
 
        uri = webkit_uri_scheme_request_get_uri (request);
 
@@ -1449,13 +1486,16 @@ mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
                camel_debug_end ();
        }
 
-       if (!part_list)
+       if (!part_list) {
+               g_task_return_boolean (task, FALSE);
                return;
+       }
 
        soup_uri = soup_uri_new (uri);
        if (!soup_uri || !soup_uri->query) {
                if (soup_uri)
                        soup_uri_free (soup_uri);
+               g_task_return_boolean (task, FALSE);
                return;
        }
        query = soup_form_decode (soup_uri->query);
@@ -1522,7 +1562,8 @@ mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
 
                        mime_part = e_mail_part_ref_mime_part (part);
                        dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
-                       g_return_if_fail (dw);
+                       if (!dw)
+                               goto no_part;
 
                        camel_data_wrapper_decode_to_stream_sync (
                                dw, output_stream, cancellable, NULL);
@@ -1563,11 +1604,144 @@ mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
        stream = g_memory_input_stream_new_from_bytes (
                g_byte_array_free_to_bytes (byte_array));
 
-       /* FIXME This can be done async */
        webkit_uri_scheme_request_finish (request, stream, -1, "text/html");
+
        g_object_unref (stream);
-       g_hash_table_destroy (query);
-       soup_uri_free (soup_uri);
+
+       if (query)
+               g_hash_table_destroy (query);
+
+       if (soup_uri)
+               soup_uri_free (soup_uri);
+
+       g_task_return_boolean (task, TRUE);
+}
+
+static GInputStream *
+get_empty_image_stream (void)
+{
+       GdkPixbuf *pixbuf;
+       gchar *buffer;
+       gsize length;
+
+       pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
+       gdk_pixbuf_fill (pixbuf, 0x00000000); /* transparent black */
+       gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &length, "png", NULL, NULL);
+       g_object_unref (pixbuf);
+
+       return g_memory_input_stream_new_from_data (buffer, length, g_free);
+}
+
+static void
+mail_display_process_contact_photo_uri_scheme_request (GTask *task,
+                                                       gpointer source_object,
+                                                       gpointer task_data,
+                                                       GCancellable *cancellable)
+{
+       EShell *shell;
+       EShellBackend *shell_backend;
+       EMailBackend *mail_backend;
+       EMailSession *mail_session;
+       EPhotoCache *photo_cache;
+       CamelInternetAddress *cia;
+       GInputStream *stream = NULL;
+       const gchar *uri;
+       const gchar *email_address;
+       const gchar *escaped_string;
+       gchar *unescaped_string;
+       GError *error = NULL;
+       SoupURI *soup_uri;
+       GHashTable *uri_query;
+       WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
+
+       /* XXX Is this really the only way to obtain
+        *     the mail session instance from here? */
+       shell = e_shell_get_default ();
+       shell_backend = e_shell_get_backend_by_name (shell, "mail");
+       mail_backend = E_MAIL_BACKEND (shell_backend);
+       mail_session = e_mail_backend_get_session (mail_backend);
+
+       photo_cache = e_mail_ui_session_get_photo_cache (
+               E_MAIL_UI_SESSION (mail_session));
+
+       uri = webkit_uri_scheme_request_get_uri (request);
+
+       soup_uri = soup_uri_new (uri);
+       if (!soup_uri || !soup_uri->query)
+               goto exit;
+
+       uri_query = soup_form_decode (soup_uri->query);
+       escaped_string = g_hash_table_lookup (uri_query, "mailaddr");
+       if (escaped_string == NULL || *escaped_string == '\0')
+               goto exit;
+
+       cia = camel_internet_address_new ();
+
+       unescaped_string = g_uri_unescape_string (escaped_string, NULL);
+       camel_address_decode (CAMEL_ADDRESS (cia), unescaped_string);
+       g_free (unescaped_string);
+
+       if (camel_internet_address_get (cia, 0, NULL, &email_address))
+               e_photo_cache_get_photo_sync (
+                       photo_cache, email_address,
+                       cancellable, &stream, &error);
+
+       g_object_unref (cia);
+
+       /* Ignore cancellations. */
+       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+               g_clear_error (&error);
+       } else if (error != NULL) {
+               g_warning ("%s: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+       }
+
+exit:
+       if (!stream)
+               stream = get_empty_image_stream ();
+
+       webkit_uri_scheme_request_finish (request, stream, -1, "image/*");
+
+       g_object_unref (request);
+       g_object_unref (stream);
+
+       if (uri_query)
+               g_hash_table_destroy (uri_query);
+
+       if (soup_uri)
+               soup_uri_free (soup_uri);
+
+       g_task_return_boolean (task, TRUE);
+}
+
+static void
+mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+                                  EMailDisplay *display)
+{
+       GTask *task;
+       GCancellable *cancellable;
+       const gchar *uri;
+
+       g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+       cancellable = g_cancellable_new ();
+
+       uri = webkit_uri_scheme_request_get_uri (request);
+
+       task = g_task_new (
+               display, cancellable,
+               (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
+               request);
+
+       g_task_set_task_data (task, g_object_ref (request), NULL);
+
+       if (g_ascii_strncasecmp (uri, "mail://contact-photo", 20) == 0)
+               g_task_run_in_thread (task, mail_display_process_contact_photo_uri_scheme_request);
+       else
+               g_task_run_in_thread (task, mail_display_process_mail_uri_scheme_request);
+
+       g_object_unref (task);
+       g_object_unref (cancellable);
 }
 
 static void


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