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 int get_media_type (GrlMedia *media) { if (GRL_IS_MEDIA_AUDIO (media)) { return MEDIA_AUDIO; } if (GRL_IS_MEDIA_VIDEO (media)) { return MEDIA_VIDEO; } if (GRL_IS_MEDIA_IMAGE (media)) { return MEDIA_IMAGE; } if (GRL_IS_MEDIA_BOX (media)) { return MEDIA_BOX; } return MEDIA; }
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_IS_MEDIA_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_raitv_source_resolve (GrlSource *source, GrlSourceResolveSpec *rs) { gchar *urltarget; GrlRaitvSource *self = GRL_RAITV_SOURCE (source); RaitvOperation *op; RaitvMediaType mediatype; GRL_DEBUG ("Starting resolve source: url=%s",grl_media_get_url (rs->media)); if (!GRL_IS_MEDIA_VIDEO (rs->media) && !GRL_IS_MEDIA_BOX (rs->media)) { rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); return; } mediatype = classify_media_id (grl_media_get_id (rs->media)); switch (mediatype) { case RAITV_MEDIA_TYPE_ROOT: rs->media = produce_container_from_directory (rs->media, NULL, 0, mediatype); break; case RAITV_MEDIA_TYPE_POPULARS: rs->media = produce_container_from_directory (rs->media, root_dir, ROOT_DIR_POPULARS_INDEX, mediatype); break; case RAITV_MEDIA_TYPE_RECENTS: rs->media = produce_container_from_directory (rs->media, root_dir, ROOT_DIR_RECENTS_INDEX, mediatype); break; case RAITV_MEDIA_TYPE_POPULAR_THEME: case RAITV_MEDIA_TYPE_RECENT_THEME: rs->media = produce_container_from_directory (rs->media, themes_dir, get_theme_index_from_id (grl_media_get_id (rs->media)), mediatype); break; case RAITV_MEDIA_TYPE_VIDEO: op = g_slice_new0 (RaitvOperation); op->source = g_object_ref (source); op->cancellable = g_cancellable_new (); op->operation_id = rs->operation_id; op->resolveCb = rs->callback; op->user_data = rs->user_data; op->media = rs->media; grl_operation_set_data_full (rs->operation_id, op, (GDestroyNotify) raitv_operation_free); urltarget = g_strdup_printf ("http://www.rai.tv/dl/RaiTV/programmi/media/%s.html", grl_media_get_id(rs->media)); GRL_DEBUG ("Opening '%s'", urltarget); grl_net_wc_request_async (self->priv->wc, urltarget, op->cancellable, proxy_call_resolve_grlnet_async_cb, op); g_free(urltarget); return; } rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); return; if ( grl_media_get_url (rs->media) != NULL) { rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); return; } op = g_slice_new0 (RaitvOperation); op->source = g_object_ref (source); op->cancellable = g_cancellable_new (); op->operation_id = rs->operation_id; op->resolveCb = rs->callback; op->user_data = rs->user_data; op->media = rs->media; grl_operation_set_data_full (rs->operation_id, op, (GDestroyNotify) raitv_operation_free); urltarget = g_strdup_printf("%s/%s.html","http://www.rai.tv/dl/RaiTV/programmi/media",grl_media_get_id(rs->media)); GRL_DEBUG ("Opening '%s'", urltarget); grl_net_wc_request_async (self->priv->wc, urltarget, op->cancellable, proxy_call_resolve_grlnet_async_cb, op); g_free(urltarget); }
static void grl_local_metadata_source_resolve (GrlSource *source, GrlSourceResolveSpec *rs) { GError *error = NULL; resolution_flags_t flags; GrlLocalMetadataSourcePriv *priv = GRL_LOCAL_METADATA_SOURCE_GET_PRIVATE (source); gboolean can_access; ResolveData *data = NULL; GRL_DEBUG (__FUNCTION__); /* Wrap the whole resolve operation in a GTask, as there are various async * components which need to run in parallel. */ data = g_slice_new0 (ResolveData); data->source = g_object_ref (source); data->rs = rs; data->n_pending_operations = 1; /* to track the initial checks */ /* Can we access the media through gvfs? */ can_access = has_compatible_media_url (rs->media); flags = get_resolution_flags (rs->keys, priv); if (grl_data_get_boolean (GRL_DATA (rs->media), GRL_METADATA_KEY_TITLE_FROM_FILENAME)) flags |= FLAG_VIDEO_TITLE; if (!flags) error = g_error_new_literal (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED, _("Cannot resolve any of the given keys")); if (GRL_IS_MEDIA_IMAGE (rs->media) && can_access == FALSE) error = g_error_new_literal (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED, _("A GIO supported URL for images is required")); if (error) { /* No can do! */ resolve_data_finish_operation (data, "root", error); g_error_free (error); return; } GRL_DEBUG ("\ttrying to resolve for: %s", grl_media_get_url (rs->media)); if (GRL_IS_MEDIA_VIDEO (rs->media)) { if (priv->guess_video) resolve_video (data, can_access ? GRL_METADATA_KEY_URL : GRL_METADATA_KEY_TITLE, flags); if (can_access) resolve_image (data, flags); } else if (GRL_IS_MEDIA_IMAGE (rs->media)) { resolve_image (data, flags); } else if (GRL_IS_MEDIA_AUDIO (rs->media)) { /* Try for a per-track thumbnail first; we'll fall back to album art * if the track doesn't have one */ resolve_image (data, flags); } /* Finish the overall operation (this might not call the callback if there * are still some sub-operations pending). */ resolve_data_finish_operation (data, "root", NULL); }
static gboolean grl_local_metadata_source_may_resolve (GrlSource *source, GrlMedia *media, GrlKeyID key_id, GList **missing_keys) { GrlLocalMetadataSourcePriv *priv = GRL_LOCAL_METADATA_SOURCE_GET_PRIVATE (source); if (!media) return FALSE; if (GRL_IS_MEDIA_AUDIO (media)) { gboolean have_artist = FALSE, have_album = FALSE; if ((have_artist = grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_ARTIST)) && (have_album = grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_ALBUM)) && key_id == GRL_METADATA_KEY_THUMBNAIL) { return TRUE; } else if (missing_keys) { GList *result = NULL; if (!have_artist) result = g_list_append (result, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ARTIST)); if (!have_album) result = g_list_append (result, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM)); if (result) *missing_keys = result; } return FALSE; } if (GRL_IS_MEDIA_IMAGE (media)) { if (key_id != GRL_METADATA_KEY_THUMBNAIL) return FALSE; if (!grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_URL)) goto missing_url; if (!has_compatible_media_url (media)) return FALSE; return TRUE; } if (GRL_IS_MEDIA_VIDEO (media)) { switch (key_id) { case GRL_METADATA_KEY_TITLE: case GRL_METADATA_KEY_SHOW: case GRL_METADATA_KEY_PUBLICATION_DATE: case GRL_METADATA_KEY_SEASON: case GRL_METADATA_KEY_EPISODE: case GRL_METADATA_KEY_EPISODE_TITLE: if (!priv->guess_video) return FALSE; if (grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_URL) && has_compatible_media_url (media)) return TRUE; if (!grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_TITLE)) goto missing_title; return TRUE; case GRL_METADATA_KEY_THUMBNAIL: if (grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_URL) == FALSE) goto missing_url; return has_compatible_media_url (media); default: if (key_id == priv->hash_keyid) return has_compatible_media_url (media); } } missing_title: if (missing_keys) { if (grl_data_has_key (GRL_DATA (media), GRL_METADATA_KEY_URL) == FALSE) *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE, GRL_METADATA_KEY_URL, NULL); else *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE, NULL); } return FALSE; missing_url: if (missing_keys) *missing_keys = grl_metadata_key_list_new (GRL_METADATA_KEY_URL, NULL); return FALSE; }
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_IS_MEDIA_VIDEO (rs->media)) { /* We only entertain videos */ 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 (source); 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_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); } }