PATCH: local-metadata: Check the user's cache for album art
- From: Michael Wood <michael g wood intel com>
- To: grilo-list gnome org
- Subject: PATCH: local-metadata: Check the user's cache for album art
- Date: Mon, 05 Dec 2011 13:24:29 +0000
Check the user's cache for album art
Implements getting album art according to:
http://live.gnome.org/MediaArtStorageSpec
https://bugzilla.gnome.org/show_bug.cgi?id=665316
>From aca16d62e23d5f8ae06ea4d7b4165c73e7242f84 Mon Sep 17 00:00:00 2001
From: Michael Wood <michael g wood linux intel com>
Date: Thu, 1 Dec 2011 17:53:25 +0000
Subject: [PATCH] local-metadata: Check the user's cache for album art
Implements getting album art according to:
http://live.gnome.org/MediaArtStorageSpec
---
src/metadata/local-metadata/grl-local-metadata.c | 203 ++++++++++++++++++++-
1 files changed, 193 insertions(+), 10 deletions(-)
diff --git a/src/metadata/local-metadata/grl-local-metadata.c b/src/metadata/local-metadata/grl-local-metadata.c
index 9bcea12..2fd73e2 100644
--- a/src/metadata/local-metadata/grl-local-metadata.c
+++ b/src/metadata/local-metadata/grl-local-metadata.c
@@ -572,22 +572,199 @@ resolve_image (GrlMetadataSource *source,
}
}
+/* Taken from: http://live.gnome.org/MediaArtStorageSpec/SampleStripCodeInC */
+static gboolean
+strip_find_next_block (const gchar *original,
+ const gunichar open_char,
+ const gunichar close_char,
+ gint *open_pos,
+ gint *close_pos)
+{
+ const gchar *p1, *p2;
+
+ if (open_pos) {
+ *open_pos = -1;
+ }
+
+ if (close_pos) {
+ *close_pos = -1;
+ }
+
+ p1 = g_utf8_strchr (original, -1, open_char);
+ if (p1) {
+ if (open_pos) {
+ *open_pos = p1 - original;
+ }
+
+ p2 = g_utf8_strchr (g_utf8_next_char (p1), -1, close_char);
+ if (p2) {
+ if (close_pos) {
+ *close_pos = p2 - original;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/* Taken from: http://live.gnome.org/MediaArtStorageSpec/SampleStripCodeInC
+ * strips out invalid characters in a album name or artist name before md5sum
+ * to get the unique identifier to find the album art.
+ */
+static gchar *
+albumart_strip_invalid_entities (const gchar *original)
+{
+ GString *str_no_blocks;
+ gchar **strv;
+ gchar *str, *res;
+ gboolean blocks_done = FALSE;
+ const gchar *p;
+ const gchar *invalid_chars = "()[]<>{}_!@#$^&*+=|\\/\"'?~";
+ const gchar *invalid_chars_delimiter = "*";
+ const gchar *convert_chars = "\t";
+ const gchar *convert_chars_delimiter = " ";
+ const gunichar blocks[5][2] = {
+ { '(', ')' },
+ { '{', '}' },
+ { '[', ']' },
+ { '<', '>' },
+ { 0, 0 }
+ };
+
+ str_no_blocks = g_string_new ("");
+
+ p = original;
+
+ while (!blocks_done) {
+ gint pos1, pos2, i;
+
+ pos1 = -1;
+ pos2 = -1;
+
+ for (i = 0; blocks[i][0] != 0; i++) {
+ gint start, end;
+
+ /* Go through blocks, find the earliest block we can */
+ if (strip_find_next_block (p, blocks[i][0], blocks[i][1], &start,
+ &end))
+ {
+ if (pos1 == -1 || start < pos1) {
+ pos1 = start;
+ pos2 = end;
+ }
+ }
+ }
+
+ /* If either are -1 we didn't find any */
+ if (pos1 == -1) {
+ /* This means no blocks were found */
+ g_string_append (str_no_blocks, p);
+ blocks_done = TRUE;
+ } else {
+ /* Append the test BEFORE the block */
+ if (pos1 > 0) {
+ g_string_append_len (str_no_blocks, p, pos1);
+ }
+
+ p = g_utf8_next_char (p + pos2);
+
+ /* Do same again for position AFTER block */
+ if (*p == '\0') {
+ blocks_done = TRUE;
+ }
+ }
+ }
+
+ str = g_string_free (str_no_blocks, FALSE);
+
+ /* Now strip invalid chars */
+ g_strdelimit (str, invalid_chars, *invalid_chars_delimiter);
+ strv = g_strsplit (str, invalid_chars_delimiter, -1);
+ g_free (str);
+ str = g_strjoinv (NULL, strv);
+ g_strfreev (strv);
+
+ /* Now convert chars */
+ g_strdelimit (str, convert_chars, *convert_chars_delimiter);
+ strv = g_strsplit (str, convert_chars_delimiter, -1);
+ g_free (str);
+ str = g_strjoinv (convert_chars_delimiter, strv);
+ g_strfreev (strv);
+
+ /* Now remove double spaces */
+ strv = g_strsplit (str, " ", -1);
+ g_free (str);
+ str = g_strjoinv (" ", strv);
+ g_strfreev (strv);
+
+ /* Now strip leading/trailing white space */
+ g_strstrip (str);
+
+ res = g_utf8_strdown (str, -1);
+ g_free (str);
+
+ return res;
+}
+
static void
resolve_album_art (GrlMetadataSource *source,
GrlMetadataSourceResolveSpec *rs,
resolution_flags_t flags)
{
- /* FIXME: implement this, according to
- * http://live.gnome.org/MediaArtStorageSpec
- *
- * When this is implemented, _may_resolve() should be modified to accept
- * GrlMediaAudio.
+ const gchar *artist_value, *album_value;
+ gchar *artist, *album, *artist_md5, *album_md5, *file_path;
+ GRegex *regex;
+
+ artist_value = grl_media_audio_get_artist (GRL_MEDIA_AUDIO (rs->media));
+ album_value = grl_media_audio_get_album (GRL_MEDIA_AUDIO (rs->media));
+
+ if (!artist_value || !album_value)
+ return;
+
+ /* regex to find if we need to strip invalid chars
+ * ()[]<>{}_!@#$^&*+=|\\/\"'?~" and 2 or more spaces
*/
- GError *error;
- error = g_error_new (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED,
- "Thumbnail resolution for GrlMediaAudio not implemented in local-metadata");
- rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, error);
- g_error_free (error);
+
+ regex =
+ g_regex_new ("([\\(\\)\\[\\]\\<\\>\\{\\}_!@#$\\^&\\*"
+ "\\+=\\|\\\\/\\\"\\'\?~]|\\s{2,})",
+ 0, 0, NULL);
+
+ if ((g_regex_match (regex, artist_value, 0, NULL)))
+ artist = albumart_strip_invalid_entities (artist_value);
+ else
+ artist = g_utf8_strdown (artist_value, -1);
+
+ if (g_regex_match (regex, album_value, 0, NULL))
+ album = albumart_strip_invalid_entities (album_value);
+ else
+ album = g_utf8_strdown (album_value, -1);
+
+ g_regex_unref (regex);
+
+ artist_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, artist, -1);
+ album_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, album, -1);
+
+ file_path = g_strdup_printf ("%s/media-art/album-%s-%s.jpeg",
+ g_get_user_cache_dir (),
+ artist_md5,
+ album_md5);
+ g_free (album_md5);
+ g_free (artist_md5);
+
+ if (g_file_test (file_path, G_FILE_TEST_EXISTS))
+ {
+ gchar *thumbnail_uri = g_filename_to_uri (file_path, NULL, NULL);
+ grl_media_set_thumbnail (rs->media, thumbnail_uri);
+ g_free (thumbnail_uri);
+ g_free (file_path);
+
+ rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+ return;
+ }
}
static gboolean
@@ -683,6 +860,12 @@ grl_local_metadata_source_may_resolve (GrlMetadataSource *source,
return TRUE;
}
}
+
+ if (GRL_IS_MEDIA_AUDIO (media)) {
+ if (has_compatible_media_url (media) &&
+ (key_id == GRL_METADATA_KEY_THUMBNAIL))
+ return TRUE;
+ }
}
if (missing_keys)
--
1.7.8.rc0
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]