[tracker/tracker-store] Merge with master



commit 2c3ace5930648a2a00642aeb14ed1d7b95d93cdf
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Jun 3 16:01:34 2009 +0200

    Merge with master
---
 data/languages/stopwords.hu                    |  264 +++++++++---------
 data/ontologies/35-ncal.ontology               |    4 +-
 src/libtracker-common/tracker-albumart.c       |   10 +-
 src/libtracker-common/tracker-storage-hal.c    |  346 +++++++++++++++---------
 src/libtracker/tracker.c                       |    1 +
 src/tracker-extract/tracker-extract-albumart.c |   96 +++++--
 src/tracker-extract/tracker-extract-playlist.c |    6 +-
 src/tracker-indexer/tracker-processor.c        |   29 ++-
 8 files changed, 454 insertions(+), 302 deletions(-)

diff --git a/data/languages/stopwords.hu b/data/languages/stopwords.hu
index e9cd016..694feb1 100644
--- a/data/languages/stopwords.hu
+++ b/data/languages/stopwords.hu
@@ -1,13 +1,13 @@
 a
-�¡
+á
 ahogy
 ahol
 aki
 akik
 akkor
 alatt
-�¡ltal
-�¡ltal�¡ban
+által
+általában
 amely
 amelyek
 amelyekben
@@ -18,27 +18,27 @@ ami
 amit
 amolyan
 amp
-am�­g
+amíg
 amikor
-�¡t
+át
 abban
 ahhoz
 annak
 arra
-arr�³l
+arról
 az
 azok
 azon
 azt
 azzal
-az�©rt
-azt�¡n
-azut�¡n
+azért
+aztán
+azután
 azonban
 b
-b�¡r
+bár
 be
-bel�¼l
+belül
 benne
 c
 cikk
@@ -48,25 +48,25 @@ csak
 d
 de
 e
-�©
+é
 eddig
-eg�©sz
+egész
 egy
 egyes
 egyetlen
-egy�©b
+egyéb
 egyik
 egyre
 ekkor
 el
-el�©g
+elég
 ellen
-elÃ?Â?
-el��sz�¶r
-elÃ?Â?tt
-elsÃ?Â?
-�©n
-�©ppen
+elÅ?
+elÅ?ször
+elÅ?tt
+elsÅ?
+én
+éppen
 ebben
 ehhez
 emilyen
@@ -77,11 +77,11 @@ ezt
 ezek
 ezen
 ezzel
-ez�©rt
-�©s
+ezért
+és
 f
 fel
-fel�©
+felé
 g
 h
 hanem
@@ -89,9 +89,9 @@ hiszen
 hogy
 hogyan
 i
-�­
+í
 igen
-�­gy
+így
 illetve
 ill.
 ill
@@ -99,23 +99,23 @@ ilyen
 ilyenkor
 is
 ison
-ism�©t
+ismét
 itt
 j
-j�³
-j�³l
+jó
+jól
 jobban
 k
 kell
 kellett
-kereszt�¼l
-keress�¼nk
+keresztül
+keressünk
 ki
-k�­v�¼l
-k�¶z�¶tt
-k�¶z�¼l
+kívül
+között
+közül
 l
-legal�¡bb
+legalább
 lehet
 lehetett
 legyen
@@ -125,22 +125,22 @@ lesz
 lett
 m
 maga
-mag�¡t
+magát
 majd
 majd
-m�¡r
-m�¡s
-m�¡sik
+már
+más
+másik
 meg
-m�©g
+még
 mellett
 mert
 mely
 melyek
 mi
 mit
-m�­g
-mi�©rt
+míg
+miért
 milyen
 mikor
 minden
@@ -156,59 +156,59 @@ nagy
 nagyobb
 nagyon
 ne
-n�©ha
+néha
 nekem
 neki
 nem
-n�©h�¡ny
-n�©lk�¼l
+néhány
+nélkül
 nincs
 o
-�³
+ó
 olyan
 ott
-�¶ssze
-�¶
-Ã?Â?
-Ã?Â?k
-Ã?Â?ket
+össze
+ö
+Å?
+Å?k
+Å?ket
 p
 pedig
 persze
 q
 r
-r�¡
+rá
 s
-saj�¡t
+saját
 sem
 semmi
 sok
 sokat
 sokkal
 sz
-sz�¡m�¡ra
+számára
 szemben
 szerint
 szinte
 t
-tal�¡n
-teh�¡t
+talán
+tehát
 teljes
-tov�¡bb
-tov�¡bb�¡
-t�¶bb
+tovább
+továbbá
+több
 u
-�º
-�ºgy
+ú
+úgy
 ugyanis
-�ºj
-�ºjabb
-�ºjra
-ut�¡n
-ut�¡na
-utols�³
-�¼
-�±
+új
+újabb
+újra
+után
+utána
+utolsó
+ü
+ű
 v
 vagy
 vagyis
@@ -216,7 +216,7 @@ valaki
 valamely
 valami
 valamint
-val�³
+való
 vagyok
 van
 vannak
@@ -228,9 +228,9 @@ vissza
 vele
 viszont
 volna
-sz�¡molnak
-sz�³lnak
-sz�³l
+számolnak
+szólnak
+szól
 w
 x
 y
@@ -242,83 +242,83 @@ ahol
 aki
 akkor
 alatt
-�¡ltal�¡ban
-�¡ltal
+általában
+által
 amely
-am�­g
+amíg
 amikor
 ami
 amolyan
 arra
-�¡t
+át
 az
-az�©rt
+azért
 azonban
 azon
-azt�¡n
+aztán
 azt
-azut�¡n
+azután
 azzal
-b�¡r
+bár
 be
-bel�¼l
+belül
 benne
 cikk
 csak
 de
 eddig
-eg�©sz
+egész
 egy
-egy�©b
+egyéb
 egyes
 egyetlen
 egyik
 egyre
 ekkor
 el
-el�©g
+elég
 ellen
-elÃ?Â?
-el��sz�¶r
-elÃ?Â?tt
-elsÃ?Â?
+elÅ?
+elÅ?ször
+elÅ?tt
+elsÅ?
 emilyen
-�©n
-�©ppen
+én
+éppen
 erre
-�©s
+és
 e
 ez
 ezen
-ez�©rt
+ezért
 ezzel
 fel
-fel�©
+felé
 hanem
 hiszen
 hogy
 hogyan
 igen
-�­gy
+így
 ill.
 illetve
 ill
 ilyen
 ilyenkor
-ism�©t
+ismét
 ison
 itt
-j�³
+jó
 jobban
-j�³l
+jól
 kell
 keres
-kereszt�¼l
+keresztül
 ki
-k�­v�¼l
-k�¶z�¶tt
-k�¶z�¼l
-legal�¡bb
+kívül
+között
+közül
+legalább
 legyen
 lehet
 lenni
@@ -326,16 +326,16 @@ lett
 maga
 maga
 majd
-m�¡r
-m�¡s
-m�¡sik
-m�©g
+már
+más
+másik
+még
 meg
 mellett
 mely
 mert
-mi�©rt
-m�­g
+miért
+míg
 mikor
 milyen
 minden
@@ -350,52 +350,52 @@ nagy
 nagyobb
 nagyon
 ne
-n�©ha
-n�©h�¡ny
+néha
+néhány
 neki
-n�©lk�¼l
+nélkül
 nem
 nincs
-Ã?Â?k
+Å?k
 olyan
-Ã?Â?
-�¶ssze
+Å?
+össze
 ott
 pedig
 persze
-r�¡
-saj�¡t
+rá
+saját
 s
 sem
 semmi
 sokkal
 sok
-sz�¡m�¡ra
-sz�¡mol
+számára
+számol
 szemben
 szerint
 szinte
-sz�³l
-tal�¡n
-teh�¡t
+szól
+talán
+tehát
 teljes
-tov�¡bb�¡
-tov�¡bb
-�ºgy
+továbbá
+tovább
+úgy
 ugyanis
-�ºj
-�ºjabb
-�ºjra
-ut�¡na
-ut�¡n
-utols�³
+új
+újabb
+újra
+utána
+után
+utolsó
 vagy
 vagyis
 valaki
 valamely
 valami
 valamint
-val�³
+való
 van
 vissza
 viszont
diff --git a/data/ontologies/35-ncal.ontology b/data/ontologies/35-ncal.ontology
index ab6293a..9a9b153 100644
--- a/data/ontologies/35-ncal.ontology
+++ b/data/ontologies/35-ncal.ontology
@@ -181,11 +181,13 @@ ncal:Alarm a rdfs:Class ;
 ncal:Event a rdfs:Class ;
 	rdfs:label "Event" ;
 	rdfs:comment "Provide a grouping of component properties that describe an event." ;
+	tracker:notify true ;
 	rdfs:subClassOf ncal:UnionParentClass , nie:InformationElement .
 
 ncal:Todo a rdfs:Class ;
 	rdfs:label "Todo" ;
 	rdfs:comment "Provide a grouping of calendar properties that describe a to-do." ;
+	tracker:notify true ;
 	rdfs:subClassOf ncal:UnionParentClass , nie:InformationElement .
 
 ncal:Freebusy a rdfs:Class ;
@@ -196,6 +198,7 @@ ncal:Freebusy a rdfs:Class ;
 ncal:Journal a rdfs:Class ;
 	rdfs:label "Journal" ;
 	rdfs:comment "Provide a grouping of component properties that describe a journal entry." ;
+	tracker:notify true ;
 	rdfs:subClassOf ncal:UnionParentClass , nie:InformationElement .
 
 ncal:Timezone a rdfs:Class ;
@@ -742,7 +745,6 @@ ncal:contactAltRep a rdf:Property ;
 ncal:rdate a rdf:Property ;
 	rdfs:label "rdate" ;
 	rdfs:comment "['This property defines the list of date/times for a recurrence set. Inspired by RFC 2445 sec. 4.8.5.3. Note that RFC allows both DATE', 'DATE-TIME and PERIOD values for this property. That's why the range has been set to NcalTimeEntity.']" ;
-	nrl:maxCardinality 1 ;
 	rdfs:domain ncal:UnionParentClass ;
 	rdfs:range ncal:NcalTimeEntity .
 
diff --git a/src/libtracker-common/tracker-albumart.c b/src/libtracker-common/tracker-albumart.c
index f2599e6..1221f01 100644
--- a/src/libtracker-common/tracker-albumart.c
+++ b/src/libtracker-common/tracker-albumart.c
@@ -385,7 +385,6 @@ tracker_albumart_heuristic (const gchar *artist_,
 	gchar *dirname;
 	const gchar *name;
 	gboolean retval;
-	gint tracks;
 	gint count;
 	gchar *artist = NULL;
 	gchar *album = NULL;
@@ -451,12 +450,6 @@ tracker_albumart_heuristic (const gchar *artist_,
 	/* do not count . and .. */
 	count = st.st_nlink - 2;
 	
-	if (tracks_str) {
-		tracks = atoi (tracks_str);
-	} else {
-		tracks = -1;
-	}
-
 	if (artist_) {
 		artist = tracker_albumart_strip_invalid_entities (artist_);
 	}
@@ -467,8 +460,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 >= 2 && count < 50)) {
+	if (count >= 2 && count < 50) {
 		gchar *found = NULL;
 
 		/* Try to find cover art in the directory */
diff --git a/src/libtracker-common/tracker-storage-hal.c b/src/libtracker-common/tracker-storage-hal.c
index 18c5177..6ad6ddb 100644
--- a/src/libtracker-common/tracker-storage-hal.c
+++ b/src/libtracker-common/tracker-storage-hal.c
@@ -47,13 +47,27 @@ typedef struct {
 	DBusConnection *connection;
 
 	GHashTable    *all_devices;
-	GHashTable    *mounted_devices;
-	GHashTable    *removable_devices;
+
+	GNode *mounts;
+	GHashTable *mounts_by_udi;
+
 } TrackerStoragePriv;
 
 typedef struct {
+	gchar *mount_point;
+	gchar *udi;
+ 	guint removable : 1;
+} MountInfo;
+
+typedef struct {
+	const gchar *path;
+	GNode *node;
+} TraverseData;
+
+typedef struct {
 	LibHalContext *context;
 	GList	      *roots;
+	gboolean       only_removable;
 } GetRoots;
 
 static void	tracker_storage_finalize	(GObject	 *object);
@@ -140,16 +154,12 @@ tracker_storage_init (TrackerStorage *storage)
 						   g_str_equal,
 						   (GDestroyNotify) g_free,
 						   (GDestroyNotify) g_free);
+	priv->mounts = g_node_new (NULL);
 
-	priv->mounted_devices = g_hash_table_new_full (g_str_hash,
-						       g_str_equal,
-						       (GDestroyNotify) g_free,
-						       (GDestroyNotify) g_free);
-
-	priv->removable_devices = g_hash_table_new_full (g_str_hash,
-							 g_str_equal,
-							 (GDestroyNotify) g_free,
-							 (GDestroyNotify) g_free);
+	priv->mounts_by_udi = g_hash_table_new_full (g_str_hash,
+						     g_str_equal,
+						     (GDestroyNotify) g_free,
+						     NULL);
 
 	dbus_error_init (&error);
 
@@ -202,6 +212,38 @@ tracker_storage_init (TrackerStorage *storage)
 	}
 }
 
+static gboolean
+free_mount_info (GNode *node,
+		 gpointer user_data)
+{
+	MountInfo *info;
+
+	info = node->data;
+
+	if (info) {
+		g_free (info->mount_point);
+		g_free (info->udi);
+
+		g_slice_free (MountInfo, info);
+	}
+
+	return FALSE;
+}
+
+static void
+free_mount_node (GNode *node)
+{
+	g_node_traverse (node,
+			 G_POST_ORDER,
+			 G_TRAVERSE_ALL,
+			 -1,
+			 free_mount_info,
+			 NULL);
+
+	g_node_destroy (node);
+}
+
+
 static void
 tracker_storage_finalize (GObject *object)
 {
@@ -209,18 +251,18 @@ tracker_storage_finalize (GObject *object)
 
 	priv = GET_PRIV (object);
 
-	if (priv->removable_devices) {
-		g_hash_table_unref (priv->removable_devices);
-	}
-
-	if (priv->mounted_devices) {
-		g_hash_table_unref (priv->mounted_devices);
+	if (priv->mounts_by_udi) {
+		g_hash_table_unref (priv->mounts_by_udi);
 	}
 
 	if (priv->all_devices) {
 		g_hash_table_unref (priv->all_devices);
 	}
 
+	if (priv->mounts) {
+		free_mount_node (priv->mounts);
+	}
+
 	if (priv->context) {
 		libhal_ctx_shutdown (priv->context, NULL);
 		libhal_ctx_set_user_data (priv->context, NULL);
@@ -312,6 +354,87 @@ hal_setup_devices (TrackerStorage *storage)
 	return TRUE;
 }
 
+static gboolean
+mount_point_traverse_func (GNode *node,
+			   gpointer user_data)
+{
+	TraverseData *data;
+	MountInfo *info;
+
+	if (!node->data) {
+		/* Root node */
+		return FALSE;
+	}
+
+	data = user_data;
+	info = node->data;
+
+	if (g_str_has_prefix (data->path, info->mount_point)) {
+		data->node = node;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static GNode *
+find_mount_point (GNode *root,
+		  const gchar *path)
+{
+	TraverseData data = { path, NULL };
+
+	g_node_traverse (root,
+			 G_POST_ORDER,
+			 G_TRAVERSE_ALL,
+			 -1,
+			 mount_point_traverse_func,
+			 &data);
+
+	return data.node;
+}
+
+static MountInfo *
+find_mount_point_info (GNode *root,
+		       const gchar *path)
+{
+	GNode *node;
+
+	node = find_mount_point (root, path);
+	return (node) ? node->data : NULL;
+}
+
+static GNode *
+mount_point_hierarchy_add (GNode *root,
+			   const gchar *mount_point,
+			   const gchar *udi,
+			   gboolean removable)
+{
+	MountInfo *info;
+	GNode *node;
+	gchar *mp;
+
+	/* Normalize all mount points to have a / at the end */
+	if (g_str_has_suffix (mount_point, G_DIR_SEPARATOR_S)) {
+		mp = g_strdup (mount_point);
+	} else {
+		mp = g_strconcat (mount_point, G_DIR_SEPARATOR_S, NULL);
+	}
+
+	node = find_mount_point (root, mp);
+
+	if (!node) {
+		node = root;
+	}
+
+	info = g_slice_new (MountInfo);
+	info->mount_point = mp;
+	info->udi = g_strdup (udi);
+	info->removable = removable;
+
+	return g_node_append_data (node, info);
+}
+
+
 static void
 hal_mount_point_add (TrackerStorage *storage,
 		     const gchar    *udi,
@@ -319,6 +442,7 @@ hal_mount_point_add (TrackerStorage *storage,
 		     gboolean	     removable_device)
 {
 	TrackerStoragePriv *priv;
+	GNode *node;
 
 	priv = GET_PRIV (storage);
 
@@ -327,15 +451,8 @@ hal_mount_point_add (TrackerStorage *storage,
 		   mount_point,
 		   removable_device ? "yes" : "no");
 	
-	g_hash_table_insert (priv->mounted_devices,
-			     g_strdup (udi),
-			     g_strdup (mount_point));
-
-	if (removable_device) {
-		g_hash_table_insert (priv->removable_devices,
-				     g_strdup (udi),
-				     g_strdup (mount_point));
-	}
+	node = mount_point_hierarchy_add (priv->mounts, mount_point, udi, removable_device);
+	g_hash_table_insert (priv->mounts_by_udi, g_strdup (udi), node);
 
 	g_signal_emit (storage, signals[MOUNT_POINT_ADDED], 0, udi, mount_point, NULL);
 }
@@ -344,27 +461,30 @@ static void
 hal_mount_point_remove (TrackerStorage *storage,
 			const gchar    *udi)
 {
+	MountInfo *info;
 	TrackerStoragePriv *priv;
-	const gchar    *mount_point;
+	GNode *node;
 
 	priv = GET_PRIV (storage);
 
-	mount_point = g_hash_table_lookup (priv->mounted_devices, udi);
+	node = g_hash_table_lookup (priv->mounts_by_udi, udi);
 
-	if (!mount_point) {
+	if (!node) {
 		return;
 	}
 
+	info = node->data;
+
 	g_message ("HAL device:'%s' with mount point:'%s' (uuid:'%s'), removable:%s NO LONGER being tracked",
 		   (const gchar*) g_hash_table_lookup (priv->all_devices, udi),
-		   mount_point,
+		   info->mount_point,
 		   udi,
-		   g_hash_table_remove (priv->removable_devices, udi) ? "yes" : "no");
+		   info->removable ? "yes" : "no");
 	
-	g_signal_emit (storage, signals[MOUNT_POINT_REMOVED], 0, udi, mount_point, NULL);
+	g_signal_emit (storage, signals[MOUNT_POINT_REMOVED], 0, udi, info->mount_point, NULL);
 
-	g_hash_table_remove (priv->mounted_devices, udi);
-	g_hash_table_remove (priv->removable_devices, udi);
+	g_hash_table_remove (priv->mounts_by_udi, udi);
+	free_mount_node (node);
 }
 
 static const gchar *
@@ -595,7 +715,6 @@ hal_device_removed_cb (LibHalContext *context,
 	TrackerStorage     *storage;
 	TrackerStoragePriv *priv;
 	const gchar        *device_file;
-	const gchar        *mount_point;
 
 	storage = (TrackerStorage*) libhal_ctx_get_user_data (context);
 	priv = GET_PRIV (storage);
@@ -608,14 +727,10 @@ hal_device_removed_cb (LibHalContext *context,
 			return;
 		}
 
-		mount_point = g_hash_table_lookup (priv->mounted_devices, udi);
-
 		g_message ("HAL device:'%s' removed:",
 			   device_file);
 		g_message ("  UDI	 : %s",
 			   udi);
-		g_message ("  Mount point: %s",
-			   mount_point);
 
 		g_hash_table_remove (priv->all_devices, udi);
 
@@ -716,31 +831,19 @@ hal_get_mount_point_by_udi_foreach (gpointer key,
 				    gpointer value,
 				    gpointer user_data)
 {
-	LibHalVolume  *volume;
 	GetRoots      *gr;
 	const gchar   *udi;
-	const gchar   *mount_point;
-	gboolean       is_mounted;
+	GNode *node;
+	MountInfo *info;
 
 	gr = (GetRoots*) user_data;
 	udi = key;
+	node = value;
+	info = node->data;
 
-	volume = libhal_volume_from_udi (gr->context, udi);
-	if (!volume) {
-		g_message ("HAL device with udi:'%s' has no volume, "
-			   "should we delete?",
-			   udi);
-		return;
-	}
-
-	mount_point = libhal_volume_get_mount_point (volume);
-	is_mounted = libhal_volume_is_mounted (volume);
-
-	if (is_mounted && mount_point) {
-		gr->roots = g_list_prepend (gr->roots, g_strdup (mount_point));
+	if (!gr->only_removable || info->removable) {
+		gr->roots = g_list_prepend (gr->roots, g_strdup (info->mount_point));
 	}
-
-	libhal_volume_free (volume);
 }
 
 /**
@@ -764,8 +867,9 @@ tracker_storage_get_mounted_directory_roots (TrackerStorage *storage)
 
 	gr.context = priv->context;
 	gr.roots = NULL;
+	gr.only_removable = FALSE;
 
-	g_hash_table_foreach (priv->mounted_devices,
+	g_hash_table_foreach (priv->mounts_by_udi,
 			      hal_get_mount_point_by_udi_foreach,
 			      &gr);
 
@@ -793,8 +897,9 @@ tracker_storage_get_removable_device_roots (TrackerStorage *storage)
 
 	gr.context = priv->context;
 	gr.roots = NULL;
+	gr.only_removable = TRUE;
 
-	g_hash_table_foreach (priv->removable_devices,
+	g_hash_table_foreach (priv->mounts_by_udi,
 			      hal_get_mount_point_by_udi_foreach,
 			      &gr);
 
@@ -821,11 +926,9 @@ tracker_storage_uri_is_on_removable_device (TrackerStorage *storage,
 					    gboolean       *available)
 {
 	TrackerStoragePriv *priv;
-	GHashTableIter  iter;
-	gboolean        found = FALSE;
-	gpointer        key, value;
-	gchar          *path;
-	GFile          *file;
+	gchar              *path;
+	GFile              *file;
+	MountInfo          *info;
 
 	g_return_val_if_fail (TRACKER_IS_STORAGE (storage), FALSE);
 
@@ -838,34 +941,33 @@ tracker_storage_uri_is_on_removable_device (TrackerStorage *storage,
 	}
 
 	priv = GET_PRIV (storage);
+	info = find_mount_point_info (priv->mounts, path);
 
-	g_hash_table_iter_init (&iter, priv->removable_devices);
-
-	while (g_hash_table_iter_next (&iter, &key, &value)) {
-		const gchar *mp;
-
-		mp = value;
-
-		if (mp && path &&
-		    g_str_has_prefix (path, mp)) {
-			found = TRUE;
+	if (!info) {
+		g_free (path);
+		g_object_unref (file);
+		return FALSE;
+	}
 
-			if (mount_point) {
-				*mount_point = g_strdup (mp);
-			}
+	if (!info->removable) {
+		g_free (path);
+		g_object_unref (file);
+		return FALSE;
+	}
 
-			if (available) {
-				*available = TRUE;
-			}
+	/* Mount point found and is removable */
+	if (mount_point) {
+		*mount_point = g_strdup (info->mount_point);
+	}
 
-			break;
-		}
+	if (available) {
+		*available = TRUE;
 	}
 
 	g_free (path);
 	g_object_unref (file);
 
-	return found;
+	return TRUE;
 }
 
 
@@ -883,12 +985,31 @@ GList *
 tracker_storage_get_removable_device_udis (TrackerStorage *storage)
 {
 	TrackerStoragePriv *priv;
+	GHashTableIter iter;
+	gpointer key, value;
+	GList *udis = NULL;
 
 	g_return_val_if_fail (TRACKER_IS_STORAGE (storage), NULL);
 
 	priv = GET_PRIV (storage);
 	
-	return g_hash_table_get_keys (priv->removable_devices);
+	g_hash_table_iter_init (&iter, priv->mounts_by_udi);
+
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		const gchar *udi;
+		GNode *node;
+		MountInfo *info;
+
+		udi = key;
+		node = value;
+		info = node->data;
+
+		if (info->removable) {
+			udis = g_list_prepend (udis, (gpointer) udi);
+		}
+	}
+
+	return g_list_reverse (udis);
 }
 
 /**
@@ -903,13 +1024,22 @@ tracker_storage_udi_get_mount_point (TrackerStorage *storage,
 				     const gchar    *udi)
 {
 	TrackerStoragePriv *priv;
+	GNode *node;
+	MountInfo *info;
 
 	g_return_val_if_fail (TRACKER_IS_STORAGE (storage), NULL);
 	g_return_val_if_fail (udi != NULL, NULL);
 
 	priv = GET_PRIV (storage);
 	
-	return g_hash_table_lookup (priv->removable_devices, udi);
+	node = g_hash_table_lookup (priv->mounts_by_udi, udi);
+
+	if (!node) {
+		return NULL;
+	}
+
+	info = node->data;
+	return info->mount_point;
 }
 
 /**
@@ -966,11 +1096,8 @@ tracker_storage_get_volume_udi_for_file (TrackerStorage *storage,
 					 GFile          *file)
 {
 	TrackerStoragePriv *priv;
-	GHashTableIter  iter;
-	gboolean        found = FALSE;
-	gpointer        key, value;
-	gchar          *path;
-	const gchar    *udi;
+	gchar              *path;
+	MountInfo          *info;
 
 	g_return_val_if_fail (TRACKER_IS_STORAGE (storage), FALSE);
 
@@ -982,41 +1109,16 @@ tracker_storage_get_volume_udi_for_file (TrackerStorage *storage,
 
 	priv = GET_PRIV (storage);
 
-	g_hash_table_iter_init (&iter, priv->removable_devices);
-
-	while (g_hash_table_iter_next (&iter, &key, &value)) {
-		LibHalVolume  *volume;
-		const gchar   *mp;
-
-		udi = key;
-
-		volume = libhal_volume_from_udi (priv->context, udi);
-
-		if (!volume) {
-			g_message ("HAL device with udi:'%s' has no volume, "
-				   "should we delete?",
-				   udi);
-			continue;
-		}
+	info = find_mount_point_info (priv->mounts, path);
 
-		mp = libhal_volume_get_mount_point (volume);
-
-		if (g_strcmp0 (mp, path) != 0) {
-			if (g_strrstr (path, mp)) {
-				found = TRUE;
-				libhal_volume_free (volume);
-				break;
-			}
-		}
-
-		libhal_volume_free (volume);
+	if (!info) {
+		g_free (path);
+		return NULL;
 	}
 
-	g_free (path);
-
-	if (!found)
-		udi = NULL;
+	g_debug ("Mount for path '%s' is '%s' (UDI:'%s')",
+		 path, info->mount_point, info->udi);
 
-	return udi;
+	return info->udi;
 }
 #endif /* HAVE_HAL */
diff --git a/src/libtracker/tracker.c b/src/libtracker/tracker.c
index 88de01e..82931b9 100644
--- a/src/libtracker/tracker.c
+++ b/src/libtracker/tracker.c
@@ -136,6 +136,7 @@ tracker_void_reply (DBusGProxy *proxy, GError *error, gpointer user_data)
 }
 
 
+/* copied from tracker-module-metadata.c */
 gchar *
 tracker_sparql_escape (const gchar *str)
 {
diff --git a/src/tracker-extract/tracker-extract-albumart.c b/src/tracker-extract/tracker-extract-albumart.c
index 9f1a93a..ce0654e 100644
--- a/src/tracker-extract/tracker-extract-albumart.c
+++ b/src/tracker-extract/tracker-extract-albumart.c
@@ -45,6 +45,8 @@
 
 #ifdef HAVE_GDKPIXBUF
 
+static GHashTable *album_art_done = NULL;
+
 static gboolean
 set_albumart (const unsigned char *buffer,
 	      size_t               len,
@@ -125,6 +127,8 @@ tracker_process_albumart (const unsigned char *buffer,
 	gchar *local_uri = NULL;
 	gchar *filename_uri;
 	gboolean lcopied = FALSE;
+	gboolean art_exists;
+	gchar *as_uri;
 
 	if (strchr (filename, ':')) {
 		filename_uri = g_strdup (filename);
@@ -146,7 +150,9 @@ tracker_process_albumart (const unsigned char *buffer,
 		return FALSE;
 	}
 
-	if (!g_file_test (art_path, G_FILE_TEST_EXISTS)) {
+	art_exists = g_file_test (art_path, G_FILE_TEST_EXISTS);
+
+	if (!art_exists) {
 #ifdef HAVE_GDKPIXBUF
 		/* If we have embedded album art */
 		if (buffer && len) {
@@ -161,45 +167,78 @@ tracker_process_albumart (const unsigned char *buffer,
 		} 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 *key;
+			gchar *dirname;
+			GFile *file, *dirf;
+
+			file = g_file_new_for_path (filename);
+			dirf = g_file_get_parent (file);
+			dirname = g_file_get_path (dirf);
+			g_object_unref (file);
+			g_object_unref (dirf);
+
+			key = g_strdup_printf ("%s-%s-%s", artist ? artist : "",
+					       album ? album : "",
+					       dirname ? dirname : "");
+
+			g_free (dirname);
+
+			/* We store these in a table because we want to avoid 
+			  * that we do many requests for the same directory
+			  * subsequently without success. It's a small but
+			  * known leak on the variable "key" and the hashtable
+			  * itself.
+			  *
+			  * We could get rid of the leak by having a shutdown 
+			  * function for extract modules. I don't think this 
+			  * mini leak is enough reason to add such shutdown
+			  * infrastructure to the extract modules. */
+
+			if (!album_art_done) {
+				album_art_done = g_hash_table_new_full (g_str_hash,
+									g_str_equal,
+									(GDestroyNotify) g_free,
+									NULL);
+			}
+
+			if (!g_hash_table_lookup (album_art_done, key)) {
+				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);
+				}
+				g_hash_table_insert (album_art_done, key, GINT_TO_POINTER(TRUE));
+			} else {
+				g_free (key);
 			}
 #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);
-		}
+		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))
+		/* We can't reuse art_exists here because the situation might
+		 * have changed */
+		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);
@@ -208,3 +247,4 @@ tracker_process_albumart (const unsigned char *buffer,
 
 	return retval;
 }
+
diff --git a/src/tracker-extract/tracker-extract-playlist.c b/src/tracker-extract/tracker-extract-playlist.c
index 38e25d9..1dc3156 100644
--- a/src/tracker-extract/tracker-extract-playlist.c
+++ b/src/tracker-extract/tracker-extract-playlist.c
@@ -51,8 +51,8 @@
 #define RDF_TYPE RDF_PREFIX "type"
 
 typedef struct {
-	gint         track_counter;
-	gint         total_time;
+	guint        track_counter;
+	gint64      total_time;
 	GPtrArray   *metadata;
 	const gchar *uri;
 } PlaylistMetadata;
@@ -94,7 +94,7 @@ entry_parsed (TotemPlParser *parser, const gchar *to_uri, GHashTable *to_metadat
 	}
 
 	if (duration != NULL) {
-		gint secs = atoi (duration);
+		gint64 secs = totem_pl_parser_parse_duration (duration, FALSE);
 		if (secs > 0) {
 			data->total_time += secs;
 		}
diff --git a/src/tracker-indexer/tracker-processor.c b/src/tracker-indexer/tracker-processor.c
index 35877c4..195ddeb 100644
--- a/src/tracker-indexer/tracker-processor.c
+++ b/src/tracker-indexer/tracker-processor.c
@@ -1402,6 +1402,16 @@ crawler_finished_cb (TrackerCrawler *crawler,
 
 #ifdef HAVE_HAL
 
+static gchar *
+normalize_mount_point (const gchar *mount_point)
+{
+	if (g_str_has_suffix (mount_point, G_DIR_SEPARATOR_S)) {
+		return g_strdup (mount_point);
+	} else {
+		return g_strconcat (mount_point, G_DIR_SEPARATOR_S, NULL);
+	}
+}
+
 static void
 mount_point_added_cb (TrackerStorage  *hal,
 		      const gchar *udi,
@@ -1412,19 +1422,20 @@ mount_point_added_cb (TrackerStorage  *hal,
 	TrackerProcessorPrivate *priv;
 	TrackerStatus	         status;
 	GList                   *l;
+	gchar                   *mp;
 
 	processor = user_data;
 	priv = processor->private;
 
 	status = tracker_status_get ();
+	mp = normalize_mount_point (mount_point);
 
 	/* Add removable device to list of known devices to iterate */
-	priv->removable_devices = g_list_append (priv->removable_devices, 
-						 g_strdup (mount_point));
+	priv->removable_devices = g_list_append (priv->removable_devices, mp);
 
 	/* Remove from completed list so we don't ignore it */
-	l = g_list_find_custom (priv->removable_devices_completed, 
-				mount_point,
+	l = g_list_find_custom (priv->removable_devices_completed,
+				mp,
 				(GCompareFunc) g_strcmp0);
 
 	if (l) {
@@ -1460,15 +1471,17 @@ mount_point_removed_cb (TrackerStorage  *hal,
 	TrackerProcessorPrivate *priv;
 	GFile		        *file;
 	GList                   *l;
+	gchar                   *mp;
 
 	processor = user_data;
 	priv = processor->private;
+	mp = normalize_mount_point (mount_point);
 
 	/* Remove directory from list of iterated_removable_media, so
 	 * we don't traverse it.
 	 */
-	l = g_list_find_custom (priv->removable_devices, 
-				mount_point,
+	l = g_list_find_custom (priv->removable_devices,
+				mp,
 				(GCompareFunc) g_strcmp0);
 
 	if (l) {
@@ -1478,7 +1491,7 @@ mount_point_removed_cb (TrackerStorage  *hal,
 	}
 
 	l = g_list_find_custom (priv->removable_devices_completed, 
-				mount_point,
+				mp,
 				(GCompareFunc) g_strcmp0);
 
 	if (l) {
@@ -1493,6 +1506,8 @@ mount_point_removed_cb (TrackerStorage  *hal,
 	file = g_file_new_for_path (mount_point);
 	tracker_monitor_remove_recursively (priv->monitor, file);
 	g_object_unref (file);
+
+	g_free (mp);
 }
 
 #endif /* HAVE_HAL */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]