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; }
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 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; }
/** * 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; }
static void set_string_prop_from_key (RhythmDB *db, RhythmDBEntry *entry, RhythmDBPropType prop, GrlData *data, GrlKeyID key) { GValue v = {0,}; if (grl_data_has_key (data, key) == FALSE) return; g_value_init (&v, G_TYPE_STRING); g_value_set_string (&v, grl_data_get_string (data, key)); rhythmdb_entry_set (db, entry, prop, &v); g_value_unset (&v); }
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; }
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); }
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 RhythmDBEntry * create_entry_for_media (RhythmDB *db, RhythmDBEntryType *entry_type, GrlData *data, GrlData *container) { RhythmDBEntry *entry; RBGriloEntryData *entry_data; entry = rhythmdb_entry_lookup_by_location (db, grl_media_get_url (GRL_MEDIA (data))); if (entry != NULL) { return entry; } rb_debug ("creating entry for %s / %s", grl_media_get_url (GRL_MEDIA (data)), grl_media_get_id (GRL_MEDIA (data))); entry = rhythmdb_entry_new (db, entry_type, grl_media_get_url (GRL_MEDIA (data))); /* just use the url? */ if (entry == NULL) { /* crap. */ return NULL; } set_string_prop_from_key (db, entry, RHYTHMDB_PROP_TITLE, data, GRL_METADATA_KEY_TITLE); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_ALBUM, data, GRL_METADATA_KEY_ALBUM); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_ARTIST, data, GRL_METADATA_KEY_ARTIST); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_GENRE, data, GRL_METADATA_KEY_GENRE); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_TITLE, data, GRL_METADATA_KEY_TITLE); if (grl_data_has_key (data, GRL_METADATA_KEY_PUBLICATION_DATE)) { /* something - grilo has this as a string? */ } if (grl_data_has_key (data, GRL_METADATA_KEY_BITRATE)) { GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_BITRATE)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_BITRATE, &v); g_value_unset (&v); } if (grl_data_has_key (data, GRL_METADATA_KEY_DURATION)) { /* this is probably in seconds */ GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_DURATION)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &v); g_value_unset (&v); } if (grl_data_has_key (data, GRL_METADATA_KEY_MIME)) { const char *media_type; media_type = rb_gst_mime_type_to_media_type (grl_data_get_string (data, GRL_METADATA_KEY_MIME)); if (media_type) { GValue v = {0,}; g_value_init (&v, G_TYPE_STRING); g_value_set_string (&v, media_type); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_MEDIA_TYPE, &v); g_value_unset (&v); } } if (grl_data_has_key (data, GRL_METADATA_KEY_TRACK_NUMBER)) { GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_TRACK_NUMBER)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &v); g_value_unset (&v); } /* rating and play count? */ entry_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBGriloEntryData); entry_data->grilo_data = g_object_ref (data); if (container != NULL) { entry_data->grilo_container = g_object_ref (container); } /* might want to consider batching this */ rhythmdb_commit (db); return entry; }
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); }
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 fill_properties_table (MS2Server *server, GHashTable *properties_table, GList *keys, GrlMedia *media) { GList *prop; GrlKeyID key; const gchar *title; gchar *id; gchar *urls[2] = { 0 }; for (prop = keys; prop; prop = g_list_next (prop)) { key = GRLPOINTER_TO_KEYID (prop->data); if (key == GRL_METADATA_KEY_ID || grl_data_has_key (GRL_DATA (media), key)) { if (key == GRL_METADATA_KEY_ID) { id = serialize_media (media); if (id) { ms2_server_set_path (server, properties_table, id, grl_media_is_container (media)); g_free (id); } } else if (key == GRL_METADATA_KEY_TITLE) { /* Ensure we always insert a valid title */ title = grl_media_get_title (media); if (!title) { title = "Unknown"; } ms2_server_set_display_name (server, properties_table, title); } else if (key == GRL_METADATA_KEY_ALBUM) { ms2_server_set_album (server, properties_table, grl_data_get_string (GRL_DATA (media), GRL_METADATA_KEY_ALBUM)); } else if (key == GRL_METADATA_KEY_ARTIST) { ms2_server_set_artist (server, properties_table, grl_data_get_string (GRL_DATA (media), GRL_METADATA_KEY_ARTIST)); } else if (key == GRL_METADATA_KEY_GENRE) { ms2_server_set_genre (server, properties_table, grl_data_get_string (GRL_DATA (media), GRL_METADATA_KEY_GENRE)); } else if (key == GRL_METADATA_KEY_MIME) { ms2_server_set_mime_type (server, properties_table, grl_media_get_mime (media)); } else if (key == GRL_METADATA_KEY_URL) { urls[0] = (gchar *) grl_media_get_url (media); ms2_server_set_urls (server, properties_table, urls); } else if (key == GRL_METADATA_KEY_BITRATE) { ms2_server_set_bitrate (server, properties_table, grl_data_get_int (GRL_DATA (media), GRL_METADATA_KEY_BITRATE)); } else if (key == GRL_METADATA_KEY_DURATION) { ms2_server_set_duration (server, properties_table, grl_media_get_duration (media)); } else if (key == GRL_METADATA_KEY_HEIGHT) { ms2_server_set_height (server, properties_table, grl_data_get_int (GRL_DATA (media), GRL_METADATA_KEY_HEIGHT)); } else if (key == GRL_METADATA_KEY_WIDTH) { ms2_server_set_width (server, properties_table, grl_data_get_int (GRL_DATA (media), GRL_METADATA_KEY_WIDTH)); } else if (key == GRL_METADATA_KEY_GRILO_MS2_PARENT) { if (grl_media_get_id (media) == NULL) { ms2_server_set_parent (server, properties_table, MS2_ROOT); } else { ms2_server_set_parent (server, properties_table, grl_media_get_grilo_ms2_parent (media)); } } } } }