static void
resolve_video (ResolveData         *resolve_data,
               GrlKeyID             key,
               resolution_flags_t   flags)
{
  gchar *title, *showname, *display_name;
  GDateTime *date;
  gint season, episode;
  GrlData *data = GRL_DATA (resolve_data->rs->media);
  resolution_flags_t miss_flags = 0, fill_flags;

  GRL_DEBUG ("%s",__FUNCTION__);

  resolve_data_start_operation (resolve_data, "video");

  if (!(flags & (FLAG_VIDEO_TITLE |
                 FLAG_VIDEO_SHOWNAME |
                 FLAG_VIDEO_DATE |
                 FLAG_VIDEO_SEASON |
                 FLAG_VIDEO_EPISODE |
                 FLAG_VIDEO_EPISODE_TITLE))) {
    resolve_data_finish_operation (resolve_data, "video", NULL);
    return;
  }

  if (grl_data_has_key (data, GRL_METADATA_KEY_TITLE)) {
    if (grl_data_get_boolean (data, GRL_METADATA_KEY_TITLE_FROM_FILENAME)) {
      miss_flags = FLAG_VIDEO_TITLE;
    } else
      miss_flags = 0;
  } else {
    miss_flags = FLAG_VIDEO_TITLE;
  }
  miss_flags |= grl_data_has_key (data, GRL_METADATA_KEY_SHOW) ?
    0 : FLAG_VIDEO_SHOWNAME;
  miss_flags |= grl_data_has_key (data, GRL_METADATA_KEY_PUBLICATION_DATE) ?
    0 : FLAG_VIDEO_DATE;
  miss_flags |= grl_data_has_key (data, GRL_METADATA_KEY_SEASON) ?
    0 : FLAG_VIDEO_SEASON;
  miss_flags |= grl_data_has_key (data, GRL_METADATA_KEY_EPISODE) ?
    0 : FLAG_VIDEO_EPISODE;
  miss_flags |= grl_data_has_key (data, GRL_METADATA_KEY_EPISODE_TITLE) ?
    0 : FLAG_VIDEO_EPISODE_TITLE;

  fill_flags = flags & miss_flags;

  if (!fill_flags) {
    resolve_data_finish_operation (resolve_data, "video", NULL);
    return;
  }

  if (key == GRL_METADATA_KEY_URL) {
    GFile *file;

    file = g_file_new_for_uri (grl_media_get_url (resolve_data->rs->media));
    display_name = g_file_get_basename (file);
    g_object_unref (file);
  } else {
    display_name = g_strdup (grl_media_get_title (resolve_data->rs->media));
  }

  video_guess_values_from_display_name (display_name,
                                        &title, &showname, &date,
                                        &season, &episode);

  g_free (display_name);

  GRL_DEBUG ("\tfound title=%s/showname=%s/year=%i/season=%i/episode=%i",
             title, showname,
             date != NULL ? g_date_time_get_year (date) : 0,
             season, episode);

  if (showname) {
    if (fill_flags & FLAG_VIDEO_SHOWNAME) {
      grl_data_set_string (data, GRL_METADATA_KEY_SHOW, showname);
    }
    g_free (showname);

    if (fill_flags & FLAG_VIDEO_EPISODE_TITLE &&
        title != NULL) {
      grl_data_set_string (data, GRL_METADATA_KEY_EPISODE_TITLE, title);
    }
  } else {
    /* As this is just a guess, don't erase already provided values,
     * unless GRL_METADATA_KEY_TITLE_FROM_FILENAME is set */
    if (grl_data_get_boolean (data, GRL_METADATA_KEY_TITLE_FROM_FILENAME)) {
      if (fill_flags & FLAG_VIDEO_TITLE) {
        grl_data_set_string (data, GRL_METADATA_KEY_TITLE, title);
      }
    }
  }
  g_free (title);

  if (date) {
    if (fill_flags & FLAG_VIDEO_DATE) {
      grl_data_set_boxed (data, GRL_METADATA_KEY_PUBLICATION_DATE, date);
    }
    g_date_time_unref (date);
  }

  if (season && (fill_flags & FLAG_VIDEO_SEASON)) {
    grl_data_set_int (data, GRL_METADATA_KEY_SEASON, season);
  }

  if (episode && (fill_flags & FLAG_VIDEO_EPISODE)) {
    grl_data_set_int (data, GRL_METADATA_KEY_EPISODE, episode);
  }

  resolve_data_finish_operation (resolve_data, "video", NULL);
}
Beispiel #2
0
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
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);
}