[tracker/media-art-enhancements: 4/5] tracker-extract: Rewrite tracker_albumart_find_external()
- From: Sam Thursfield <sthursfield src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/media-art-enhancements: 4/5] tracker-extract: Rewrite tracker_albumart_find_external()
- Date: Wed, 12 Oct 2011 14:18:01 +0000 (UTC)
commit bfe392d77778b0f4fdbf81f6cf7ed43642edfe14
Author: Sam Thursfield <sam thursfield codethink co uk>
Date: Wed Sep 28 19:54:16 2011 +0100
tracker-extract: Rewrite tracker_albumart_find_external()
The new code reads through the directory in one pass and allows more
detailed logic to run on the results, also taking into account the type
of media file.
src/tracker-extract/tracker-albumart.c | 249 +++++++++++++++++++++++---------
1 files changed, 179 insertions(+), 70 deletions(-)
---
diff --git a/src/tracker-extract/tracker-albumart.c b/src/tracker-extract/tracker-albumart.c
index 60da28e..d7a0cda 100644
--- a/src/tracker-extract/tracker-albumart.c
+++ b/src/tracker-extract/tracker-albumart.c
@@ -61,6 +61,12 @@ typedef struct {
gchar *local_uri;
} GetFileInfo;
+typedef struct {
+ gchar *uri;
+ TrackerMediaArtType type;
+ gchar *artist_strdown;
+ gchar *title_strdown;
+} TrackerMediaArtSearch;
static gboolean initialized;
static gboolean disable_requests;
@@ -74,6 +80,40 @@ albumart_queue_cb (GObject *source_object,
gpointer user_data);
+static GDir *
+get_parent_g_dir (const gchar *uri,
+ gchar **dirname,
+ GError **error)
+{
+ GFile *file, *dirf;
+ GDir *dir;
+
+ g_return_val_if_fail (dirname != NULL, NULL);
+
+ *dirname = NULL;
+
+ file = g_file_new_for_uri (uri);
+ dirf = g_file_get_parent (file);
+ if (dirf) {
+ *dirname = g_file_get_path (dirf);
+ g_object_unref (dirf);
+ }
+ g_object_unref (file);
+
+ if ((*dirname) == NULL) {
+ *error = g_error_new (G_FILE_ERROR,
+ G_FILE_ERROR_EXIST,
+ "No parent directory found for '%s'",
+ uri);
+ return NULL;
+ }
+
+ dir = g_dir_open (*dirname, 0, error);
+
+ return dir;
+}
+
+
static gchar *
checksum_for_data (GChecksumType checksum_type,
const guchar *data,
@@ -245,118 +285,187 @@ convert_from_other_format (const gchar *found,
return retval;
}
+static TrackerMediaArtSearch *
+tracker_media_art_search_new (const gchar *uri,
+ TrackerMediaArtType type,
+ const gchar *artist,
+ const gchar *title)
+{
+ TrackerMediaArtSearch *search;
+ gchar *temp;
+
+ search = g_slice_new0 (TrackerMediaArtSearch);
+ search->uri = g_strdup (uri);
+ search->type = type;
+
+ if (artist) {
+ temp = tracker_albumart_strip_invalid_entities (artist);
+ search->artist_strdown = g_utf8_strdown (temp, -1);
+ g_free (temp);
+ }
+
+ temp = tracker_albumart_strip_invalid_entities (title);
+ search->title_strdown = g_utf8_strdown (temp, -1);
+ g_free (temp);
+
+ return search;
+}
+
+static void
+tracker_media_art_search_free (TrackerMediaArtSearch *search)
+{
+ g_free (search->uri);
+ g_free (search->artist_strdown);
+ g_free (search->title_strdown);
+
+ g_slice_free (TrackerMediaArtSearch, search);
+}
+
+static int
+classify_image_file (TrackerMediaArtSearch *search,
+ const gchar *file_name_strdown)
+{
+ if ((search->artist_strdown && search->artist_strdown[0] != '\0' &&
+ strstr (file_name_strdown, search->artist_strdown)) ||
+ (search->title_strdown && search->title_strdown[0] != '\0' &&
+ strstr (file_name_strdown, search->title_strdown))) {
+ return 2;
+ }
+
+ if (search->type == TRACKER_MEDIA_ART_ALBUM) {
+ /* Accept cover, front, folder, AlbumArt_{GUID}_Large (first choice)
+ * second choice is AlbumArt_{GUID}_Small and AlbumArtSmall. We
+ * don't support just AlbumArt. (it must have a Small or Large) */
+
+ if (strstr (file_name_strdown, "cover") ||
+ strstr (file_name_strdown, "front") ||
+ strstr (file_name_strdown, "folder")) {
+ return 2;
+ }
+
+ if (strstr (file_name_strdown, "albumart")) {
+ if (strstr (file_name_strdown, "large")) {
+ return 2;
+ } else if (strstr (file_name_strdown, "small")) {
+ return 1;
+ }
+ }
+ }
+
+ if (search->type == TRACKER_MEDIA_ART_VIDEO) {
+ if (strstr (file_name_strdown, "folder") ||
+ strstr (file_name_strdown, "poster")) {
+ return 2;
+ }
+ }
+
+ /* Lowest priority for other images, but we still might use it for videos */
+ return 0;
+}
+
static gchar *
tracker_albumart_find_external (const gchar *uri,
TrackerMediaArtType type,
const gchar *artist,
const gchar *title)
{
- GFile *file, *dirf;
+ TrackerMediaArtSearch *search;
GDir *dir;
GError *error = NULL;
gchar *dirname = NULL;
- const gchar *name;
- gint count;
- gchar *artist_strdown, *title_strdown;
guint i;
- gchar *temp;
- gchar *art_file_path = NULL;
+ gchar *art_file_name;
+ gchar *art_file_path;
+ gint priority;
+
+ GList *image_list[3] = { NULL, NULL, NULL };
g_return_val_if_fail (type > TRACKER_MEDIA_ART_NONE && type < TRACKER_MEDIA_ART_TYPE_COUNT, FALSE);
g_return_val_if_fail (title != NULL, FALSE);
- file = g_file_new_for_uri (uri);
- dirf = g_file_get_parent (file);
- if (dirf) {
- dirname = g_file_get_path (dirf);
- g_object_unref (dirf);
- }
- g_object_unref (file);
+ search = tracker_media_art_search_new (uri, type, artist, title);
-
- if (!dirname) {
- g_debug ("No media art directory found for '%s'", uri);
- return FALSE;
- }
-
- dir = g_dir_open (dirname, 0, &error);
+ dir = get_parent_g_dir (uri, &dirname, &error);
if (!dir) {
- g_debug ("Media art directory could not be opened:'%s', %s",
- dirname,
+ g_debug ("Media art directory could not be opened: %s",
error ? error->message : "no error given");
g_clear_error (&error);
g_free (dirname);
+ tracker_media_art_search_free (search);
- return FALSE;
- }
-
- if (artist) {
- temp = tracker_albumart_strip_invalid_entities (artist);
- artist_strdown = g_utf8_strdown (temp, -1);
+ return NULL;
}
- temp = tracker_albumart_strip_invalid_entities (title);
- title_strdown = g_utf8_strdown (temp, -1);
+ /* First, classify each file in the directory as either an image, relevant
+ * to the media object in question, or irrelevant. We use this information
+ * to decide if the image is a cover or if the file is in a random directory.
+ */
- for (i = 0; i < 2 && !art_file_path; i++) {
- /* We loop twice to find secondary choices, or just once as soon as a
- * primary choice is found. When i != 0 it means that we're in the
- * secondary choice's loop (current only switch is 'large' vs. 'small') */
+ const gchar *name;
+ gchar *name_utf8, *name_strdown;
- g_dir_rewind (dir);
+ for (name = g_dir_read_name (dir);
+ name != NULL;
+ name = g_dir_read_name (dir)) {
- /* Try to find cover art in the directory */
- for (name = g_dir_read_name (dir), count = 0;
- name != NULL && art_file_path == NULL && count < 50;
- name = g_dir_read_name (dir), count++) {
- gchar *name_utf8, *name_strdown;
+ name_utf8 = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
- name_utf8 = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
+ if (!name_utf8) {
+ g_debug ("Could not convert filename '%s' to UTF-8", name);
+ continue;
+ }
- if (!name_utf8) {
- g_debug ("Could not convert filename '%s' to UTF-8", name);
- continue;
- }
+ name_strdown = g_utf8_strdown (name_utf8, -1);
- name_strdown = g_utf8_strdown (name_utf8, -1);
+ if (g_str_has_suffix (name_strdown, "jpeg") ||
+ g_str_has_suffix (name_strdown, "jpg") ||
+ g_str_has_suffix (name_strdown, "png")) {
- /* Accept cover, front, folder, AlbumArt_{GUID}_Large (first choice)
- * second choice is AlbumArt_{GUID}_Small and AlbumArtSmall. We
- * don't support just AlbumArt. (it must have a Small or Large) */
+ priority = classify_image_file (search, name_strdown);
+ image_list[priority] = g_list_prepend (image_list[priority], name_strdown);
+ } else {
+ g_free (name_strdown);
+ }
- if ((artist_strdown && artist_strdown[0] != '\0' && strstr (name_strdown, artist_strdown)) ||
- (title_strdown && title_strdown[0] != '\0' && strstr (name_strdown, title_strdown)) ||
- (strstr (name_strdown, "cover")) ||
- (strstr (name_strdown, "front")) ||
- (strstr (name_strdown, "folder")) ||
- ((strstr (name_strdown, "albumart") && strstr (name_strdown, i == 0 ? "large" : "small")))) {
+ g_free (name_utf8);
+ }
- if (g_str_has_suffix (name_strdown, "jpeg") ||
- g_str_has_suffix (name_strdown, "jpg") ||
- g_str_has_suffix (name_strdown, "png")) {
+ /* Use the results to pick a media art image */
- art_file_path = g_build_filename (dirname, name, NULL);
- }
- }
+ art_file_name = NULL;
+ art_file_path = NULL;
- g_free (name_utf8);
- g_free (name_strdown);
+ if (g_list_length (image_list[2]) > 0) {
+ /* Use the obvious choices, if available */
+ art_file_name = g_strdup (image_list[2]->data);
+ } else if (g_list_length (image_list[1]) > 0) {
+ art_file_name = g_strdup (image_list[1]->data);
+ } else {
+ if (type == TRACKER_MEDIA_ART_VIDEO && g_list_length (image_list[0]) == 1) {
+ /* For videos, if there was only one image in the directory
+ * use it as poster regardless of name */
+ art_file_name = g_strdup (image_list[0]->data);
}
}
- if (count >= 50) {
- g_debug ("Album art NOT found in same directory (over 50 files found)");
- } else if (!art_file_path) {
- g_debug ("Album art NOT found in same directory");
+ for (i = 0; i < 3; i ++) {
+ g_list_foreach (image_list[i], (GFunc)g_free, NULL);
+ g_list_free (image_list[i]);
}
- g_free (artist_strdown);
- g_free (title_strdown);
- g_free (dirname);
+ if (art_file_name) {
+ art_file_path = g_build_filename (dirname, art_file_name, NULL);
+ g_free (art_file_name);
+ } else {
+ g_debug ("Album art NOT found in same directory");
+ art_file_path = NULL;
+ }
+ tracker_media_art_search_free (search);
g_dir_close (dir);
+ g_free (dirname);
return art_file_path;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]