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 }