Blame src/gom-application.c

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
}