tracker-0.16.2/src/tracker-extract/tracker-extract-playlist.c

No issues found

  1 /*
  2  * Copyright (C) 2007, Jamie McCracken <jamiemcc@gnome.org>
  3  * Copyright (C) 2008, Nokia <ivan.frade@nokia.com>
  4  *
  5  * This library is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2.1 of the License, or (at your option) any later version.
  9  *
 10  * This library is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with this library; if not, write to the
 17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 18  * Boston, MA  02110-1301, USA.
 19  */
 20 
 21 #include "config.h"
 22 
 23 #ifndef _GNU_SOURCE
 24 #define _GNU_SOURCE
 25 #endif
 26 
 27 #include <string.h>
 28 #include <stdlib.h>
 29 
 30 #include <glib.h>
 31 #include <glib/gstdio.h>
 32 #include <gio/gio.h>
 33 
 34 #include <totem-pl-parser.h>
 35 
 36 #include <libtracker-extract/tracker-extract.h>
 37 
 38 #define PLAYLIST_PROPERTY_NO_TRACKS "entryCounter"
 39 #define PLAYLIST_PROPERTY_DURATION  "listDuration"
 40 /*
 41   FIXME Decide what to do with this in nepomuk
 42   #define PLAYLIST_PROPERTY_CALCULATED "Playlist:ValidDuration"
 43 */
 44 
 45 #define PLAYLIST_DEFAULT_NO_TRACKS 0
 46 #define PLAYLIST_DEFAULT_DURATION 0
 47 
 48 typedef struct {
 49 	guint32 track_counter;
 50 	gint64 total_time;
 51 	gchar *title;
 52 	TrackerSparqlBuilder *metadata;
 53 } PlaylistMetadata;
 54 
 55 static void
 56 playlist_started (TotemPlParser         *parser,
 57                   gchar                 *to_uri,
 58                   TotemPlParserMetadata *to_metadata,
 59                   gpointer               user_data)
 60 {
 61 	PlaylistMetadata *data;
 62 
 63 	data = (PlaylistMetadata *) user_data;
 64 
 65 	/* Avoid looking up every time */
 66 	data->title = g_strdup (g_hash_table_lookup (to_metadata, TOTEM_PL_PARSER_FIELD_TITLE));
 67 }
 68 
 69 static void
 70 entry_parsed (TotemPlParser *parser,
 71               gchar         *to_uri,
 72               GHashTable    *to_metadata,
 73               gpointer       user_data)
 74 {
 75 	PlaylistMetadata *data;
 76 
 77 	data = (PlaylistMetadata *) user_data;
 78 	data->track_counter++;
 79 
 80 	if (data->track_counter > 1000) {
 81 		/* limit playlists to 1000 entries for query performance reasons */
 82 		g_message ("Playlist has > 1000 entries. Ignoring for performance reasons.");
 83 		return;
 84 	}
 85 
 86 	if (data->track_counter == 1) {
 87 		/* first track, predicate needed */
 88 		tracker_sparql_builder_predicate (data->metadata, "nfo:hasMediaFileListEntry");
 89 	}
 90 
 91 	tracker_sparql_builder_object_blank_open (data->metadata);
 92 	tracker_sparql_builder_predicate (data->metadata, "a");
 93 	tracker_sparql_builder_object (data->metadata, "nfo:MediaFileListEntry");
 94 
 95 	tracker_sparql_builder_predicate (data->metadata, "nfo:entryUrl");
 96 	tracker_sparql_builder_object_unvalidated (data->metadata, to_uri);
 97 
 98 	tracker_sparql_builder_predicate (data->metadata, "nfo:listPosition");
 99 	tracker_sparql_builder_object_int64 (data->metadata, (gint64) data->track_counter);
100 
101 	tracker_sparql_builder_object_blank_close (data->metadata);
102 
103 	if (to_metadata) {
104 		gchar *duration;
105 
106 		duration = g_hash_table_lookup (to_metadata, TOTEM_PL_PARSER_FIELD_DURATION);
107 
108 		if (duration == NULL) {
109 			duration = g_hash_table_lookup (to_metadata, TOTEM_PL_PARSER_FIELD_DURATION_MS);
110 		}
111 
112 		if (duration != NULL) {
113 			gint64 secs = totem_pl_parser_parse_duration (duration, FALSE);
114 
115 			if (secs > 0) {
116 				data->total_time += secs;
117 			}
118 		}
119 	}
120 }
121 
122 G_MODULE_EXPORT gboolean
123 tracker_extract_get_metadata (TrackerExtractInfo *info)
124 {
125 	TotemPlParser *pl;
126 	TrackerSparqlBuilder *metadata;
127 	PlaylistMetadata data;
128 	GFile *file;
129 	gchar *uri;
130 
131 	pl = totem_pl_parser_new ();
132 	file = tracker_extract_info_get_file (info);
133 	uri = g_file_get_uri (file);
134 	metadata = tracker_extract_info_get_metadata_builder (info);
135 
136 	data.track_counter = PLAYLIST_DEFAULT_NO_TRACKS;
137 	data.total_time =  PLAYLIST_DEFAULT_DURATION;
138 	data.title = NULL;
139 	data.metadata = metadata;
140 
141 	g_object_set (pl, "recurse", FALSE, "disable-unsafe", TRUE, NULL);
142 
143 	g_signal_connect (G_OBJECT (pl), "playlist-started", G_CALLBACK (playlist_started), &data);
144 	g_signal_connect (G_OBJECT (pl), "entry-parsed", G_CALLBACK (entry_parsed), &data);
145 
146 	tracker_sparql_builder_predicate (metadata, "a");
147 	tracker_sparql_builder_object (metadata, "nmm:Playlist");
148 	tracker_sparql_builder_object (metadata, "nfo:MediaList");
149 
150 	if (totem_pl_parser_parse (pl, uri, FALSE) == TOTEM_PL_PARSER_RESULT_SUCCESS) {
151 		if (data.title != NULL) {
152 			g_message ("Playlist title:'%s'", data.title);
153 			tracker_sparql_builder_predicate (metadata, "nie:title");
154 			tracker_sparql_builder_object_unvalidated (metadata, data.title);
155 			g_free (data.title);
156 		} else {
157 			g_message ("Playlist has no title");
158 		}
159 
160 		if (data.total_time > 0) {
161 			tracker_sparql_builder_predicate (metadata, "nfo:listDuration");
162 			tracker_sparql_builder_object_int64 (metadata, data.total_time);
163 		}
164 
165 		if (data.track_counter > 0) {
166 			tracker_sparql_builder_predicate (metadata, "nfo:entryCounter");
167 			tracker_sparql_builder_object_int64 (metadata, data.track_counter);
168 		}
169 	} else {
170 		g_warning ("Playlist could not be parsed, no error given");
171 	}
172 
173 	g_object_unref (pl);
174 	g_free (uri);
175 
176 	return TRUE;
177 }