aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile.am1
-rw-r--r--modules/gravatar/Makefile.am30
-rw-r--r--modules/gravatar/e-gravatar-photo-source.c281
-rw-r--r--modules/gravatar/e-gravatar-photo-source.h68
-rw-r--r--modules/gravatar/e-photo-cache-gravatar-loader.c88
-rw-r--r--modules/gravatar/e-photo-cache-gravatar-loader.h66
-rw-r--r--modules/gravatar/evolution-module-gravatar.c40
7 files changed, 574 insertions, 0 deletions
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 048817a2fa..d08372d710 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -43,6 +43,7 @@ SUBDIRS = \
cal-config-webcal \
composer-autosave \
contact-photos \
+ gravatar \
itip-formatter \
mail-config \
mailto-handler \
diff --git a/modules/gravatar/Makefile.am b/modules/gravatar/Makefile.am
new file mode 100644
index 0000000000..47c9e6570b
--- /dev/null
+++ b/modules/gravatar/Makefile.am
@@ -0,0 +1,30 @@
+module_LTLIBRARIES = module-gravatar.la
+
+module_gravatar_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"evolution-gravatar\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(NULL)
+
+module_gravatar_la_SOURCES = \
+ evolution-module-gravatar.c \
+ e-gravatar-photo-source.c \
+ e-gravatar-photo-source.h \
+ e-photo-cache-gravatar-loader.c \
+ e-photo-cache-gravatar-loader.h \
+ $(NULL)
+
+module_gravatar_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(NULL)
+
+module_gravatar_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/gravatar/e-gravatar-photo-source.c b/modules/gravatar/e-gravatar-photo-source.c
new file mode 100644
index 0000000000..eb6e653130
--- /dev/null
+++ b/modules/gravatar/e-gravatar-photo-source.c
@@ -0,0 +1,281 @@
+/*
+ * e-gravatar-photo-source.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-gravatar-photo-source.h"
+
+#include <libsoup/soup.h>
+#include <libsoup/soup-requester.h>
+#include <libsoup/soup-request-http.h>
+
+#define E_GRAVATAR_PHOTO_SOURCE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_GRAVATAR_PHOTO_SOURCE, EGravatarPhotoSourcePrivate))
+
+#define AVATAR_BASE_URI "http://www.gravatar.com/avatar/"
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EGravatarPhotoSourcePrivate {
+ SoupSession *soup_session;
+};
+
+struct _AsyncContext {
+ gchar *email_address;
+ GInputStream *stream;
+};
+
+/* Forward Declarations */
+static void e_gravatar_photo_source_interface_init
+ (EPhotoSourceInterface *interface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EGravatarPhotoSource,
+ e_gravatar_photo_source,
+ G_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_PHOTO_SOURCE,
+ e_gravatar_photo_source_interface_init))
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ g_free (async_context->email_address);
+ g_clear_object (&async_context->stream);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+gravatar_photo_source_get_photo_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ EGravatarPhotoSourcePrivate *priv;
+ AsyncContext *async_context;
+ SoupRequester *requester;
+ SoupRequest *request;
+ GInputStream *stream = NULL;
+ gchar *hash;
+ gchar *uri;
+ GError *local_error = NULL;
+
+ priv = E_GRAVATAR_PHOTO_SOURCE_GET_PRIVATE (source_object);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ hash = e_gravatar_get_hash (async_context->email_address);
+ uri = g_strdup_printf ("%s%s?d=404", AVATAR_BASE_URI, hash);
+
+ g_debug ("Requesting avatar for %s", async_context->email_address);
+ g_debug ("%s", uri);
+
+ requester = (SoupRequester *) soup_session_get_feature (
+ priv->soup_session, SOUP_TYPE_REQUESTER);
+
+ /* We control the URI so there should be no error. */
+ request = soup_requester_request (requester, uri, NULL);
+ g_return_if_fail (request != NULL);
+
+ stream = soup_request_send (request, cancellable, &local_error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((stream != NULL) && (local_error == NULL)) ||
+ ((stream == NULL) && (local_error != NULL)));
+
+ /* XXX soup_request_send() returns a stream on HTTP errors.
+ * We need to check the status code on the SoupMessage
+ * to make sure the we're not getting an error message. */
+ if (stream != NULL) {
+ SoupMessage *message;
+
+ message = soup_request_http_get_message (
+ SOUP_REQUEST_HTTP (request));
+
+ if (SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
+ async_context->stream = g_object_ref (stream);
+
+ } else if (message->status_code != SOUP_STATUS_NOT_FOUND) {
+ local_error = g_error_new_literal (
+ SOUP_HTTP_ERROR,
+ message->status_code,
+ message->reason_phrase);
+ }
+
+ g_object_unref (message);
+ g_object_unref (stream);
+ }
+
+ if (local_error != NULL) {
+ const gchar *domain;
+
+ domain = g_quark_to_string (local_error->domain);
+ g_debug ("Error: %s (%s)", local_error->message, domain);
+ g_simple_async_result_take_error (simple, local_error);
+ }
+
+ g_debug ("Request complete");
+
+ g_clear_object (&request);
+
+ g_free (hash);
+ g_free (uri);
+}
+
+static void
+gravatar_photo_source_dispose (GObject *object)
+{
+ EGravatarPhotoSourcePrivate *priv;
+
+ priv = E_GRAVATAR_PHOTO_SOURCE_GET_PRIVATE (object);
+
+ g_clear_object (&priv->soup_session);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_gravatar_photo_source_parent_class)->
+ dispose (object);
+}
+
+static void
+gravatar_photo_source_get_photo (EPhotoSource *photo_source,
+ const gchar *email_address,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->email_address = g_strdup (email_address);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (photo_source), callback,
+ user_data, gravatar_photo_source_get_photo);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, gravatar_photo_source_get_photo_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+gravatar_photo_source_get_photo_finish (EPhotoSource *photo_source,
+ GAsyncResult *result,
+ GInputStream **out_stream,
+ gint *out_priority,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (photo_source),
+ gravatar_photo_source_get_photo), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ if (async_context->stream != NULL) {
+ *out_stream = g_object_ref (async_context->stream);
+ if (out_priority != NULL)
+ *out_priority = G_PRIORITY_DEFAULT;
+ } else {
+ *out_stream = NULL;
+ }
+
+ return TRUE;
+}
+
+static void
+e_gravatar_photo_source_class_init (EGravatarPhotoSourceClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EGravatarPhotoSourcePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = gravatar_photo_source_dispose;
+}
+
+static void
+e_gravatar_photo_source_class_finalize (EGravatarPhotoSourceClass *class)
+{
+}
+
+static void
+e_gravatar_photo_source_interface_init (EPhotoSourceInterface *interface)
+{
+ interface->get_photo = gravatar_photo_source_get_photo;
+ interface->get_photo_finish = gravatar_photo_source_get_photo_finish;
+}
+
+static void
+e_gravatar_photo_source_init (EGravatarPhotoSource *photo_source)
+{
+ photo_source->priv =
+ E_GRAVATAR_PHOTO_SOURCE_GET_PRIVATE (photo_source);
+
+ photo_source->priv->soup_session = soup_session_sync_new ();
+
+ soup_session_add_feature_by_type (
+ photo_source->priv->soup_session,
+ SOUP_TYPE_REQUESTER);
+}
+
+void
+e_gravatar_photo_source_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_gravatar_photo_source_register_type (type_module);
+}
+
+EPhotoSource *
+e_gravatar_photo_source_new (void)
+{
+ return g_object_new (E_TYPE_GRAVATAR_PHOTO_SOURCE, NULL);
+}
+
+gchar *
+e_gravatar_get_hash (const gchar *email_address)
+{
+ gchar *string;
+ gchar *hash;
+
+ g_return_val_if_fail (email_address != NULL, NULL);
+ g_return_val_if_fail (g_utf8_validate (email_address, -1, NULL), NULL);
+
+ string = g_strstrip (g_utf8_strdown (email_address, -1));
+ hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, string, -1);
+ g_free (string);
+
+ return hash;
+}
+
diff --git a/modules/gravatar/e-gravatar-photo-source.h b/modules/gravatar/e-gravatar-photo-source.h
new file mode 100644
index 0000000000..de409d9031
--- /dev/null
+++ b/modules/gravatar/e-gravatar-photo-source.h
@@ -0,0 +1,68 @@
+/*
+ * e-gravatar-photo-source.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_GRAVATAR_PHOTO_SOURCE_H
+#define E_GRAVATAR_PHOTO_SOURCE_H
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_GRAVATAR_PHOTO_SOURCE \
+ (e_gravatar_photo_source_get_type ())
+#define E_GRAVATAR_PHOTO_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_GRAVATAR_PHOTO_SOURCE, EGravatarPhotoSource))
+#define E_GRAVATAR_PHOTO_SOURCE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_GRAVATAR_PHOTO_SOURCE, EGravatarPhotoSourceClass))
+#define E_IS_GRAVATAR_PHOTO_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_GRAVATAR_PHOTO_SOURCE))
+#define E_IS_GRAVATAR_PHOTO_SOURCE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_GRAVATAR_PHOTO_SOURCE))
+#define E_GRAVATAR_PHOTO_SOURCE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_GRAVATAR_PHOTO_SOURCE, EGravatarPhotoSourceClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EGravatarPhotoSource EGravatarPhotoSource;
+typedef struct _EGravatarPhotoSourceClass EGravatarPhotoSourceClass;
+typedef struct _EGravatarPhotoSourcePrivate EGravatarPhotoSourcePrivate;
+
+struct _EGravatarPhotoSource {
+ GObject parent;
+ EGravatarPhotoSourcePrivate *priv;
+};
+
+struct _EGravatarPhotoSourceClass {
+ GObjectClass parent_class;
+};
+
+GType e_gravatar_photo_source_get_type
+ (void) G_GNUC_CONST;
+void e_gravatar_photo_source_type_register
+ (GTypeModule *type_module);
+EPhotoSource * e_gravatar_photo_source_new (void);
+gchar * e_gravatar_get_hash (const gchar *email_address);
+
+G_END_DECLS
+
+#endif /* E_GRAVATAR_PHOTO_SOURCE_H */
+
diff --git a/modules/gravatar/e-photo-cache-gravatar-loader.c b/modules/gravatar/e-photo-cache-gravatar-loader.c
new file mode 100644
index 0000000000..33dd39b471
--- /dev/null
+++ b/modules/gravatar/e-photo-cache-gravatar-loader.c
@@ -0,0 +1,88 @@
+/*
+ * e-photo-cache-gravatar-loader.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-photo-cache-gravatar-loader.h"
+
+#include "e-gravatar-photo-source.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+ EPhotoCacheGravatarLoader,
+ e_photo_cache_gravatar_loader,
+ E_TYPE_EXTENSION)
+
+static EPhotoCache *
+photo_cache_gravatar_loader_get_photo_cache (EPhotoCacheGravatarLoader *loader)
+{
+ EExtensible *extensible;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (loader));
+
+ return E_PHOTO_CACHE (extensible);
+}
+
+static void
+photo_cache_gravatar_loader_constructed (GObject *object)
+{
+ EPhotoCacheGravatarLoader *loader;
+ EPhotoCache *photo_cache;
+ EPhotoSource *photo_source;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_photo_cache_gravatar_loader_parent_class)->
+ constructed (object);
+
+ loader = E_PHOTO_CACHE_GRAVATAR_LOADER (object);
+ photo_cache = photo_cache_gravatar_loader_get_photo_cache (loader);
+
+ photo_source = e_gravatar_photo_source_new ();
+ e_photo_cache_add_photo_source (photo_cache, photo_source);
+ g_object_unref (photo_source);
+}
+
+static void
+e_photo_cache_gravatar_loader_class_init (EPhotoCacheGravatarLoaderClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = photo_cache_gravatar_loader_constructed;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_PHOTO_CACHE;
+}
+
+static void
+e_photo_cache_gravatar_loader_class_finalize (EPhotoCacheGravatarLoaderClass *class)
+{
+}
+
+static void
+e_photo_cache_gravatar_loader_init (EPhotoCacheGravatarLoader *loader)
+{
+}
+
+void
+e_photo_cache_gravatar_loader_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_photo_cache_gravatar_loader_register_type (type_module);
+}
+
diff --git a/modules/gravatar/e-photo-cache-gravatar-loader.h b/modules/gravatar/e-photo-cache-gravatar-loader.h
new file mode 100644
index 0000000000..13b0d1d0dd
--- /dev/null
+++ b/modules/gravatar/e-photo-cache-gravatar-loader.h
@@ -0,0 +1,66 @@
+/*
+ * e-photo-cache-gravatar-loader.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_PHOTO_CACHE_GRAVATAR_LOADER_H
+#define E_PHOTO_CACHE_GRAVATAR_LOADER_H
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER \
+ (e_photo_cache_gravatar_loader_get_type ())
+#define E_PHOTO_CACHE_GRAVATAR_LOADER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER, EPhotoCacheGravatarLoader))
+#define E_PHOTO_CACHE_GRAVATAR_LOADER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER, EPhotoCacheGravatarLoaderClass))
+#define E_IS_PHOTO_CACHE_GRAVATAR_LOADER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER))
+#define E_IS_PHOTO_CACHE_GRAVATAR_LOADER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER))
+#define E_PHOTO_CACHE_GRAVATAR_LOADER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_PHOTO_CACHE_GRAVATAR_LOADER, EPhotoCacheGravatarLoaderClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPhotoCacheGravatarLoader EPhotoCacheGravatarLoader;
+typedef struct _EPhotoCacheGravatarLoaderClass EPhotoCacheGravatarLoaderClass;
+typedef struct _EPhotoCacheGravatarLoaderPrivate EPhotoCacheGravatarLoaderPrivate;
+
+struct _EPhotoCacheGravatarLoader {
+ EExtension parent;
+ EPhotoCacheGravatarLoaderPrivate *priv;
+};
+
+struct _EPhotoCacheGravatarLoaderClass {
+ EExtensionClass parent_class;
+};
+
+GType e_photo_cache_gravatar_loader_get_type
+ (void) G_GNUC_CONST;
+void e_photo_cache_gravatar_loader_type_register
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PHOTO_CACHE_GRAVATAR_LOADER_H */
+
diff --git a/modules/gravatar/evolution-module-gravatar.c b/modules/gravatar/evolution-module-gravatar.c
new file mode 100644
index 0000000000..0f452babfd
--- /dev/null
+++ b/modules/gravatar/evolution-module-gravatar.c
@@ -0,0 +1,40 @@
+/*
+ * evolution-module-gravatar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <gmodule.h>
+#include <glib-object.h>
+
+#include "e-gravatar-photo-source.h"
+#include "e-photo-cache-gravatar-loader.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ e_gravatar_photo_source_type_register (type_module);
+ e_photo_cache_gravatar_loader_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+