static void add_image (GrlTmdbSource *self, GrlMedia *media, GrlKeyID detail_key, const char *image_path) { SoupURI *uri; GrlRelatedKeys *related_keys; char *str; int i, l; str = g_strconcat ("original", image_path, NULL); uri = soup_uri_new_with_base (self->priv->image_base_uri, str); g_free (str); str = soup_uri_to_string (uri, FALSE); l = grl_data_length (GRL_DATA (media), detail_key); for (i = 0; i < l; ++i) { related_keys = grl_data_get_related_keys (GRL_DATA (media), detail_key, i); if (g_strcmp0 (grl_related_keys_get_string (related_keys, detail_key), str) == 0) break; } if (i == l) { grl_data_add_string (GRL_DATA (media), detail_key, str); } g_free (str); soup_uri_free (uri); }
static gboolean has_compatible_media_url (GrlMedia *media) { gboolean ret = FALSE; const gchar *url; gchar *scheme; /* HACK: Cheat slightly, we don't want to use UPnP URLs */ if (grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_SOURCE)) { const char *source; source = grl_data_get_string (GRL_DATA (media), GRL_METADATA_KEY_SOURCE); if (g_str_has_prefix (source, "grl-upnp-uuid:")) return FALSE; if (g_str_has_prefix (source, "grl-dleyna-uuid:")) return FALSE; } url = grl_media_get_url (media); if (!url) { return FALSE; } scheme = g_uri_parse_scheme (url); ret = is_supported_scheme (scheme); g_free (scheme); return ret; }
static void set_metadata_to_media (GrlMedia *media, MexContentMetadata mex_key, const gchar *value) { int ival; float fval; GrlKeyID grl_key = _get_grl_key_from_mex (mex_key); if (!grl_key) { g_warning ("No grilo key to handle %s", mex_content_metadata_key_to_string (mex_key)); return; } switch (G_PARAM_SPEC (grl_key)->value_type) { case G_TYPE_STRING: grl_data_set_string (GRL_DATA (media), grl_key, value); break; case G_TYPE_INT: ival = atoi (value); grl_data_set_int (GRL_DATA (media), grl_key, ival); break; case G_TYPE_FLOAT: fval = atof (value); grl_data_set_float (GRL_DATA (media), grl_key, fval); break; } }
static void grl_gravatar_source_resolve (GrlSource *source, GrlSourceResolveSpec *rs) { gboolean artist_avatar_required = FALSE; gboolean author_avatar_required = FALSE; GRL_DEBUG (__FUNCTION__); GList *iter; /* Check that albumart is requested */ iter = rs->keys; while (iter && (!artist_avatar_required || !author_avatar_required)) { GrlKeyID key = GRLPOINTER_TO_KEYID (iter->data); if (key == GRL_METADATA_KEY_ARTIST_AVATAR) { artist_avatar_required = TRUE; } else if (key == GRL_METADATA_KEY_AUTHOR_AVATAR) { author_avatar_required = TRUE; } iter = g_list_next (iter); } if (artist_avatar_required) { set_avatar (GRL_DATA (rs->media), GRL_METADATA_KEY_ARTIST); } if (author_avatar_required) { set_avatar (GRL_DATA (rs->media), GRL_METADATA_KEY_AUTHOR); } rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL); }
gchar * grl_tracker_tracker_get_insert_string (GrlMedia *media, const GList *keys) { gboolean first = TRUE; const GList *key = keys, *assoc_list; tracker_grl_sparql_t *assoc; GString *gstr = g_string_new (""); gchar *ret; while (key != NULL) { assoc_list = get_mapping_from_grl (GRLPOINTER_TO_KEYID (key->data)); while (assoc_list != NULL) { assoc = (tracker_grl_sparql_t *) assoc_list->data; if (assoc != NULL) { if (grl_data_has_key (GRL_DATA (media), GRLPOINTER_TO_KEYID (key->data))) { if (first) { gen_prop_insert_string (gstr, assoc, GRL_DATA (media)); first = FALSE; } else { g_string_append (gstr, " ; "); gen_prop_insert_string (gstr, assoc, GRL_DATA (media)); } } } assoc_list = assoc_list->next; } key = key->next; } ret = gstr->str; g_string_free (gstr, FALSE); return ret; }
static gboolean grl_metadata_store_source_may_resolve (GrlSource *source, GrlMedia *media, GrlKeyID key_id, GList **missing_keys) { if (!(key_id == GRL_METADATA_KEY_RATING || key_id == GRL_METADATA_KEY_PLAY_COUNT || key_id == GRL_METADATA_KEY_LAST_PLAYED || key_id == GRL_METADATA_KEY_LAST_POSITION || key_id == GRL_METADATA_KEY_FAVOURITE)) return FALSE; if (media) { if (!(GRL_IS_MEDIA_VIDEO (media) || GRL_IS_MEDIA_AUDIO (media) || key_id == GRL_METADATA_KEY_FAVOURITE)) /* the keys we handle for now only make sense for audio and video, with exception of the 'favourite' key, valid as well for pictures and boxes */ return FALSE; if (grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_ID)) return TRUE; } if (missing_keys) *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ID, NULL); return FALSE; }
static void extract_gibest_hash (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { GFile *file = source_object; guint64 buffer[2][CHUNK_N_BYTES/8]; GInputStream *stream = NULL; gssize n_bytes, file_size; GError *error = NULL; guint64 hash = 0; gint i; char *str; ResolveData *resolve_data = task_data; GrlLocalMetadataSourcePriv *priv; priv = GRL_LOCAL_METADATA_SOURCE_GET_PRIVATE (resolve_data->source); stream = G_INPUT_STREAM (g_file_read (file, cancellable, &error)); if (stream == NULL) goto fail; /* Extract start/end chunks of the file */ n_bytes = g_input_stream_read (stream, buffer[0], CHUNK_N_BYTES, cancellable, &error); if (n_bytes == -1) goto fail; if (!g_seekable_seek (G_SEEKABLE (stream), -CHUNK_N_BYTES, G_SEEK_END, cancellable, &error)) goto fail; n_bytes = g_input_stream_read (stream, buffer[1], CHUNK_N_BYTES, cancellable, &error); if (n_bytes == -1) goto fail; for (i = 0; i < G_N_ELEMENTS (buffer[0]); i++) hash += buffer[0][i] + buffer[1][i]; file_size = g_seekable_tell (G_SEEKABLE (stream)); if (file_size < CHUNK_N_BYTES) goto fail; /* Include file size */ hash += file_size; g_object_unref (stream); str = g_strdup_printf ("%" G_GINT64_FORMAT, hash); grl_data_set_string (GRL_DATA (resolve_data->rs->media), priv->hash_keyid, str); g_free (str); g_task_return_boolean (task, TRUE); return; fail: GRL_DEBUG ("Could not get file hash: %s\n", error ? error->message : "Unknown error"); g_task_return_error (task, error); g_clear_object (&stream); }
static void set_orientation (TrackerSparqlCursor *cursor, gint column, GrlMedia *media, GrlKeyID key) { const gchar *str = tracker_sparql_cursor_get_string (cursor, column, NULL); if (g_str_has_suffix (str, "nfo#orientation-top")) grl_data_set_int (GRL_DATA (media), key, 0); else if (g_str_has_suffix (str, "nfo#orientation-right")) grl_data_set_int (GRL_DATA (media), key, 90); else if (g_str_has_suffix (str, "nfo#orientation-bottom")) grl_data_set_int (GRL_DATA (media), key, 180); else if (g_str_has_suffix (str, "nfo#orientation-left")) grl_data_set_int (GRL_DATA (media), key, 270); }
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); }
/** * Returns: TRUE if @dependency is in @media, FALSE else. * When returning FALSE, if @missing_keys is not NULL it is populated with a * list containing @dependency as only element. */ static gboolean has_dependency (GrlMedia *media, GrlKeyID dependency, GList **missing_keys) { if (media && grl_data_has_key (GRL_DATA (media), dependency)) return TRUE; if (missing_keys) *missing_keys = grl_metadata_key_list_new (dependency, NULL); return FALSE; }
gchar * grl_tracker_tracker_get_insert_string (GrlMedia *media, const GList *keys) { gboolean first = TRUE; const GList *key; GString *gstr = g_string_new (""); for (key = keys; key != NULL; key = key->next) { const GList *assoc_list; GrlKeyID key_id = GRLPOINTER_TO_KEYID (key->data); for (assoc_list = get_mapping_from_grl (key_id); assoc_list != NULL; assoc_list = assoc_list->next) { tracker_grl_sparql_t *assoc = assoc_list->data; if (assoc == NULL) continue; /* The favourite key is really setting or deleting a tag * in tracker, so in the case of setting it to false skip * the insert string creation step for this key completely. */ if (assoc->grl_key == GRL_METADATA_KEY_FAVOURITE && !grl_media_get_favourite (media)) continue; if (!grl_data_has_key (GRL_DATA (media), key_id)) continue; if (!first) g_string_append (gstr, " ; "); gen_prop_insert_string (gstr, assoc, GRL_DATA (media)); first = FALSE; } } return g_string_free (gstr, FALSE); }
/* Returns whether to free the value parameter or not. */ static void set_metadata_from_media (MexContent *content, GrlMedia *media, MexContentMetadata mex_key) { gchar *string; const gchar *cstring; GrlKeyID grl_key = _get_grl_key_from_mex (mex_key); gint n; if (!grl_key) return; switch (G_PARAM_SPEC (grl_key)->value_type) { case G_TYPE_STRING: cstring = grl_data_get_string (GRL_DATA (media), grl_key); if (cstring) mex_grilo_program_set_metadata (content, mex_key, cstring); break; case G_TYPE_INT: n = grl_data_get_int (GRL_DATA (media), grl_key); if (n > 0) { string = g_strdup_printf ("%i", n); mex_grilo_program_set_metadata (content, mex_key, string); g_free (string); } break; case G_TYPE_FLOAT: string = g_strdup_printf ("%f", grl_data_get_float (GRL_DATA (media), grl_key)); mex_grilo_program_set_metadata (content, mex_key, string); g_free (string); break; } }
static void set_favourite (TrackerSparqlCursor *cursor, gint column, GrlMedia *media, GrlKeyID key) { const gchar *str = tracker_sparql_cursor_get_string (cursor, column, NULL); gboolean is_favourite = FALSE; if (str != NULL && g_str_has_suffix (str, "predefined-tag-favorite")) is_favourite = TRUE; grl_data_set_boolean (GRL_DATA (media), key, is_favourite); }
static gboolean grl_tmdb_source_may_resolve (GrlSource *source, GrlMedia *media, GrlKeyID key_id, GList **missing_keys) { GrlTmdbSource *self = GRL_TMDB_SOURCE (source); if (!g_hash_table_contains (self->priv->supported_keys, GRLKEYID_TO_POINTER (key_id)) && !g_hash_table_contains (self->priv->slow_keys, GRLKEYID_TO_POINTER (key_id))) return FALSE; /* We can only entertain videos */ if (media && !grl_media_is_video (media)) return FALSE; /* Caller wants to check what's needed to resolve */ if (!media) { if (missing_keys) *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE, NULL); return FALSE; } /* We can do nothing without a title or the movie-id */ if (!grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_TITLE) && !grl_data_has_key (GRL_DATA (media), GRL_TMDB_METADATA_KEY_TMDB_ID)) { if (missing_keys) *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE, NULL); return FALSE; } return TRUE; }
static void grl_bookmarks_source_store (GrlSource *source, GrlSourceStoreSpec *ss) { GError *error = NULL; GList *keylist; GRL_DEBUG ("grl_bookmarks_source_store"); /* FIXME: Try to guess bookmark mime somehow */ keylist = grl_data_get_keys (GRL_DATA (ss->media)); store_bookmark (GRL_BOOKMARKS_SOURCE (ss->source), &keylist, ss->parent, ss->media, &error); ss->callback (ss->source, ss->media, keylist, ss->user_data, error); g_clear_error (&error); }
void mex_grilo_set_media_content_metadata (GrlMedia *media, MexContentMetadata mex_key, const gchar *value) { int ival; float fval; GrlKeyID grl_key; g_return_if_fail (GRL_IS_MEDIA (media)); g_return_if_fail (mex_key < MEX_CONTENT_METADATA_LAST_ID); grl_key = _get_grl_key_from_mex (mex_key); if (!grl_key) { g_warning ("No grilo key to handle %s", mex_content_metadata_key_to_string (mex_key)); return; } switch (grl_metadata_key_get_type (grl_key)) { case G_TYPE_STRING: grl_data_set_string (GRL_DATA (media), grl_key, value); break; case G_TYPE_INT: ival = atoi (value); grl_data_set_int (GRL_DATA (media), grl_key, ival); break; case G_TYPE_FLOAT: fval = atof (value); grl_data_set_float (GRL_DATA (media), grl_key, fval); break; } }
static void set_date (TrackerSparqlCursor *cursor, gint column, GrlMedia *media, GrlKeyID key) { const gchar *str = tracker_sparql_cursor_get_string (cursor, column, NULL); if (key == GRL_METADATA_KEY_CREATION_DATE || key == GRL_METADATA_KEY_MODIFICATION_DATE) { GDateTime *date = grl_date_time_from_iso8601 (str); if (date) { grl_data_set_boxed (GRL_DATA (media), key, date); g_date_time_unref (date); } } }
static void set_test_data (GrlSource **source, GrlMedia **media, GrlOperationOptions **options, GList **keys, GrlSupportedOps source_op) { *source = test_lua_factory_get_source (FAKE_SOURCE_ID, source_op); g_assert_nonnull (*source); *media = grl_media_new (); grl_data_add_string (GRL_DATA (*media), GRL_METADATA_KEY_URL, LOCAL_CONTENT); *keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE, NULL); *options = grl_operation_options_new (NULL); grl_operation_options_set_resolution_flags (*options, GRL_RESOLVE_NORMAL); }
static void resolve_cb (GrlSource *src, guint operation_id, GrlMedia *media, gpointer user_data, const GError *error) { g_assert_no_error (error); g_assert (media); const gchar *title = grl_media_get_title (media); const gchar *studio = grl_media_get_studio (media); printf ("Media: Title='%s', Studio='%s'\n", title, studio); if (director_key != 0) { const gchar *director = grl_data_get_string (GRL_DATA (media), director_key); printf (" Director=%s\n", director); } g_main_loop_quit (loop); }
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 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 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 grilo_media_browse_cb (GrlSource *grilo_source, guint operation_id, GrlMedia *media, guint remaining, RBGriloSource *source, const GError *error) { if (operation_id != source->priv->media_browse_op) { return; } if (error != NULL) { /* do something? */ rb_debug ("got error for %s: %s", grl_source_get_name (grilo_source), error->message); return; } GDK_THREADS_ENTER (); if (media != NULL) { source->priv->media_browse_got_results = TRUE; source->priv->media_browse_position++; if (GRL_IS_MEDIA_AUDIO (media)) { RhythmDBEntry *entry; entry = create_entry_for_media (source->priv->db, source->priv->entry_type, GRL_DATA (media), GRL_DATA (source->priv->browse_container)); if (entry != NULL) { rhythmdb_query_model_add_entry (source->priv->query_model, entry, -1); } } else if (GRL_IS_MEDIA_BOX (media)) { source->priv->media_browse_got_containers = TRUE; } } if (remaining == 0) { source->priv->media_browse_op = 0; if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (source->priv->query_model), NULL) == 0 && source->priv->media_browse_position >= CONTAINER_GIVE_UP_POINT) { /* if we don't find any media within the first 100 or so results, * assume this container doesn't have any. otherwise we'd load * the entire thing when it got selected, which would suck. */ rb_debug ("didn't find any media in %s, giving up", grl_media_get_title (source->priv->media_browse_container)); gtk_tree_store_set (source->priv->browser_model, &source->priv->media_browse_container_iter, 2, CONTAINER_NO_MEDIA, -1); } else if (source->priv->media_browse_got_results) { if (source->priv->media_browse_position < source->priv->media_browse_limit) { media_browse_next (source); } else { char *text; text = g_strdup_printf (ngettext ("Only showing %d result", "Only showing %d results", source->priv->media_browse_position), source->priv->media_browse_position); gtk_label_set_text (GTK_LABEL (source->priv->info_bar_label), text); g_free (text); gtk_widget_show (source->priv->info_bar); } } else if (source->priv->media_browse_got_containers == FALSE && source->priv->media_browse_container != NULL) { /* make sure there's no marker row for this container */ delete_marker_row (source, &source->priv->media_browse_container_iter); } } GDK_THREADS_LEAVE (); }
static void set_metadata_from_media (MexContent *content, GrlMedia *media, MexContentMetadata mex_key) { gchar *string; const gchar *cstring; GrlKeyID grl_key = _get_grl_key_from_mex (mex_key); gint n; gint year = 0; if (!grl_key) return; switch (grl_metadata_key_get_type (grl_key)) { case G_TYPE_STRING: cstring = grl_data_get_string (GRL_DATA (media), grl_key); if (cstring) { if (mex_key == MEX_CONTENT_METADATA_TITLE) { gchar *showname = NULL, *title, *season_str; gint season, episode; gchar *replacement; const gchar *mimetype; mimetype = mex_content_get_metadata (content, MEX_CONTENT_METADATA_MIMETYPE); if (!mimetype) mimetype = ""; if (g_str_has_prefix (mimetype, "video/")) { mex_metadata_from_uri (cstring, &title, &showname, &year, &season, &episode); } if (showname) { replacement = g_strdup_printf (_("Episode %d"), episode); } else { GRegex *regex; /* strip off any file extensions */ regex = g_regex_new ("\\.....?$", 0, 0, NULL); replacement = g_regex_replace (regex, cstring, -1, 0, "", 0, NULL); g_regex_unref (regex); } if (!replacement) replacement = g_strdup (cstring); mex_content_set_metadata (content, mex_key, replacement); mex_content_set_metadata (content, MEX_CONTENT_METADATA_SERIES_NAME, showname); season_str = g_strdup_printf (_("Season %d"), season); mex_content_set_metadata (content, MEX_CONTENT_METADATA_SEASON, season_str); g_free (season_str); if (year) { replacement = g_strdup_printf ("%d", year); mex_content_set_metadata (content, MEX_CONTENT_METADATA_YEAR, replacement); g_free (replacement); } } else mex_content_set_metadata (content, mex_key, cstring); } break; case G_TYPE_INT: n = grl_data_get_int (GRL_DATA (media), grl_key); string = g_strdup_printf ("%i", n); mex_content_set_metadata (content, mex_key, string); g_free (string); break; case G_TYPE_FLOAT: string = g_strdup_printf ("%f", grl_data_get_float (GRL_DATA (media), grl_key)); mex_content_set_metadata (content, mex_key, string); g_free (string); break; } }
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); } }
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); }
static void grl_tmdb_source_resolve (GrlSource *source, GrlSourceResolveSpec *rs) { ResolveClosure *closure; GrlTmdbRequest *request; const char *title = NULL; const char *str_movie_id; GrlTmdbSource *self = GRL_TMDB_SOURCE (source); guint64 movie_id = 0; GList *it; if (!grl_media_is_video (rs->media)) { /* We only entertain videos */ rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL); return; } /* If the media is a TV show, don't handle it */ if (grl_media_get_show (rs->media) != NULL) { rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL); return; } /* Prefer resolving by movie-id: This is more reliable and saves the search query. */ str_movie_id = grl_data_get_string (GRL_DATA (rs->media), GRL_TMDB_METADATA_KEY_TMDB_ID); if (str_movie_id) movie_id = strtoull (str_movie_id, NULL, 10); /* Try title if no movie-id could be found. */ if (movie_id == 0) title = grl_media_get_title (rs->media); if (movie_id == 0 && title == NULL) { /* Can't search for anything without a title or the movie-id ... */ rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL); return; } GRL_DEBUG ("grl_tmdb_source_resolve"); closure = g_slice_new0 (ResolveClosure); closure->self = g_object_ref (self); closure->rs = rs; closure->pending_requests = g_queue_new (); closure->keys = g_hash_table_new (g_direct_hash, g_direct_equal); closure->slow = FALSE; closure->id = movie_id; it = rs->keys; /* Copy keys to list for faster lookup */ while (it) { g_hash_table_add (closure->keys, it->data); /* Enable slow resolution if slow keys are requested */ closure->slow |= g_hash_table_contains (self->priv->slow_keys, it->data); it = it->next; } /* Disable slow resolution if slow keys where requested, but the operation * options explicitly ask for fast resolving only. */ if (grl_operation_options_get_resolution_flags (rs->options) & GRL_RESOLVE_FAST_ONLY) closure->slow = FALSE; /* We did not receive the config yet, queue request. Config callback will * take care of flushing the queue when ready. */ if (self->priv->configuration == NULL && self->priv->config_pending) { g_queue_push_tail (self->priv->pending_resolves, closure); return; } if (self->priv->configuration == NULL) { GRL_DEBUG ("Fetching TMDb configuration..."); /* We need to fetch TMDb's configuration for the image paths */ request = grl_tmdb_request_new_configuration (closure->self->priv->api_key); g_assert (g_queue_is_empty (closure->pending_requests)); queue_request (closure, request, on_configuration_ready); self->priv->config_pending = TRUE; } if (title) { GRL_DEBUG ("Running initial search for title \"%s\"...", title); request = grl_tmdb_request_new_search (closure->self->priv->api_key, title); queue_request (closure, request, on_search_ready); run_pending_requests (closure, 1); } else { GRL_DEBUG ("Running %s lookup for movie #%" G_GUINT64_FORMAT "...", closure->slow ? "slow" : "fast", movie_id); if (closure->slow) { resolve_slow_details (closure); } else { queue_detail_request (closure, GRL_TMDB_REQUEST_DETAIL_MOVIE); } run_pending_requests (closure, G_MAXINT); } }
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; }