[gnome-control-center] background: Add CcBackgroundGriloMiner



commit 92d121fe9ca5b51010e7a4ea6fa5371bf040d4d1
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Feb 17 09:29:13 2014 +0100

    background: Add CcBackgroundGriloMiner
    
    It fetches the most recent 50 images from every Grilo source that has
    a corresponding GOA account. Currently the only such source is Flickr.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707569

 panels/background/Makefile.am                 |    2 +
 panels/background/cc-background-grilo-miner.c |  328 +++++++++++++++++++++++++
 panels/background/cc-background-grilo-miner.h |   59 +++++
 3 files changed, 389 insertions(+), 0 deletions(-)
---
diff --git a/panels/background/Makefile.am b/panels/background/Makefile.am
index 9b3668c..c3de612 100644
--- a/panels/background/Makefile.am
+++ b/panels/background/Makefile.am
@@ -27,6 +27,8 @@ libbackground_chooser_la_SOURCES =    \
        $(BUILT_SOURCES)                \
        cc-background-chooser-dialog.c  \
        cc-background-chooser-dialog.h  \
+       cc-background-grilo-miner.c     \
+       cc-background-grilo-miner.h     \
        cc-background-item.c            \
        cc-background-item.h            \
        cc-background-xml.c             \
diff --git a/panels/background/cc-background-grilo-miner.c b/panels/background/cc-background-grilo-miner.c
new file mode 100644
index 0000000..ff7e498
--- /dev/null
+++ b/panels/background/cc-background-grilo-miner.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 2 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+#include <grilo.h>
+
+#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <goa/goa.h>
+
+#include "bg-pictures-source.h"
+#include "cc-background-grilo-miner.h"
+
+struct _CcBackgroundGriloMiner
+{
+  GObject parent;
+  GCancellable *cancellable;
+  GList *accounts;
+};
+
+struct _CcBackgroundGriloMinerClass
+{
+  GObjectClass parent_class;
+};
+
+enum
+{
+  MEDIA_FOUND,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (CcBackgroundGriloMiner, cc_background_grilo_miner, G_TYPE_OBJECT)
+
+#define REMOTE_ITEM_COUNT 50
+
+static gchar *
+get_grilo_id (GoaObject *goa_object)
+{
+  GoaAccount *account;
+
+  account = goa_object_peek_account (goa_object);
+  return g_strdup_printf ("grl-flickr-%s", goa_account_get_id (account));
+}
+
+static void
+is_online_data_cached (GObject      *object,
+                       GAsyncResult *res,
+                       gpointer      user_data)
+{
+  CcBackgroundGriloMiner *self;
+  GError *error = NULL;
+  GFileInfo *info = NULL;
+  GFile *cache_file = G_FILE (object);
+  GrlMedia *media;
+  const gchar *uri;
+
+  info = g_file_query_info_finish (cache_file, res, &error);
+  if (info == NULL)
+    {
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        goto out;
+    }
+
+  self = CC_BACKGROUND_GRILO_MINER (user_data);
+
+  media = g_object_get_data (G_OBJECT (cache_file), "grl-media");
+  uri = grl_media_get_url (media);
+
+  if (info != NULL)
+    {
+      g_debug ("Ignored URL '%s' as it is already in the cache", uri);
+      goto out;
+    }
+
+  g_signal_emit (self, signals[MEDIA_FOUND], 0, media);
+
+ out:
+  g_clear_object (&info);
+  g_clear_error (&error);
+}
+
+static void
+searched_online_source (GrlSource    *source,
+                        guint         operation_id,
+                        GrlMedia     *media,
+                        guint         remaining,
+                        gpointer      user_data,
+                        const GError *error)
+{
+  CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (user_data);
+  GFile *cache_file = NULL;
+  const gchar *uri;
+  gchar *cache_path = NULL;
+
+  if (error != NULL)
+    {
+      const gchar *source_id;
+
+      source_id = grl_source_get_id (source);
+      g_warning ("Error searching %s: %s", source_id, error->message);
+      grl_operation_cancel (operation_id);
+      remaining = 0;
+      goto out;
+    }
+
+  uri = grl_media_get_url (media);
+  cache_path = bg_pictures_source_get_unique_path (uri);
+  cache_file = g_file_new_for_path (cache_path);
+  g_object_set_data_full (G_OBJECT (cache_file), "grl-media", g_object_ref (media), g_object_unref);
+  g_file_query_info_async (cache_file,
+                           G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                           G_FILE_QUERY_INFO_NONE,
+                           G_PRIORITY_DEFAULT,
+                           self->cancellable,
+                           is_online_data_cached,
+                           self);
+
+ out:
+  g_clear_object (&cache_file);
+  g_free (cache_path);
+  if (remaining == 0)
+    g_object_unref (self);
+}
+
+static void
+query_online_source (CcBackgroundGriloMiner *self, GrlSource *source)
+{
+  const GList *keys;
+  GrlCaps *caps;
+  GrlOperationOptions *options;
+
+  keys = grl_source_supported_keys (source);
+  caps = grl_source_get_caps (source, GRL_OP_BROWSE);
+  options = grl_operation_options_new (caps);
+  grl_operation_options_set_count (options, REMOTE_ITEM_COUNT);
+  grl_operation_options_set_flags (options, GRL_RESOLVE_FAST_ONLY);
+  grl_operation_options_set_type_filter (options, GRL_TYPE_FILTER_IMAGE);
+
+  grl_source_search (source, NULL, keys, options, searched_online_source, g_object_ref (self));
+  g_object_unref (options);
+}
+
+static void
+add_online_source_cb (CcBackgroundGriloMiner *self,
+                      GrlSource              *source)
+{
+  GList *l;
+  gboolean found = FALSE;
+  const gchar *source_id;
+
+  source_id = grl_source_get_id (source);
+  for (l = self->accounts; l != NULL && !found; l = l->next)
+    {
+      GoaObject *goa_object = GOA_OBJECT (l->data);
+      gchar *account_id;
+
+      account_id = get_grilo_id (goa_object);
+      if (g_strcmp0 (source_id, account_id) == 0)
+        {
+          query_online_source (self, source);
+          found = TRUE;
+        }
+
+      g_free (account_id);
+    }
+}
+
+static void
+client_async_ready (GObject      *source,
+                    GAsyncResult *res,
+                    gpointer      user_data)
+{
+  CcBackgroundGriloMiner *self;
+  GError *error = NULL;
+  GList *accounts = NULL;
+  GList *photo_accounts = NULL;
+  GList *l;
+  GoaClient *client = NULL;
+  GrlRegistry *registry;
+
+  client = goa_client_new_finish (res, &error);
+  if (client == NULL)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to create GoaClient: %s", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  self = CC_BACKGROUND_GRILO_MINER (user_data);
+
+  accounts = goa_client_get_accounts (client);
+  for (l = accounts; l != NULL; l = l->next)
+    {
+      GoaObject *goa_object = GOA_OBJECT (l->data);
+      GoaAccount *account;
+      GoaPhotos *photos;
+      const gchar *provider_type;
+
+      account = goa_object_peek_account (goa_object);
+      provider_type = goa_account_get_provider_type (account);
+
+      photos = goa_object_peek_photos (goa_object);
+      if (photos != NULL && g_strcmp0 (provider_type, "flickr") == 0)
+        photo_accounts = g_list_prepend (photo_accounts, g_object_ref (goa_object));
+    }
+
+  if (photo_accounts == NULL)
+    goto out;
+
+  registry = grl_registry_get_default ();
+
+  for (l = photo_accounts; l != NULL; l = l->next)
+    {
+      GoaObject *goa_object = GOA_OBJECT (l->data);
+      GrlSource *source;
+      gchar *account_id;
+
+      account_id = get_grilo_id (goa_object);
+      source = grl_registry_lookup_source (registry, account_id);
+      if (source != NULL)
+        query_online_source (self, source);
+
+      g_free (account_id);
+    }
+
+  self->accounts = photo_accounts;
+  photo_accounts = NULL;
+
+  g_signal_connect_object (registry, "source-added", G_CALLBACK (add_online_source_cb), self, 
G_CONNECT_SWAPPED);
+
+ out:
+  g_list_free_full (photo_accounts, g_object_unref);
+  g_list_free_full (accounts, g_object_unref);
+  g_clear_object (&client);
+}
+
+static void
+setup_online_accounts (CcBackgroundGriloMiner *self)
+{
+  goa_client_new (self->cancellable, client_async_ready, self);
+}
+
+static void
+cc_background_grilo_miner_dispose (GObject *object)
+{
+  CcBackgroundGriloMiner *self = CC_BACKGROUND_GRILO_MINER (object);
+
+  if (self->cancellable)
+    {
+      g_cancellable_cancel (self->cancellable);
+      g_clear_object (&self->cancellable);
+    }
+
+  if (self->accounts)
+    {
+      g_list_free_full (self->accounts, g_object_unref);
+      self->accounts = NULL;
+    }
+
+  G_OBJECT_CLASS (cc_background_grilo_miner_parent_class)->dispose (object);
+}
+
+static void
+cc_background_grilo_miner_init (CcBackgroundGriloMiner *self)
+{
+  self->cancellable = g_cancellable_new ();
+}
+
+static void
+cc_background_grilo_miner_class_init (CcBackgroundGriloMinerClass *klass)
+{
+  GError *error;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GrlRegistry *registry;
+
+  object_class->dispose = cc_background_grilo_miner_dispose;
+
+  signals[MEDIA_FOUND] = g_signal_new ("media-found",
+                                       G_TYPE_FROM_CLASS (klass),
+                                       G_SIGNAL_RUN_LAST,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       g_cclosure_marshal_VOID__OBJECT,
+                                       G_TYPE_NONE,
+                                       1,
+                                       GRL_TYPE_MEDIA);
+
+  grl_init (NULL, NULL);
+  registry = grl_registry_get_default ();
+
+  error = NULL;
+  if (!grl_registry_load_plugin_by_id (registry, "grl-flickr", &error))
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+    }
+}
+
+CcBackgroundGriloMiner *
+cc_background_grilo_miner_new (void)
+{
+  return g_object_new (CC_TYPE_BACKGROUND_GRILO_MINER, NULL);
+}
+
+void
+cc_background_grilo_miner_start (CcBackgroundGriloMiner *self)
+{
+  setup_online_accounts (self);
+}
diff --git a/panels/background/cc-background-grilo-miner.h b/panels/background/cc-background-grilo-miner.h
new file mode 100644
index 0000000..97d0375
--- /dev/null
+++ b/panels/background/cc-background-grilo-miner.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 2 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _CC_BACKGROUND_GRILO_MINER_H
+#define _CC_BACKGROUND_GRILO_MINER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_BACKGROUND_GRILO_MINER cc_background_grilo_miner_get_type()
+
+#define CC_BACKGROUND_GRILO_MINER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CC_TYPE_BACKGROUND_GRILO_MINER, CcBackgroundGriloMiner))
+
+#define CC_BACKGROUND_GRILO_MINER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CC_TYPE_BACKGROUND_GRILO_MINER, CcBackgroundGriloMinerClass))
+
+#define CC_IS_BACKGROUND_GRILO_MINER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CC_TYPE_BACKGROUND_GRILO_MINER))
+
+#define CC_IS_BACKGROUND_GRILO_MINER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CC_TYPE_BACKGROUND_GRILO_MINER))
+
+#define CC_BACKGROUND_GRILO_MINER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CC_TYPE_BACKGROUND_GRILO_MINER, CcBackgroundGriloMinerClass))
+
+typedef struct _CcBackgroundGriloMiner CcBackgroundGriloMiner;
+typedef struct _CcBackgroundGriloMinerClass CcBackgroundGriloMinerClass;
+
+GType                     cc_background_grilo_miner_get_type       (void) G_GNUC_CONST;
+
+CcBackgroundGriloMiner   *cc_background_grilo_miner_new            (void);
+
+void                      cc_background_grilo_miner_start          (CcBackgroundGriloMiner *self);
+
+G_END_DECLS
+
+#endif /* _CC_BACKGROUND_GRILO_MINER_H */


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