static GrlMedia * build_media(gint track_id, const gchar *artist_name, const gchar *album_name, const gchar *track_name, gint track_number, gint duration, const gchar *url_to_mp3) { GrlMedia *media = NULL; GrlMediaAudio *audio = NULL; gchar *str_track_id = NULL; media = grl_media_audio_new(); audio = GRL_MEDIA_AUDIO(media); grl_media_audio_set_track_number(audio, track_number); grl_media_audio_set_artist(audio, artist_name); grl_media_audio_set_album(audio, album_name); grl_media_set_url(media, url_to_mp3); grl_media_set_duration(media, duration); grl_media_set_title(media, track_name); str_track_id = g_strdup_printf("%d", track_id); grl_media_set_id(media, str_track_id); g_free(str_track_id); return media; }
static gchar * get_lyrics (GrlSource *source, const gchar *artist, const gchar *title) { GList *keys; GrlMedia *audio; GrlOperationOptions *options; GError *error = NULL; gchar *lyrics; audio = grl_media_audio_new (); grl_media_set_artist (audio, artist); grl_media_set_title (audio, title); keys = grl_metadata_key_list_new (GRL_METADATA_KEY_LYRICS, NULL); options = grl_operation_options_new (NULL); grl_operation_options_set_resolution_flags (options, GRL_RESOLVE_NORMAL); grl_source_resolve_sync (source, GRL_MEDIA (audio), keys, options, &error); g_assert_no_error (error); lyrics = g_strdup (grl_media_get_lyrics (audio)); g_list_free (keys); g_object_unref (options); g_object_unref (audio); return lyrics; }
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 * build_media(gint track_id, const gchar *artist_name, const gchar *album_name, const gchar *track_name, gint track_number, gint duration, const gchar *url_to_mp3, GPtrArray *url_to_covers) { GrlMedia *media = NULL; gchar *str_track_id = NULL; media = grl_media_audio_new(); grl_media_set_track_number(media, track_number); grl_media_set_artist(media, artist_name); grl_media_set_album(media, album_name); grl_media_set_url(media, url_to_mp3); grl_media_set_duration(media, duration); grl_media_set_title(media, track_name); g_ptr_array_foreach(url_to_covers, add_cover, media); str_track_id = g_strdup_printf("%d", track_id); grl_media_set_id(media, str_track_id); g_free(str_track_id); return media; }
static void magnatune_browse_root(OperationSpec *os) { GrlMedia *media = NULL; guint num = 0; gchar *id = NULL; GRL_DEBUG("magnatune_browse_root"); if (os->skip > 1 || os->count == 0) { os->callback(os->source, os->operation_id, NULL, 0, os->user_data, NULL); return; } num = (os->count > MAGNATUNE_NUM_CAT) ? MAGNATUNE_NUM_CAT: os->count; media = grl_media_box_new(); grl_media_set_title(media, MAGNATUNE_ROOT_ARTIST); id = g_strdup_printf("root-%d", MAGNATUNE_ARTIST_CAT); grl_media_set_id(media, id); num--; os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); g_free(id); if (num == 0) return; media = grl_media_box_new(); grl_media_set_title(media, MAGNATUNE_ROOT_ALBUM); id = g_strdup_printf("root-%d", MAGNATUNE_ALBUM_CAT); grl_media_set_id(media, id); num--; os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); g_free(id); if (num == 0) return; media = grl_media_box_new(); grl_media_set_title(media, MAGNATUNE_ROOT_GENRE); id = g_strdup_printf("root-%d", MAGNATUNE_GENRE_CAT); grl_media_set_id(media, id); num--; os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); g_free(id); }
static GrlMedia * produce_container_from_directory (GrlMedia *media, CategoryInfo *dir, guint index, RaitvMediaType type) { GrlMedia *content; gchar* mediaid=NULL; if (!media) { content = grl_media_box_new (); } else { content = media; } if (!dir) { grl_media_set_id (content, NULL); grl_media_set_title (content, RAITV_ROOT_NAME); } else { switch(type) { case RAITV_MEDIA_TYPE_ROOT : case RAITV_MEDIA_TYPE_POPULARS : case RAITV_MEDIA_TYPE_RECENTS : mediaid = g_strdup_printf("%s",dir[index].id); break; case RAITV_MEDIA_TYPE_POPULAR_THEME : mediaid = g_strdup_printf("%s/%s", RAITV_POPULARS_THEME_ID, dir[index].id); break; case RAITV_MEDIA_TYPE_RECENT_THEME : mediaid = g_strdup_printf("%s/%s", RAITV_RECENTS_THEME_ID, dir[index].id); break; default: break; } GRL_DEBUG ("MediaId=%s, Type:%d, Titolo:%s",mediaid, type, dir[index].name); grl_media_set_id (content, mediaid); grl_media_set_title (content, g_dgettext (GETTEXT_PACKAGE, dir[index].name)); g_free(mediaid); } return content; }
static GrlMedia * create_media_box (GrlDvbDaemonExporter *self) { GrlMedia * box = GRL_MEDIA (grl_media_box_new ()); grl_media_set_id (box, self->priv->channel_list_path); grl_media_set_title (box, self->priv->name); return box; }
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); }
static void set_title (TrackerSparqlCursor *cursor, gint column, GrlMedia *media, GrlKeyID key) { const gchar *str = tracker_sparql_cursor_get_string (cursor, column, NULL); grl_data_set_boolean (GRL_DATA (media), GRL_METADATA_KEY_TITLE_FROM_FILENAME, FALSE); grl_media_set_title (media, str); }
static void bookmark_resolve (GrlSourceResolveSpec *rs) { GomRepository *repository; GValue value = { 0, }; GomFilter *filter; GomResource *resource; GError *error = NULL; gint64 id; GrlTypeFilter type_filter; GRL_DEBUG (__FUNCTION__); repository = GRL_BOOKMARKS_SOURCE (rs->source)->priv->repository; id = g_ascii_strtoll (grl_media_get_id (rs->media), NULL, 0); if (!id) { /* Root category: special case */ grl_media_set_title (rs->media, GRL_ROOT_TITLE); rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); return; } g_value_init (&value, G_TYPE_INT64); g_value_set_int64 (&value, id); filter = gom_filter_new_eq (BOOKMARKS_TYPE_RESOURCE, "id", &value); g_value_unset (&value); resource = gom_repository_find_one_sync (repository, BOOKMARKS_TYPE_RESOURCE, filter, &error); g_object_unref (filter); if (!resource) { GRL_WARNING ("Failed to get bookmark: %s", error->message); g_error_free (error); error = g_error_new_literal (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED, _("Failed to get bookmark metadata")); rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error); g_error_free (error); return; } type_filter = grl_operation_options_get_type_filter (rs->options); build_media_from_resource (rs->media, resource, type_filter); g_object_unref (resource); rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); }
static GrlMedia* build_media_id_name_from_stmt(sqlite3_stmt *sql_stmt) { GrlMedia *media = NULL; guint media_id = 0; gchar *id = NULL; const gchar *media_name = NULL; media = grl_media_box_new(); media_id = (guint) sqlite3_column_int(sql_stmt, 0); media_name = (gchar *) sqlite3_column_text(sql_stmt, 1); id = g_strdup_printf("%d", media_id); grl_media_set_id(media, id); grl_media_set_title(media, media_name); g_free(id); return media; }
static void media_set_metadata (GMount *mount, GrlMedia *media) { char *name, *icon_uri; GIcon *icon; /* Work out an icon to display */ icon = g_mount_get_icon (mount); icon_uri = get_uri_for_gicon (icon); g_object_unref (icon); grl_media_set_thumbnail (media, icon_uri); g_free (icon_uri); /* Get the mount's pretty name for the menu label */ name = g_mount_get_name (mount); g_strstrip (name); grl_media_set_title (media, name); g_free (name); }
static void resolve_cb (GrlSource *source, guint operation_id, GrlMedia *media, gpointer user_data, const GError *error) { GriloMs2Data *grdata = (GriloMs2Data *) user_data; if (error) { grdata->error = g_error_copy (error); grdata->updated = TRUE; return; } /* Special case: for root media, if there is no title use the source's name */ if (grl_media_get_id (media) == NULL && !grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_TITLE)) { grl_media_set_title (media, grl_source_get_name (source)); } grdata->properties = ms2_server_new_properties_hashtable (); fill_properties_table (grdata->server, grdata->properties, grdata->keys, media); fill_other_properties_table (grdata->server, source, grdata->properties, grdata->other_keys, media); grdata->updated = TRUE; }
static void update_media (GrlMedia *media, GHashTable *video) { gchar *str; str = g_hash_table_lookup (video, VIMEO_VIDEO_ID); if (str) { char *external_url; grl_media_set_id (media, str); external_url = g_strdup_printf ("https://vimeo.com/%s", str); grl_media_set_external_url (media, external_url); g_free (external_url); } str = g_hash_table_lookup (video, VIMEO_VIDEO_TITLE); if (str) { grl_media_set_title (media, str); } str = g_hash_table_lookup (video, VIMEO_VIDEO_DESCRIPTION); if (str) { grl_media_set_description (media, str); } str = g_hash_table_lookup (video, VIMEO_VIDEO_DURATION); if (str) { grl_media_set_duration (media, str_to_gint (str)); } str = g_hash_table_lookup (video, VIMEO_VIDEO_OWNER_NAME); if (str) { grl_media_set_author (media, str); } str = g_hash_table_lookup (video, VIMEO_VIDEO_UPLOAD_DATE); if (str) { GDateTime *date = parse_date (str); if (date) { grl_media_set_publication_date (media, date); g_date_time_unref (date); } } str = g_hash_table_lookup (video, VIMEO_VIDEO_THUMBNAIL); if (str) { grl_media_set_thumbnail (media, str); } str = g_hash_table_lookup (video, VIMEO_VIDEO_WIDTH); if (str) { grl_media_set_width (media, str_to_gint (str)); } str = g_hash_table_lookup (video, VIMEO_VIDEO_HEIGHT); if (str) { grl_media_set_height (media, str_to_gint (str)); } }
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 proxy_call_resolve_grlnet_async_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { RaitvOperation *op = (RaitvOperation *) user_data; xmlDocPtr doc = NULL; xmlXPathContextPtr xpath = NULL; GError *wc_error = NULL; GError *error = NULL; gchar *content = NULL; gsize length; gchar *value; gchar *thumbnail; gchar **tokens; GDateTime *date; GRL_DEBUG ("Response id=%u", op->operation_id); 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 resolve: %s"), wc_error->message); op->resolveCb (op->source, op->operation_id, op->media, 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; } if (!grl_data_has_key (GRL_DATA (op->media), GRL_METADATA_KEY_URL)) { value = eval_xquery ("/html/head/meta[@name='videourl']", xpath); if (value) { grl_media_set_url (op->media, value); g_free (value); } } if (!grl_data_has_key (GRL_DATA (op->media), GRL_METADATA_KEY_TITLE)) { value = eval_xquery ("/html/head/meta[@name='title']", xpath); if (value) { grl_media_set_title (op->media, value); g_free (value); } } if (!grl_data_has_key (GRL_DATA (op->media), GRL_METADATA_KEY_PUBLICATION_DATE)) { value = eval_xquery ("/html/head/meta[@name='itemDate']", xpath); if (value) { tokens = g_strsplit (value, "/", -1); if (g_strv_length (tokens) >= 3) { date = g_date_time_new_local (atoi (tokens[2]), atoi (tokens[1]), atoi (tokens[0]), 0, 0, 0); grl_media_set_publication_date (op->media, date); g_date_time_unref (date); } g_strfreev (tokens); g_free (value); } } if (!grl_data_has_key (GRL_DATA (op->media), GRL_METADATA_KEY_THUMBNAIL)) { value = eval_xquery ("/html/head/meta[@name='vod-image']", xpath); if (value) { /* Sometimes thumbnail doesn't report a complete url */ if (value[0] == '/') { thumbnail = g_strconcat ("http://www.rai.tv", value, NULL); g_free (value); } else { thumbnail = value; } grl_media_set_thumbnail (op->media, thumbnail); g_free (thumbnail); } } finalize: op->resolveCb (op->source, op->operation_id, op->media, op->user_data, NULL); g_clear_pointer (&xpath, xmlXPathFreeContext); g_clear_pointer (&doc, xmlFreeDoc); }
static GrlMedia * build_media_from_resource (GrlMedia *content, GomResource *resource, GrlTypeFilter type_filter) { GrlMedia *media = NULL; gint64 id; gchar *str_id; gchar *title; gchar *url; gchar *desc; gchar *date; gchar *mime; gchar *thumb; guint type; if (content) { media = content; } g_object_get (resource, "id", &id, "title", &title, "url", &url, "desc", &desc, "date", &date, "mime", &mime, "type", &type, "thumbnail-url", &thumb, NULL); if (!media) { if (type == BOOKMARK_TYPE_CATEGORY) { media = GRL_MEDIA (grl_media_box_new ()); } else if (mime_is_audio (mime)) { if (type_filter & GRL_TYPE_FILTER_AUDIO) media = GRL_MEDIA (grl_media_new ()); } else if (mime_is_video (mime)) { if (type_filter & GRL_TYPE_FILTER_VIDEO) media = GRL_MEDIA (grl_media_new ()); } else if (mime_is_image (mime)) { if (type_filter & GRL_TYPE_FILTER_IMAGE) media = GRL_MEDIA (grl_media_image_new ()); } else { if (type_filter != GRL_TYPE_FILTER_NONE) media = GRL_MEDIA (grl_media_new ()); } } if (!media) return NULL; str_id = g_strdup_printf ("%" G_GINT64_FORMAT, id); grl_media_set_id (media, str_id); g_free (str_id); grl_media_set_title (media, title); if (url) { grl_media_set_url (media, url); } if (desc) { grl_media_set_description (media, desc); } if (date) { GDateTime *date_time = grl_date_time_from_iso8601 (date); if (date_time) { grl_data_set_boxed (GRL_DATA (media), GRL_BOOKMARKS_KEY_BOOKMARK_TIME, date_time); g_date_time_unref (date_time); } } if (thumb) { grl_media_set_thumbnail (media, thumb); } g_free (title); g_free (url); g_free (desc); g_free (date); g_free (mime); g_free (thumb); return media; }
static void on_search_ready (GObject *source, GAsyncResult *result, gpointer user_data) { ResolveClosure *closure = (ResolveClosure *) user_data; GrlTmdbRequest *request = GRL_TMDB_REQUEST (source); GValue *value; GError *error = NULL; GRL_DEBUG ("Initial search ready..."); if (!grl_tmdb_request_run_finish (GRL_TMDB_REQUEST (source), result, &error)) { resolve_closure_callback (closure, error); resolve_closure_free (closure); g_error_free (error); return; } value = grl_tmdb_request_get (request, "$.total_results"); if (g_value_get_int64 (value) == 0) { /* Nothing found */ resolve_closure_callback (closure, NULL); resolve_closure_free (closure); g_value_unset (value); g_free (value); return; } g_value_unset (value); g_free (value); value = grl_tmdb_request_get (request, "$.results[0].id"); if (value == NULL) { /* Cannot continue without id */ error = g_error_new_literal (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED, _("Remote data does not contain valid identifier")); resolve_closure_callback (closure, error); resolve_closure_free (closure); g_error_free (error); return; } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_TMDB_ID)) { char *tmdb_id = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (value)); grl_data_set_string (GRL_DATA (closure->rs->media), GRL_TMDB_METADATA_KEY_TMDB_ID, tmdb_id); g_free (tmdb_id); } closure->id = g_value_get_int64 (value); g_value_unset (value); g_free (value); if (grl_data_get_boolean (GRL_DATA (closure->rs->media), GRL_METADATA_KEY_TITLE_FROM_FILENAME)) { value = grl_tmdb_request_get (request, "$.results[0].title"); if (value) { grl_media_set_title (closure->rs->media, g_value_get_string (value)); grl_data_set_boolean (GRL_DATA (closure->rs->media), GRL_METADATA_KEY_TITLE_FROM_FILENAME, FALSE); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_RATING)) { value = grl_tmdb_request_get (request, "$.results[0].vote_average"); if (value != NULL) { grl_media_set_rating (closure->rs->media, (float) g_value_get_double (value), 10.0f); g_value_unset (value); g_free (value); } g_hash_table_remove (closure->keys, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_RATING)); } /* Add thumbnails first, and posters and backdrops later. * Posters more likely make a good thumbnail than backdrops. */ if (SHOULD_RESOLVE (GRL_METADATA_KEY_THUMBNAIL)) { value = grl_tmdb_request_get (request, "$.results[0].poster_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_METADATA_KEY_THUMBNAIL, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_POSTER)) { value = grl_tmdb_request_get (request, "$.results[0].poster_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_POSTER, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_BACKDROP)) { value = grl_tmdb_request_get (request, "$.results[0].backdrop_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_BACKDROP, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_ORIGINAL_TITLE)) { value = grl_tmdb_request_get (request, "$.results[0].original_title"); if (value != NULL) { grl_media_set_original_title (closure->rs->media, g_value_get_string (value)); g_value_unset (value); g_free (value); } g_hash_table_remove (closure->keys, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ORIGINAL_TITLE)); } remove_request (closure, request); /* Check if we need to do additional requests. */ if (closure->slow) { resolve_slow_details (closure); if (run_pending_requests (closure, G_MAXINT) > 0) return; } resolve_closure_callback (closure, NULL); resolve_closure_free (closure); }
static void on_request_ready (GObject *source, GAsyncResult *result, gpointer user_data) { ResolveClosure *closure = (ResolveClosure *) user_data; GrlTmdbRequest *request = GRL_TMDB_REQUEST (source); const GrlTmdbRequestDetail detail = grl_tmdb_request_get_detail (request); GError *error = NULL; GList *values, *iter; GValue *value; if (detail != GRL_TMDB_REQUEST_DETAIL_COUNT) { GRL_DEBUG ("Detail request (%s) ready for movie #%" G_GUINT64_FORMAT "...", grl_tmdb_request_detail_to_string (detail), closure->id); } else { GRL_DEBUG ("Detail request (aggregated) ready for movie #%" G_GUINT64_FORMAT "...", closure->id); } if (!grl_tmdb_request_run_finish (GRL_TMDB_REQUEST (source), result, &error)) { /* Just remove the request and hope the others have some data */ GRL_WARNING ("Failed to get %s: %s", grl_tmdb_request_get_uri (request), error->message); goto out; } if (SHOULD_RESOLVE (GRL_METADATA_KEY_GENRE)) { iter = values = grl_tmdb_request_get_string_list (request, "$.genres..name"); while (iter != NULL) { grl_data_add_string (GRL_DATA (closure->rs->media), GRL_METADATA_KEY_GENRE, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_STUDIO)) { iter = values = grl_tmdb_request_get_string_list (request, "$.production_companies..name"); while (iter != NULL) { grl_data_add_string (GRL_DATA (closure->rs->media), GRL_METADATA_KEY_STUDIO, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_SITE)) { value = grl_tmdb_request_get (request, "$.homepage"); if (value != NULL) { grl_media_set_site (closure->rs->media, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_DESCRIPTION)) { value = grl_tmdb_request_get (request, "$.overview"); if (value != NULL) { grl_media_set_description (closure->rs->media, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_IMDB_ID)) { value = grl_tmdb_request_get (request, "$.imdb_id"); if (value != NULL) { grl_data_set_string (GRL_DATA (closure->rs->media), GRL_TMDB_METADATA_KEY_IMDB_ID, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_RATING)) { value = grl_tmdb_request_get (request, "$.vote_average"); if (value != NULL) { grl_media_set_rating (closure->rs->media, (float) g_value_get_double (value), 10.0f); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_ORIGINAL_TITLE)) { value = grl_tmdb_request_get (request, "$.original_title"); if (value != NULL) { grl_media_set_original_title (closure->rs->media, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_METADATA_KEY_TITLE)) { value = grl_tmdb_request_get (request, "$.title"); if (value != NULL) { grl_media_set_title (closure->rs->media, g_value_get_string (value)); grl_data_set_boolean (GRL_DATA (closure->rs->media), GRL_METADATA_KEY_TITLE_FROM_FILENAME, FALSE); g_value_unset (value); g_free (value); } } if (!closure->slow) { /* Add thumbnails first and poster and backdrops later. * Posters more likely make a good thumbnail than backdrops. */ if (SHOULD_RESOLVE (GRL_METADATA_KEY_THUMBNAIL)) { value = grl_tmdb_request_get (request, "$.poster_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_METADATA_KEY_THUMBNAIL, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_POSTER)) { value = grl_tmdb_request_get (request, "$.poster_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_POSTER, g_value_get_string (value)); g_value_unset (value); g_free (value); } } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_BACKDROP)) { value = grl_tmdb_request_get (request, "$.backdrop_path"); if (value != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_BACKDROP, g_value_get_string (value)); g_value_unset (value); g_free (value); } } } /* Add thumbnails first, and posters and backdrops later. * Posters more likely make a good thumbnail than backdrops. */ if (SHOULD_RESOLVE (GRL_METADATA_KEY_THUMBNAIL)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.posters", neutral_backdrop_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.images.posters", neutral_backdrop_filter); iter = values; while (iter != NULL) { add_image (closure->self, closure->rs->media, GRL_METADATA_KEY_THUMBNAIL, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_POSTER)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.posters", neutral_backdrop_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.images.posters", neutral_backdrop_filter); iter = values; while (iter != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_POSTER, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_TMDB_METADATA_KEY_BACKDROP)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.backdrops", neutral_backdrop_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.images.backdrops", neutral_backdrop_filter); iter = values; while (iter != NULL) { add_image (closure->self, closure->rs->media, GRL_TMDB_METADATA_KEY_BACKDROP, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_KEYWORD)) { values = grl_tmdb_request_get_string_list (request, "$.keywords..name"); if (!values) values = grl_tmdb_request_get_string_list (request, "$.keywords.keywords..name"); iter = values; while (iter != NULL) { grl_media_add_keyword (closure->rs->media, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_PERFORMER)) { values = grl_tmdb_request_get_string_list (request, "$.cast..name"); if (!values) values = grl_tmdb_request_get_string_list (request, "$.casts.cast..name"); iter = values; while (iter != NULL) { grl_media_add_performer (closure->rs->media, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_PRODUCER)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.crew[*]", producer_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.casts.crew[*]", producer_filter); iter = values; while (iter != NULL) { grl_media_add_producer (closure->rs->media, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_DIRECTOR)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.crew[*]", director_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.casts.crew[*]", director_filter); iter = values; while (iter != NULL) { grl_media_add_director (closure->rs->media, iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_AUTHOR)) { values = grl_tmdb_request_get_string_list_with_filter (request, "$.crew[*]", writer_filter); if (!values) values = grl_tmdb_request_get_string_list_with_filter (request, "$.casts.crew[*]", writer_filter); iter = values; while (iter != NULL) { grl_media_add_author (GRL_MEDIA (closure->rs->media), iter->data); iter = iter->next; } g_list_free_full (values, g_free); } if (SHOULD_RESOLVE (GRL_METADATA_KEY_REGION) || SHOULD_RESOLVE (GRL_METADATA_KEY_CERTIFICATE) || SHOULD_RESOLVE (GRL_METADATA_KEY_PUBLICATION_DATE)) { values = grl_tmdb_request_get_list_with_filter (request, "$.countries[*]", NULL); if (!values) values = grl_tmdb_request_get_list_with_filter (request, "$.releases.countries[*]", NULL); for (iter = values; iter != NULL; iter = iter->next) { const char *region, *cert, *date; GDateTime *pubdate; JsonObject *object; object = json_node_get_object (iter->data); region = json_object_get_string_member (object, "iso_3166_1"); cert = json_object_get_string_member (object, "certification"); date = json_object_get_string_member (object, "release_date"); pubdate = parse_date (date); grl_media_add_region_data (closure->rs->media, region, pubdate, cert); g_date_time_unref (pubdate); } g_list_free_full (values, (GDestroyNotify) json_node_free); } out: if (error != NULL) { g_error_free (error); } remove_request (closure, request); if (g_queue_is_empty (closure->pending_requests)) { resolve_closure_callback (closure, NULL); resolve_closure_free (closure); } }