|
Packit |
f01ec2 |
/*
|
|
Packit |
f01ec2 |
* GNOME Online Miners - crawls through your online content
|
|
Packit |
f01ec2 |
* Copyright (C) 2014 Red Hat, Inc.
|
|
Packit |
f01ec2 |
*
|
|
Packit |
f01ec2 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
f01ec2 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
f01ec2 |
* as published by the Free Software Foundation; either version 2
|
|
Packit |
f01ec2 |
* of the License, or (at your option) any later version.
|
|
Packit |
f01ec2 |
*
|
|
Packit |
f01ec2 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
f01ec2 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
f01ec2 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
f01ec2 |
* GNU General Public License for more details.
|
|
Packit |
f01ec2 |
*
|
|
Packit |
f01ec2 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
f01ec2 |
* along with this program; if not, write to the Free Software
|
|
Packit |
f01ec2 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit |
f01ec2 |
* 02110-1301, USA.
|
|
Packit |
f01ec2 |
*
|
|
Packit |
f01ec2 |
* Author: Debarshi Ray <debarshir@gnome.org>
|
|
Packit |
f01ec2 |
*
|
|
Packit |
f01ec2 |
*/
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
#include "config.h"
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
#include "gom-application.h"
|
|
Packit |
f01ec2 |
#include "gom-dbus.h"
|
|
Packit |
f01ec2 |
#include "gom-miner.h"
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
#define AUTOQUIT_TIMEOUT 5 /* seconds */
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
struct _GomApplication
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GApplication parent;
|
|
Packit |
f01ec2 |
GCancellable *cancellable;
|
|
Packit |
f01ec2 |
GomDBus *skeleton;
|
|
Packit |
f01ec2 |
GomMiner *miner;
|
|
Packit |
f01ec2 |
GQueue *queue;
|
|
Packit |
f01ec2 |
GType miner_type;
|
|
Packit |
f01ec2 |
gboolean refreshing;
|
|
Packit |
f01ec2 |
};
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
struct _GomApplicationClass
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GApplicationClass parent_class;
|
|
Packit |
f01ec2 |
};
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
enum
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
PROP_0,
|
|
Packit |
f01ec2 |
PROP_MINER_TYPE
|
|
Packit |
f01ec2 |
};
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
G_DEFINE_TYPE (GomApplication, gom_application, G_TYPE_APPLICATION);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void gom_application_refresh_db_cb (GObject *source, GAsyncResult *res, gpointer user_data);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_insert_shared_content_cb (GObject *source,
|
|
Packit |
f01ec2 |
GAsyncResult *res,
|
|
Packit |
f01ec2 |
gpointer user_data)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self;
|
|
Packit |
f01ec2 |
GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
|
|
Packit |
f01ec2 |
GError *error;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self = GOM_APPLICATION (g_application_get_default ());
|
|
Packit |
f01ec2 |
g_application_release (G_APPLICATION (self));
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
error = NULL;
|
|
Packit |
f01ec2 |
if (!gom_miner_insert_shared_content_finish (GOM_MINER (source), res, &error))
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
g_printerr ("Failed to insert shared content: %s\n", error->message);
|
|
Packit |
f01ec2 |
g_dbus_method_invocation_take_error (invocation, error);
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
gom_dbus_complete_insert_shared_content (self->skeleton, invocation);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
out:
|
|
Packit |
f01ec2 |
g_object_unref (invocation);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static gboolean
|
|
Packit |
f01ec2 |
gom_application_insert_shared_content (GomApplication *self,
|
|
Packit |
f01ec2 |
GDBusMethodInvocation *invocation,
|
|
Packit |
f01ec2 |
const gchar *account_id,
|
|
Packit |
f01ec2 |
const gchar *shared_id,
|
|
Packit |
f01ec2 |
const gchar *shared_type,
|
|
Packit |
f01ec2 |
const gchar *source_urn)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
g_application_hold (G_APPLICATION (self));
|
|
Packit |
f01ec2 |
gom_miner_insert_shared_content_async (self->miner,
|
|
Packit |
f01ec2 |
account_id,
|
|
Packit |
f01ec2 |
shared_id,
|
|
Packit |
f01ec2 |
shared_type,
|
|
Packit |
f01ec2 |
source_urn,
|
|
Packit |
f01ec2 |
self->cancellable,
|
|
Packit |
f01ec2 |
gom_application_insert_shared_content_cb,
|
|
Packit |
f01ec2 |
g_object_ref (invocation));
|
|
Packit |
f01ec2 |
return TRUE;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_process_queue (GomApplication *self)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GDBusMethodInvocation *invocation = NULL;
|
|
Packit |
f01ec2 |
const gchar **index_types;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (self->refreshing)
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (g_queue_is_empty (self->queue))
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
invocation = G_DBUS_METHOD_INVOCATION (g_queue_pop_head (self->queue));
|
|
Packit |
f01ec2 |
index_types = g_object_get_data (G_OBJECT (invocation), "index-types");
|
|
Packit |
f01ec2 |
gom_miner_set_index_types (self->miner, index_types);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self->refreshing = TRUE;
|
|
Packit |
f01ec2 |
g_application_hold (G_APPLICATION (self));
|
|
Packit |
f01ec2 |
gom_miner_refresh_db_async (self->miner,
|
|
Packit |
f01ec2 |
self->cancellable,
|
|
Packit |
f01ec2 |
gom_application_refresh_db_cb,
|
|
Packit |
f01ec2 |
g_object_ref (invocation));
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
out:
|
|
Packit |
f01ec2 |
g_clear_object (&invocation);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_refresh_db_cb (GObject *source,
|
|
Packit |
f01ec2 |
GAsyncResult *res,
|
|
Packit |
f01ec2 |
gpointer user_data)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self;
|
|
Packit |
f01ec2 |
GDBusMethodInvocation *invocation = user_data;
|
|
Packit |
f01ec2 |
GError *error = NULL;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self = GOM_APPLICATION (g_application_get_default ());
|
|
Packit |
f01ec2 |
g_application_release (G_APPLICATION (self));
|
|
Packit |
f01ec2 |
self->refreshing = FALSE;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
gom_miner_refresh_db_finish (GOM_MINER (source), res, &error);
|
|
Packit |
f01ec2 |
if (error != NULL)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
g_printerr ("Failed to refresh the DB cache: %s\n", error->message);
|
|
Packit |
f01ec2 |
g_dbus_method_invocation_take_error (invocation, error);
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
gom_dbus_complete_refresh_db (self->skeleton, invocation);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
out:
|
|
Packit |
f01ec2 |
g_object_unref (invocation);
|
|
Packit |
f01ec2 |
gom_application_process_queue (self);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static gboolean
|
|
Packit |
f01ec2 |
gom_application_refresh_db (GomApplication *self,
|
|
Packit |
f01ec2 |
GDBusMethodInvocation *invocation,
|
|
Packit |
f01ec2 |
const gchar *const *arg_index_types)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
gchar **index_types;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
index_types = g_strdupv ((gchar **) arg_index_types);
|
|
Packit |
f01ec2 |
g_object_set_data_full (G_OBJECT (invocation), "index-types", index_types, (GDestroyNotify) g_strfreev);
|
|
Packit |
f01ec2 |
g_queue_push_tail (self->queue, g_object_ref (invocation));
|
|
Packit |
f01ec2 |
gom_application_process_queue (self);
|
|
Packit |
f01ec2 |
return TRUE;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static gboolean
|
|
Packit |
f01ec2 |
gom_application_dbus_register (GApplication *application,
|
|
Packit |
f01ec2 |
GDBusConnection *connection,
|
|
Packit |
f01ec2 |
const gchar *object_path,
|
|
Packit |
f01ec2 |
GError **error)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (application);
|
|
Packit |
f01ec2 |
gboolean retval = FALSE;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (!G_APPLICATION_CLASS (gom_application_parent_class)->dbus_register (application,
|
|
Packit |
f01ec2 |
connection,
|
|
Packit |
f01ec2 |
object_path,
|
|
Packit |
f01ec2 |
error))
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton),
|
|
Packit |
f01ec2 |
connection,
|
|
Packit |
f01ec2 |
object_path,
|
|
Packit |
f01ec2 |
error))
|
|
Packit |
f01ec2 |
goto out;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
retval = TRUE;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
out:
|
|
Packit |
f01ec2 |
return retval;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_dbus_unregister (GApplication *application,
|
|
Packit |
f01ec2 |
GDBusConnection *connection,
|
|
Packit |
f01ec2 |
const gchar *object_path)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (application);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (self->skeleton != NULL)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
if (g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (self->skeleton), connection))
|
|
Packit |
f01ec2 |
g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (self->skeleton),
|
|
Packit |
f01ec2 |
connection);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
G_APPLICATION_CLASS (gom_application_parent_class)->dbus_unregister (application, connection, object_path);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_shutdown (GApplication *application)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (application);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
g_cancellable_cancel (self->cancellable);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
G_APPLICATION_CLASS (gom_application_parent_class)->shutdown (application);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_constructed (GObject *object)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (object);
|
|
Packit |
f01ec2 |
const gchar *display_name;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
G_OBJECT_CLASS (gom_application_parent_class)->constructed (object);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self->miner = g_object_new (self->miner_type, NULL);
|
|
Packit |
f01ec2 |
display_name = gom_miner_get_display_name (self->miner);
|
|
Packit |
f01ec2 |
gom_dbus_set_display_name (self->skeleton, display_name);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_dispose (GObject *object)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (object);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
g_clear_object (&self->cancellable);
|
|
Packit |
f01ec2 |
g_clear_object (&self->miner);
|
|
Packit |
f01ec2 |
g_clear_object (&self->skeleton);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
if (self->queue != NULL)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
g_queue_free_full (self->queue, g_object_unref);
|
|
Packit |
f01ec2 |
self->queue = NULL;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
G_OBJECT_CLASS (gom_application_parent_class)->dispose (object);
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_set_property (GObject *object,
|
|
Packit |
f01ec2 |
guint prop_id,
|
|
Packit |
f01ec2 |
const GValue *value,
|
|
Packit |
f01ec2 |
GParamSpec *pspec)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GomApplication *self = GOM_APPLICATION (object);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
switch (prop_id)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
case PROP_MINER_TYPE:
|
|
Packit |
f01ec2 |
self->miner_type = g_value_get_gtype (value);
|
|
Packit |
f01ec2 |
break;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
default:
|
|
Packit |
f01ec2 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
f01ec2 |
break;
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_init (GomApplication *self)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
self->cancellable = g_cancellable_new ();
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self->skeleton = gom_dbus_skeleton_new ();
|
|
Packit |
f01ec2 |
g_signal_connect_swapped (self->skeleton,
|
|
Packit |
f01ec2 |
"handle-insert-shared-content",
|
|
Packit |
f01ec2 |
G_CALLBACK (gom_application_insert_shared_content),
|
|
Packit |
f01ec2 |
self);
|
|
Packit |
f01ec2 |
g_signal_connect_swapped (self->skeleton, "handle-refresh-db", G_CALLBACK (gom_application_refresh_db), self);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
self->queue = g_queue_new ();
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
static void
|
|
Packit |
f01ec2 |
gom_application_class_init (GomApplicationClass *klass)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
GObjectClass *oclass = G_OBJECT_CLASS (klass);
|
|
Packit |
f01ec2 |
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
oclass->constructed = gom_application_constructed;
|
|
Packit |
f01ec2 |
oclass->dispose = gom_application_dispose;
|
|
Packit |
f01ec2 |
oclass->set_property = gom_application_set_property;
|
|
Packit |
f01ec2 |
application_class->dbus_register = gom_application_dbus_register;
|
|
Packit |
f01ec2 |
application_class->dbus_unregister = gom_application_dbus_unregister;
|
|
Packit |
f01ec2 |
application_class->shutdown = gom_application_shutdown;
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
g_object_class_install_property (oclass,
|
|
Packit |
f01ec2 |
PROP_MINER_TYPE,
|
|
Packit |
f01ec2 |
g_param_spec_gtype ("miner-type",
|
|
Packit |
f01ec2 |
"Miner type",
|
|
Packit |
f01ec2 |
"A GType representing the miner class",
|
|
Packit |
f01ec2 |
GOM_TYPE_MINER,
|
|
Packit |
f01ec2 |
G_PARAM_CONSTRUCT_ONLY
|
|
Packit |
f01ec2 |
| G_PARAM_STATIC_STRINGS
|
|
Packit |
f01ec2 |
| G_PARAM_WRITABLE));
|
|
Packit |
f01ec2 |
}
|
|
Packit |
f01ec2 |
|
|
Packit |
f01ec2 |
GApplication *
|
|
Packit |
f01ec2 |
gom_application_new (const gchar *application_id,
|
|
Packit |
f01ec2 |
GType miner_type)
|
|
Packit |
f01ec2 |
{
|
|
Packit |
f01ec2 |
return g_object_new (GOM_TYPE_APPLICATION,
|
|
Packit |
f01ec2 |
"application-id", application_id,
|
|
Packit |
f01ec2 |
"flags", G_APPLICATION_IS_SERVICE,
|
|
Packit |
f01ec2 |
"inactivity-timeout", AUTOQUIT_TIMEOUT,
|
|
Packit |
f01ec2 |
"miner-type", miner_type,
|
|
Packit |
f01ec2 |
NULL);
|
|
Packit |
f01ec2 |
}
|