Commit 2bf21059 authored by Martyn Russell's avatar Martyn Russell

tracker-extract: push all albumart code to tracker-miner-fs

Now we signal data that is used to be processed for albumart. This is
all handled in the miner-fs now, so the extractors simply say, here is
my data and length of data (and some other details like artist), now
process it. The miner-fs then uses the code previously
tracker-extract-albumart.c to either download the art, use GdkPixbuf
or save the data directly to the right filename. The thumbnails are
then requested staight after.
parent 036a5b4a
......@@ -22,8 +22,13 @@
<arg type="s" name="sparql" direction="out" />
</method>
<signal name="NeedsThumbnailing">
<arg type="s" name="uri"/>
<signal name="ProcessAlbumArt">
<arg type="y" name="buffer"/>
<arg type="i" name="size"/>
<arg type="s" name="mime"/>
<arg type="s" name="artist"/>
<arg type="s" name="album"/>
<arg type="s" name="filename"/>
</signal>
</interface>
</node>
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2006, Mr Jamie McCracken (jamiemcc@gnome.org)
* Copyright (C) 2008, Nokia
* This library is free software; you can redistribute it and/or
......@@ -63,16 +62,17 @@ typedef struct {
static gboolean no_more_requesting = FALSE;
static gchar *
my_compute_checksum_for_data (GChecksumType checksum_type,
const guchar *data,
gsize length)
checksum_for_data (GChecksumType checksum_type,
const guchar *data,
gsize length)
{
GChecksum *checksum;
gchar *retval;
checksum = g_checksum_new (checksum_type);
if (!checksum)
if (!checksum) {
return NULL;
}
g_checksum_update (checksum, data, length);
retval = g_strdup (g_checksum_get_string (checksum));
......@@ -304,9 +304,9 @@ tracker_albumart_strip_invalid_entities (const gchar *original)
}
void
tracker_albumart_copy_to_local (TrackerStorage *hal,
const gchar *filename,
const gchar *local_uri)
tracker_albumart_copy_to_local (TrackerStorage *hal,
const gchar *filename,
const gchar *local_uri)
{
GList *removable_roots, *l;
gboolean on_removable_device = FALSE;
......@@ -371,9 +371,8 @@ tracker_albumart_copy_to_local (TrackerStorage *hal,
}
gboolean
tracker_albumart_heuristic (const gchar *artist_,
const gchar *album_,
const gchar *tracks_str,
tracker_albumart_heuristic (const gchar *artist,
const gchar *album,
const gchar *filename,
const gchar *local_uri,
gboolean *copied)
......@@ -386,13 +385,25 @@ tracker_albumart_heuristic (const gchar *artist_,
const gchar *name;
gboolean retval;
gint count;
gchar *artist = NULL;
gchar *album = NULL;
gchar *artist_stripped = NULL;
gchar *album_stripped = NULL;
g_return_val_if_fail (artist != NULL, FALSE);
g_return_val_if_fail (album != NULL, FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
if (copied) {
*copied = FALSE;
}
if (artist) {
artist_stripped = tracker_albumart_strip_invalid_entities (artist);
}
if (album) {
album_stripped = tracker_albumart_strip_invalid_entities (album);
}
/* Copy from local album art (.mediaartlocal) to spec */
if (local_uri) {
GFile *local_file;
......@@ -400,7 +411,8 @@ tracker_albumart_heuristic (const gchar *artist_,
local_file = g_file_new_for_uri (local_uri);
if (g_file_query_exists (local_file, NULL)) {
tracker_albumart_get_path (artist, album,
tracker_albumart_get_path (artist_stripped,
album_stripped,
"album", NULL,
&target, NULL);
if (target) {
......@@ -418,6 +430,8 @@ tracker_albumart_heuristic (const gchar *artist_,
}
g_free (target);
g_free (artist_stripped);
g_free (album_stripped);
return TRUE;
}
......@@ -432,13 +446,19 @@ tracker_albumart_heuristic (const gchar *artist_,
g_object_unref (dirf);
if (!dirname) {
g_free (artist_stripped);
g_free (album_stripped);
return FALSE;
}
dir = g_dir_open (dirname, 0, NULL);
if (!dir) {
g_free (artist_stripped);
g_free (album_stripped);
g_free (dirname);
return FALSE;
}
......@@ -448,21 +468,17 @@ tracker_albumart_heuristic (const gchar *artist_,
if (g_stat (dirname, &st) == -1) {
g_warning ("Could not g_stat() directory:'%s' for albumart heuristic",
dirname);
g_free (dirname);
g_free (artist_stripped);
g_free (album_stripped);
return FALSE;
}
/* do not count . and .. */
count = st.st_nlink - 2;
if (artist_) {
artist = tracker_albumart_strip_invalid_entities (artist_);
}
if (album_) {
album = tracker_albumart_strip_invalid_entities (album_);
}
/* If amount of files and amount of tracks in the album somewhat match */
if (count >= 2 && count < 50) {
......@@ -470,15 +486,16 @@ tracker_albumart_heuristic (const gchar *artist_,
/* Try to find cover art in the directory */
for (name = g_dir_read_name (dir); name; name = g_dir_read_name (dir)) {
if ((artist && strcasestr (name, artist)) ||
(album && strcasestr (name, album)) ||
if ((artist_stripped && strcasestr (name, artist_stripped)) ||
(album_stripped && strcasestr (name, album_stripped)) ||
(strcasestr (name, "cover"))) {
GError *error = NULL;
if (g_str_has_suffix (name, "jpeg") ||
g_str_has_suffix (name, "jpg")) {
if (!target) {
tracker_albumart_get_path (artist, album,
tracker_albumart_get_path (artist_stripped,
album_stripped,
"album", NULL,
&target, NULL);
}
......@@ -519,8 +536,8 @@ tracker_albumart_heuristic (const gchar *artist_,
retval = FALSE;
} else {
if (!target) {
tracker_albumart_get_path (artist,
album,
tracker_albumart_get_path (artist_stripped,
album_stripped,
"album",
NULL,
&target,
......@@ -560,8 +577,8 @@ tracker_albumart_heuristic (const gchar *artist_,
g_free (target);
g_free (dirname);
g_free (artist);
g_free (album);
g_free (artist_stripped);
g_free (album_stripped);
return retval;
}
......@@ -618,7 +635,7 @@ tracker_albumart_queue_cb (DBusGProxy *proxy,
gchar *uri;
uri = g_filename_to_uri (info->art_path, NULL, NULL);
tracker_thumbnailer_queue_file (uri, "image/jpeg");
tracker_thumbnailer_queue_add (uri, "image/jpeg");
g_free (uri);
tracker_albumart_copy_to_local (info->hal,
......@@ -637,8 +654,8 @@ tracker_albumart_queue_cb (DBusGProxy *proxy,
}
void
tracker_albumart_get_path (const gchar *a,
const gchar *b,
tracker_albumart_get_path (const gchar *artist,
const gchar *album,
const gchar *prefix,
const gchar *uri,
gchar **path,
......@@ -646,9 +663,12 @@ tracker_albumart_get_path (const gchar *a,
{
gchar *art_filename;
gchar *dir;
gchar *down1, *down2;
gchar *str1 = NULL, *str2 = NULL;
gchar *f_a = NULL, *f_b = NULL;
gchar *artist_down, *album_down;
gchar *artist_stripped, *album_stripped;
gchar *artist_checksum, *album_checksum;
/* g_return_if_fail ((local_uri != NULL && uri != NULL) || local_uri == NULL); */
/* g_return_if_fail (artist != NULL || album != NULL); */
/* http://live.gnome.org/MediaArtStorageSpec */
......@@ -660,46 +680,54 @@ tracker_albumart_get_path (const gchar *a,
*local_uri = NULL;
}
if (!a && !b) {
if (!artist && !album) {
return;
}
if (!a) {
f_a = g_strdup (" ");
if (!artist) {
artist_stripped = g_strdup (" ");
} else {
f_a = tracker_albumart_strip_invalid_entities (a);
artist_stripped = tracker_albumart_strip_invalid_entities (artist);
}
if (!b) {
f_b = g_strdup (" ");
if (!album) {
album_stripped = g_strdup (" ");
} else {
f_b = tracker_albumart_strip_invalid_entities (b);
album_stripped = tracker_albumart_strip_invalid_entities (album);
}
down1 = g_utf8_strdown (f_a, -1);
down2 = g_utf8_strdown (f_b, -1);
artist_down = g_utf8_strdown (artist_stripped, -1);
album_down = g_utf8_strdown (album_stripped, -1);
g_free (f_a);
g_free (f_b);
g_free (artist_stripped);
g_free (album_stripped);
dir = g_build_filename (g_get_user_cache_dir (), "media-art", NULL);
dir = g_build_filename (g_get_user_cache_dir (),
"media-art",
NULL);
if (!g_file_test (dir, G_FILE_TEST_EXISTS)) {
g_mkdir_with_parents (dir, 0770);
}
str1 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down1, strlen (down1));
str2 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down2, strlen (down2));
g_free (down1);
g_free (down2);
artist_checksum = checksum_for_data (G_CHECKSUM_MD5,
(const guchar *) artist_down,
strlen (artist_down));
album_checksum = checksum_for_data (G_CHECKSUM_MD5,
(const guchar *) album_down,
strlen (album_down));
g_free (artist_down);
g_free (album_down);
art_filename = g_strdup_printf ("%s-%s-%s.jpeg",
prefix ? prefix : "album",
str1,
str2);
artist_checksum,
album_checksum);
*path = g_build_filename (dir, art_filename, NULL);
if (path) {
*path = g_build_filename (dir, art_filename, NULL);
}
if (local_uri) {
gchar *local_dir;
......@@ -724,19 +752,20 @@ tracker_albumart_get_path (const gchar *a,
g_free (dir);
g_free (art_filename);
g_free (str1);
g_free (str2);
g_free (artist_checksum);
g_free (album_checksum);
}
void
tracker_albumart_request_download (TrackerStorage *hal,
const gchar *album,
const gchar *artist,
const gchar *local_uri,
const gchar *art_path)
const gchar *album,
const gchar *artist,
const gchar *local_uri,
const gchar *art_path)
{
GetFileInfo *info;
if (no_more_requesting) {
return;
}
......@@ -744,7 +773,7 @@ tracker_albumart_request_download (TrackerStorage *hal,
info = g_slice_new (GetFileInfo);
#ifdef HAVE_HAL
info->hal = hal?g_object_ref (hal):NULL;
info->hal = hal ? g_object_ref (hal) : NULL;
#else
info->hal = NULL;
#endif
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2006, Mr Jamie McCracken (jamiemcc@gnome.org)
* Copyright (C) 2008, Nokia
* This library is free software; you can redistribute it and/or
......@@ -34,7 +33,6 @@ G_BEGIN_DECLS
gboolean tracker_albumart_heuristic (const gchar *artist_,
const gchar *album_,
const gchar *tracks_str,
const gchar *filename,
const gchar *local_uri,
gboolean *copied);
......
......@@ -50,7 +50,6 @@ typedef struct {
guint request_id;
gboolean service_is_available;
gboolean service_is_enabled;
} TrackerThumbnailerPrivate;
static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
......@@ -113,8 +112,6 @@ tracker_thumbnailer_init (void)
private = g_new0 (TrackerThumbnailerPrivate, 1);
private->service_is_enabled = TRUE;
g_static_private_set (&private_key,
private,
private_free);
......@@ -224,13 +221,13 @@ tracker_thumbnailer_move (const gchar *from_uri,
to_uri,
private->request_id);
if (!strstr (to_uri, ":/")) {
if (!strstr (to_uri, "://")) {
to[0] = g_filename_to_uri (to_uri, NULL, NULL);
} else {
to[0] = g_strdup (to_uri);
}
if (!strstr (from_uri, ":/")) {
if (!strstr (from_uri, "://")) {
from[0] = g_filename_to_uri (from_uri, NULL, NULL);
} else {
from[0] = g_strdup (from_uri);
......@@ -278,7 +275,7 @@ tracker_thumbnailer_remove (const gchar *uri,
private->request_id++;
if (!strstr (uri, ":/")) {
if (!strstr (uri, "://")) {
uris[0] = g_filename_to_uri (uri, NULL, NULL);
} else {
uris[0] = g_strdup (uri);
......@@ -302,6 +299,8 @@ tracker_thumbnailer_cleanup (const gchar *uri_prefix)
{
TrackerThumbnailerPrivate *private;
g_return_if_fail (uri_prefix != NULL);
private = g_static_private_get (&private_key);
g_return_if_fail (private != NULL);
......@@ -328,8 +327,8 @@ tracker_thumbnailer_cleanup (const gchar *uri_prefix)
}
void
tracker_thumbnailer_queue_file (const gchar *uri,
const gchar *mime_type)
tracker_thumbnailer_queue_add (const gchar *uri,
const gchar *mime_type)
{
TrackerThumbnailerPrivate *private;
gchar *used_uri;
......@@ -341,8 +340,7 @@ tracker_thumbnailer_queue_file (const gchar *uri,
private = g_static_private_get (&private_key);
g_return_if_fail (private != NULL);
if (!private->service_is_available ||
!private->service_is_enabled) {
if (!private->service_is_available) {
return;
}
......@@ -356,7 +354,7 @@ tracker_thumbnailer_queue_file (const gchar *uri,
private->request_id++;
/* Add new URI (detect if we got passed a path) */
if (!strstr (uri, ":/")) {
if (!strstr (uri, "://")) {
used_uri = g_filename_to_uri (uri, NULL, NULL);
} else {
used_uri = g_strdup (uri);
......
......@@ -30,16 +30,15 @@ G_BEGIN_DECLS
void tracker_thumbnailer_init (void);
void tracker_thumbnailer_shutdown (void);
void tracker_thumbnailer_queue_file (const gchar *path,
const gchar *mime);
void tracker_thumbnailer_queue_add (const gchar *uri,
const gchar *mime);
void tracker_thumbnailer_queue_send (void);
void tracker_thumbnailer_move (const gchar *from_uri,
const gchar *mime_type,
const gchar *to_uri);
void tracker_thumbnailer_remove (const gchar *uri,
const gchar *mime_type);
void tracker_thumbnailer_cleanup (const gchar *uri_prefix);
void tracker_thumbnailer_move (const gchar *from_uri,
const gchar *mime_type,
const gchar *to_uri);
void tracker_thumbnailer_remove (const gchar *uri,
const gchar *mime_type);
void tracker_thumbnailer_cleanup (const gchar *uri_prefix);
G_END_DECLS
......
......@@ -12,7 +12,6 @@ INCLUDES = \
$(WARN_CFLAGS) \
$(GLIB2_CFLAGS) \
$(GCOV_CFLAGS) \
$(GDKPIXBUF_CFLAGS) \
$(GMODULE_CFLAGS) \
$(DBUS_CFLAGS) \
$(EXEMPI_CFLAGS) \
......@@ -232,8 +231,6 @@ libextract_playlist_la_LIBADD = $(GLIB2_LIBS) $(TOTEM_PL_PARSER_LIBS) $(GCOV_LIB
libexec_PROGRAMS = tracker-extract
tracker_extract_SOURCES = \
tracker-albumart.c \
tracker-albumart.h \
tracker-config.c \
tracker-config.h \
tracker-dbus.c \
......@@ -241,7 +238,8 @@ tracker_extract_SOURCES = \
tracker-extract.c \
tracker-extract.h \
tracker-main.c \
tracker-main.h
tracker-main.h \
tracker-marshal-main.c
tracker_extract_LDADD = \
$(top_builddir)/src/libtracker-common/libtracker-common.la \
......@@ -252,15 +250,23 @@ tracker_extract_LDADD = \
$(GLIB2_LIBS) \
$(STREAMANALYZER_LIBS)
if HAVE_GDKPIXBUF
tracker_extract_LDADD += $(GDKPIXBUF_LIBS)
endif
if HAVE_STREAMANALYZER
tracker_extract_SOURCES += tracker-topanalyzer.cpp tracker-topanalyzer.h
tracker_extract_LDADD += $(STREAMANALYZER_LIBS)
endif
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
dbus_sources = \
tracker-extract-glue.h
......@@ -268,6 +274,9 @@ dbus_sources = \
$(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
BUILT_SOURCES = \
$(dbus_sources)
$(dbus_sources) \
$(marshal_sources)
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = tracker-marshal.list
\ No newline at end of file
......@@ -39,7 +39,8 @@
#include <libtracker-common/tracker-utils.h>
#include "tracker-main.h"
#include "tracker-albumart.h"
#include "tracker-dbus.h"
#include "tracker-extract.h"
/* We wait this long (seconds) for NULL state before freeing */
#define TRACKER_EXTRACT_GUARD_TIMEOUT 3
......@@ -903,22 +904,26 @@ tracker_extract_gstreamer (const gchar *uri,
/* Save embedded art */
if (extractor->album_art_data && extractor->album_art_size) {
GObject *object;
object = tracker_dbus_get_object (TRACKER_TYPE_EXTRACT);
#ifdef HAVE_GDKPIXBUF
tracker_albumart_process (extractor->album_art_data,
extractor->album_art_size,
extractor->album_art_mime,
/* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
album,
scount,
uri);
tracker_extract_process_albumart (TRACKER_EXTRACT (object),
extractor->album_art_data,
extractor->album_art_size,
extractor->album_art_mime,
/* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
album,
uri);
#else
tracker_albumart_process (NULL,
0,
NULL,
/* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
album,
scount,
uri);
tracker_extract_process_albumart (TRACKER_EXTRACT (object),
NULL,
0,
NULL,
/* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
album,
uri);
#endif /* HAVE_GDKPIXBUF */
}
......
......@@ -50,7 +50,8 @@
#include <libtracker-common/tracker-utils.h>
#include "tracker-main.h"
#include "tracker-albumart.h"
#include "tracker-dbus.h"
#include "tracker-extract.h"
/* We mmap the beginning of the file and read separately the last 128 bytes
for id3v1 tags. While these are probably cornercases the rationale is that
......@@ -1809,15 +1810,16 @@ static void
extract_mp3 (const gchar *uri,
TrackerSparqlBuilder *metadata)
{
gchar *filename;
int fd;
void *buffer;
void *id3v1_buffer;
goffset size;
goffset buffer_size;
id3tag info;
goffset audio_offset;
file_data filedata;
GObject *object;
gchar *filename;
int fd;
void *buffer;
void *id3v1_buffer;
goffset size;
goffset buffer_size;
id3tag info;
goffset audio_offset;
file_data filedata;
info.title = NULL;
info.artist = NULL;
......@@ -1966,22 +1968,24 @@ extract_mp3 (const gchar *uri,
g_free (info.genre);
/* TODO */
object = tracker_dbus_get_object (TRACKER_TYPE_EXTRACT);
#ifdef HAVE_GDKPIXBUF
tracker_albumart_process (filedata.albumartdata,
filedata.albumartsize,
filedata.albumartmime,
/* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
filedata.title,
"-1",
filename);
tracker_extract_process_albumart (TRACKER_EXTRACT (object),
filedata.albumartdata,
filedata.albumartsize,
filedata.albumartmime,
/* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
filedata.title,
filename);
#else
tracker_albumart_process (NULL,
0,
NULL,
/* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
filedata.title,
"-1",
filename);
tracker_extract_process_albumart (TRACKER_EXTRACT (object),
NULL,
0,
NULL,
/* tracker_statement_list_find (metadata, NMM_PREFIX "performer") */ NULL,
filedata.title,
filename);
#endif /* HAVE_GDKPIXBUF */
......
......@@ -29,9 +29,10 @@
#include <libtracker-common/tracker-dbus.h>
#include <libtracker-common/tracker-sparql-builder.h>
#include "tracker-main.h"
#include "tracker-dbus.h"
#include "tracker-extract.h"
#include "tracker-main.h"
#include "tracker-marshal.h"
#ifdef HAVE_STREAMANALYZER
#include "tracker-topanalyzer.h"
......@@ -54,7 +55,7 @@ typedef struct {
} ModuleData;
enum {
NEEDS_THUMBNAILING,
PROCESS_ALBUM_ART,
LAST_SIGNAL
};
......@@ -73,15 +74,20 @@ tracker_extract_class_init (TrackerExtractClass *klass)
object_class->finalize = tracker_extract_finalize;
signals[NEEDS_THUMBNAILING] =
g_signal_new ("needs-thumbnailing",
signals[PROCESS_ALBUM_ART] =
g_signal_new ("process-album-art",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
tracker_marshal_VOID__UCHAR_INT_STRING_STRING_STRING_STRING,
G_TYPE_NONE,
1,
6,
G_TYPE_UCHAR,
G_TYPE_INT,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING);
g_type_class_add_private (object_class, sizeof (TrackerExtractPrivate));
......@@ -476,3 +482,29 @@ tracker_extract_get_metadata (TrackerExtract *object,
alarm (0);
}
}
void
tracker_extract_process_albumart (TrackerExtract *object,
const unsigned char *buffer,
size_t len,
const gchar *mime,
const gchar *artist,
const gchar *album,
const gchar *filename)
{
g_return_if_fail (buffer != NULL);
g_return_if_fail (len > 0);
g_return_if_fail (object != NULL);
g_return_if_fail (mime != NULL);
g_return_if_fail (filename != NULL);
g_signal_emit (object,
signals[PROCESS_ALBUM_ART],
0,
buffer,
len,
mime,
artist,
album,
filename);