[PATCH 1/1] [gravatar] Add Gravatar plugin



This metadata source checks if either "artist" or "author" fields contain a
valid email. If so, it uses Gravatar services to return an avatar in
"artist-avatar" and/or "author-avatar".
---
 AUTHORS                     |    1 +
 configure.ac                |   21 +++
 src/Makefile.am             |    6 +-
 src/gravatar/Makefile.am    |   24 ++++
 src/gravatar/grl-gravatar.c |  305 +++++++++++++++++++++++++++++++++++++++++++
 src/gravatar/grl-gravatar.h |   74 +++++++++++
 6 files changed, 430 insertions(+), 1 deletions(-)
 create mode 100644 src/gravatar/Makefile.am
 create mode 100644 src/gravatar/grl-gravatar.c
 create mode 100644 src/gravatar/grl-gravatar.h

diff --git a/AUTHORS b/AUTHORS
index b17ba92..6eb3e55 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,7 @@ Juan A. Suarez Romero <jasuarez igalia com>
 * Flickr plugin
 * Jamendo plugin
 * LastFM-Albumart plugin
+* Gravatar plugin
 
 Joaquim Rocha <jrocha igalia com>
 * Vimeo plugin
diff --git a/configure.ac b/configure.ac
index 783a06d..5887824 100644
--- a/configure.ac
+++ b/configure.ac
@@ -562,6 +562,26 @@ then
 fi
 
 # ----------------------------------------------------------
+# BUILD GRAVATAR PLUGIN
+# ----------------------------------------------------------
+
+AC_ARG_ENABLE(gravatar,
+        AC_HELP_STRING([--enable-gravatar],
+                [enable Gravatar plugin (default: auto)]),
+        [
+        ],
+        [
+                enable_gravatar=yes
+        ])
+
+AM_CONDITIONAL([GRAVATAR_PLUGIN], [test "x$enable_gravatar" = "xyes"])
+GRL_PLUGINS_ALL="$GRL_PLUGINS_ALL gravatar"
+if test "x$enable_gravatar" = "xyes"
+then
+	GRL_PLUGINS_ENABLED="$GRL_PLUGINS_ENABLED gravatar"
+fi
+
+# ----------------------------------------------------------
 # GETTEXT
 # ----------------------------------------------------------
 
@@ -598,6 +618,7 @@ AC_CONFIG_FILES([
   src/apple-trailers/Makefile
   src/metadata-store/Makefile
   src/vimeo/Makefile
+  src/gravatar/Makefile
   test/Makefile
 ])
 
diff --git a/src/Makefile.am b/src/Makefile.am
index e00b176..72ac7cd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,7 +59,11 @@ if VIMEO_PLUGIN
 SUBDIRS += vimeo
 endif
 
-DIST_SUBDIRS = youtube fake-metadata filesystem jamendo lastfm-albumart upnp flickr podcasts bookmarks shoutcast apple-trailers metadata-store vimeo
+if GRAVATAR_PLUGIN
+SUBDIRS += gravatar
+endif
+
+DIST_SUBDIRS = youtube fake-metadata filesystem jamendo lastfm-albumart upnp flickr podcasts bookmarks shoutcast apple-trailers metadata-store vimeo gravatar
 
 MAINTAINERCLEANFILES = \
         *.in \
diff --git a/src/gravatar/Makefile.am b/src/gravatar/Makefile.am
new file mode 100644
index 0000000..027d102
--- /dev/null
+++ b/src/gravatar/Makefile.am
@@ -0,0 +1,24 @@
+#
+# Makefile.am
+#
+# Author: Juan A. Suarez Romero <jasuarez igalia com>
+#
+# Copyright (C) 2010 Igalia S.L. All rights reserved.
+
+lib_LTLIBRARIES = libgrlgravatar.la
+
+libgrlgravatar_la_CFLAGS =	\
+	$(DEPS_CFLAGS)
+
+libgrlgravatar_la_LIBADD =	\
+	$(DEPS_LIBS)
+
+libgrlgravatar_la_SOURCES = grl-gravatar.c grl-gravatar.h
+
+libdir=$(GRL_PLUGINS_DIR)
+
+MAINTAINERCLEANFILES =	\
+	*.in	\
+	*~
+
+DISTCLEANFILES = $(MAINTAINERCLEANFILES)
diff --git a/src/gravatar/grl-gravatar.c b/src/gravatar/grl-gravatar.c
new file mode 100644
index 0000000..09b0bac
--- /dev/null
+++ b/src/gravatar/grl-gravatar.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez igalia com>
+ *
+ * This library 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; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "grl-gravatar.h"
+
+/* ---------- Logging ---------- */
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "grl-gravatar"
+
+/* -------- Gravatar API -------- */
+
+#define GRAVATAR_URL "http://www.gravatar.com/avatar/%s.jpg";
+
+/* ------- Pluging Info -------- */
+
+#define PLUGIN_ID   "grl-gravatar"
+#define PLUGIN_NAME "Avatar provider from Gravatar"
+#define PLUGIN_DESC "A plugin to get avatars for artist and author fields"
+
+#define SOURCE_ID   PLUGIN_ID
+#define SOURCE_NAME PLUGIN_NAME
+#define SOURCE_DESC PLUGIN_DESC
+
+#define AUTHOR      "Igalia S.L."
+#define LICENSE     "LGPL"
+#define SITE        "http://www.igalia.com";
+
+
+static GrlGravatarSource *grl_gravatar_source_new (void);
+
+static void grl_gravatar_source_resolve (GrlMetadataSource *source,
+                                         GrlMetadataSourceResolveSpec *rs);
+
+static const GList *grl_gravatar_source_supported_keys (GrlMetadataSource *source);
+
+static const GList *grl_gravatar_source_key_depends (GrlMetadataSource *source,
+                                                     GrlKeyID key_id);
+
+static GrlKeyID register_gravatar_key (GrlPluginRegistry *registry,
+                                       const gchar *name,
+                                       const gchar *nick,
+                                       const gchar *blurb);
+
+gboolean grl_gravatar_source_plugin_init (GrlPluginRegistry *registry,
+                                          const GrlPluginInfo *plugin,
+                                          GList *configs);
+
+GrlKeyID GRL_METADATA_KEY_ARTIST_AVATAR = NULL;
+GrlKeyID GRL_METADATA_KEY_AUTHOR_AVATAR = NULL;
+
+/* =================== Gravatar Plugin  =============== */
+
+gboolean
+grl_gravatar_source_plugin_init (GrlPluginRegistry *registry,
+                                 const GrlPluginInfo *plugin,
+                                 GList *configs)
+{
+  g_debug ("grl_gravatar_source_plugin_init");
+  /* Register keys */
+  GRL_METADATA_KEY_ARTIST_AVATAR =
+    register_gravatar_key (registry,
+                           "artist-avatar",
+                           "ArtistAvatar",
+                           "Avatar for the artist");
+
+  GRL_METADATA_KEY_AUTHOR_AVATAR =
+    register_gravatar_key (registry,
+                           "author-avatar",
+                            "AuthorAvatar",
+                            "Avatar for the author");
+  if (!GRL_METADATA_KEY_ARTIST_AVATAR &&
+      !GRL_METADATA_KEY_AUTHOR_AVATAR) {
+    g_warning ("Unable to register \"autor-avatar\" nor \"artist-avatar\"");
+    return FALSE;
+  }
+
+  GrlGravatarSource *source = grl_gravatar_source_new ();
+  grl_plugin_registry_register_source (registry,
+                                       plugin,
+                                       GRL_MEDIA_PLUGIN (source));
+  return TRUE;
+}
+
+GRL_PLUGIN_REGISTER (grl_gravatar_source_plugin_init,
+                     NULL,
+                     PLUGIN_ID,
+                     PLUGIN_NAME,
+                     PLUGIN_DESC,
+                     PACKAGE_VERSION,
+                     AUTHOR,
+                     LICENSE,
+                     SITE);
+
+/* ================== Gravatar GObject ================ */
+
+static GrlGravatarSource *
+grl_gravatar_source_new (void)
+{
+  g_debug ("grl_gravatar_source_new");
+  return g_object_new (GRL_GRAVATAR_SOURCE_TYPE,
+		       "source-id", SOURCE_ID,
+		       "source-name", SOURCE_NAME,
+		       "source-desc", SOURCE_DESC,
+		       NULL);
+}
+
+static void
+grl_gravatar_source_class_init (GrlGravatarSourceClass * klass)
+{
+  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
+  metadata_class->supported_keys = grl_gravatar_source_supported_keys;
+  metadata_class->key_depends = grl_gravatar_source_key_depends;
+  metadata_class->resolve = grl_gravatar_source_resolve;
+}
+
+static void
+grl_gravatar_source_init (GrlGravatarSource *source)
+{
+}
+
+G_DEFINE_TYPE (GrlGravatarSource,
+               grl_gravatar_source,
+               GRL_TYPE_METADATA_SOURCE);
+
+/* ======================= Utilities ==================== */
+
+static GrlKeyID
+register_gravatar_key (GrlPluginRegistry *registry,
+                       const gchar *name,
+                       const gchar *nick,
+                       const gchar *blurb)
+{
+  GParamSpec *spec;
+  GrlKeyID key;
+
+  spec = g_param_spec_string (name,
+                              nick,
+                              blurb,
+                              NULL,
+                              G_PARAM_READWRITE);
+
+  key = grl_plugin_registry_register_metadata_key (registry, spec);
+
+  /* If key was not registered, could be that it is already registered. If so,
+     check if type is the expected one, and reuse it */
+  if (!key) {
+    g_param_spec_unref (spec);
+    key = grl_plugin_registry_lookup_metadata_key (registry, name);
+    if (!key || GRL_METADATA_KEY_GET_TYPE (key) != G_TYPE_STRING) {
+      key = NULL;
+    }
+  }
+
+  return key;
+}
+
+static gchar *
+get_avatar (const gchar *field) {
+  GMatchInfo *match_info = NULL;
+  gchar *avatar = NULL;
+  gchar *email;
+  gchar *email_hash;
+  gchar *lowercased_field;
+  static GRegex *email_regex = NULL;
+
+  if (!field) {
+    return NULL;
+  }
+
+  lowercased_field = g_utf8_strdown (field, -1);
+
+  if (!email_regex) {
+    email_regex = g_regex_new ("[\\w-]+@([\\w-]+\\.)+[\\w-]+", G_REGEX_OPTIMIZE, 0, NULL);
+  }
+
+  if (g_regex_match (email_regex, lowercased_field, 0, &match_info)) {
+    email = g_match_info_fetch (match_info, 0);
+    g_match_info_free (match_info);
+    email_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, email, -1);
+    avatar = g_strdup_printf (GRAVATAR_URL, email_hash);
+    g_free (email);
+    g_free (email_hash);
+  }
+
+  return avatar;
+}
+
+/* ================== API Implementation ================ */
+
+static const GList *
+grl_gravatar_source_supported_keys (GrlMetadataSource *source)
+{
+  static GList *keys = NULL;
+
+  if (!keys) {
+    if (GRL_METADATA_KEY_ARTIST_AVATAR) {
+      keys = g_list_prepend (keys, GRL_METADATA_KEY_ARTIST_AVATAR);
+    }
+    if (GRL_METADATA_KEY_AUTHOR_AVATAR) {
+      keys =g_list_prepend (keys, GRL_METADATA_KEY_AUTHOR_AVATAR);
+    }
+  }
+
+ return keys;
+}
+
+static const GList *
+grl_gravatar_source_key_depends (GrlMetadataSource *source,
+                                 GrlKeyID key_id)
+{
+  static GList *artist_avatar_deps = NULL;
+  static GList *author_avatar_deps = NULL;
+
+  if (!artist_avatar_deps) {
+    artist_avatar_deps = grl_metadata_key_list_new (GRL_METADATA_KEY_ARTIST,
+                                                    NULL);
+  }
+
+  if (!author_avatar_deps) {
+    author_avatar_deps = grl_metadata_key_list_new (GRL_METADATA_KEY_AUTHOR,
+                                                    NULL);
+  }
+
+  if (key_id == GRL_METADATA_KEY_ARTIST_AVATAR) {
+    return artist_avatar_deps;
+  } else if (key_id == GRL_METADATA_KEY_AUTHOR_AVATAR) {
+    return author_avatar_deps;
+  } else {
+    return  NULL;
+  }
+}
+
+static void
+grl_gravatar_source_resolve (GrlMetadataSource *source,
+                             GrlMetadataSourceResolveSpec *rs)
+{
+  gboolean artist_avatar_required = FALSE;
+  gboolean author_avatar_required = FALSE;
+  gchar *avatar_url;
+
+  g_debug ("grl_gravatar_source_resolve");
+
+  GList *iter;
+
+  /* Check that albumart is requested */
+  iter = rs->keys;
+  while (iter && (!artist_avatar_required || !author_avatar_required)) {
+    if (iter->data == GRL_METADATA_KEY_ARTIST_AVATAR) {
+      artist_avatar_required = TRUE;
+    } else if (iter->data == GRL_METADATA_KEY_AUTHOR_AVATAR) {
+      author_avatar_required = TRUE;
+    }
+    iter = g_list_next (iter);
+  }
+
+  if (artist_avatar_required) {
+    avatar_url = get_avatar (grl_data_get_string (GRL_DATA (rs->media),
+                                                  GRL_METADATA_KEY_ARTIST));
+    if (avatar_url) {
+      grl_data_set_string (GRL_DATA (rs->media),
+                           GRL_METADATA_KEY_ARTIST_AVATAR,
+                           avatar_url);
+      g_free (avatar_url);
+    }
+  }
+
+  if (author_avatar_required) {
+    avatar_url = get_avatar (grl_data_get_string (GRL_DATA (rs->media),
+                                                  GRL_METADATA_KEY_AUTHOR));
+    if (avatar_url) {
+      grl_data_set_string (GRL_DATA (rs->media),
+                           GRL_METADATA_KEY_AUTHOR_AVATAR,
+                           avatar_url);
+      g_free (avatar_url);
+    }
+  }
+
+  rs->callback (source, rs->media, rs->user_data, NULL);
+}
diff --git a/src/gravatar/grl-gravatar.h b/src/gravatar/grl-gravatar.h
new file mode 100644
index 0000000..644efdb
--- /dev/null
+++ b/src/gravatar/grl-gravatar.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez igalia com>
+ *
+ * This library 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; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_GRAVATAR_H_
+#define _GRL_GRAVATAR_H_
+
+#include <grilo.h>
+
+#define GRL_GRAVATAR_SOURCE_TYPE                \
+  (grl_gravatar_source_get_type ())
+
+#define GRL_GRAVATAR_SOURCE(obj)                                \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                           \
+                               GRL_GRAVATAR_SOURCE_TYPE,        \
+                               GrlGravatarSource))
+
+#define GRL_IS_GRAVATAR_SOURCE(obj)                             \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                           \
+                               GRL_GRAVATAR_SOURCE_TYPE))
+
+#define GRL_GRAVATAR_SOURCE_CLASS(klass)                \
+  (G_TYPE_CHECK_CLASS_CAST((klass),                     \
+                           GRL_GRAVATAR_SOURCE_TYPE,    \
+                           GrlGravatarSourceClass))
+
+#define GRL_IS_GRAVATAR_SOURCE_CLASS(klass)             \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),                     \
+                           GRL_GRAVATAR_SOURCE_TYPE))
+
+#define GRL_GRAVATAR_SOURCE_GET_CLASS(obj)              \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj),                    \
+                              GRL_GRAVATAR_SOURCE_TYPE, \
+                              GrlGravatarSourceClass))
+
+typedef struct _GrlGravatarSource GrlGravatarSource;
+
+struct _GrlGravatarSource {
+
+  GrlMetadataSource parent;
+
+};
+
+typedef struct _GrlGravatarSourceClass GrlGravatarSourceClass;
+
+struct _GrlGravatarSourceClass {
+
+  GrlMetadataSourceClass parent_class;
+
+};
+
+GType grl_gravatar_source_get_type (void);
+
+#endif /* _GRL_GRAVATAR_H_ */
-- 
1.7.0.4



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