示例#1
0
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;
}
示例#3
0
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);
}
示例#5
0
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;
}
示例#6
0
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);
}
示例#8
0
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);
}
示例#9
0
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;
}
示例#11
0
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);
}
示例#12
0
/* 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;
  }
}
示例#13
0
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);
}
示例#14
0
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;
}
示例#15
0
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);
}
示例#16
0
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;
  }
}
示例#17
0
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;
}
示例#21
0
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);
}
示例#22
0
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;
		  }

    }
  }

}
示例#23
0
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 ();
}
示例#25
0
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;
  }
}
示例#26
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);
}
示例#27
0
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);
  }
}
示例#28
0
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);
}
示例#29
0
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);
  }
}
示例#30
0
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;
}