diff --git a/data/dbus/tracker-extract.xml b/data/dbus/tracker-extract.xml index 4d9de37..377ac59 100644 --- a/data/dbus/tracker-extract.xml +++ b/data/dbus/tracker-extract.xml @@ -21,5 +21,11 @@ + + + + + + diff --git a/src/libtracker-common/tracker-albumart.c b/src/libtracker-common/tracker-albumart.c index fb0fe7e..4fa1d37 100644 --- a/src/libtracker-common/tracker-albumart.c +++ b/src/libtracker-common/tracker-albumart.c @@ -41,6 +41,8 @@ #include #include +#include +#include #include "tracker-albumart.h" @@ -54,62 +56,32 @@ #define THUMBNAILER_PATH "/org/freedesktop/thumbnailer/Generic" #define THUMBNAILER_INTERFACE "org.freedesktop.thumbnailer.Generic" +#define ALBUMART_HEURISTIC_SCAN_TIMEOUT 30 + typedef struct { + gboolean no_more_requesting; + GHashTable *queue; + guint queue_timeout; TrackerHal *hal; - gchar *art_path; - gchar *local_uri; -} GetFileInfo; +} TrackerAlbumArtPrivate; -static gboolean no_more_requesting = FALSE; +typedef struct { + gchar *dirname; + gchar *album; + gchar *artist; + gchar *count; +} QueuedAlbumArtScanRequest; -static gchar * -my_compute_checksum_for_data (GChecksumType checksum_type, - const guchar *data, - gsize length) -{ - GChecksum *checksum; - gchar *retval; - - checksum = g_checksum_new (checksum_type); - if (!checksum) - return NULL; - - g_checksum_update (checksum, data, length); - retval = g_strdup (g_checksum_get_string (checksum)); - g_checksum_free (checksum); - - return retval; -} +typedef struct { + TrackerHal *hal; + gchar *album; + gchar *artist; + gchar *dirname; +} GetFileInfo; -#ifndef HAVE_STRCASESTR +static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT; -static gchar * -strcasestr (const gchar *haystack, - const gchar *needle) -{ - gchar *p; - gchar *startn = NULL; - gchar *np = NULL; - for (p = (gchar *) haystack; *p; p++) { - if (np) { - if (toupper (*p) == toupper (*np)) { - if (!*++np) { - return startn; - } - } else { - np = 0; - } - } else if (toupper (*p) == toupper (*needle)) { - np = (gchar *) needle + 1; - startn = p; - } - } - - return NULL; -} - -#endif /* HAVE_STRCASESTR */ /* NOTE: This function was stolen from GLib 2.18.x. Since upstream and * the Maemo branch don't have this in circulation yet, we have copied @@ -175,6 +147,144 @@ make_directory_with_parents (GFile *file, return g_file_make_directory (file, cancellable, error); } +static void +tracker_albumart_copy_to_local_if (const gchar *album_art_file, + const gchar *dirname) +{ + GList *removable_roots, *l; + gboolean on_removable_device = FALSE; + TrackerAlbumArtPrivate *private; + guint flen = dirname ? strlen (dirname) : 0; + + private = g_static_private_get (&private_key); + g_return_if_fail (private != NULL); + + + /* Determining if we are on a removable device */ +#ifdef HAVE_HAL + g_return_if_fail (private->hal != NULL); + + removable_roots = tracker_hal_get_removable_device_roots (private->hal); +#else + removable_roots = g_list_append (removable_roots, "/media"); + removable_roots = g_list_append (removable_roots, "/mnt"); +#endif + + for (l = removable_roots; l; l = l->next) { + guint len; + + len = strlen (l->data); + + if (flen >= len && strncmp (dirname, l->data, len) == 0) { + on_removable_device = TRUE; + break; + } + } + +#ifdef HAVE_HAL + g_list_foreach (removable_roots, (GFunc) g_free, NULL); +#endif + + g_list_free (removable_roots); + + /* Going to copy to .mediaartlocal if file is on a removable device */ + + if (on_removable_device) { + GError *error = NULL; + gchar *local_dir, *basename, *local_uri; + GFile *file, *parent; + + /* album_art_file points to the newly made album-art */ + file = g_file_new_for_path (album_art_file); + basename = g_file_get_basename (file); + + /* dirname points to the dir where the album is located */ + parent = g_file_new_for_path (dirname); + local_dir = g_file_get_uri (parent); + g_object_unref (parent); + + local_uri = g_strdup_printf ("%s/.mediaartlocal", local_dir); + parent = g_file_new_for_uri (local_uri); + + g_free (local_uri); + + /* Ensure directory is made */ + make_directory_with_parents (parent, NULL, &error); + + if (!error) { + GFile *local_file; + + /* This is a URI, don't use g_build_filename here */ + local_uri = g_strdup_printf ("%s/.mediaartlocal/%s", + local_dir, basename); + local_file = g_file_new_for_uri (local_uri); + g_free (local_uri); + + g_file_copy_async (file, local_file, 0, 0, + NULL, NULL, NULL, NULL, NULL); + + g_object_unref (local_file); + } else { + /* Removable media probably not writable, ignore */ + g_error_free (error); + } + + g_free (local_dir); + g_free (basename); + g_object_unref (file); + } +} + +static gchar * +my_compute_checksum_for_data (GChecksumType checksum_type, + const guchar *data, + gsize length) +{ + GChecksum *checksum; + gchar *retval; + + checksum = g_checksum_new (checksum_type); + if (!checksum) + return NULL; + + g_checksum_update (checksum, data, length); + retval = g_strdup (g_checksum_get_string (checksum)); + g_checksum_free (checksum); + + return retval; +} + +#ifndef HAVE_STRCASESTR + +static gchar * +strcasestr (const gchar *haystack, + const gchar *needle) +{ + gchar *p; + gchar *startn = NULL; + gchar *np = NULL; + + for (p = (gchar *) haystack; *p; p++) { + if (np) { + if (toupper (*p) == toupper (*np)) { + if (!*++np) { + return startn; + } + } else { + np = 0; + } + } else if (toupper (*p) == toupper (*needle)) { + np = (gchar *) needle + 1; + startn = p; + } + } + + return NULL; +} + +#endif /* HAVE_STRCASESTR */ + + static gchar* strip_characters (const gchar *original) { @@ -242,146 +352,40 @@ strip_characters (const gchar *original) return retval; } -void -tracker_albumart_copy_to_local (TrackerHal *hal, - const gchar *filename, - const gchar *local_uri) -{ - GList *removable_roots, *l; - gboolean on_removable_device = FALSE; - guint flen; - - g_return_if_fail (filename != NULL); - g_return_if_fail (local_uri != NULL); - - flen = strlen (filename); - - /* Determining if we are on a removable device */ -#ifdef HAVE_HAL - g_return_if_fail (hal != NULL); - - removable_roots = tracker_hal_get_removable_device_roots (hal); -#else - removable_roots = g_list_append (removable_roots, "/media"); - removable_roots = g_list_append (removable_roots, "/mnt"); -#endif - - for (l = removable_roots; l; l = l->next) { - guint len; - - len = strlen (l->data); - - if (flen >= len && strncmp (filename, l->data, len)) { - on_removable_device = TRUE; - break; - } - } - -#ifdef HAVE_HAL - g_list_foreach (removable_roots, (GFunc) g_free, NULL); -#endif - - g_list_free (removable_roots); - - if (on_removable_device) { - GFile *local_file, *from; - - from = g_file_new_for_path (filename); - local_file = g_file_new_for_uri (local_uri); - - /* We don't try to overwrite, but we also ignore all errors. - * Such an error could be that the removable device is - * read-only. Well that's fine then ... ignore */ - if (!g_file_query_exists (local_file, NULL)) { - GFile *dirf; - - dirf = g_file_get_parent (local_file); - make_directory_with_parents (dirf, NULL, NULL); - g_object_unref (dirf); - - g_file_copy_async (from, local_file, 0, 0, - NULL, NULL, NULL, NULL, NULL); - } - - g_object_unref (local_file); - g_object_unref (from); - } -} - -gboolean +static gboolean tracker_albumart_heuristic (const gchar *artist_, const gchar *album_, const gchar *tracks_str, - const gchar *filename, - const gchar *local_uri, - gboolean *copied) + const gchar *dirname) { - GFile *file; GDir *dir; struct stat st; gchar *target = NULL; - gchar *basename; const gchar *name; gboolean retval; gint tracks; gint count; gchar *artist = NULL; gchar *album = NULL; + GFile *file; - /* Copy from local album art (.mediaartlocal) to spec */ - if (local_uri) { - GFile *local_file; - - local_file = g_file_new_for_uri (local_uri); - - if (g_file_query_exists (local_file, NULL)) { - tracker_albumart_get_path (artist, album, - "album", NULL, - &target, NULL); - - file = g_file_new_for_path (target); - - g_file_copy_async (local_file, file, 0, 0, - NULL, NULL, NULL, NULL, NULL); - - g_object_unref (file); - g_object_unref (local_file); - - *copied = TRUE; - g_free (target); - - return TRUE; - } - - g_object_unref (local_file); - } - - *copied = FALSE; - - file = g_file_new_for_path (filename); - basename = g_file_get_basename (file); - g_object_unref (file); - - if (!basename) { - return FALSE; - } - - dir = g_dir_open (basename, 0, NULL); + dir = g_dir_open (dirname, 0, NULL); if (!dir) { - g_free (basename); return FALSE; } retval = FALSE; file = NULL; - g_stat (basename, &st); - count = st.st_nlink; - + g_stat (dirname, &st); + count = st.st_nlink + st.st_ino; + if (tracks_str) { tracks = atoi (tracks_str); + if (tracks == 0) + tracks = -1; } else { tracks = -1; } @@ -397,7 +401,7 @@ tracker_albumart_heuristic (const gchar *artist_, /* If amount of files and amount of tracks in the album somewhat match */ if ((tracks != -1 && tracks < count + 3 && tracks > count - 3) || - (tracks == -1 && count > 8 && count < 50)) { + (tracks == -1 && count >= 8 && count < 50)) { gchar *found = NULL; /* Try to find cover art in the directory */ @@ -413,19 +417,18 @@ tracker_albumart_heuristic (const gchar *artist_, if (!target) { tracker_albumart_get_path (artist, album, - "album", NULL, - &target, NULL); + "album", &target); } if (!file) { file = g_file_new_for_path (target); } - found = g_build_filename (basename, name, NULL); + found = g_build_filename (dirname, name, NULL); file_found = g_file_new_for_path (found); - + g_file_copy (file_found, file, 0, NULL, NULL, NULL, &error); - + if (!error) { retval = TRUE; } else { @@ -439,7 +442,7 @@ tracker_albumart_heuristic (const gchar *artist_, #ifdef HAVE_GDKPIXBUF GdkPixbuf *pixbuf; - found = g_build_filename (basename, name, NULL); + found = g_build_filename (dirname, name, NULL); pixbuf = gdk_pixbuf_new_from_file (found, &error); if (error) { @@ -447,16 +450,12 @@ tracker_albumart_heuristic (const gchar *artist_, retval = FALSE; } else { if (!target) { - tracker_albumart_get_path (artist, - album, - "album", - NULL, - &target, - NULL); + tracker_albumart_get_path (artist, album, + "album", &target); } gdk_pixbuf_save (pixbuf, target, "jpeg", &error, NULL); - + if (!error) { retval = TRUE; } else { @@ -472,6 +471,7 @@ tracker_albumart_heuristic (const gchar *artist_, } if (retval) { + tracker_albumart_copy_to_local_if (target, dirname); break; } } @@ -486,7 +486,6 @@ tracker_albumart_heuristic (const gchar *artist_, } g_free (target); - g_free (basename); g_free (artist); g_free (album); @@ -525,6 +524,11 @@ tracker_albumart_queue_cb (DBusGProxy *proxy, GError *error = NULL; guint handle; GetFileInfo *info; + gchar *art_path; + TrackerAlbumArtPrivate *private; + + private = g_static_private_get (&private_key); + g_return_if_fail (private != NULL); info = user_data; @@ -534,43 +538,47 @@ tracker_albumart_queue_cb (DBusGProxy *proxy, if (error) { if (error->code == DBUS_GERROR_SERVICE_UNKNOWN) - no_more_requesting = TRUE; + private->no_more_requesting = TRUE; else g_warning ("%s", error->message); g_clear_error (&error); + + return; } - if (info->art_path && - g_file_test (info->art_path, G_FILE_TEST_EXISTS)) { + tracker_albumart_get_path (info->artist, info->album, + "album", &art_path); + + if (art_path && g_file_test (art_path, G_FILE_TEST_EXISTS)) { gchar *uri; - - uri = g_filename_to_uri (info->art_path, NULL, NULL); + + uri = g_filename_to_uri (art_path, NULL, NULL); tracker_thumbnailer_queue_file (uri, "image/jpeg"); g_free (uri); - tracker_albumart_copy_to_local (info->hal, - info->art_path, - info->local_uri); + tracker_albumart_copy_to_local_if (art_path, info->dirname); } - g_free (info->art_path); - g_free (info->local_uri); + g_free (art_path); if (info->hal) { g_object_unref (info->hal); } + g_free (info->artist); + g_free (info->album); + g_free (info->dirname); + g_slice_free (GetFileInfo, info); } void -tracker_albumart_get_path (const gchar *a, - const gchar *b, +tracker_albumart_get_path (const gchar *album, + const gchar *artist, const gchar *prefix, - const gchar *uri, - gchar **path, - gchar **local_uri) + gchar **path) { + const gchar *a = album, *b = artist; gchar *art_filename; gchar *dir; gchar *down1, *down2; @@ -583,10 +591,6 @@ tracker_albumart_get_path (const gchar *a, *path = NULL; } - if (local_uri) { - *local_uri = NULL; - } - if (!a && !b) { return; } @@ -628,45 +632,27 @@ tracker_albumart_get_path (const gchar *a, *path = g_build_filename (dir, art_filename, NULL); - if (local_uri) { - gchar *local_dir; - GFile *file, *parent; - - if (strchr (uri, ':')) { - file = g_file_new_for_uri (uri); - } else { - file = g_file_new_for_path (uri); - } - - parent = g_file_get_parent (file); - local_dir = g_file_get_uri (parent); - - /* This is a URI, don't use g_build_filename here */ - *local_uri = g_strdup_printf ("%s/.mediaartlocal/%s", local_dir, art_filename); - - g_free (local_dir); - g_object_unref (file); - g_object_unref (parent); - } - g_free (dir); g_free (art_filename); g_free (str1); g_free (str2); } -void +static void tracker_albumart_request_download (TrackerHal *hal, const gchar *album, - const gchar *artist, - const gchar *local_uri, - const gchar *art_path) + const gchar *artist, + const gchar *dirname) { GetFileInfo *info; + TrackerAlbumArtPrivate *private; + + private = g_static_private_get (&private_key); + g_return_if_fail (private != NULL); g_return_if_fail (hal != NULL); - if (no_more_requesting) { + if (private->no_more_requesting) { return; } @@ -678,8 +664,9 @@ tracker_albumart_request_download (TrackerHal *hal, info->hal = NULL; #endif - info->local_uri = g_strdup (local_uri); - info->art_path = g_strdup (art_path); + info->album = g_strdup (album); + info->artist = g_strdup (artist); + info->dirname = g_strdup (dirname); dbus_g_proxy_begin_call (get_albumart_requester (), "Queue", @@ -691,3 +678,149 @@ tracker_albumart_request_download (TrackerHal *hal, G_TYPE_UINT, 0, G_TYPE_INVALID); } + + +static void +queued_album_art_scan_request_free (QueuedAlbumArtScanRequest *info) +{ + g_free (info->dirname); + g_free (info->album); + g_free (info->artist); + g_free (info->count); + g_slice_free (QueuedAlbumArtScanRequest, info); +} + +static gboolean +on_queue_timeout (gpointer user_data) +{ + if (!g_source_is_destroyed (g_main_current_source ())) { + TrackerAlbumArtPrivate *private; + GHashTableIter iter; + gpointer key, value; + + private = g_static_private_get (&private_key); + g_return_val_if_fail (private != NULL, FALSE); + + g_hash_table_iter_init (&iter, private->queue); + + while (g_hash_table_iter_next (&iter, &key, &value)) { + QueuedAlbumArtScanRequest *info = value; + + if (!tracker_albumart_heuristic (info->artist, + info->album, + info->count, + info->dirname)) { + + /* If the heuristic failed, we request the download + * of the media-art to the media-art downloaders */ + + tracker_albumart_request_download (private->hal, + info->artist, + info->album, + info->dirname); + } + + /* Once handled, we remove from the queue */ + g_hash_table_iter_remove (&iter); + } + + } + + return FALSE; +} + +void +tracker_albumart_heuristic_queue (const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count) +{ + TrackerAlbumArtPrivate *private; + gchar *key; + QueuedAlbumArtScanRequest *info; + + private = g_static_private_get (&private_key); + g_return_if_fail (private != NULL); + + key = g_strdup_printf ("%s%s%s", dirname, album, artist); + info = g_slice_new (QueuedAlbumArtScanRequest); + + /* This method is typically called-for by the extractors. It's a request + * for us (we're the delegate here) to do a heuristic scan for album-art. + * + * This is a non-urgent request and these can happen rapidly with the + * same directory/album/artist combination many times in a row. + * + * We are allowed to merge such requests together and perform it delayed */ + + info->dirname = g_strdup (dirname); + info->album = g_strdup (album); + info->artist = g_strdup (artist); + info->count = g_strdup (count); + + g_hash_table_replace (private->queue, key, info); + + /* If there's a queue-run already enqueued, then we'll remove that one + * and we'll start a new one. */ + + if (private->queue_timeout != 0) { + g_source_remove (private->queue_timeout); + } + + /* We hope to collect all requests for a album-art heuristic scan for + * a given combination of album, artist and directory within 30 seconds. + * + * If a request comes after 30 seconds then that's too bad, we'll just + * do a new heuristic scan in that case.*/ + + private->queue_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + ALBUMART_HEURISTIC_SCAN_TIMEOUT, + on_queue_timeout, NULL, + NULL); +} + + +static void +private_free (gpointer data) +{ + TrackerAlbumArtPrivate *private; + + private = data; + + if (private->queue_timeout != 0) { + g_source_remove (private->queue_timeout); + } + + on_queue_timeout (private->queue); + + g_hash_table_destroy (private->queue); + g_object_unref (private->hal); + + g_free (private); +} + + +void +tracker_albumart_init (void) +{ + TrackerAlbumArtPrivate *private; + + private = g_new0 (TrackerAlbumArtPrivate, 1); + + private->queue_timeout = 0; + private->no_more_requesting = FALSE; + private->hal = tracker_hal_new (); + private->queue = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) queued_album_art_scan_request_free); + + g_static_private_set (&private_key, + private, + private_free); +} + +void +tracker_albumart_shutdown (void) +{ + g_static_private_set (&private_key, NULL, NULL); +} diff --git a/src/libtracker-common/tracker-albumart.h b/src/libtracker-common/tracker-albumart.h index 9e7e15a..60fc017 100644 --- a/src/libtracker-common/tracker-albumart.h +++ b/src/libtracker-common/tracker-albumart.h @@ -32,26 +32,19 @@ G_BEGIN_DECLS #include "tracker-hal.h" -gboolean tracker_albumart_heuristic (const gchar *artist_, - const gchar *album_, - const gchar *tracks_str, - const gchar *filename, - const gchar *local_uri, - gboolean *copied); -void tracker_albumart_copy_to_local (TrackerHal *hal, - const gchar *filename, - const gchar *local_uri); -void tracker_albumart_get_path (const gchar *a, - const gchar *b, +void tracker_albumart_heuristic_queue (const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count); + +void tracker_albumart_get_path (const gchar *album, + const gchar *artist, const gchar *prefix, - const gchar *uri, - gchar **path, - gchar **local); -void tracker_albumart_request_download (TrackerHal *hal, - const gchar *album, - const gchar *artist, - const gchar *local_uri, - const gchar *art_path); + gchar **path); + +void tracker_albumart_init (void); +void tracker_albumart_shutdown (void); + G_END_DECLS diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am index 0a660cb..7ad0a70 100644 --- a/src/tracker-extract/Makefile.am +++ b/src/tracker-extract/Makefile.am @@ -211,6 +211,7 @@ libextract_playlist_la_LIBADD = $(GLIB2_LIBS) $(TOTEM_PL_PARSER_LIBS) $(GCOV_LIB libexec_PROGRAMS = tracker-extract tracker_extract_SOURCES = \ + tracker-marshal-main.c \ tracker-dbus.c \ tracker-dbus.h \ tracker-extract.c \ @@ -231,7 +232,23 @@ dbus_sources = \ %-glue.h: $(top_srcdir)/data/dbus/%.xml $(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^ +tracker-marshal.h: tracker-marshal.list + $(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --header > $@ + +tracker-marshal.c: tracker-marshal.list + $(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --body > $@ + +tracker-marshal-main.c: tracker-marshal.c tracker-marshal.h + +marshal_sources = \ + tracker-marshal.h \ + tracker-marshal.c + BUILT_SOURCES = \ - $(dbus_sources) + $(dbus_sources) \ + $(marshal_sources) CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = tracker-marshal.list + diff --git a/src/tracker-extract/tracker-extract-albumart.c b/src/tracker-extract/tracker-extract-albumart.c index 206a836..c8e2f42 100644 --- a/src/tracker-extract/tracker-extract-albumart.c +++ b/src/tracker-extract/tracker-extract-albumart.c @@ -42,6 +42,7 @@ #include "tracker-main.h" #include "tracker-extract-albumart.h" +#include "tracker-extract.h" #ifdef HAVE_GDKPIXBUF @@ -64,7 +65,7 @@ set_albumart (const unsigned char *buffer, return FALSE; } - tracker_albumart_get_path (artist, album, "album", NULL, &filename, NULL); + tracker_albumart_get_path (artist, album, "album", &filename); loader = gdk_pixbuf_loader_new (); @@ -116,27 +117,10 @@ tracker_process_albumart (const unsigned char *buffer, { gchar *art_path; gboolean retval = TRUE; - gchar *local_uri = NULL; - gchar *filename_uri; - gboolean lcopied = FALSE; - - if (strchr (filename, ':')) { - filename_uri = g_strdup (filename); - } else { - filename_uri = g_filename_to_uri (filename, NULL, NULL); - } - tracker_albumart_get_path (artist, - album, - "album", - filename_uri, - &art_path, - &local_uri); + tracker_albumart_get_path (artist, album, "album", &art_path); if (!art_path) { - g_free (filename_uri); - g_free (local_uri); - return FALSE; } @@ -144,61 +128,21 @@ tracker_process_albumart (const unsigned char *buffer, #ifdef HAVE_GDKPIXBUF /* If we have embedded album art */ if (buffer && len) { - retval = set_albumart (buffer, - len, - artist, - album, - filename); - - lcopied = !retval; - + retval = set_albumart (buffer, len, artist, album, filename); } else { #endif /* HAVE_GDK_PIXBUF */ - /* If not, we perform a heuristic on the dir */ - if (!tracker_albumart_heuristic (artist, album, - trackercnt_str, - filename, - local_uri, - &lcopied)) { - - /* If the heuristic failed, we request the download - * of the media-art to the media-art downloaders */ - lcopied = TRUE; - tracker_albumart_request_download (tracker_main_get_hal (), - artist, - album, - local_uri, - art_path); - } + gchar *dirname = g_path_get_dirname (filename); + tracker_extract_emit_scan_for_albumart (dirname, artist, + album, trackercnt_str); + g_free (dirname); + #ifdef HAVE_GDKPIXBUF } #endif /* HAVE_GDKPIXBUF */ - /* If the heuristic didn't copy from the .mediaartlocal, then - * we'll perhaps copy it to .mediaartlocal (perhaps because this - * only copies in case the media is located on a removable - * device */ - - if (g_file_test (art_path, G_FILE_TEST_EXISTS)) { - gchar *as_uri; - - as_uri = g_filename_to_uri (art_path, NULL, NULL); - tracker_thumbnailer_queue_file (as_uri, "image/jpeg"); - g_free (as_uri); - } - - } - - if (local_uri && !g_file_test (local_uri, G_FILE_TEST_EXISTS)) { - if (g_file_test (art_path, G_FILE_TEST_EXISTS)) - tracker_albumart_copy_to_local (tracker_main_get_hal (), - art_path, - local_uri); } g_free (art_path); - g_free (filename_uri); - g_free (local_uri); return retval; } diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c index 648ed8b..1cd673f 100644 --- a/src/tracker-extract/tracker-extract.c +++ b/src/tracker-extract/tracker-extract.c @@ -30,7 +30,11 @@ #include "tracker-main.h" #include "tracker-dbus.h" +#include "tracker-marshal.h" + +#define TRACKER_EXTRACT_C #include "tracker-extract.h" +#undef TRACKER_EXTRACT_C #define MAX_EXTRACT_TIME 5 #define TRACKER_EXTRACT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EXTRACT, TrackerExtractPrivate)) @@ -39,10 +43,21 @@ typedef struct { GArray *extractors; } TrackerExtractPrivate; + +enum { + TO_SCAN_FOR_ALBUMART, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + + static void tracker_extract_finalize (GObject *object); G_DEFINE_TYPE(TrackerExtract, tracker_extract, G_TYPE_OBJECT) +TrackerExtract *dbus_object = NULL; + static void tracker_extract_class_init (TrackerExtractClass *klass) { @@ -50,6 +65,20 @@ tracker_extract_class_init (TrackerExtractClass *klass) object_class = G_OBJECT_CLASS (klass); + signals[TO_SCAN_FOR_ALBUMART] = + g_signal_new ("to-scan-for-albumart", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TrackerExtractClass, to_scan_for_albumart), + NULL, NULL, + tracker_marshal_VOID__STRING_STRING_STRING_STRING, + G_TYPE_NONE, + 4, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + object_class->finalize = tracker_extract_finalize; g_type_class_add_private (object_class, sizeof (TrackerExtractPrivate)); @@ -60,6 +89,19 @@ tracker_extract_init (TrackerExtract *object) { } +void +tracker_extract_emit_scan_for_albumart (const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count) +{ + if (dbus_object) { + g_signal_emit (dbus_object, signals[TO_SCAN_FOR_ALBUMART], 0, + dirname, artist, album, count); + } +} + + static void tracker_extract_finalize (GObject *object) { @@ -166,6 +208,8 @@ tracker_extract_new (void) priv->extractors = extractors; + dbus_object = object; + return object; } diff --git a/src/tracker-extract/tracker-extract.h b/src/tracker-extract/tracker-extract.h index 8cc031f..33fc669 100644 --- a/src/tracker-extract/tracker-extract.h +++ b/src/tracker-extract/tracker-extract.h @@ -47,6 +47,11 @@ struct TrackerExtract { struct TrackerExtractClass { GObjectClass parent; + + void (*to_scan_for_albumart) (const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count); }; GType tracker_extract_get_type (void); @@ -60,11 +65,18 @@ void tracker_extract_get_metadata (TrackerExtract DBusGMethodInvocation *context, GError **error); +void tracker_extract_emit_scan_for_albumart (const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count); + /* Not DBus API, convenience for command line */ void tracker_extract_get_metadata_by_cmdline (TrackerExtract *object, const gchar *path, const gchar *mime); + + G_END_DECLS #endif /* __TRACKERD_EXTRACT_H__ */ diff --git a/src/tracker-indexer/tracker-main.c b/src/tracker-indexer/tracker-main.c index 8106af4..720c6cd 100644 --- a/src/tracker-indexer/tracker-main.c +++ b/src/tracker-indexer/tracker-main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -391,6 +392,7 @@ main (gint argc, gchar *argv[]) /* Set up connections to the thumbnailer if supported */ tracker_thumbnailer_init (config); + tracker_albumart_init (); if (process_all) { /* Tell the indexer to process all configured modules */ @@ -431,6 +433,7 @@ main (gint argc, gchar *argv[]) tracker_push_shutdown (); + tracker_albumart_shutdown (); tracker_thumbnailer_shutdown (); tracker_dbus_shutdown (); tracker_db_index_manager_shutdown (); diff --git a/src/tracker-indexer/tracker-marshal.list b/src/tracker-indexer/tracker-marshal.list index f17b920..bca43c9 100644 --- a/src/tracker-indexer/tracker-marshal.list +++ b/src/tracker-indexer/tracker-marshal.list @@ -1,3 +1,4 @@ VOID:DOUBLE,UINT,UINT,BOOL VOID:DOUBLE,STRING,UINT,UINT,UINT VOID:STRING,BOOL +VOID:STRING,STRING,STRING,STRING diff --git a/src/tracker-indexer/tracker-module-metadata-utils.c b/src/tracker-indexer/tracker-module-metadata-utils.c index b830efd..2ee26b2 100644 --- a/src/tracker-indexer/tracker-module-metadata-utils.c +++ b/src/tracker-indexer/tracker-module-metadata-utils.c @@ -37,10 +37,12 @@ #include #include #include +#include #include "tracker-module-metadata-utils.h" #include "tracker-extract-client.h" #include "tracker-dbus.h" +#include "tracker-marshal.h" #define METADATA_FILE_NAME_DELIMITED "File:NameDelimited" #define METADATA_FILE_EXT "File:Ext" @@ -73,6 +75,18 @@ typedef struct { GPid pid; } ExtractorContext; + +static void +extractor_asks_to_scan_for_albumart (DBusGProxy *proxy, + const gchar *dirname, + const gchar *artist, + const gchar *album, + const gchar *count, + gpointer user_data) +{ + tracker_albumart_heuristic_queue (dirname, artist, album, count); +} + static DBusGProxy * get_dbus_extract_proxy (void) { @@ -104,6 +118,26 @@ get_dbus_extract_proxy (void) g_critical ("Could not create a DBusGProxy to the extract service"); } + dbus_g_object_register_marshaller (tracker_marshal_VOID__STRING_STRING_STRING_STRING, + G_TYPE_NONE, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_add_signal (proxy, + "ToScanForAlbumart", + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (proxy, "ToScanForAlbumart", + G_CALLBACK (extractor_asks_to_scan_for_albumart), + NULL, NULL); + return proxy; }