Merge lp:~didrocks/unity-lens-music/add-local-radio into lp:unity-lens-music
- add-local-radio
- Merge into trunk
Proposed by
Didier Roche-Tolomelli
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Paweł Stołowski | ||||||||
Approved revision: | 86 | ||||||||
Merged at revision: | 83 | ||||||||
Proposed branch: | lp:~didrocks/unity-lens-music/add-local-radio | ||||||||
Merge into: | lp:unity-lens-music | ||||||||
Diff against target: |
668 lines (+354/-74) 10 files modified
Makefile.am (+1/-1) configure.ac (+1/-0) src/categories.vala (+2/-1) src/daemon.vala (+5/-1) src/rhythmbox-collection.vala (+99/-70) src/rhythmbox-scope.vala (+1/-1) src/track.vala (+7/-0) tests/Makefile.am (+45/-0) tests/assertions.vapi (+23/-0) tests/test-rhythmbox-parser.vala (+170/-0) |
||||||||
To merge this branch: | bzr merge lp:~didrocks/unity-lens-music/add-local-radio | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paweł Stołowski (community) | Approve | ||
Review via email: mp+111875@code.launchpad.net |
Commit message
Description of the change
This branch adds local radio detection from rhythmbox. The category will
only be placed after the "for purchase one" to be unobstrusive (LP: #969697)
Also fix the non translated "Unknown" album filter appearing for non english
users (LP: #1009069)
Add some tests for the parser part (radios and songs)
To post a comment you must log in.
- 86. By Didier Roche-Tolomelli
-
add it to an album if only it's a song, make type_track TypeTrack
Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : | # |
Good spot! Changes made :)
I only add albums for now if the type is a song. Please rereview
Revision history for this message
Paweł Stołowski (stolowski) wrote : | # |
Looks good now, and works fine. Well done!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile.am' |
2 | --- Makefile.am 2011-09-14 18:16:32 +0000 |
3 | +++ Makefile.am 2012-06-29 15:58:20 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -SUBDIRS = src data po |
6 | +SUBDIRS = src data po tests |
7 | |
8 | # |
9 | # Install the music.lens and musicstore.scope files |
10 | |
11 | === modified file 'configure.ac' |
12 | --- configure.ac 2012-04-27 07:45:16 +0000 |
13 | +++ configure.ac 2012-06-29 15:58:20 +0000 |
14 | @@ -121,6 +121,7 @@ |
15 | src/Makefile |
16 | src/config.vala |
17 | po/Makefile.in |
18 | + tests/Makefile |
19 | ]) |
20 | AC_OUTPUT |
21 | |
22 | |
23 | === modified file 'src/categories.vala' |
24 | --- src/categories.vala 2012-01-20 11:48:10 +0000 |
25 | +++ src/categories.vala 2012-06-29 15:58:20 +0000 |
26 | @@ -23,7 +23,8 @@ |
27 | SONGS, |
28 | ALBUMS, |
29 | PURCHASE, |
30 | - MUSIC |
31 | + MUSIC, |
32 | + RADIOS |
33 | } |
34 | |
35 | } |
36 | |
37 | === modified file 'src/daemon.vala' |
38 | --- src/daemon.vala 2012-04-23 12:35:38 +0000 |
39 | +++ src/daemon.vala 2012-06-29 15:58:20 +0000 |
40 | @@ -74,7 +74,7 @@ |
41 | filter.add_option ("1960", _("60s")); |
42 | filter.add_option ("1970", _("70s")); |
43 | filter.add_option ("1980", _("80s")); |
44 | - filter.add_option ("1990", _("90s")); |
45 | + filter.add_option ("1990", _("90s")); |
46 | filter.add_option ("2000", _("00s")); |
47 | filter.add_option ("2010", _("10s")); |
48 | |
49 | @@ -135,6 +135,10 @@ |
50 | new FileIcon (icon_dir.get_child ("group-songs.svg"))); |
51 | categories.append (cat); |
52 | |
53 | + cat = new Unity.Category (_("Radio"), |
54 | + new FileIcon (icon_dir.get_child ("group-songs.svg"))); |
55 | + categories.append (cat); |
56 | + |
57 | lens.categories = categories; |
58 | } |
59 | } |
60 | |
61 | === modified file 'src/rhythmbox-collection.vala' |
62 | --- src/rhythmbox-collection.vala 2012-04-25 17:26:44 +0000 |
63 | +++ src/rhythmbox-collection.vala 2012-06-29 15:58:20 +0000 |
64 | @@ -26,6 +26,7 @@ |
65 | |
66 | private enum Columns |
67 | { |
68 | + TYPE, |
69 | URI, |
70 | TITLE, |
71 | ARTIST, |
72 | @@ -43,7 +44,7 @@ |
73 | |
74 | class RhythmboxCollection : Object |
75 | { |
76 | - const string UNKNOWN_ALBUM = "Unknown"; |
77 | + const string UNKNOWN_ALBUM = _("Unknown"); |
78 | |
79 | SequenceModel all_tracks; |
80 | ModelTag<int> album_art_tag; |
81 | @@ -56,7 +57,7 @@ |
82 | |
83 | HashTable<unowned string, Variant> variant_store; |
84 | HashTable<int, Variant> int_variant_store; |
85 | - Variant row_buffer[11]; |
86 | + Variant row_buffer[12]; |
87 | |
88 | Analyzer analyzer; |
89 | Index? index; |
90 | @@ -64,7 +65,7 @@ |
91 | |
92 | string media_art_dir; |
93 | |
94 | - class XmlParser: Object |
95 | + public class XmlParser: Object |
96 | { |
97 | const MarkupParser parser = |
98 | { |
99 | @@ -91,7 +92,7 @@ |
100 | return context.parse (content, (ssize_t) len); |
101 | } |
102 | |
103 | - bool processing_song; |
104 | + bool processing_track; |
105 | Track current_track; |
106 | int current_data = -1; |
107 | |
108 | @@ -99,21 +100,24 @@ |
109 | [CCode (array_length = false, array_null_terminated = true)] string[] attr_names, [CCode (array_length = false, array_null_terminated = true)] string[] attr_values) |
110 | throws MarkupError |
111 | { |
112 | - if (!processing_song) |
113 | + if (!processing_track) |
114 | { |
115 | switch (name) |
116 | { |
117 | case "rhythmdb": is_rhythmdb_xml = true; break; |
118 | case "entry": |
119 | - bool is_song = false; |
120 | + string accepted_element_name = null; |
121 | for (int i = 0; attr_names[i] != null; i++) |
122 | { |
123 | - if (attr_names[i] == "type" && attr_values[i] == "song") |
124 | - is_song = true; |
125 | + if (attr_names[i] == "type" && (attr_values[i] == "song" |
126 | + || attr_values[i] == "iradio")) |
127 | + accepted_element_name = attr_values[i]; |
128 | } |
129 | - if (!is_song) return; |
130 | - processing_song = true; |
131 | + if (accepted_element_name == null) return; |
132 | + processing_track = true; |
133 | current_track = new Track (); |
134 | + current_track.type_track = accepted_element_name == "song" ? |
135 | + TrackType.SONG : TrackType.RADIO; |
136 | break; |
137 | } |
138 | } |
139 | @@ -156,14 +160,14 @@ |
140 | if (current_data >= 0) current_data = -1; |
141 | break; |
142 | case "hidden": |
143 | - if (processing_song) processing_song = false; |
144 | + if (processing_track) processing_track = false; |
145 | break; |
146 | case "entry": |
147 | - if (processing_song && current_track != null) |
148 | + if (processing_track && current_track != null) |
149 | { |
150 | track_info_ready (current_track); |
151 | } |
152 | - processing_song = false; |
153 | + processing_track = false; |
154 | break; |
155 | } |
156 | } |
157 | @@ -172,7 +176,7 @@ |
158 | string text, size_t text_len) |
159 | throws MarkupError |
160 | { |
161 | - if (!processing_song || current_data < 0) return; |
162 | + if (!processing_track || current_data < 0) return; |
163 | switch (current_data) |
164 | { |
165 | case Columns.URI: current_track.uri = text; break; |
166 | @@ -203,7 +207,7 @@ |
167 | |
168 | construct |
169 | { |
170 | - static_assert (11 == Columns.N_COLUMNS); // sync with row_buffer size |
171 | + static_assert (12 == Columns.N_COLUMNS); // sync with row_buffer size |
172 | media_art_dir = Path.build_filename ( |
173 | Environment.get_user_cache_dir (), "media-art"); |
174 | |
175 | @@ -213,7 +217,7 @@ |
176 | direct_equal); |
177 | all_tracks = new SequenceModel (); |
178 | // the columns correspond to the Columns enum |
179 | - all_tracks.set_schema ("s", "s", "s", "s", "s", "s", |
180 | + all_tracks.set_schema ("i", "s", "s", "s", "s", "s", "s", |
181 | "s", "s", "i", "i", "i"); |
182 | assert (all_tracks.get_schema ().length == Columns.N_COLUMNS); |
183 | album_art_tag = new ModelTag<int> (all_tracks); |
184 | @@ -383,6 +387,7 @@ |
185 | |
186 | private void prepare_row_buffer (Track track) |
187 | { |
188 | + Variant type = cached_variant_for_int (track.type_track); |
189 | Variant uri = new Variant.string (track.uri); |
190 | Variant title = new Variant.string (track.title); |
191 | Variant artist = cached_variant_for_string (track.artist); |
192 | @@ -395,17 +400,18 @@ |
193 | Variant year = cached_variant_for_int (track.year); |
194 | Variant play_count = cached_variant_for_int (track.play_count); |
195 | |
196 | - row_buffer[0] = uri; |
197 | - row_buffer[1] = title; |
198 | - row_buffer[2] = artist; |
199 | - row_buffer[3] = album; |
200 | - row_buffer[4] = artwork; |
201 | - row_buffer[5] = mime_type; |
202 | - row_buffer[6] = genre; |
203 | - row_buffer[7] = album_artist; |
204 | - row_buffer[8] = track_number; |
205 | - row_buffer[9] = year; |
206 | - row_buffer[10] = play_count; |
207 | + row_buffer[0] = type; |
208 | + row_buffer[1] = uri; |
209 | + row_buffer[2] = title; |
210 | + row_buffer[3] = artist; |
211 | + row_buffer[4] = album; |
212 | + row_buffer[5] = artwork; |
213 | + row_buffer[6] = mime_type; |
214 | + row_buffer[7] = genre; |
215 | + row_buffer[8] = album_artist; |
216 | + row_buffer[9] = track_number; |
217 | + row_buffer[10] = year; |
218 | + row_buffer[11] = play_count; |
219 | } |
220 | |
221 | public void parse_metadata_file (string path) |
222 | @@ -475,7 +481,7 @@ |
223 | prepare_row_buffer (track); |
224 | var iter = all_tracks.append_row (row_buffer); |
225 | |
226 | - if (track.album == UNKNOWN_ALBUM) return; |
227 | + if (track.album == "" || track.album == UNKNOWN_ALBUM) return; |
228 | var album_key = "%s - %s".printf (track.album, track.album_artist != null ? track.album_artist : track.artist); |
229 | var arr = album_to_tracks_map[album_key]; |
230 | if (arr == null) |
231 | @@ -520,7 +526,8 @@ |
232 | private enum ResultType |
233 | { |
234 | ALBUM, |
235 | - SONG |
236 | + SONG, |
237 | + RADIO |
238 | } |
239 | |
240 | private void add_result (Model results_model, Model model, |
241 | @@ -556,14 +563,15 @@ |
242 | album_art_tag[model, iter] = current_album_art_tag; |
243 | } |
244 | |
245 | - var title_col = result_type == ResultType.SONG ? |
246 | + var title_col = (result_type == ResultType.SONG |
247 | + || result_type == ResultType.RADIO) ? |
248 | Columns.TITLE : Columns.ALBUM; |
249 | unowned string title = model.get_string (iter, title_col); |
250 | var uri = model.get_string (iter, Columns.URI); |
251 | var dnd_uri = model.get_string (iter, Columns.URI); |
252 | if (result_type == ResultType.ALBUM) |
253 | { |
254 | - if (title == UNKNOWN_ALBUM) return; |
255 | + if (title == "" || title == UNKNOWN_ALBUM) return; |
256 | unowned string artist = model.get_string (iter, |
257 | Columns.ALBUM_ARTIST); |
258 | if (artist == "") |
259 | @@ -598,6 +606,7 @@ |
260 | int min_year; |
261 | int max_year; |
262 | int category_id; |
263 | + ResultType result_type; |
264 | |
265 | Model model = all_tracks; |
266 | get_decade_filter (filters, out min_year, out max_year); |
267 | @@ -639,26 +648,36 @@ |
268 | } |
269 | } |
270 | |
271 | - unowned string album = model.get_string (iter, |
272 | - Columns.ALBUM); |
273 | - // it's not first as in track #1, but first found from album |
274 | - bool first_track_from_album = !(album in albums_list_nosearch); |
275 | - albums_list_nosearch.add (album); |
276 | - |
277 | - if (first_track_from_album) |
278 | - { |
279 | - category_id = category_override >= 0 ? |
280 | - category_override : Category.ALBUMS; |
281 | - |
282 | - add_result (search.results_model, model, iter, |
283 | - ResultType.ALBUM, category_id); |
284 | - } |
285 | - |
286 | - category_id = category_override >= 0 ? |
287 | - category_override : Category.SONGS; |
288 | - |
289 | + if (model.get_int32 (iter, Columns.TYPE) == TrackType.SONG) |
290 | + { |
291 | + category_id = Category.SONGS; |
292 | + result_type = ResultType.SONG; |
293 | + |
294 | + unowned string album = model.get_string (iter, |
295 | + Columns.ALBUM); |
296 | + // it's not first as in track #1, but first found from album |
297 | + bool first_track_from_album = !(album in albums_list_nosearch); |
298 | + albums_list_nosearch.add (album); |
299 | + |
300 | + if (first_track_from_album) |
301 | + { |
302 | + category_id = category_override >= 0 ? |
303 | + category_override : Category.ALBUMS; |
304 | + |
305 | + add_result (search.results_model, model, iter, |
306 | + ResultType.ALBUM, category_id); |
307 | + } |
308 | + } |
309 | + else |
310 | + { |
311 | + category_id = Category.RADIOS; |
312 | + result_type = ResultType.RADIO; |
313 | + } |
314 | + if (category_override >= 0) |
315 | + category_id = category_override; |
316 | + |
317 | add_result (helper_model, model, iter, |
318 | - ResultType.SONG, category_id); |
319 | + result_type, category_id); |
320 | |
321 | num_results++; |
322 | if (max_results >= 0 && num_results >= max_results) break; |
323 | @@ -730,27 +749,37 @@ |
324 | } |
325 | } |
326 | |
327 | - unowned string album = model.get_string (model_iter, |
328 | - Columns.ALBUM); |
329 | - |
330 | - // it's not first as in track #1, but first found from album |
331 | - bool first_track_from_album = !(album in albums_list); |
332 | - albums_list.add (album); |
333 | - |
334 | - if (first_track_from_album) |
335 | - { |
336 | - category_id = category_override >= 0 ? |
337 | - category_override : Category.ALBUMS; |
338 | - |
339 | - add_result (search.results_model, model, model_iter, |
340 | - ResultType.ALBUM, category_id); |
341 | - } |
342 | - |
343 | - category_id = category_override >= 0 ? |
344 | - category_override : Category.SONGS; |
345 | - |
346 | + |
347 | + if (model.get_int32 (model_iter, Columns.TYPE) == TrackType.SONG) |
348 | + { |
349 | + category_id = Category.SONGS; |
350 | + result_type = ResultType.SONG; |
351 | + |
352 | + unowned string album = model.get_string (model_iter, |
353 | + Columns.ALBUM); |
354 | + // it's not first as in track #1, but first found from album |
355 | + bool first_track_from_album = !(album in albums_list); |
356 | + albums_list.add (album); |
357 | + |
358 | + if (first_track_from_album) |
359 | + { |
360 | + category_id = category_override >= 0 ? |
361 | + category_override : Category.ALBUMS; |
362 | + |
363 | + add_result (search.results_model, model, model_iter, |
364 | + ResultType.ALBUM, category_id); |
365 | + } |
366 | + } |
367 | + else |
368 | + { |
369 | + category_id = Category.RADIOS; |
370 | + result_type = ResultType.RADIO; |
371 | + } |
372 | + if (category_override >= 0) |
373 | + category_id = category_override; |
374 | + |
375 | add_result (helper_model, model, model_iter, |
376 | - ResultType.SONG, category_id); |
377 | + result_type, category_id); |
378 | |
379 | num_results++; |
380 | if (max_results >= 0 && num_results >= max_results) break; |
381 | |
382 | === modified file 'src/rhythmbox-scope.vala' |
383 | --- src/rhythmbox-scope.vala 2012-04-25 17:26:44 +0000 |
384 | +++ src/rhythmbox-scope.vala 2012-06-29 15:58:20 +0000 |
385 | @@ -68,7 +68,7 @@ |
386 | yield; |
387 | } |
388 | /** |
389 | - * Tells banshee to play the selected uri(s) |
390 | + * Tells rhythmbox to play the selected uri(s) |
391 | */ |
392 | public Unity.ActivationResponse activate (string uri) |
393 | { |
394 | |
395 | === modified file 'src/track.vala' |
396 | --- src/track.vala 2012-03-27 13:31:14 +0000 |
397 | +++ src/track.vala 2012-06-29 15:58:20 +0000 |
398 | @@ -19,8 +19,15 @@ |
399 | |
400 | namespace Unity.MusicLens { |
401 | |
402 | + public enum TrackType |
403 | + { |
404 | + SONG, |
405 | + RADIO |
406 | + } |
407 | + |
408 | public class Track : GLib.Object |
409 | { |
410 | + public TrackType type_track { get; set; } |
411 | public string title { get; set; } |
412 | public string uri { get; set; } |
413 | public string artist { get; set; } |
414 | |
415 | === added directory 'tests' |
416 | === added file 'tests/Makefile.am' |
417 | --- tests/Makefile.am 1970-01-01 00:00:00 +0000 |
418 | +++ tests/Makefile.am 2012-06-29 15:58:20 +0000 |
419 | @@ -0,0 +1,45 @@ |
420 | +check_PROGRAMS = test-rhythmbox-parser |
421 | + |
422 | +TESTS = $(check_PROGRAMS) |
423 | + |
424 | +AM_CPPFLAGS = \ |
425 | + -w \ |
426 | + $(LENS_DAEMON_CFLAGS) \ |
427 | + -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ |
428 | + -I$(top_srcdir)/src \ |
429 | + $(NULL) |
430 | + |
431 | +AM_VALAFLAGS = \ |
432 | + -C \ |
433 | + --pkg dee-1.0 \ |
434 | + --pkg gee-1.0 \ |
435 | + --pkg gio-2.0 \ |
436 | + --pkg gio-unix-2.0 \ |
437 | + --pkg glib-2.0 \ |
438 | + --vapidir $(top_srcdir)/src \ |
439 | + --pkg tdb \ |
440 | + --pkg unity \ |
441 | + $(srcdir)/assertions.vapi \ |
442 | + $(NULL) |
443 | + |
444 | +test_libs = \ |
445 | + $(LENS_DAEMON_LIBS) \ |
446 | + $(NULL) |
447 | + |
448 | +test_rhythmbox_parser_LDADD = $(test_libs) |
449 | + |
450 | +test_rhythmbox_parser_SOURCES = \ |
451 | + test-rhythmbox-parser.vala \ |
452 | + $(top_srcdir)/src/album.vala \ |
453 | + $(top_srcdir)/src/categories.vala \ |
454 | + $(top_srcdir)/src/config.vala \ |
455 | + $(top_srcdir)/src/filter-parser.vala \ |
456 | + $(top_srcdir)/src/filter-parser-decade.vala \ |
457 | + $(top_srcdir)/src/filter-parser-genre.vala \ |
458 | + $(top_srcdir)/src/genre.vala \ |
459 | + $(top_srcdir)/src/rhythmbox-collection.vala \ |
460 | + $(top_srcdir)/src/track.vala \ |
461 | + $(NULL) |
462 | + |
463 | +CLEANFILES = *.stamp |
464 | + |
465 | |
466 | === added file 'tests/assertions.vapi' |
467 | --- tests/assertions.vapi 1970-01-01 00:00:00 +0000 |
468 | +++ tests/assertions.vapi 2012-06-29 15:58:20 +0000 |
469 | @@ -0,0 +1,23 @@ |
470 | +[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h")] |
471 | +namespace Assertions { |
472 | + public enum OperatorType { |
473 | + [CCode (cname = "==")] |
474 | + EQUAL, |
475 | + [CCode (cname = "!=")] |
476 | + NOT_EQUAL, |
477 | + [CCode (cname = "<")] |
478 | + LESS_THAN, |
479 | + [CCode (cname = ">")] |
480 | + GREATER_THAN, |
481 | + [CCode (cname = "<=")] |
482 | + LESS_OR_EQUAL, |
483 | + [CCode (cname = ">=")] |
484 | + GREATER_OR_EQUAL |
485 | + } |
486 | + |
487 | + public void assert_cmpstr (string? s1, OperatorType op, string? s2); |
488 | + public void assert_cmpint (int n1, OperatorType op, int n2); |
489 | + public void assert_cmpuint (uint n1, OperatorType op, uint n2); |
490 | + public void assert_cmphex (uint n1, OperatorType op, uint n2); |
491 | + public void assert_cmpfloat (float n1, OperatorType op, float n2); |
492 | +} |
493 | |
494 | === added file 'tests/test-rhythmbox-parser.vala' |
495 | --- tests/test-rhythmbox-parser.vala 1970-01-01 00:00:00 +0000 |
496 | +++ tests/test-rhythmbox-parser.vala 2012-06-29 15:58:20 +0000 |
497 | @@ -0,0 +1,170 @@ |
498 | +/* |
499 | + * Copyright (C) 2012 Canonical Ltd |
500 | + * |
501 | + * This program is free software: you can redistribute it and/or modify |
502 | + * it under the terms of the GNU General Public License version 3 as |
503 | + * published by the Free Software Foundation. |
504 | + * |
505 | + * This program is distributed in the hope that it will be useful, |
506 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
507 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
508 | + * GNU General Public License for more details. |
509 | + * |
510 | + * You should have received a copy of the GNU General Public License |
511 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
512 | + * |
513 | + * Authored by Didier Roche <didrocks@ubuntu.com> |
514 | + * |
515 | + */ |
516 | + |
517 | +using Unity.MusicLens; |
518 | +using Assertions; |
519 | + |
520 | +public class Main |
521 | +{ |
522 | + public static int main (string[] args) |
523 | + { |
524 | + Test.init (ref args); |
525 | + |
526 | + Test.add_data_func ("/Unit/ParserChecker/Radios", test_radios); |
527 | + Test.add_data_func ("/Unit/ParserChecker/Songs", test_songs); |
528 | + Test.add_data_func ("/Unit/ParserChecker/LazyLoad", test_lazy_load); |
529 | + Test.add_data_func ("/Unit/ParserChecker/LazyLoad", test_invalid_songload); |
530 | + |
531 | + Test.run (); |
532 | + |
533 | + return 0; |
534 | + } |
535 | + |
536 | + private static void test_radios () |
537 | + { |
538 | + var parser = new RhythmboxCollection.XmlParser (); |
539 | + |
540 | + string collection_to_parse = """<?xml version="1.0" standalone="yes"?> |
541 | +<rhythmdb version="1.8"> |
542 | + <entry type="iradio"> |
543 | + <title>Absolute Radio 80s (Modem)</title> |
544 | + <genre>80's</genre> |
545 | + <artist></artist> |
546 | + <album></album> |
547 | + <location>http://network.absoluteradio.co.uk/core/audio/ogg/live.pls?service=a8</location> |
548 | + <play-count>6</play-count> |
549 | + <last-played>1339693331</last-played> |
550 | + <bitrate>32</bitrate> |
551 | + <date>0</date> |
552 | + <media-type>application/octet-stream</media-type> |
553 | + </entry> |
554 | +</rhythmdb>"""; |
555 | + |
556 | + parser.track_info_ready.connect ((track) => |
557 | + { |
558 | + assert_cmpstr (track.title, OperatorType.EQUAL, "Absolute Radio 80s (Modem)"); |
559 | + assert_cmpstr (track.genre, OperatorType.EQUAL, "other"); |
560 | + assert_cmpstr (track.artist, OperatorType.EQUAL, ""); |
561 | + assert_cmpstr (track.album, OperatorType.EQUAL, ""); |
562 | + assert_cmpstr (track.uri, OperatorType.EQUAL, "http://network.absoluteradio.co.uk/core/audio/ogg/live.pls?service=a8"); |
563 | + assert_cmpint (track.year, OperatorType.EQUAL, 0); |
564 | + assert (track.type_track == TrackType.RADIO); |
565 | + }); |
566 | + parser.parse(collection_to_parse, collection_to_parse.length); |
567 | + } |
568 | + |
569 | + |
570 | + private static void test_songs () |
571 | + { |
572 | + var parser = new RhythmboxCollection.XmlParser (); |
573 | + |
574 | + string collection_to_parse = """<?xml version="1.0" standalone="yes"?> |
575 | +<rhythmdb version="1.8"> |
576 | + <entry type="song"> |
577 | + <title>LA PASSION</title> |
578 | + <genre>Dance</genre> |
579 | + <artist>GIGI D'AGOSTINO</artist> |
580 | + <album>Loulou 007</album> |
581 | + <duration>228</duration> |
582 | + <file-size>3661842</file-size> |
583 | + <location>file:///home/moi/Gigi%20d'agostino%20Passion.mp3</location> |
584 | + <mtime>1338273042</mtime> |
585 | + <first-seen>1338536342</first-seen> |
586 | + <last-seen>1340378542</last-seen> |
587 | + <bitrate>128</bitrate> |
588 | + <date>730142</date> |
589 | + <media-type>audio/mpeg</media-type> |
590 | + <comment>http://www.danceparadise.ca.tc</comment> |
591 | + </entry> |
592 | +</rhythmdb>"""; |
593 | + |
594 | + parser.track_info_ready.connect ((track) => |
595 | + { |
596 | + assert_cmpstr (track.title, OperatorType.EQUAL, "LA PASSION"); |
597 | + assert_cmpstr (track.genre, OperatorType.EQUAL, "techno"); |
598 | + assert_cmpstr (track.artist, OperatorType.EQUAL, "GIGI D'AGOSTINO"); |
599 | + assert_cmpstr (track.album, OperatorType.EQUAL, "Loulou 007"); |
600 | + assert_cmpstr (track.uri, OperatorType.EQUAL, "file:///home/moi/Gigi%20d'agostino%20Passion.mp3"); |
601 | + assert_cmpint (track.year, OperatorType.EQUAL, 2000); |
602 | + assert_cmpstr (track.mime_type, OperatorType.EQUAL, "audio/mpeg"); |
603 | + assert (track.type_track == TrackType.SONG); |
604 | + }); |
605 | + parser.parse(collection_to_parse, collection_to_parse.length); |
606 | + } |
607 | + |
608 | + |
609 | + private static void test_lazy_load () |
610 | + { |
611 | + var parser = new RhythmboxCollection.XmlParser (); |
612 | + |
613 | + string collection_to_parse_chunk = """<?xml version="1.0" standalone="yes"?> |
614 | +<rhythmdb version="1.8"> |
615 | + <entry type="song"> |
616 | + <title>LA PASSION</title> |
617 | + <genre>Dance</genre> |
618 | + <artist>GIGI D'AGOSTINO</artist> |
619 | +"""; |
620 | + parser.parse(collection_to_parse_chunk, collection_to_parse_chunk.length); |
621 | + |
622 | + collection_to_parse_chunk = """ |
623 | + <album>Loulou 007</album> |
624 | + <duration>228</duration> |
625 | + <file-size>3661842</file-size> |
626 | + <location>file:///home/moi/Gigi%20d'agostino%20Passion.mp3</location> |
627 | + <mtime>1338273042</mtime> |
628 | + <first-seen>1338536342</first-seen> |
629 | + <last-seen>1340378542</last-seen> |
630 | + <bitrate>128</bitrate> |
631 | + <date>730142</date> |
632 | + <media-type>audio/mpeg</media-type> |
633 | + <comment>http://www.danceparadise.ca.tc</comment> |
634 | + </entry>"""; |
635 | + parser.track_info_ready.connect ((track) => |
636 | + { |
637 | + assert_cmpstr (track.title, OperatorType.EQUAL, "LA PASSION"); |
638 | + assert_cmpstr (track.album, OperatorType.EQUAL, "Loulou 007"); |
639 | + assert (track.type_track == TrackType.SONG); |
640 | + }); |
641 | + parser.parse(collection_to_parse_chunk, collection_to_parse_chunk.length); |
642 | + } |
643 | + |
644 | + |
645 | + private static void test_invalid_songload () |
646 | + { |
647 | + var parser = new RhythmboxCollection.XmlParser (); |
648 | + |
649 | + string collection_to_parse_chunk = """<?xml version="1.0" standalone="yes"?> |
650 | +<rhythmdb version="1.8"> |
651 | + <entry type="song"> |
652 | + <title>LA PASSION</title> |
653 | + <genre>Dance</genre> |
654 | + <entry type="song"> |
655 | + <title>le poisson</title> |
656 | + <genre>Dance</genre> |
657 | + </entry>"""; |
658 | + |
659 | + parser.track_info_ready.connect ((track) => |
660 | + { |
661 | + assert_cmpstr (track.title, OperatorType.EQUAL, "le poisson"); |
662 | + assert (track.type_track == TrackType.SONG); |
663 | + }); |
664 | + parser.parse(collection_to_parse_chunk, collection_to_parse_chunk.length); |
665 | + } |
666 | + |
667 | +} |
668 | \ No newline at end of file |
1) I think we may need to adjust album handling logic in "search" method, as iradio records seem to have empty album names - I think we should skip album if TYPE == RADIO; see lines 654 - 665, i.e. from_album = !(album in albums_ list_nosearch) ; track_from_ album) results_ model, model, iter, ResultType.ALBUM, category_id);
bool first_track_
...
if (first_
...
add_result (search.
2) Can you use TrackType as the type of Track - type_track instead of int?