示例#1
0
static void
source_browser (gpointer data,
                gpointer user_data)
{
  GrlSource *source = GRL_SOURCE (data);
  GrlMedia *media = GRL_MEDIA (user_data);
  GList *media_elements;
  GError *error = NULL;
  GList *keys;
  GrlOperationOptions *options = NULL;
  GrlCaps *caps;

  keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
                                    GRL_METADATA_KEY_URL,
                                    GRL_METADATA_KEY_MODIFICATION_DATE,
                                    GRL_METADATA_KEY_MIME,
                                    GRL_METADATA_KEY_CHILDCOUNT,
                                    NULL);

  g_debug ("Detected new source available: '%s'",
	   grl_source_get_name (source));

  if (!(grl_source_supported_operations (source) & GRL_OP_BROWSE))
    goto out;

  g_debug ("Browsing source: %s", grl_source_get_name (source));
  /* Here is how you can browse a source, you have to provide:
     1) The source you want to browse contents from.
     2) The container object you want to browse (NULL for the root container)
     3) A list of metadata keys we are interested in.
     4) Options to control certain aspects of the browse operation.
     5) A callback that the framework will invoke for each available result
     6) User data for the callback
     It returns an operation identifier that you can use to match results
     with the corresponding request (we ignore it here) */

  caps = grl_source_get_caps (source, GRL_OP_BROWSE);
  options = grl_operation_options_new (caps);
  grl_operation_options_set_count (options, BROWSE_CHUNK_SIZE);
  grl_operation_options_set_resolution_flags (options, GRL_RESOLVE_IDLE_RELAY);
  media_elements = grl_pls_browse_sync (GRL_SOURCE (source),
                                        media, keys,
                                        options,
                                        NULL,
                                        &error);
  if (!media_elements) {
    g_debug ("No elements found for source: %s!",
             grl_source_get_name (source));
    goto out;
  }

  if (error)
    g_error ("Failed to browse source: %s", error->message);

  g_list_foreach (media_elements, element_browser, source);

out:
  g_list_free (keys);
  g_clear_object (&options);
}
示例#2
0
static guint
_mex_grilo_feed_search (MexGriloFeed      *feed,
                        const char        *search_text,
                        int                offset,
                        int                limit,
                        GrlSourceResultCb  callback)
{
  MexGriloFeedPrivate *priv = feed->priv;
  GrlOperationOptions *options;
	int op_id;

  options = grl_operation_options_new (NULL);
  grl_operation_options_set_flags (options, BROWSE_FLAGS);
  grl_operation_options_set_skip (options, priv->op->offset);
  grl_operation_options_set_count (options, priv->op->limit);

  op_id = grl_source_search (priv->source, priv->op->text,
                             priv->query_keys,
                             options,
                             callback, feed);

	g_object_unref (options);

	return op_id;
}
static void
browse_cb (GrlSource *source,
           guint browse_id,
           GrlMedia *media,
           guint remaining,
           gpointer user_data,
           const GError *error)
{
  GHashTable *prop_table;
  GriloMs2Data *grdata = (GriloMs2Data *) user_data;
  gboolean add_media = FALSE;

  if (error) {
    grdata->error = g_error_copy (error);
    grdata->updated = TRUE;
    return;
  }

  if (media) {
    if ((grdata->list_type == LIST_ITEMS && !grl_media_is_container (media)) ||
        (grdata->list_type == LIST_CONTAINERS && grl_media_is_container (media))) {
      if (grdata->offset == 0) {
        add_media = TRUE;
      } else {
        grdata->offset--;
      }
    } else if (grdata->list_type == LIST_ALL) {
      add_media = TRUE;
    }
  }

  if (add_media) {
    if (grdata->parent_id) {
      grl_media_set_grilo_ms2_parent (media,
                                      grdata->parent_id);
    }
    prop_table = ms2_server_new_properties_hashtable ();
    fill_properties_table (grdata->server,
                           prop_table,
                           grdata->keys,
                           media);
    fill_other_properties_table (grdata->server,
                                 source,
                                 prop_table,
                                 grdata->other_keys,
                                 media);
    grdata->children = g_list_prepend (grdata->children, prop_table);
    grl_operation_options_set_count (grdata->options,
                                     grl_operation_options_get_count (grdata->options) -1);
  }

  if (!remaining) {
    grdata->children = g_list_reverse (grdata->children);
    grdata->updated = TRUE;
  } else if (grl_operation_options_get_count (grdata->options) == 0) {
    grl_operation_cancel (grdata->operation_id);
  }
}
static GrlOperationOptions *
make_operation_options (RBGriloSource *source, GrlSupportedOps op, int position)
{
	GrlOperationOptions *options;
	GrlCaps *caps;

	caps = grl_source_get_caps (source->priv->grilo_source, op);

	options = grl_operation_options_new (caps);
	grl_operation_options_set_skip (options, position);
	grl_operation_options_set_count (options,
					 CONTAINER_FETCH_SIZE);
	grl_operation_options_set_type_filter (options, GRL_TYPE_FILTER_AUDIO);
	grl_operation_options_set_flags (options, GRL_RESOLVE_NORMAL);

	return options;
}
示例#5
0
static struct MultipleSearchData *
start_multiple_search_operation (guint search_id,
				 const GList *sources,
				 const gchar *text,
				 const GList *keys,
				 const GList *skip_counts,
				 gint count,
				 GrlOperationOptions *options,
				 GrlSourceResultCb user_callback,
				 gpointer user_data)
{
  GRL_DEBUG ("start_multiple_search_operation");

  struct MultipleSearchData *msd;
  GList *iter_sources, *iter_skips;
  guint n;
  gint first_count, individual_count;

  /* Prepare data required to execute the operation */
  msd = g_new0 (struct MultipleSearchData, 1);
  msd->table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
				      NULL, g_free);
  msd->remaining =
      (count == GRL_COUNT_INFINITY) ? GRL_COUNT_INFINITY : (count - 1);
  msd->search_id = search_id;
  msd->text = g_strdup (text);
  msd->keys = g_list_copy ((GList *) keys);
  msd->options = g_object_ref (options);
  msd->user_callback = user_callback;
  msd->user_data = user_data;

  /* Compute the # of items to request by each source */
  n = g_list_length ((GList *) sources);
  if (count == GRL_COUNT_INFINITY) {
    individual_count = GRL_COUNT_INFINITY;
    first_count = GRL_COUNT_INFINITY;
  } else {
    individual_count = count / n;
    first_count = individual_count + count % n;
  }

  /* Issue search operations on each source */
  iter_sources = (GList *) sources;
  iter_skips = (GList *) skip_counts;
  n = 0;
  while (iter_sources) {
    GrlSource *source;
    guint c, id;
    struct ResultCount *rc;
    guint skip;

    source = GRL_SOURCE (iter_sources->data);

    /* c is the count to use for this source */
    c = (n == 0) ? first_count : individual_count;
    n++;

    /* Only interested in sources with c != 0 */
    if (c != 0) {
      GrlOperationOptions *source_options = NULL;
      GrlCaps *source_caps;

      /* We use ResultCount to keep track of results emitted by this source */
      rc = g_new0 (struct ResultCount, 1);
      rc->count = c;
      g_hash_table_insert (msd->table, source, rc);

      /* Check if we have to apply a "skip" parameter to this source
	 (useful when we are chaining queries to complete the result count) */
      if (iter_skips) {
	skip = GPOINTER_TO_INT (iter_skips->data);
      } else {
	skip = 0;
      }

      source_caps = grl_source_get_caps (source, GRL_OP_SEARCH);
      grl_operation_options_obey_caps (options, source_caps, &source_options, NULL);
      grl_operation_options_set_skip (source_options, skip);
      grl_operation_options_set_count (source_options, rc->count);

      /* Execute the search on this source */
      id = grl_source_search (source,
				    msd->text,
				    msd->keys,
				    source_options,
				    multiple_search_cb,
				    msd);

      GRL_DEBUG ("Operation %s:%u: Searching %u items from offset %u",
                 grl_source_get_name (GRL_SOURCE (source)),
                 id, rc->count, skip);

      g_object_unref (source_options);

      /* Keep track of this operation and this source */
      msd->search_ids = g_list_prepend (msd->search_ids, GINT_TO_POINTER (id));
      msd->sources = g_list_prepend (msd->sources, source);
      msd->sources_count++;
    }

    /* Move to the next source */
    iter_sources = g_list_next (iter_sources);
    iter_skips = g_list_next (iter_skips);
  }
static GList *
search_objects_cb (MS2Server *server,
                   const gchar *id,
                   const gchar *query,
                   guint offset,
                   guint max_count,
                   const gchar **properties,
                   gpointer data,
                   GError **error)
{
  GList *objects;
  GriloMs2Data *grdata;
  gint count;

  /* Browse is only allowed in root container */
  if (g_strcmp0 (id, MS2_ROOT) != 0) {
    if (error) {
      /* FIXME: a better error should be reported */
      *error = g_error_new (0, 0, "search is only allowed in root container");
    }
    return NULL;
  }

  grdata = g_slice_new0 (GriloMs2Data);
  grdata->server = g_object_ref (server);
  grdata->source = (GrlSource *) data;
  grdata->options = grl_operation_options_new (NULL);
  grdata->keys = get_grilo_keys (properties, &grdata->other_keys);
  grdata->parent_id = g_strdup (id);
  grdata->list_type = LIST_ALL;

  grl_operation_options_set_resolution_flags (grdata->options,
                                              GRL_RESOLVE_FULL |
                                              GRL_RESOLVE_IDLE_RELAY);

  /* Adjust limits */
  if (offset >= limit) {
    browse_cb (grdata->source, 0, NULL, 0, grdata, NULL);
  } else {
    count = max_count == 0? (limit - offset): CLAMP (max_count,
                                                     1,
                                                     limit - offset);
    grl_operation_options_set_count (grdata->options, count);
    grl_operation_options_set_skip (grdata->options, offset);
    grl_source_search (grdata->source,
                       query,
                       grdata->keys,
                       grdata->options,
                       browse_cb,
                       grdata);
  }

  wait_for_result (grdata);

  if (grdata->error) {
    if (error) {
      *error = grdata->error;
    }
    g_list_foreach (grdata->children, (GFunc) g_hash_table_unref, NULL);
    g_list_free (grdata->children);
    objects = NULL;
  } else {
    objects = grdata->children;
  }

  g_list_free (grdata->keys);
  g_list_free (grdata->other_keys);
  g_free (grdata->parent_id);
  g_object_unref (grdata->server);
  g_object_unref (grdata->options);
  g_slice_free (GriloMs2Data, grdata);

  return objects;
}
static GList *
list_children_cb (MS2Server *server,
                  const gchar *id,
                  ListType list_type,
                  guint offset,
                  guint max_count,
                  const gchar **properties,
                  gpointer data,
                  GError **error)
{
  GList *children;
  GrlMedia *media;
  GriloMs2Data *grdata;
  gint count;

  grdata = g_slice_new0 (GriloMs2Data);
  grdata->server = g_object_ref (server);
  grdata->source = (GrlSource *) data;
  grdata->options = grl_operation_options_new (NULL);
  grdata->keys = get_grilo_keys (properties, &grdata->other_keys);
  grdata->parent_id = g_strdup (id);
  grdata->offset = offset;
  grdata->list_type = list_type;

  grl_operation_options_set_resolution_flags (grdata->options,
                                              GRL_RESOLVE_FULL |
                                              GRL_RESOLVE_IDLE_RELAY);

  media = unserialize_media (grdata->source, id);

  /* Adjust limits */
  if (offset >= limit) {
    browse_cb (grdata->source, 0, NULL, 0, grdata, NULL);
  } else {
    /* TIP: as Grilo is not able to split containers and items, in this case we
       will ask for all elements and then remove unneeded children in callback */
    switch (list_type) {
    case LIST_ALL:
      count = max_count == 0? (limit - offset): CLAMP (max_count,
                                                       1,
                                                       limit - offset);
      grl_operation_options_set_count (grdata->options, count);
      grl_operation_options_set_skip (grdata->options, offset);
      grdata->operation_id = grl_source_browse (grdata->source,
                                                media,
                                                grdata->keys,
                                                grdata->options,
                                                browse_cb,
                                                grdata);
      break;
    case LIST_CONTAINERS:
    case LIST_ITEMS:
      count = max_count == 0? limit: max_count;
      grl_operation_options_set_count  (grdata->options, count);
      grl_operation_options_set_skip (grdata->options, 0);
      grdata->operation_id = grl_source_browse (grdata->source,
                                                media,
                                                grdata->keys,
                                                grdata->options,
                                                browse_cb,
                                                grdata);
      break;
    default:
      /* Protection. It should never be reached, unless ListType is extended */
      browse_cb (grdata->source, 0, NULL, 0, grdata, NULL);
    }
  }

  wait_for_result (grdata);

  if (grdata->error) {
    if (error) {
      *error = grdata->error;
    }
    g_list_foreach (grdata->children, (GFunc) g_hash_table_unref, NULL);
    g_list_free (grdata->children);
    children = NULL;
  } else {
    children = grdata->children;
  }

  g_object_unref (media);
  g_list_free (grdata->keys);
  g_list_free (grdata->other_keys);
  g_free (grdata->parent_id);
  g_object_unref (grdata->server);
  g_object_unref (grdata->options);
  g_slice_free (GriloMs2Data, grdata);

  return children;
}