Merge lp:~cjcurran/indicator-sound/remote-art-handling into lp:indicator-sound/sound-menu-v2
- remote-art-handling
- Merge into trunk.0.1
Proposed by
Conor Curran
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 126 | ||||
Proposed branch: | lp:~cjcurran/indicator-sound/remote-art-handling | ||||
Merge into: | lp:indicator-sound/sound-menu-v2 | ||||
Diff against target: |
463 lines (+261/-32) 7 files modified
src/Makefile.am (+6/-2) src/fetch-file.vala (+86/-0) src/metadata-menu-item.vala (+126/-4) src/metadata-widget.c (+26/-12) src/player-item.vala (+15/-11) src/sound-service.c (+1/-2) vapi/common-defs.vapi (+1/-1) |
||||
To merge this branch: | bzr merge lp:~cjcurran/indicator-sound/remote-art-handling | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email: mp+34766@code.launchpad.net |
This proposal supersedes a proposal from 2010-09-02.
Commit message
Description of the change
- Deals with last fm plugin for rhythmbox which uses remote artwork. Dynamically remote artwork will now be fetched asynchronously, rounded and exposed.
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote : Posted in a previous version of this proposal | # |
review:
Needs Fixing
Revision history for this message
Ted Gould (ted) wrote : | # |
Probably should change "/XXXXXX" to be something that someone can find if they look at the filesystem. I'd suggest "/downloaded-
review:
Approve
- 132. By Conor Curran
-
changed temp name to be more telling of its purpose
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/Makefile.am' | |||
2 | --- src/Makefile.am 2010-08-27 11:25:47 +0000 | |||
3 | +++ src/Makefile.am 2010-09-07 15:31:44 +0000 | |||
4 | @@ -67,7 +67,9 @@ | |||
5 | 67 | player-controller.vala \ | 67 | player-controller.vala \ |
6 | 68 | mpris2-controller.vala \ | 68 | mpris2-controller.vala \ |
7 | 69 | player-item.vala \ | 69 | player-item.vala \ |
9 | 70 | familiar-players-db.vala | 70 | familiar-players-db.vala \ |
10 | 71 | fetch-file.vala | ||
11 | 72 | |||
12 | 71 | 73 | ||
13 | 72 | music_bridge_VALAFLAGS = \ | 74 | music_bridge_VALAFLAGS = \ |
14 | 73 | --ccode \ | 75 | --ccode \ |
15 | @@ -81,7 +83,9 @@ | |||
16 | 81 | --pkg Dbusmenu-Glib-0.2 \ | 83 | --pkg Dbusmenu-Glib-0.2 \ |
17 | 82 | --pkg common-defs \ | 84 | --pkg common-defs \ |
18 | 83 | --pkg dbus-glib-1 \ | 85 | --pkg dbus-glib-1 \ |
20 | 84 | --pkg gio-unix-2.0 | 86 | --pkg gio-unix-2.0 \ |
21 | 87 | --pkg gdk-pixbuf-2.0 | ||
22 | 88 | |||
23 | 85 | 89 | ||
24 | 86 | $(MAINTAINER_VALAFLAGS) | 90 | $(MAINTAINER_VALAFLAGS) |
25 | 87 | 91 | ||
26 | 88 | 92 | ||
27 | === added file 'src/fetch-file.vala' | |||
28 | --- src/fetch-file.vala 1970-01-01 00:00:00 +0000 | |||
29 | +++ src/fetch-file.vala 2010-09-07 15:31:44 +0000 | |||
30 | @@ -0,0 +1,86 @@ | |||
31 | 1 | /* | ||
32 | 2 | * Copyright (C) 2010 Canonical, Ltd. | ||
33 | 3 | * | ||
34 | 4 | * This library is free software; you can redistribute it and/or modify | ||
35 | 5 | * it under the terms of the GNU Lesser General Public License | ||
36 | 6 | * version 3.0 as published by the Free Software Foundation. | ||
37 | 7 | * | ||
38 | 8 | * This library is distributed in the hope that it will be useful, | ||
39 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
40 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
41 | 11 | * GNU Lesser General Public License version 3.0 for more details. | ||
42 | 12 | * | ||
43 | 13 | * You should have received a copy of the GNU Lesser General Public | ||
44 | 14 | * License along with this library. If not, see | ||
45 | 15 | * <http://www.gnu.org/licenses/>. | ||
46 | 16 | * | ||
47 | 17 | * Authors | ||
48 | 18 | * Gordon Allott <gord.allott@canonical.com> | ||
49 | 19 | * Conor Curran <conor.curran@canonical.com> | ||
50 | 20 | */ | ||
51 | 21 | |||
52 | 22 | public class FetchFile : Object | ||
53 | 23 | { | ||
54 | 24 | /* public variables */ | ||
55 | 25 | public string uri {get; construct;} | ||
56 | 26 | public string intended_property {get; construct;} | ||
57 | 27 | |||
58 | 28 | /* private variables */ | ||
59 | 29 | private DataInputStream stream; | ||
60 | 30 | private File? file; | ||
61 | 31 | private ByteArray data; | ||
62 | 32 | |||
63 | 33 | /* public signals */ | ||
64 | 34 | public signal void failed (); | ||
65 | 35 | public signal void completed (ByteArray data, string property); | ||
66 | 36 | |||
67 | 37 | public FetchFile (string uri, string prop) | ||
68 | 38 | { | ||
69 | 39 | Object (uri: uri, intended_property: prop); | ||
70 | 40 | } | ||
71 | 41 | |||
72 | 42 | construct | ||
73 | 43 | { | ||
74 | 44 | this.file = File.new_for_uri(this.uri); | ||
75 | 45 | this.data = new ByteArray (); | ||
76 | 46 | } | ||
77 | 47 | |||
78 | 48 | public async void fetch_data () | ||
79 | 49 | { | ||
80 | 50 | try { | ||
81 | 51 | this.stream = new DataInputStream(this.file.read(null)); | ||
82 | 52 | this.stream.set_byte_order (DataStreamByteOrder.LITTLE_ENDIAN); | ||
83 | 53 | } catch (GLib.Error e) { | ||
84 | 54 | this.failed (); | ||
85 | 55 | } | ||
86 | 56 | this.read_something_async (); | ||
87 | 57 | } | ||
88 | 58 | |||
89 | 59 | private async void read_something_async () | ||
90 | 60 | { | ||
91 | 61 | ssize_t size = 1024; | ||
92 | 62 | uint8[] buffer = new uint8[size]; | ||
93 | 63 | |||
94 | 64 | ssize_t bufsize = 1; | ||
95 | 65 | do { | ||
96 | 66 | try { | ||
97 | 67 | bufsize = yield this.stream.read_async (buffer, size, GLib.Priority.DEFAULT, null); | ||
98 | 68 | if (bufsize < 1) { break;} | ||
99 | 69 | |||
100 | 70 | if (bufsize != size) | ||
101 | 71 | { | ||
102 | 72 | uint8[] cpybuf = new uint8[bufsize]; | ||
103 | 73 | Memory.copy (cpybuf, buffer, bufsize); | ||
104 | 74 | this.data.append (cpybuf); | ||
105 | 75 | } | ||
106 | 76 | else | ||
107 | 77 | { | ||
108 | 78 | this.data.append (buffer); | ||
109 | 79 | } | ||
110 | 80 | } catch (Error e) { | ||
111 | 81 | this.failed (); | ||
112 | 82 | } | ||
113 | 83 | } while (bufsize > 0); | ||
114 | 84 | this.completed (this.data, this.intended_property); | ||
115 | 85 | } | ||
116 | 86 | } | ||
117 | 0 | 87 | ||
118 | === modified file 'src/metadata-menu-item.vala' | |||
119 | --- src/metadata-menu-item.vala 2010-08-24 16:59:15 +0000 | |||
120 | +++ src/metadata-menu-item.vala 2010-09-07 15:31:44 +0000 | |||
121 | @@ -17,18 +17,141 @@ | |||
122 | 17 | with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | with this program. If not, see <http://www.gnu.org/licenses/>. |
123 | 18 | */ | 18 | */ |
124 | 19 | 19 | ||
125 | 20 | using Dbusmenu; | ||
126 | 21 | using Gee; | 20 | using Gee; |
127 | 22 | using DbusmenuMetadata; | 21 | using DbusmenuMetadata; |
128 | 22 | using Gdk; | ||
129 | 23 | 23 | ||
130 | 24 | public class MetadataMenuitem : PlayerItem | 24 | public class MetadataMenuitem : PlayerItem |
131 | 25 | { | 25 | { |
132 | 26 | public const string ALBUM_ART_DIR_SUFFIX = "indicators/sound/album-art-cache"; | ||
133 | 27 | |||
134 | 28 | public static string album_art_cache_dir; | ||
135 | 29 | private static FetchFile fetcher; | ||
136 | 30 | private string previous_temp_album_art_path; | ||
137 | 31 | |||
138 | 26 | public MetadataMenuitem() | 32 | public MetadataMenuitem() |
139 | 27 | { | 33 | { |
140 | 28 | Object(item_type: MENUITEM_TYPE); | 34 | Object(item_type: MENUITEM_TYPE); |
141 | 29 | reset(attributes_format()); | 35 | reset(attributes_format()); |
142 | 30 | } | 36 | } |
144 | 31 | 37 | ||
145 | 38 | construct{ | ||
146 | 39 | MetadataMenuitem.clean_album_art_temp_dir(); | ||
147 | 40 | this.previous_temp_album_art_path = null; | ||
148 | 41 | this.album_art_cache_dir = MetadataMenuitem.create_album_art_temp_dir(); | ||
149 | 42 | } | ||
150 | 43 | |||
151 | 44 | private static void clean_album_art_temp_dir() | ||
152 | 45 | { | ||
153 | 46 | string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); | ||
154 | 47 | |||
155 | 48 | GLib.File? album_art_dir = GLib.File.new_for_path(path); | ||
156 | 49 | |||
157 | 50 | if(delete_album_art_contents(album_art_dir) == false) | ||
158 | 51 | { | ||
159 | 52 | warning("could not remove the temp album art files %s", path); | ||
160 | 53 | } | ||
161 | 54 | } | ||
162 | 55 | |||
163 | 56 | private static string? create_album_art_temp_dir() | ||
164 | 57 | { | ||
165 | 58 | string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); | ||
166 | 59 | if(DirUtils.create(path, 0700) == -1){ | ||
167 | 60 | warning("could not create a temp dir for remote album art, it must have been created already"); | ||
168 | 61 | } | ||
169 | 62 | return path; | ||
170 | 63 | } | ||
171 | 64 | |||
172 | 65 | private static bool delete_album_art_contents (GLib.File dir) | ||
173 | 66 | { | ||
174 | 67 | bool result = true; | ||
175 | 68 | try { | ||
176 | 69 | var e = dir.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, | ||
177 | 70 | FileQueryInfoFlags.NOFOLLOW_SYMLINKS, | ||
178 | 71 | null); | ||
179 | 72 | while (true) | ||
180 | 73 | { | ||
181 | 74 | var file = e.next_file (null); | ||
182 | 75 | |||
183 | 76 | debug("file name = %s", file.get_name()); | ||
184 | 77 | |||
185 | 78 | if (file == null) | ||
186 | 79 | break; | ||
187 | 80 | |||
188 | 81 | var child = dir.get_child (file.get_name ()); | ||
189 | 82 | |||
190 | 83 | try { | ||
191 | 84 | child.delete (null); | ||
192 | 85 | } catch (Error error_) { | ||
193 | 86 | warning (@"Unable to delete file '$(child.get_basename ()): $(error_.message)"); | ||
194 | 87 | result = false; | ||
195 | 88 | } | ||
196 | 89 | } | ||
197 | 90 | } catch (Error error) { | ||
198 | 91 | warning (@"Unable to read files from directory '$(dir.get_basename ())': %s", | ||
199 | 92 | error.message); | ||
200 | 93 | result = false; | ||
201 | 94 | } | ||
202 | 95 | return result; | ||
203 | 96 | } | ||
204 | 97 | |||
205 | 98 | public void fetch_art(string uri, string prop) | ||
206 | 99 | { | ||
207 | 100 | File art_file = File.new_for_uri(uri); | ||
208 | 101 | if(art_file.is_native() == true){ | ||
209 | 102 | string path; | ||
210 | 103 | try{ | ||
211 | 104 | path = Filename.from_uri(uri.strip()); | ||
212 | 105 | this.property_set(prop, path); | ||
213 | 106 | } | ||
214 | 107 | catch(ConvertError e){ | ||
215 | 108 | warning("Problem converting URI %s to file path", | ||
216 | 109 | uri); | ||
217 | 110 | } | ||
218 | 111 | // eitherway return, the artwork was local | ||
219 | 112 | return; | ||
220 | 113 | } | ||
221 | 114 | debug("fetch_art -remotely %s", this.album_art_cache_dir); | ||
222 | 115 | // If we didn't manage to create the temp dir | ||
223 | 116 | // don't bother with remote | ||
224 | 117 | if(this.album_art_cache_dir == null){ | ||
225 | 118 | return; | ||
226 | 119 | } | ||
227 | 120 | // green light to go remote | ||
228 | 121 | this.fetcher = new FetchFile (uri, prop); | ||
229 | 122 | this.fetcher.failed.connect (() => { this.on_fetcher_failed ();}); | ||
230 | 123 | this.fetcher.completed.connect (this.on_fetcher_completed); | ||
231 | 124 | this.fetcher.fetch_data (); | ||
232 | 125 | } | ||
233 | 126 | |||
234 | 127 | private void on_fetcher_failed () | ||
235 | 128 | { | ||
236 | 129 | warning("on_fetcher_failed -> could not fetch artwork"); | ||
237 | 130 | } | ||
238 | 131 | |||
239 | 132 | private void on_fetcher_completed(ByteArray update, string property) | ||
240 | 133 | { | ||
241 | 134 | try{ | ||
242 | 135 | PixbufLoader loader = new PixbufLoader (); | ||
243 | 136 | loader.write (update.data, update.len); | ||
244 | 137 | loader.close (); | ||
245 | 138 | Pixbuf icon = loader.get_pixbuf (); | ||
246 | 139 | string path = this.album_art_cache_dir.concat("/downloaded-coverart-XXXXXX"); | ||
247 | 140 | int r = FileUtils.mkstemp(path); | ||
248 | 141 | if(r != -1){ | ||
249 | 142 | icon.save (path, loader.get_format().get_name()); | ||
250 | 143 | this.property_set(property, path); | ||
251 | 144 | if(this.previous_temp_album_art_path != null){ | ||
252 | 145 | FileUtils.remove(this.previous_temp_album_art_path); | ||
253 | 146 | } | ||
254 | 147 | this.previous_temp_album_art_path = path; | ||
255 | 148 | } | ||
256 | 149 | } | ||
257 | 150 | catch(GLib.Error e){ | ||
258 | 151 | warning("Problem creating file from bytearray fetched from the interweb - error: %s", | ||
259 | 152 | e.message); | ||
260 | 153 | } | ||
261 | 154 | } | ||
262 | 32 | 155 | ||
263 | 33 | public static HashSet<string> attributes_format() | 156 | public static HashSet<string> attributes_format() |
264 | 34 | { | 157 | { |
265 | @@ -38,6 +161,5 @@ | |||
266 | 38 | attrs.add(MENUITEM_ALBUM); | 161 | attrs.add(MENUITEM_ALBUM); |
267 | 39 | attrs.add(MENUITEM_ARTURL); | 162 | attrs.add(MENUITEM_ARTURL); |
268 | 40 | return attrs; | 163 | return attrs; |
271 | 41 | } | 164 | } |
270 | 42 | |||
272 | 43 | } | 165 | } |
273 | 44 | 166 | ||
274 | === modified file 'src/metadata-widget.c' | |||
275 | --- src/metadata-widget.c 2010-09-06 17:07:15 +0000 | |||
276 | +++ src/metadata-widget.c 2010-09-07 15:31:44 +0000 | |||
277 | @@ -25,6 +25,7 @@ | |||
278 | 25 | #include "metadata-widget.h" | 25 | #include "metadata-widget.h" |
279 | 26 | #include "common-defs.h" | 26 | #include "common-defs.h" |
280 | 27 | #include <gtk/gtk.h> | 27 | #include <gtk/gtk.h> |
281 | 28 | #include <glib.h> | ||
282 | 28 | 29 | ||
283 | 29 | static DbusmenuMenuitem* twin_item; | 30 | static DbusmenuMenuitem* twin_item; |
284 | 30 | 31 | ||
285 | @@ -69,7 +70,7 @@ | |||
286 | 69 | MetadataWidget* metadata, | 70 | MetadataWidget* metadata, |
287 | 70 | GdkPixbuf *source); | 71 | GdkPixbuf *source); |
288 | 71 | 72 | ||
290 | 72 | 73 | static void draw_album_art_placeholder(GtkWidget *metadata); | |
291 | 73 | 74 | ||
292 | 74 | G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); | 75 | G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); |
293 | 75 | 76 | ||
294 | @@ -178,7 +179,7 @@ | |||
295 | 178 | 179 | ||
296 | 179 | /** | 180 | /** |
297 | 180 | * We override the expose method to enable primitive drawing of the | 181 | * We override the expose method to enable primitive drawing of the |
299 | 181 | * empty album art image (and soon rounded rectangles on the album art) | 182 | * empty album art image and rounded rectangles on the album art. |
300 | 182 | */ | 183 | */ |
301 | 183 | static gboolean | 184 | static gboolean |
302 | 184 | metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user_data) | 185 | metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user_data) |
303 | @@ -186,24 +187,33 @@ | |||
304 | 186 | g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); | 187 | g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); |
305 | 187 | MetadataWidget* widget = METADATA_WIDGET(user_data); | 188 | MetadataWidget* widget = METADATA_WIDGET(user_data); |
306 | 188 | MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); | 189 | MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); |
307 | 189 | |||
308 | 190 | if(priv->image_path->len > 0){ | 190 | if(priv->image_path->len > 0){ |
311 | 191 | 191 | if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE){ | |
310 | 192 | if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE){ | ||
312 | 193 | GdkPixbuf* pixbuf; | 192 | GdkPixbuf* pixbuf; |
313 | 194 | pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); | 193 | pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); |
316 | 195 | g_debug("metadata_widget_expose, album art update -> pixbuf from %s", | 194 | g_debug("metadata_load_new_image -> pixbuf from %s", |
317 | 196 | priv->image_path->str); | 195 | priv->image_path->str); |
318 | 196 | if(GDK_IS_PIXBUF(pixbuf) == FALSE){ | ||
319 | 197 | g_debug("problem loading the downloaded image just use the placeholder instead"); | ||
320 | 198 | draw_album_art_placeholder(metadata); | ||
321 | 199 | return TRUE; | ||
322 | 200 | } | ||
323 | 197 | pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); | 201 | pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); |
324 | 198 | image_set_from_pixbuf (metadata, widget, pixbuf); | 202 | image_set_from_pixbuf (metadata, widget, pixbuf); |
325 | 199 | g_string_erase(priv->old_image_path, 0, -1); | 203 | g_string_erase(priv->old_image_path, 0, -1); |
326 | 200 | g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); | 204 | g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); |
327 | 201 | 205 | ||
329 | 202 | g_object_unref(pixbuf); | 206 | g_object_unref(pixbuf); |
330 | 203 | } | 207 | } |
331 | 204 | return FALSE; | 208 | return FALSE; |
332 | 205 | } | 209 | } |
334 | 206 | 210 | draw_album_art_placeholder(metadata); | |
335 | 211 | return TRUE; | ||
336 | 212 | } | ||
337 | 213 | |||
338 | 214 | static void draw_album_art_placeholder(GtkWidget *metadata) | ||
339 | 215 | { | ||
340 | 216 | |||
341 | 207 | cairo_t *cr; | 217 | cairo_t *cr; |
342 | 208 | cr = gdk_cairo_create (metadata->window); | 218 | cr = gdk_cairo_create (metadata->window); |
343 | 209 | GtkAllocation alloc; | 219 | GtkAllocation alloc; |
344 | @@ -255,8 +265,7 @@ | |||
345 | 255 | g_object_unref(pcontext); | 265 | g_object_unref(pcontext); |
346 | 256 | g_string_free (string, TRUE); | 266 | g_string_free (string, TRUE); |
347 | 257 | cairo_destroy (cr); | 267 | cairo_destroy (cr); |
350 | 258 | 268 | ||
349 | 259 | return TRUE; | ||
351 | 260 | } | 269 | } |
352 | 261 | 270 | ||
353 | 262 | /* Suppress/consume keyevents */ | 271 | /* Suppress/consume keyevents */ |
354 | @@ -314,7 +323,12 @@ | |||
355 | 314 | } | 323 | } |
356 | 315 | else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ | 324 | else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ |
357 | 316 | g_string_erase(priv->image_path, 0, -1); | 325 | g_string_erase(priv->image_path, 0, -1); |
359 | 317 | g_string_overwrite(priv->image_path, 0, g_value_get_string (value)); | 326 | g_string_overwrite(priv->image_path, 0, g_value_get_string (value)); |
360 | 327 | // if its a remote image queue a redraw incase the download took too long | ||
361 | 328 | if (g_str_has_prefix(g_value_get_string (value), g_get_user_cache_dir())){ | ||
362 | 329 | g_debug("the image update is a download so redraw"); | ||
363 | 330 | gtk_widget_queue_draw(GTK_WIDGET(mitem)); | ||
364 | 331 | } | ||
365 | 318 | } | 332 | } |
366 | 319 | } | 333 | } |
367 | 320 | 334 | ||
368 | 321 | 335 | ||
369 | === modified file 'src/player-item.vala' | |||
370 | --- src/player-item.vala 2010-08-24 16:59:15 +0000 | |||
371 | +++ src/player-item.vala 2010-09-07 15:31:44 +0000 | |||
372 | @@ -25,7 +25,7 @@ | |||
373 | 25 | public PlayerController owner {get; construct;} | 25 | public PlayerController owner {get; construct;} |
374 | 26 | public string item_type { get; construct; } | 26 | public string item_type { get; construct; } |
375 | 27 | private const int EMPTY = -1; | 27 | private const int EMPTY = -1; |
377 | 28 | 28 | ||
378 | 29 | public PlayerItem(string type) | 29 | public PlayerItem(string type) |
379 | 30 | { | 30 | { |
380 | 31 | Object(item_type: type); | 31 | Object(item_type: type); |
381 | @@ -42,6 +42,12 @@ | |||
382 | 42 | } | 42 | } |
383 | 43 | } | 43 | } |
384 | 44 | 44 | ||
385 | 45 | /** | ||
386 | 46 | * update() | ||
387 | 47 | * Base update method for playeritems, takes the attributes and the incoming updates | ||
388 | 48 | * and attmepts to update the appropriate props on the object. | ||
389 | 49 | * Album art is handled separately to deal with remote and local file paths. | ||
390 | 50 | */ | ||
391 | 45 | public void update(HashTable<string, Value?> data, HashSet<string> attributes) | 51 | public void update(HashTable<string, Value?> data, HashSet<string> attributes) |
392 | 46 | { | 52 | { |
393 | 47 | debug("PlayerItem::update()"); | 53 | debug("PlayerItem::update()"); |
394 | @@ -59,16 +65,14 @@ | |||
395 | 59 | if (v.holds (typeof (string))){ | 65 | if (v.holds (typeof (string))){ |
396 | 60 | string update = v.get_string().strip(); | 66 | string update = v.get_string().strip(); |
397 | 61 | debug("with value : %s", update); | 67 | debug("with value : %s", update); |
406 | 62 | // Special case for the arturl URI's. | 68 | if(property.contains("mpris:artUrl")){ |
407 | 63 | if(property.contains("mpris:artUrl")){ | 69 | // We know its a metadata instance because thats the only |
408 | 64 | try{ | 70 | // object with the arturl prop |
409 | 65 | update = Filename.from_uri(update.strip()); | 71 | MetadataMenuitem metadata = this as MetadataMenuitem; |
410 | 66 | } | 72 | metadata.fetch_art(update.strip(), property); |
411 | 67 | catch(ConvertError e){ | 73 | continue; |
404 | 68 | warning("Problem converting URI %s to file path", update); | ||
405 | 69 | } | ||
412 | 70 | } | 74 | } |
414 | 71 | this.property_set(property, update); | 75 | this.property_set(property, update); |
415 | 72 | } | 76 | } |
416 | 73 | else if (v.holds (typeof (int))){ | 77 | else if (v.holds (typeof (int))){ |
417 | 74 | debug("with value : %i", v.get_int()); | 78 | debug("with value : %i", v.get_int()); |
418 | @@ -83,7 +87,6 @@ | |||
419 | 83 | this.property_set_bool(property, v.get_boolean()); | 87 | this.property_set_bool(property, v.get_boolean()); |
420 | 84 | } | 88 | } |
421 | 85 | } | 89 | } |
422 | 86 | |||
423 | 87 | if(this.property_get_bool(MENUITEM_PROP_VISIBLE) == false){ | 90 | if(this.property_get_bool(MENUITEM_PROP_VISIBLE) == false){ |
424 | 88 | this.property_set_bool(MENUITEM_PROP_VISIBLE, true); | 91 | this.property_set_bool(MENUITEM_PROP_VISIBLE, true); |
425 | 89 | } | 92 | } |
426 | @@ -101,5 +104,6 @@ | |||
427 | 101 | } | 104 | } |
428 | 102 | return false; | 105 | return false; |
429 | 103 | } | 106 | } |
430 | 107 | |||
431 | 104 | } | 108 | } |
432 | 105 | 109 | ||
433 | 106 | 110 | ||
434 | === modified file 'src/sound-service.c' | |||
435 | --- src/sound-service.c 2010-09-07 09:52:23 +0000 | |||
436 | +++ src/sound-service.c 2010-09-07 15:31:44 +0000 | |||
437 | @@ -40,14 +40,13 @@ | |||
438 | 40 | { | 40 | { |
439 | 41 | if (mainloop != NULL) { | 41 | if (mainloop != NULL) { |
440 | 42 | g_debug("Service shutdown !"); | 42 | g_debug("Service shutdown !"); |
442 | 43 | // TODO: uncomment for release !! | 43 | //TODO: uncomment for release !! |
443 | 44 | close_pulse_activites(); | 44 | close_pulse_activites(); |
444 | 45 | g_main_loop_quit(mainloop); | 45 | g_main_loop_quit(mainloop); |
445 | 46 | } | 46 | } |
446 | 47 | return; | 47 | return; |
447 | 48 | } | 48 | } |
448 | 49 | 49 | ||
449 | 50 | |||
450 | 51 | /** | 50 | /** |
451 | 52 | main: | 51 | main: |
452 | 53 | **/ | 52 | **/ |
453 | 54 | 53 | ||
454 | === modified file 'vapi/common-defs.vapi' | |||
455 | --- vapi/common-defs.vapi 2010-07-21 09:56:15 +0000 | |||
456 | +++ vapi/common-defs.vapi 2010-09-07 15:31:44 +0000 | |||
457 | @@ -1,6 +1,6 @@ | |||
458 | 1 | /* | 1 | /* |
459 | 2 | Copyright 2010 Canonical Ltd. | 2 | Copyright 2010 Canonical Ltd. |
461 | 3 | 3 | ||
462 | 4 | Authors: | 4 | Authors: |
463 | 5 | Conor Curran <conor.curran@canonical.com> | 5 | Conor Curran <conor.curran@canonical.com> |
464 | 6 | 6 |
* The temporary file needs to be built with mkstemp to create a random directory for the artwork.
* It should be in the XDG temp directory instead of hardcoded to /tmp
* You can use g_file_is_native() to determine whether it's local or not, just incase they're using something other than http://