static void test_missing_configuration (void) { GrlMedia *media = NULL; GrlOperationOptions *options = NULL; GError *error = NULL; test_setup_tmdb (); /* Doesn't matter. We just need to get it to resolve */ media = grl_media_video_new (); g_assert (media != NULL); grl_media_set_title (media, "Non-Empty"); GrlSource *source = test_get_source(); g_assert (source); options = grl_operation_options_new (NULL); g_assert (options != NULL); grl_source_resolve_sync (source, media, grl_source_supported_keys (source), options, &error); /* Check that the plugin didn't even try to resolve data, otherwise the mock * file would have resulted in an error */ g_assert (error != NULL); g_clear_object (&media); g_clear_object (&options); g_clear_error (&error); test_shutdown_tmdb (); }
static GrlMedia * create_media (sqlite3_stmt * stmt, GList *keys) { GrlMedia *media; gint media_type; media_type = sqlite3_column_int (stmt, STORE_TYPE_ID); switch (media_type) { case MEDIA_AUDIO: media = grl_media_audio_new (); break; case MEDIA_VIDEO: media = grl_media_video_new (); break; case MEDIA_IMAGE: media = grl_media_image_new (); break; case MEDIA_BOX: media = grl_media_box_new (); break; default: media = grl_media_new (); } grl_media_set_source (media, (const gchar *) sqlite3_column_text (stmt, STORE_SOURCE_ID)); grl_media_set_id (media, (const gchar *) sqlite3_column_text (stmt, STORE_MEDIA_ID)); fill_metadata_from_stmt (media, keys, stmt); return media; }
static GrlMedia * create_media_from_mount (GMount *mount) { char *id; GrlMedia *media; /* Is it an audio CD or a blank media */ if (ignore_mount (mount)) { GRL_DEBUG ("%s: Ignoring mount %s", __FUNCTION__, g_mount_get_name (mount)); g_object_unref (mount); return NULL; } id = create_mount_id (mount); if (id == NULL) { GRL_DEBUG ("%s: Not adding mount %s as has no device path", __FUNCTION__, g_mount_get_name (mount)); return NULL; } media = grl_media_video_new (); grl_media_set_id (media, id); g_free (id); media_set_metadata (mount, media); grl_media_set_mime (media, "x-special/device-block"); GRL_DEBUG ("%s: Adding mount %s (id: %s)", __FUNCTION__, g_mount_get_name (mount), grl_media_get_id (media)); return media; }
static void test_preconditions (void) { GrlMedia *local_media = NULL; GrlMedia *media = NULL; GError *error = NULL; GrlOperationOptions *options = NULL; test_setup_tmdb (); local_media = grl_media_audio_new (); GrlSource *source = test_get_source(); g_assert (source); options = grl_operation_options_new (NULL); g_assert (options != NULL); grl_source_resolve_sync (source, local_media, grl_source_supported_keys (source), options, &error); /* Check that the plugin didn't even try to resolve data, otherwise the mock * file would have resulted in an error */ g_assert_no_error (error); g_object_unref (local_media); local_media = grl_media_image_new (); grl_source_resolve_sync (source, local_media, grl_source_supported_keys (source), options, &error); /* Check that the plugin didn't even try to resolve data, otherwise the * empty mock file would have resulted in an error */ g_assert (error == NULL); g_object_unref (local_media); /* Check the same for title-less video */ media = grl_media_video_new (); g_assert (media != NULL); grl_source_resolve_sync (source, media, grl_source_supported_keys (source), options, &error); g_assert_no_error (error); g_object_unref (media); media = NULL; g_object_unref (options); options = NULL; test_shutdown_tmdb (); }
static GList * add_volume (GList *media_list, GVolume *volume, GDrive *drive, GrlOpticalMediaSource *source) { char *name, *icon_uri; GIcon *icon; char *device_path, *id; GrlMedia * media; GMount *mount; device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); if (device_path == NULL) return media_list; /* Is it an audio CD or a blank media */ mount = g_volume_get_mount (volume); if (mount != NULL) { GFile *root; root = g_mount_get_root (mount); g_object_unref (mount); if (g_file_has_uri_scheme (root, "burn") != FALSE || g_file_has_uri_scheme (root, "cdda") != FALSE) { /* We don't add Audio CDs, or blank media */ g_object_unref (root); g_free (device_path); return media_list; } g_object_unref (root); } media = grl_media_video_new (); id = g_filename_to_uri (device_path, NULL, NULL); g_free (device_path); grl_media_set_id (media, id); g_free (id); /* Work out an icon to display */ icon = g_volume_get_icon (volume); icon_uri = get_uri_for_gicon (icon); g_object_unref (icon); grl_media_set_thumbnail (media, icon_uri); g_free (icon_uri); /* Get the volume's pretty name for the menu label */ name = g_volume_get_name (volume); g_strstrip (name); grl_media_set_title (media, name); g_free (name); grl_media_set_mime (media, "x-special/device-block"); return g_list_prepend (media_list, media); }
/* Builds an appropriate GrlMedia based on ontology type returned by tracker, or NULL if unknown */ GrlMedia * grl_tracker_build_grilo_media (const gchar *rdf_type, GrlTypeFilter type_filter) { GrlMedia *media = NULL; gchar **rdf_single_type; int i; GHashTable *ht; if (!rdf_type) { return NULL; } /* As rdf_type can be formed by several types, split them */ rdf_single_type = g_strsplit (rdf_type, ",", -1); i = g_strv_length (rdf_single_type) - 1; ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (; i>= 0; i--) g_hash_table_insert (ht, g_path_get_basename (rdf_single_type[i]), GINT_TO_POINTER(TRUE)); if (type_filter == GRL_TYPE_FILTER_NONE || type_filter == GRL_TYPE_FILTER_ALL) { media = grl_tracker_build_grilo_media_default (ht); } else if ((type_filter & GRL_TYPE_FILTER_AUDIO) && g_hash_table_lookup (ht, RDF_TYPE_MUSIC)) { media = grl_media_audio_new (); } else if ((type_filter & GRL_TYPE_FILTER_VIDEO) && g_hash_table_lookup (ht, RDF_TYPE_VIDEO)) { media = grl_media_video_new (); } else if ((type_filter & GRL_TYPE_FILTER_IMAGE) && g_hash_table_lookup (ht, RDF_TYPE_IMAGE)) { media = grl_media_image_new (); } else { media = grl_tracker_build_grilo_media_default (ht); } g_hash_table_destroy (ht); g_strfreev (rdf_single_type); if (!media) media = grl_media_new (); return media; }
/* Builds an appropriate GrlMedia based on ontology type returned by tracker, or NULL if unknown */ GrlMedia * grl_tracker_build_grilo_media (const gchar *rdf_type) { GrlMedia *media = NULL; gchar **rdf_single_type; int i; if (!rdf_type) { return NULL; } /* As rdf_type can be formed by several types, split them */ rdf_single_type = g_strsplit (rdf_type, ",", -1); i = g_strv_length (rdf_single_type) - 1; while (!media && i >= 0) { if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_MUSIC)) { media = grl_media_audio_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_VIDEO)) { media = grl_media_video_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_IMAGE)) { media = grl_media_image_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_ARTIST)) { media = grl_media_box_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_ALBUM)) { media = grl_media_box_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_BOX)) { media = grl_media_box_new (); } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_FOLDER)) { media = grl_media_box_new (); } i--; } g_strfreev (rdf_single_type); if (!media) media = grl_media_new (); return media; }
static GrlMedia * grl_tracker_build_grilo_media_default (GHashTable *ht) { if (g_hash_table_lookup (ht, RDF_TYPE_MUSIC)) { return grl_media_audio_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_VIDEO)) { return grl_media_video_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_IMAGE)) { return grl_media_image_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_ARTIST)) { return grl_media_container_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_ALBUM)) { return grl_media_container_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_CONTAINER)) { return grl_media_container_new (); } else if (g_hash_table_lookup (ht, RDF_TYPE_FOLDER)) { return grl_media_container_new (); } return NULL; }
static void add_model (MexBliptvPlugin *self, GrlSource *source) { MexFeed *feed; GrlMedia *box; box = grl_media_video_new (); grl_media_set_id (GRL_MEDIA (box), NULL); feed = mex_grilo_feed_new (source, self->priv->query_keys, self->priv->video_keys, box); g_object_set (feed, "icon-name", "icon-panelheader-computer", "placeholder-text", "No videos found", "category", "videos", NULL); mex_grilo_feed_browse (MEX_GRILO_FEED (feed), 0, 100); g_hash_table_insert (self->priv->video_models, source, feed); mex_model_manager_add_model (self->priv->manager, MEX_MODEL (feed)); }
static void search_cb (GVimeo *vimeo, GList *video_list, gpointer user_data) { GrlMedia *media = NULL; AddMediaUrlData *amud; SearchData *sd = (SearchData *) user_data; gint count = grl_operation_options_get_count (sd->ss->options); gint id; gchar *media_type; gint video_list_size; /* Go to offset element */ video_list = g_list_nth (video_list, sd->offset); /* No more elements can be sent */ if (!video_list) { sd->ss->callback (sd->ss->source, sd->ss->operation_id, NULL, 0, sd->ss->user_data, NULL); g_slice_free (SearchData, sd); return; } video_list_size = g_list_length (video_list); if (count > video_list_size) { count = video_list_size; } if (sd->get_url) { sd->queue = g_queue_new (); } while (video_list && count) { media_type = g_hash_table_lookup (video_list->data, "title"); if (media_type) { media = grl_media_video_new (); } else { media = NULL; } if (media) { update_media (media, video_list->data); if (sd->get_url) { amud = g_slice_new (AddMediaUrlData); amud->computed = FALSE; amud->media = media; amud->index = --count; amud->sd = sd; g_queue_push_head (sd->queue, amud); id = (gint) g_ascii_strtod (grl_media_get_id (media), NULL); g_vimeo_video_get_play_url (sd->vimeo, id, add_url_media_cb, amud); } else { sd->ss->callback (sd->ss->source, sd->ss->operation_id, media, --count, sd->ss->user_data, NULL); } } video_list = g_list_next (video_list); } if (!sd->get_url) { g_slice_free (SearchData, sd); } }
static void proxy_call_browse_grlnet_async_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { RaitvOperation *op = (RaitvOperation *) user_data; xmlDocPtr doc = NULL; xmlXPathContextPtr xpath = NULL; xmlXPathObjectPtr obj = NULL; gint i, nb_items = 0; gsize length; GRL_DEBUG ("Response id=%u", op->operation_id); GError *wc_error = NULL; GError *error = NULL; gchar *content = NULL; if (g_cancellable_is_cancelled (op->cancellable)) { goto finalize; } if (!grl_net_wc_request_finish (GRL_NET_WC (source_object), res, &content, &length, &wc_error)) { error = g_error_new (GRL_CORE_ERROR, GRL_CORE_ERROR_SEARCH_FAILED, _("Failed to browse: %s"), wc_error->message); op->callback (op->source, op->operation_id, NULL, 0, op->user_data, error); g_error_free (wc_error); g_error_free (error); return; } doc = xmlRecoverMemory (content, (gint) length); if (!doc) { GRL_DEBUG ("Doc failed"); goto finalize; } xpath = xmlXPathNewContext (doc); if (!xpath) { GRL_DEBUG ("Xpath failed"); goto finalize; } gchar* xquery=NULL; switch (classify_media_id (op->container_id)) { case RAITV_MEDIA_TYPE_POPULAR_THEME: xquery = "/CLASSIFICAVISTI/content"; break; case RAITV_MEDIA_TYPE_RECENT_THEME: xquery = "/INFORMAZIONICONTENTS/content"; break; default: goto finalize; } obj = xmlXPathEvalExpression ((xmlChar *) xquery, xpath); if (obj) { nb_items = xmlXPathNodeSetGetLength (obj->nodesetval); xmlXPathFreeObject (obj); } if (nb_items < op->count) op->count = nb_items; op->category_info->count = nb_items; for (i = 0; i < nb_items; i++) { //Skip if(op->skip>0) { op->skip--; continue; } GrlRaitvSource *source = GRL_RAITV_SOURCE (op->source); GList *mapping = source->priv->raitv_browse_mappings; GrlMedia *media = grl_media_video_new (); while (mapping) { gchar *str; gchar *strvalue; RaitvAssoc *assoc = (RaitvAssoc *) mapping->data; str = g_strdup_printf ("string(%s[%i]/%s)", xquery,i + 1, assoc->exp); obj = xmlXPathEvalExpression ((xmlChar *) str, xpath); if (obj) { if (obj->stringval && obj->stringval[0] != '\0') { strvalue = g_strdup((gchar *) obj->stringval); //Sometimes GRL_METADATA_KEY_THUMBNAIL doesn't report complete url if(assoc->grl_key == GRL_METADATA_KEY_THUMBNAIL && !g_str_has_prefix(strvalue,"http://www.rai.tv/")) { strvalue = g_strdup_printf("http://www.rai.tv%s",obj->stringval); } GType _type; _type = grl_metadata_key_get_type (assoc->grl_key); switch (_type) { case G_TYPE_STRING: grl_data_set_string (GRL_DATA (media), assoc->grl_key, strvalue); break; case G_TYPE_INT: grl_data_set_int (GRL_DATA (media), assoc->grl_key, (gint) atoi (strvalue)); break; case G_TYPE_FLOAT: grl_data_set_float (GRL_DATA (media), assoc->grl_key, (gfloat) atof (strvalue)); break; default: /* G_TYPE_DATE_TIME is not a constant, so this has to be * in "default:" */ if (_type == G_TYPE_DATE_TIME) { int year,month,day,hour,minute,seconds; sscanf((const char*)obj->stringval, "%02d/%02d/%04d %02d:%02d:%02d", &day, &month, &year, &hour,&minute, &seconds); GDateTime *date = g_date_time_new_local (year, month, day, hour,minute, seconds); grl_data_set_boxed (GRL_DATA (media), assoc->grl_key, date); if(date) g_date_time_unref (date); } else { GRL_DEBUG ("\tUnexpected data type: %s", g_type_name (_type)); } break; } g_free (strvalue); } xmlXPathFreeObject (obj); } g_free (str); mapping = mapping->next; } op->callback (op->source, op->operation_id, media, --op->count, op->user_data, NULL); if (op->count == 0) { break; } } finalize: g_clear_pointer (&xpath, xmlXPathFreeContext); g_clear_pointer (&doc, xmlFreeDoc); /* Signal the last element if it was not already signaled */ if (nb_items == 0) { op->callback (op->source, op->operation_id, NULL, 0, op->user_data, NULL); } else { //Continue the search if(op->count>0) { //Skip the ones already read op->skip += nb_items; op->offset += nb_items; switch (classify_media_id (op->container_id)) { case RAITV_MEDIA_TYPE_POPULAR_THEME: produce_from_popular_theme(op); break; case RAITV_MEDIA_TYPE_RECENT_THEME: produce_from_recent_theme(op); break; default: g_assert_not_reached (); break; } } } }
static void proxy_call_search_grlnet_async_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { RaitvOperation *op = (RaitvOperation *) user_data; xmlDocPtr doc = NULL; xmlXPathContextPtr xpath = NULL; xmlXPathObjectPtr obj = NULL; gint i, nb_items = 0; gsize length; GRL_DEBUG ("Response id=%u", op->operation_id); GError *wc_error = NULL; GError *error = NULL; gchar *content = NULL; gboolean g_bVideoNotFound = TRUE; if (g_cancellable_is_cancelled (op->cancellable)) { goto finalize; } if (!grl_net_wc_request_finish (GRL_NET_WC (source_object), res, &content, &length, &wc_error)) { error = g_error_new (GRL_CORE_ERROR, GRL_CORE_ERROR_SEARCH_FAILED, _("Failed to search: %s"), wc_error->message); op->callback (op->source, op->operation_id, NULL, 0, op->user_data, error); g_error_free (wc_error); g_error_free (error); return; } doc = xmlParseMemory (content, (gint) length); if (!doc) { GRL_DEBUG ("Doc failed"); goto finalize; } xpath = xmlXPathNewContext (doc); if (!xpath) { GRL_DEBUG ("Xpath failed"); goto finalize; } obj = xmlXPathEvalExpression ((xmlChar *) "/GSP/RES/R", xpath); if (obj) { nb_items = xmlXPathNodeSetGetLength (obj->nodesetval); xmlXPathFreeObject (obj); } for (i = 0; i < nb_items; i++) { //Search only videos gchar *str; str = g_strdup_printf ("string(/GSP/RES/R[%i]/MT[@N='videourl']/@V)", i + 1); obj = xmlXPathEvalExpression ((xmlChar *) str, xpath); if (obj->stringval && obj->stringval[0] == '\0') continue; if(op->skip>0) { op->skip--; continue; } GrlRaitvSource *source = GRL_RAITV_SOURCE (op->source); GList *mapping = source->priv->raitv_search_mappings; GrlMedia *media = grl_media_video_new (); g_bVideoNotFound = FALSE; GRL_DEBUG ("Mappings count: %d",g_list_length(mapping)); while (mapping) { RaitvAssoc *assoc = (RaitvAssoc *) mapping->data; str = g_strdup_printf ("string(/GSP/RES/R[%i]/%s)", i + 1, assoc->exp); GRL_DEBUG ("Xquery %s", str); gchar *strvalue; obj = xmlXPathEvalExpression ((xmlChar *) str, xpath); if (obj) { if (obj->stringval && obj->stringval[0] != '\0') { strvalue = g_strdup((gchar *) obj->stringval); //Sometimes GRL_METADATA_KEY_THUMBNAIL doesn't report complete url if(assoc->grl_key == GRL_METADATA_KEY_THUMBNAIL && !g_str_has_prefix(strvalue,"http://www.rai.tv")) { strvalue = g_strdup_printf("http://www.rai.tv%s",obj->stringval); } GType _type; GRL_DEBUG ("\t%s -> %s", str, obj->stringval); _type = grl_metadata_key_get_type (assoc->grl_key); switch (_type) { case G_TYPE_STRING: grl_data_set_string (GRL_DATA (media), assoc->grl_key, strvalue); break; case G_TYPE_INT: grl_data_set_int (GRL_DATA (media), assoc->grl_key, (gint) atoi (strvalue)); break; case G_TYPE_FLOAT: grl_data_set_float (GRL_DATA (media), assoc->grl_key, (gfloat) atof (strvalue)); break; default: /* G_TYPE_DATE_TIME is not a constant, so this has to be * in "default:" */ if (_type == G_TYPE_DATE_TIME) { int year,month,day; sscanf((const char*)obj->stringval, "%02d/%02d/%04d", &day, &month, &year); GDateTime *date = g_date_time_new_local (year, month, day, 0, 0, 0); GRL_DEBUG ("Setting %s to %s", grl_metadata_key_get_name (assoc->grl_key), g_date_time_format (date, "%F %H:%M:%S")); grl_data_set_boxed (GRL_DATA (media), assoc->grl_key, date); if(date) g_date_time_unref (date); } else { GRL_DEBUG ("\tUnexpected data type: %s", g_type_name (_type)); } break; } g_free (strvalue); } xmlXPathFreeObject (obj); } g_free (str); mapping = mapping->next; } op->callback (op->source, op->operation_id, media, --op->count, op->user_data, NULL); if (op->count == 0) break; } finalize: g_clear_pointer (&xpath, xmlXPathFreeContext); g_clear_pointer (&doc, xmlFreeDoc); /* Signal the last element if it was not already signaled */ if (nb_items == 0 || g_bVideoNotFound) { op->callback (op->source, op->operation_id, NULL, 0, op->user_data, NULL); } else { //Continue the search if(op->count>0) { op->offset += nb_items; g_raitv_videos_search(op); } } }
static void call_raw_async_cb (GObject * source_object, GAsyncResult *res, gpointer data) { BliptvOperation *op = (BliptvOperation *) data; xmlDocPtr doc = NULL; xmlXPathContextPtr xpath = NULL; xmlXPathObjectPtr obj = NULL; gint i, nb_items = 0; gchar *content = NULL; gchar *url; gsize length; GRL_DEBUG ("Response id=%u", op->operation_id); if (g_cancellable_is_cancelled (op->cancellable)) { goto finalize_send_last; } if (!grl_net_wc_request_finish (GRL_NET_WC (source_object), res, &content, &length, NULL)) { goto finalize_send_last; } doc = xmlParseMemory (content, (gint) length); if (!doc) goto finalize_send_last; xpath = xmlXPathNewContext (doc); if (!xpath) goto finalize_send_last; xmlXPathRegisterNs (xpath, (xmlChar *) "blip", (xmlChar *) BLIPTV_BACKEND "/dtd/blip/1.0"); xmlXPathRegisterNs (xpath, (xmlChar *) "media", (xmlChar *) "http://search.yahoo.com/mrss/"); obj = xmlXPathEvalExpression ((xmlChar *) "/rss/channel/item", xpath); if (obj) { nb_items = xmlXPathNodeSetGetLength (obj->nodesetval); xmlXPathFreeObject (obj); } if (nb_items == 0) { goto finalize_send_last; } /* Special case: when there are no results in a search, Blip.tv returns an element telling precisely that, no results found; so we need to report no results too */ if (nb_items == 1) { obj = xmlXPathEvalExpression ((xmlChar *) "string(/rss/channel/item[0]/blip:item_id)", xpath); if (!obj || !obj->stringval || obj->stringval[0] == '\0') { g_clear_pointer (&obj, (GDestroyNotify) xmlXPathFreeObject); nb_items = 0; goto finalize_send_last; } else { xmlXPathFreeObject (obj); } } for (i = op->skip; i < nb_items; i++) { GList *mapping = bliptv_mappings; GrlMedia *media = grl_media_video_new (); while (mapping) { BliptvAssoc *assoc = (BliptvAssoc *) mapping->data; gchar *str; str = g_strdup_printf ("string(/rss/channel/item[%i]/%s)", i + 1, assoc->exp); obj = xmlXPathEvalExpression ((xmlChar *) str, xpath); if (obj) { if (obj->stringval && obj->stringval[0] != '\0') { GType _type; GRL_DEBUG ("\t%s -> %s", str, obj->stringval); _type = grl_metadata_key_get_type (assoc->grl_key); switch (_type) { case G_TYPE_STRING: grl_data_set_string (GRL_DATA (media), assoc->grl_key, (gchar *) obj->stringval); break; case G_TYPE_INT: grl_data_set_int (GRL_DATA (media), assoc->grl_key, (gint) atoi ((gchar *) obj->stringval)); break; case G_TYPE_FLOAT: grl_data_set_float (GRL_DATA (media), assoc->grl_key, (gfloat) atof ((gchar *) obj->stringval)); break; default: /* G_TYPE_DATE_TIME is not a constant, so this has to be * in "default:" */ if (_type == G_TYPE_DATE_TIME) { GDateTime *date = grl_date_time_from_iso8601 ((gchar *) obj->stringval); GRL_DEBUG ("Setting %s to %s", grl_metadata_key_get_name (assoc->grl_key), g_date_time_format (date, "%F %H:%M:%S")); grl_data_set_boxed (GRL_DATA (media), assoc->grl_key, date); g_date_time_unref (date); } else { GRL_DEBUG ("\tUnexpected data type: %s", g_type_name (_type)); } break; } } xmlXPathFreeObject (obj); } g_free (str); mapping = mapping->next; } op->callback (op->source, op->operation_id, media, --op->count, op->user_data, NULL); if (op->count == 0) break; } if (op->count > 0) { /* Request next page */ op->skip = 0; url = g_strdup_printf (op->url, ++op->page); GRL_DEBUG ("Operation %d: requesting page %d", op->operation_id, op->page); grl_net_wc_request_async (GRL_BLIPTV_SOURCE (op->source)->priv->wc, url, op->cancellable, call_raw_async_cb, op); g_free (url); goto finalize_free; } finalize_send_last: /* Signal the last element if it was not already signaled */ if (nb_items == 0) { op->callback (op->source, op->operation_id, NULL, 0, op->user_data, NULL); } finalize_free: g_clear_pointer (&xpath, (GDestroyNotify) xmlXPathFreeContext); g_clear_pointer (&doc, (GDestroyNotify) xmlFreeDoc); }
int main (int argc, char *argv[]) { #if !GLIB_CHECK_VERSION(2,35,0) g_type_init (); #endif grl_init (&argc, &argv); /* * Set the TMDB API key: * You must use your own TMDB API key in your own application. */ GrlRegistry *reg = grl_registry_get_default (); GrlConfig *config = grl_config_new (TMDB_PLUGIN_ID, NULL); grl_config_set_api_key (config, TMDB_KEY); grl_registry_add_config (reg, config, NULL); /* * Get the plugin: */ GError *error = NULL; gboolean plugin_loaded = grl_registry_load_plugin_by_id (reg, TMDB_PLUGIN_ID, &error); g_assert (plugin_loaded); g_assert_no_error (error); /* * Get the Grilo source: */ GrlSource *src = grl_registry_lookup_source (reg, TMDB_PLUGIN_ID); /* * Check that it has the expected capability: */ g_assert (grl_source_supported_operations (src) & GRL_OP_RESOLVE); GrlCaps *caps = grl_source_get_caps (src, GRL_OP_RESOLVE); g_assert (caps); GrlOperationOptions *options = grl_operation_options_new (caps); /* * A media item that we will give to the TMDB plugin, * to discover its details. */ GrlMedia *media = grl_media_video_new (); grl_media_set_title (media, "Sherlock Holmes"); /* * Discover what keys are provided by the source: */ const GList *keys = grl_source_supported_keys (src); const GList* l = NULL; for (l = keys; l != NULL; l = l->next) { GrlKeyID id = GPOINTER_TO_INT (l->data); g_assert (id); const gchar *name = grl_metadata_key_get_name (id); printf ("Supported key: %s\n", name); /* * Remember this for later use: * You may instead use grl_registry_lookup_metadata_key_name(). */ if (g_strcmp0 (name, "tmdb-director") == 0) { director_key = id; } } /* * Ask the TMDB plugin for the media item's details, * from the TMDB online service: */ grl_source_resolve (src, media, keys, options, resolve_cb, NULL); /* * Start the main loop so our callback can be called: */ loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); /* * Release objects: */ g_object_unref (media); g_object_unref (config); g_object_unref (options); /* * Deinitialize Grilo: */ grl_deinit (); }
static void add_model (MexTrackerPlugin *self, GrlMediaPlugin *plugin, MexTrackerCategory category) { GList *metadata_keys, *query_keys; MexFeed *feed, *dir_feed; GrlMedia *box; gchar *query, *cat_name; GHashTable *models; const gchar *source_name = grl_metadata_source_get_name (GRL_METADATA_SOURCE (plugin)); gint priority; switch (category) { case MEX_TRACKER_CATEGORY_IMAGE: cat_name = "pictures"; query = "?urn a nfo:FileDataObject . " "?urn tracker:available true . " "FILTER (fn:starts-with(nie:mimeType(?urn),'image/'))"; models = self->priv->image_models; metadata_keys = self->priv->image_keys; query_keys = self->priv->query_image_keys; box = grl_media_image_new (); break; case MEX_TRACKER_CATEGORY_VIDEO: cat_name = "videos"; query = "?urn a nfo:FileDataObject . " "?urn tracker:available true . " "FILTER (fn:starts-with(nie:mimeType(?urn),'video/'))"; models = self->priv->video_models; metadata_keys = self->priv->video_keys; query_keys = self->priv->query_video_keys; box = grl_media_video_new (); break; case MEX_TRACKER_CATEGORY_MUSIC: cat_name = "music"; query = "?urn a nfo:FileDataObject . " "?urn tracker:available true . " "FILTER (fn:starts-with(nie:mimeType(?urn),'audio/'))"; models = self->priv->music_models; metadata_keys = self->priv->music_keys; query_keys = self->priv->query_music_keys; box = grl_media_audio_new (); break; } grl_media_set_id (GRL_MEDIA (box), NULL); feed = mex_grilo_tracker_feed_new (GRL_MEDIA_SOURCE (plugin), query_keys, metadata_keys, NULL, box); mex_model_set_sort_func (MEX_MODEL (feed), mex_model_sort_time_cb, GINT_TO_POINTER (TRUE)); mex_grilo_feed_query (MEX_GRILO_FEED (feed), query, 0, MAX_TRACKER_RESULTS); g_hash_table_insert (models, plugin, feed); /* set the local files source to appear first */ if (!g_strcmp0 (source_name, "Local files")) priority = -100; else priority = 0; dir_feed = mex_grilo_tracker_feed_new (GRL_MEDIA_SOURCE (plugin), query_keys, metadata_keys, query, NULL); mex_model_set_sort_func (MEX_MODEL (dir_feed), mex_model_sort_alpha_cb, GINT_TO_POINTER (FALSE)); mex_grilo_feed_browse (MEX_GRILO_FEED (dir_feed), 0, G_MAXINT); g_object_set (G_OBJECT (feed), "category", cat_name, "priority", priority, "alt-model", dir_feed, "alt-model-string", _("Show Folders"), NULL); mex_model_manager_add_model (self->priv->manager, MEX_MODEL (feed)); }