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 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; }
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; }