No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | tracker-media-art.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * Copyright (C) 2008, Nokia <ivan.frade@nokia.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 */
19
20 #include "config.h"
21
22 #include <string.h>
23
24 #include <glib.h>
25 #include <glib/gstdio.h>
26
27 #include <libtracker-common/tracker-media-art.h>
28 #include <libtracker-sparql/tracker-sparql.h>
29
30 #include "tracker-media-art.h"
31
32 /**
33 * SECTION:tracker-media-art
34 * @title: Media art management
35 * @short_description: Media art request and management.
36 * @include: libtracker-miner/tracker-media-art.h
37 *
38 * This is a convenience API using D-Bus to talk to the media management service.
39 **/
40
41 static gboolean had_any = FALSE;
42 static guint timer_id = 0;
43
44 static void
45 on_query_finished (GObject *source_object,
46 GAsyncResult *res,
47 gpointer user_data)
48 {
49 GError *error = NULL;
50 TrackerSparqlCursor *cursor = NULL;
51 GDir *dir = NULL;
52 GHashTable *table = NULL;
53 const gchar *name;
54 gchar *dirname = NULL;
55 GList *to_remove = NULL;
56
57 cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (source_object),
58 res,
59 &error);
60
61 if (error) {
62 goto on_error;
63 }
64
65 dirname = g_build_filename (g_get_user_cache_dir (),
66 "media-art",
67 NULL);
68
69 if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
70 /* Ignore this and just quit the function */
71 goto on_error;
72 }
73
74 dir = g_dir_open (dirname, 0, &error);
75
76 if (error) {
77 goto on_error;
78 }
79
80 table = g_hash_table_new_full (g_str_hash,
81 g_str_equal,
82 (GDestroyNotify) g_free,
83 (GDestroyNotify) NULL);
84
85 while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
86 gchar *target = NULL, *album_path = NULL;
87 const gchar *album, *artist;
88
89 album = tracker_sparql_cursor_get_string (cursor, 0, NULL);
90 artist = tracker_sparql_cursor_get_value_type (cursor, 1) != TRACKER_SPARQL_VALUE_TYPE_UNBOUND ? tracker_sparql_cursor_get_string (cursor, 1, NULL) : NULL;
91
92 /* The get_path API does stripping itself */
93 tracker_media_art_get_path (artist,
94 album,
95 "album", NULL,
96 &target, NULL);
97
98 g_hash_table_replace (table, target, target);
99
100 /* Also add the file to which the symlinks are made */
101 tracker_media_art_get_path (NULL,
102 album,
103 "album", NULL,
104 &album_path, NULL);
105
106
107 g_hash_table_replace (table, album_path, album_path);
108 }
109
110 /* Perhaps we should have an internal list of media art files that we made,
111 * instead of going over all the media art (which could also have been made
112 * by other softwares) */
113
114 for (name = g_dir_read_name (dir); name != NULL; name = g_dir_read_name (dir)) {
115 gpointer value;
116 gchar *full;
117
118 full = g_build_filename (dirname, name, NULL);
119
120 value = g_hash_table_lookup (table, full);
121
122 if (!value) {
123 g_message ("Removing media-art file %s: no album exists that has "
124 "any songs for this media-art cache", name);
125 to_remove = g_list_prepend (to_remove, (gpointer) full);
126 } else {
127 g_free (full);
128 }
129 }
130
131 g_list_foreach (to_remove, (GFunc) g_unlink, NULL);
132 g_list_foreach (to_remove, (GFunc) g_free, NULL);
133 g_list_free (to_remove);
134
135 on_error:
136
137 g_free (dirname);
138
139 if (table) {
140 g_hash_table_unref (table);
141 }
142
143 if (cursor) {
144 g_object_unref (cursor);
145 }
146
147 if (dir) {
148 g_dir_close (dir);
149 }
150
151 if (error) {
152 g_critical ("Error running cleanup of media-art: %s",
153 error->message ? error->message : "No error given");
154 g_error_free (error);
155 }
156 }
157 /**
158 * tracker_media_art_queue_remove:
159 * @uri: URI of the file
160 * @mime_type: mime-type of the file
161 *
162 * Adds a new request to tell the media art subsystem that @uri was removed.
163 * Stored requests can be processed with tracker_media_art_queue_empty().
164 *
165 * Returns: #TRUE if successfully stored to be reported, #FALSE otherwise.
166 *
167 * Since: 0.10.4
168 */
169 gboolean
170 tracker_media_art_queue_remove (const gchar *uri,
171 const gchar *mime_type)
172 {
173 /* mime_type can be NULL */
174
175 g_return_val_if_fail (uri != NULL, FALSE);
176
177 if (mime_type && (g_str_has_prefix (mime_type, "video/") || g_str_has_prefix (mime_type, "audio/"))) {
178 had_any = TRUE;
179 }
180
181 return TRUE;
182 }
183
184 static gboolean
185 on_timer_callback (gpointer data)
186 {
187 TrackerSparqlConnection *connection = data;
188
189 tracker_sparql_connection_query_async (connection,
190 "SELECT ?title nmm:artistName (?artist) WHERE { "
191 " ?mpiece nmm:musicAlbum ?album . "
192 " ?album nmm:albumTitle ?title . "
193 " OPTIONAL { ?album nmm:albumArtist ?artist } "
194 "}",
195 NULL,
196 on_query_finished,
197 NULL);
198
199 return FALSE;
200 }
201
202 static void
203 on_timer_destroy (gpointer data)
204 {
205 TrackerSparqlConnection *connection = data;
206
207 g_object_unref (connection);
208 timer_id = 0;
209 }
210
211 /**
212 * tracker_media_art_queue_execute:
213 *
214 * Process all stored media art requests.
215 *
216 * Since: 0.10.4
217 */
218 void
219 tracker_media_art_queue_empty (TrackerSparqlConnection *connection)
220 {
221 if (had_any && timer_id == 0) {
222
223 timer_id = g_timeout_add_seconds_full (G_PRIORITY_LOW,
224 1800 /* Half an hour worth of seconds*/,
225 on_timer_callback,
226 g_object_ref (connection),
227 on_timer_destroy);
228
229 had_any = FALSE;
230 }
231 }