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
This commit is contained in:
parent
cece7bc39b
commit
92d121fe9c
3 changed files with 389 additions and 0 deletions
|
@ -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 \
|
||||
|
|
328
panels/background/cc-background-grilo-miner.c
Normal file
328
panels/background/cc-background-grilo-miner.c
Normal file
|
@ -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);
|
||||
}
|
59
panels/background/cc-background-grilo-miner.h
Normal file
59
panels/background/cc-background-grilo-miner.h
Normal file
|
@ -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 */
|
Loading…
Add table
Reference in a new issue