Merge lp:~mblayman/entertainer/pythonize-musiclib into lp:entertainer/future
- pythonize-musiclib
- Merge into entertainer-future
Proposed by
Matt Layman
Status: | Merged |
---|---|
Merge reported by: | Matt Layman |
Merged at revision: | not available |
Proposed branch: | lp:~mblayman/entertainer/pythonize-musiclib |
Merge into: | lp:entertainer/future |
Prerequisite: | lp:~mblayman/entertainer/clean-up-1.0 |
Diff against target: |
1694 lines (+309/-837) 13 files modified
entertainerlib/client/medialibrary/music.py (+149/-516) entertainerlib/client/medialibrary/playable.py (+6/-25) entertainerlib/gui/screens/album.py (+11/-12) entertainerlib/gui/screens/artist.py (+1/-1) entertainerlib/gui/screens/audio_play.py (+2/-2) entertainerlib/gui/screens/disc.py (+5/-5) entertainerlib/gui/screens/music.py (+1/-1) entertainerlib/gui/tabs/albums_tab.py (+4/-4) entertainerlib/gui/tabs/lyrics_tab.py (+1/-1) entertainerlib/gui/tabs/playing_tab.py (+16/-19) entertainerlib/gui/tabs/tracks_tab.py (+5/-7) entertainerlib/tests/mock.py (+1/-15) entertainerlib/tests/test_music.py (+107/-229) |
To merge this branch: | bzr merge lp:~mblayman/entertainer/pythonize-musiclib |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matt Layman | Approve | ||
Review via email: mp+16600@code.launchpad.net |
Commit message
Made the music library code follow more pythonic behavior.
Description of the change
To post a comment you must log in.
Revision history for this message
Matt Layman (mblayman) wrote : | # |
- 452. By Matt Layman
-
Merged from parent and resolved conflicts.
Revision history for this message
Matt Layman (mblayman) wrote : | # |
Discussed on IRC that I can use my discretion for merges for the time being to bootstrap some contribution.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'entertainerlib/client/medialibrary/music.py' |
2 | --- entertainerlib/client/medialibrary/music.py 2009-09-08 02:40:16 +0000 |
3 | +++ entertainerlib/client/medialibrary/music.py 2010-01-03 23:00:31 +0000 |
4 | @@ -2,19 +2,15 @@ |
5 | '''Music Library - Interface for Entertainer music library cache''' |
6 | |
7 | import os |
8 | + |
9 | import CDDB, DiscID |
10 | from pysqlite2 import dbapi2 as sqlite |
11 | |
12 | +from entertainerlib.client.medialibrary.playable import Playable |
13 | from entertainerlib.configuration import Configuration |
14 | - |
15 | -from entertainerlib.client.medialibrary.playable import Playable |
16 | from entertainerlib.download import LyricsDownloader |
17 | |
18 | |
19 | -class MusicLibraryException(Exception): |
20 | - '''Exception to handle MusicLibrary issues''' |
21 | - pass |
22 | - |
23 | class AlbumHasNoTracks(Exception): |
24 | '''Exception to handle Albums with no tracks''' |
25 | pass |
26 | @@ -23,12 +19,8 @@ |
27 | '''Exception to handle track errors''' |
28 | pass |
29 | |
30 | -class TrackRatingOutOfRange(Exception): |
31 | - '''Exception to handle track rating problems''' |
32 | - pass |
33 | - |
34 | class MusicLibrary: |
35 | - """Interface for Entertainer's music cache.""" |
36 | + '''Interface for Entertainer's music cache.''' |
37 | |
38 | def __init__(self): |
39 | self.config = Configuration() |
40 | @@ -39,171 +31,66 @@ |
41 | self.cursor = self.db_connection.cursor() |
42 | |
43 | def __del__(self): |
44 | - """ |
45 | - Close connection when this object is destroyed |
46 | - """ |
47 | + '''Close the connection when this object is destroyed.''' |
48 | self.db_connection.close() |
49 | |
50 | def get_compact_disc_information(self): |
51 | - """ |
52 | - Get the CompactDisc object of the current disc in drive. This |
53 | - method queries CD information from Internet database (CDDB). |
54 | - @return: CompactDisc |
55 | - """ |
56 | + '''Get the CompactDisc object of the current disc in drive by querying |
57 | + CD information from an Internet database (CDDB).''' |
58 | cdrom = DiscID.open() |
59 | disc_id = DiscID.disc_id(cdrom) |
60 | return CompactDisc(disc_id) |
61 | |
62 | - def get_playlists(self): |
63 | - """ |
64 | - Get list of playlist names. |
65 | - @return: String list |
66 | - """ |
67 | - self.cursor.execute("SELECT title FROM playlist") |
68 | - playlists = [] |
69 | - for row in self.cursor: |
70 | - playlists.append(row[0]) |
71 | - return playlists |
72 | - |
73 | - def get_num_of_tracks_on_playlist(self, name): |
74 | - """ |
75 | - Get list of playlist names. |
76 | - @param name: Playlist name (see: get_playlists) |
77 | - @return: Integer (number of tracks) |
78 | - """ |
79 | - self.cursor.execute("""SELECT COUNT(filename) |
80 | - FROM playlist_relation |
81 | - WHERE title=:name""", { "name" : name }) |
82 | - result = self.cursor.fetchall() |
83 | - return result[0][0] |
84 | - |
85 | - def get_tracks_on_playlist(self, name): |
86 | - """ |
87 | - Retrun list of tracks on given playlist. |
88 | - @param name: Playlist name |
89 | - @return: List of Track objects |
90 | - """ |
91 | - self.cursor.execute( |
92 | - """SELECT filename, title, tracknumber, artist, album, |
93 | - genre, bitrate, year, rating, length, comment, lyrics |
94 | - FROM track, playlist_relation |
95 | - WHERE playlist_relation.title=:name |
96 | - AND playlist_relation.filename=track.filename |
97 | - ORDER BY title""", { "name" : name }) |
98 | - tracks = [] |
99 | - for row in self.cursor: |
100 | - tracks.append(Track(row[0], row[1], row[2], row[3], row[4], |
101 | - row[5], row[6], row[7], row[8], row[9], |
102 | - row[10], row[11])) |
103 | - return tracks |
104 | - |
105 | def get_all_artists(self): |
106 | - """ |
107 | - Get a list of all artists. |
108 | - @return: list of Strings |
109 | - """ |
110 | - self.cursor.execute( |
111 | - "SELECT DISTINCT artist FROM track ORDER BY artist") |
112 | + '''Return all the artists names.''' |
113 | + self.cursor.execute("SELECT DISTINCT artist FROM track ORDER BY artist") |
114 | |
115 | artists = [] |
116 | for row in self.cursor: |
117 | artists.append(row[0]) |
118 | return artists |
119 | |
120 | - def get_all_tracks(self): |
121 | - """ |
122 | - Get all tracks in music cache. |
123 | - @return: List of Track objects |
124 | - """ |
125 | - self.cursor.execute( |
126 | - """SELECT filename, title, tracknumber, artist, album, |
127 | - genre, bitrate, year, rating, length, comment, lyrics |
128 | - FROM track |
129 | - ORDER BY title""") |
130 | - tracks = [] |
131 | - for row in self.cursor: |
132 | - tracks.append(Track(row[0], row[1], row[2], row[3], row[4], |
133 | - row[5], row[6], row[7], row[8], row[9], |
134 | - row[10], row[11])) |
135 | - return tracks |
136 | - |
137 | - def get_tracks_by_genre(self, genre): |
138 | - """ |
139 | - Get albums from music cache by genre. |
140 | - @param genre: Genre (string) |
141 | - @return: List of Track objects |
142 | - """ |
143 | - self.cursor.execute( |
144 | - """SELECT filename, title, tracknumber, artist, album, |
145 | - genre, bitrate, year, rating, length, comment, lyrics |
146 | - FROM track |
147 | - WHERE genre=:genre |
148 | - ORDER BY title""", { "genre" : genre}) |
149 | - tracks = [] |
150 | - for row in self.cursor: |
151 | - tracks.append(Track(row[0], row[1], row[2], row[3], row[4], |
152 | - row[5], row[6], row[7], row[8], row[9], |
153 | - row[10], row[11])) |
154 | - return tracks |
155 | - |
156 | def get_tracks_by_artist(self, artist): |
157 | - """ |
158 | - Get tracks from music cache by artist. |
159 | - @param artist: Name of the artist (string) |
160 | - """ |
161 | + '''Return track objects from the given artist.''' |
162 | self.cursor.execute( |
163 | """SELECT filename, title, tracknumber, artist, album, |
164 | - genre, bitrate, year, rating, length, comment, lyrics |
165 | + year, length, lyrics |
166 | FROM track |
167 | WHERE artist=:artist |
168 | ORDER BY title""", { "artist" : artist}) |
169 | tracks = [] |
170 | for row in self.cursor: |
171 | - tracks.append(Track(row[0], row[1], row[2], row[3], row[4], |
172 | - row[5], row[6], row[7], row[8], row[9], |
173 | - row[10], row[11])) |
174 | + tracks.append(Track(row[0], row[1], row[2], row[3], row[4], row[5], |
175 | + row[6], row[7], self._create_album)) |
176 | return tracks |
177 | |
178 | def get_all_albums(self): |
179 | - """ |
180 | - Get all albums in music cache. |
181 | - @return: List of Album objects |
182 | - """ |
183 | + '''Return all the albums in the library.''' |
184 | self.cursor.execute("SELECT DISTINCT album FROM track ORDER BY album") |
185 | albums = [] |
186 | for row in self.cursor.fetchall(): |
187 | - albums.append(Album(row[0], self.cursor)) |
188 | + albums.append(self._create_album(row[0])) |
189 | return albums |
190 | |
191 | def get_albums_by_artist(self, artist): |
192 | - """ |
193 | - Get albums from music cache by artist. |
194 | - @param artist: Artist name (string) |
195 | - @return: List of Album objects |
196 | - """ |
197 | + '''Return all albums from the given artist.''' |
198 | self.cursor.execute("""SELECT DISTINCT album |
199 | FROM track |
200 | WHERE artist=:artist |
201 | ORDER BY album""", { "artist" : artist}) |
202 | albums = [] |
203 | for row in self.cursor.fetchall(): |
204 | - albums.append(Album(row[0], self.cursor)) |
205 | + albums.append(self._create_album(row[0])) |
206 | return albums |
207 | |
208 | def number_of_tracks(self): |
209 | - """ |
210 | - Get the number of tracks in music cache. |
211 | - @return: Integer (number of tracks) |
212 | - """ |
213 | + '''Return the number of tracks.''' |
214 | self.cursor.execute("SELECT COUNT(filename) FROM track") |
215 | result = self.cursor.fetchall() |
216 | return result[0][0] |
217 | |
218 | def number_of_tracks_by_artist(self, artist): |
219 | - """ |
220 | - Get the number of tracks made by given artist |
221 | - @param artist: Artist name (string) |
222 | - """ |
223 | + '''Return the number of tracks from the given artist.''' |
224 | self.cursor.execute("""SELECT COUNT(filename) |
225 | FROM track |
226 | WHERE artist=:artist""", { "artist" : artist}) |
227 | @@ -211,10 +98,7 @@ |
228 | return result[0][0] |
229 | |
230 | def number_of_albums_by_artist(self, artist): |
231 | - """ |
232 | - Get the number of albums made by given artist |
233 | - @param artist: Artist name (string) |
234 | - """ |
235 | + '''Return the number of albums from the given artist.''' |
236 | self.cursor.execute("""SELECT DISTINCT album |
237 | FROM track |
238 | WHERE artist=:artist |
239 | @@ -223,363 +107,173 @@ |
240 | return len(result) |
241 | |
242 | def save_lyrics(self, track, lyrics): |
243 | - """ |
244 | - Save lyrics to database. |
245 | - @param track: Track which lyrics we are saving |
246 | - @param lyrics: Lyrics string |
247 | - """ |
248 | - track.set_lyrics(lyrics) # Be certain to save for this track instance, |
249 | - # not just persistent storage |
250 | - self.cursor.execute("""UPDATE track |
251 | - SET lyrics=:lyrics |
252 | - WHERE filename=:fn""", { |
253 | - "lyrics" : lyrics, |
254 | - "fn" : track.get_filename()}) |
255 | + '''Save the lyrics to the database.''' |
256 | + track.lyrics = lyrics # Be certain to save for this track instance, |
257 | + # not just persistent storage |
258 | + self.cursor.execute( |
259 | + """UPDATE track SET lyrics=:lyrics WHERE filename=:fn""", |
260 | + { "lyrics" : lyrics, "fn" : track.filename}) |
261 | self.db_connection.commit() |
262 | |
263 | - |
264 | -class Album(object): |
265 | - """ |
266 | - Objects from this class represents albums. Album contains tracks. |
267 | - """ |
268 | - |
269 | - def __init__(self, title, cursor=None): |
270 | - """Initialize album (Fetch data from music cache)""" |
271 | - self.config = Configuration() |
272 | - self.tracks = [] |
273 | - self.title = title |
274 | - self.total_length = 0 |
275 | - |
276 | - if not cursor: |
277 | - self.db_connection = sqlite.connect(self.config.MUSIC_DB) |
278 | - self.cursor = self.db_connection.cursor() |
279 | - else: |
280 | - self.cursor = cursor |
281 | + def _create_album(self, title): |
282 | + '''Factory method to create an Album object.''' |
283 | self.cursor.execute( |
284 | """SELECT filename, title, tracknumber, artist, album, |
285 | - genre, bitrate, year, rating, length, comment, lyrics |
286 | + year, length, lyrics |
287 | FROM track |
288 | WHERE album=:title |
289 | ORDER BY tracknumber""", {"title" : title}) |
290 | |
291 | + length = 0 |
292 | + tracks = [] |
293 | for row in self.cursor: |
294 | - self.tracks.append(Track(row[0], row[1], row[2], row[3], self, |
295 | - row[5], row[6], row[7], row[8], row[9], |
296 | - row[10], row[11])) |
297 | - self.total_length += int(row[9]) |
298 | - if len(self.tracks) == 0: |
299 | + tracks.append(Track(row[0], row[1], row[2], row[3], row[4], row[5], |
300 | + row[6], row[7], self._create_album)) |
301 | + length += int(row[6]) |
302 | + if len(tracks) == 0: |
303 | raise AlbumHasNoTracks() |
304 | - self.artist = self.tracks[0].artist |
305 | - |
306 | - def __str__(self): |
307 | - return self.title |
308 | - |
309 | - def get_title(self): |
310 | - """ |
311 | - Get title ot the album. |
312 | - @return: String |
313 | - """ |
314 | - return self.title |
315 | + |
316 | + artist = tracks[0].artist |
317 | + |
318 | + for track in tracks: |
319 | + if track.artist != artist: |
320 | + artist = _("Various") |
321 | + break |
322 | + |
323 | + encoded_path = artist + ' - ' + title |
324 | + encoded_path = encoded_path.encode('base64') |
325 | + album_art_url = os.path.join(self.config.ALBUM_ART_DIR, |
326 | + encoded_path + '.jpg') |
327 | + |
328 | + return Album(artist, title, length, tracks[0].year, album_art_url, |
329 | + tracks) |
330 | + |
331 | + |
332 | +class Album(object): |
333 | + '''Representation of music album which contains tracks.''' |
334 | + |
335 | + def __init__(self, artist, title, length, year, album_art_url, tracks): |
336 | + self.config = Configuration() |
337 | + self.artist = artist |
338 | + self.title = title |
339 | + self.length = length |
340 | + self.year = year |
341 | + self.album_art_url = album_art_url |
342 | + self.tracks = tracks |
343 | |
344 | def has_album_art(self): |
345 | - """ |
346 | - Has this album album art graphics. |
347 | - @return: Boolean |
348 | - """ |
349 | - artist_album = self.artist + " - " + self.title |
350 | - artist_album = artist_album.encode("base64") |
351 | - album_art = os.path.join(self.config.ALBUM_ART_DIR, |
352 | - artist_album + ".jpg") |
353 | - |
354 | - return os.path.exists(album_art) |
355 | - |
356 | - def get_album_art_url(self): |
357 | - """ |
358 | - Get absolute path of album art file or raises Exception. |
359 | - @return: String |
360 | - """ |
361 | - artist_album = self.artist + " - " + self.title |
362 | - artist_album = artist_album.encode("base64") |
363 | - return os.path.join(self.config.ALBUM_ART_DIR, artist_album + ".jpg") |
364 | - |
365 | - def get_tracks(self): |
366 | - """ |
367 | - Get tracks from this Album. |
368 | - @return: List of Track object |
369 | - """ |
370 | - return self.tracks |
371 | - |
372 | - def get_number_of_tracks(self): |
373 | - """ |
374 | - Get the number of tracks on this album. |
375 | - @return: Integer |
376 | - """ |
377 | - return len(self.tracks) |
378 | - |
379 | - def get_year(self): |
380 | - """ |
381 | - Get release year of this album. This is taken from the first track. |
382 | - @return: String |
383 | - """ |
384 | - return self.tracks[0].get_year() |
385 | - |
386 | - def get_genre(self): |
387 | - """ |
388 | - Get genre of this album. This is taken from the first track. |
389 | - @return: String |
390 | - """ |
391 | - return self.tracks[0].get_genre() |
392 | - |
393 | - def get_artist(self): |
394 | - """ |
395 | - Get the artist of this album. This is taken from the first track. |
396 | - @return: String |
397 | - """ |
398 | - artist = self.tracks[0].get_artist() |
399 | - text = self.tracks[0].get_artist() |
400 | - |
401 | - for track in self.get_tracks(): |
402 | - if track.get_artist() != artist: |
403 | - text = _("Various") |
404 | - break |
405 | - else: |
406 | - artist = track.get_artist() |
407 | - |
408 | - return text |
409 | - |
410 | - def get_total_length(self): |
411 | - """ |
412 | - Get total length of the album. |
413 | - @return: Integer (Length in seconds) |
414 | - """ |
415 | - return self.total_length |
416 | + '''Test if the album has album art.''' |
417 | + return os.path.exists(self.album_art_url) |
418 | |
419 | |
420 | class Track(Playable): |
421 | - """ |
422 | - Track is a Playable object that represents one song in Music library. |
423 | - """ |
424 | - |
425 | - def __init__(self, filename, title, tracknumber, artist, album, genre, |
426 | - bitrate, year, rating, length, comment, lyrics): |
427 | - """ |
428 | - Initialize track. Notice that album parameter can be either |
429 | - Album name as string or Album object! getAlbum() returns always object. |
430 | - """ |
431 | - |
432 | - # Check that these four fields are integers |
433 | - for field in [tracknumber, year, rating, length]: |
434 | - if rating == None: # By default, there is no rating for a track |
435 | - continue |
436 | + '''Representation of a music track.''' |
437 | + |
438 | + def __init__(self, filename, title, number, artist, album, year, length, |
439 | + lyrics, create_album_callback): |
440 | + |
441 | + # Check that these fields are integers |
442 | + for field in [number, year, length]: |
443 | if type(field) != int: |
444 | raise TrackTypeError("%s is not an integer" % field) |
445 | |
446 | - # Check that the rating is in range 1-5 |
447 | - if rating != None and rating not in range(1, 6): |
448 | - raise TrackRatingOutOfRange() |
449 | - |
450 | - self.filename = str(filename) # Filename of the track |
451 | - self.title = str(title) # Track title |
452 | - self.tracknumber = tracknumber # Number of the track |
453 | - self.artist = str(artist) # Artist of the track |
454 | - if isinstance(album, Album): |
455 | - # Album that contains this track (str OR Album object!) |
456 | - self.album = album |
457 | - else: |
458 | - self.album = str(album) |
459 | - self.genre = str(genre) # Genre of the track |
460 | - self.bitrate = str(bitrate) # Bitrate of the track |
461 | - self.year = year # Release year |
462 | - self.rating = rating # Rating of the track (1-5) |
463 | + self.filename = filename |
464 | + self.title = title |
465 | + self.number = number |
466 | + self.artist = artist |
467 | + self._album = album |
468 | + self.year = year |
469 | # Length of the track in seconds (example 240) |
470 | self.length = length |
471 | - self.comment = str(comment) # Comment about this track |
472 | - self.lyrics = str(lyrics) # Lyrics of the track |
473 | - |
474 | - def get_filename(self): |
475 | - """ |
476 | - Get filename of the track |
477 | - @return: String |
478 | - """ |
479 | - return self.filename |
480 | - |
481 | - def get_title(self): |
482 | - """ |
483 | - Get title ot the track__MUSIC_DB |
484 | - @return: String |
485 | - """ |
486 | - return self.title |
487 | - |
488 | - def get_tracknumber(self): |
489 | - """ |
490 | - Get track number of the track |
491 | - @return: Interger |
492 | - """ |
493 | - return self.tracknumber |
494 | - |
495 | - def get_artist(self): |
496 | - """ |
497 | - Get artist of the track |
498 | - @return: String |
499 | - """ |
500 | - return self.artist |
501 | - |
502 | - def get_album(self, cursor=False): |
503 | - """ |
504 | - Get album that contains this Track. |
505 | - @return: Album object |
506 | - """ |
507 | - if not isinstance(self.album, Album): |
508 | - album = Album(self.album, cursor) |
509 | - self.album = album |
510 | + self._lyrics = lyrics |
511 | + self.create_album_callback = create_album_callback |
512 | + |
513 | + @property |
514 | + def album(self): |
515 | + '''Get the album object and use the callback if it's not an instance.''' |
516 | + if not isinstance(self._album, Album): |
517 | + album = self.create_album_callback(self._album) |
518 | + self._album = album |
519 | return album |
520 | else: |
521 | - return self.album |
522 | - |
523 | - def get_album_art_url(self, cursor=False): |
524 | - """ |
525 | - Get album art URL of this Track |
526 | - @return: String (or None if there is no album art for this track) |
527 | - """ |
528 | - self.get_album(cursor) # Need to have an album object |
529 | - |
530 | - if self.album.has_album_art(): |
531 | - return self.album.get_album_art_url() |
532 | - else: |
533 | - return None |
534 | - |
535 | - def get_genre(self): |
536 | - """ |
537 | - Get genre of the track |
538 | - @return: String |
539 | - """ |
540 | - return self.genre |
541 | - |
542 | - def get_bitrate(self): |
543 | - """ |
544 | - Get bitrate of the track |
545 | - @return: String |
546 | - """ |
547 | - return self.bitrate |
548 | - |
549 | - def get_year(self): |
550 | - """ |
551 | - Get year of the track |
552 | - @return: Integer |
553 | - """ |
554 | - return self.year |
555 | - |
556 | - def get_rating(self): |
557 | - """ |
558 | - Return rating of the track |
559 | - @return: Integer |
560 | - """ |
561 | - return self.rating |
562 | - |
563 | - def get_length(self): |
564 | - """ |
565 | - Get length of the track in seconds |
566 | - @return: Integer |
567 | - """ |
568 | - return self.length |
569 | - |
570 | - def get_length_string(self): |
571 | - """ |
572 | - Get length of the track as human readable string. Example: 02:46 |
573 | - @return: Timestamp as string |
574 | - """ |
575 | + return self._album |
576 | + |
577 | + @property |
578 | + def length_string(self): |
579 | + '''Return length as a human readable string. Example: 2:46.''' |
580 | return str(self.length / 60) + ":" + str.zfill(str(self.length % 60), 2) |
581 | |
582 | - def get_comment(self): |
583 | - """ |
584 | - Get comment of the track |
585 | - @return: String |
586 | - """ |
587 | - return self.comment |
588 | + def _get_lyrics(self): |
589 | + '''Get the track lyrics.''' |
590 | + return self._lyrics |
591 | + |
592 | + def _set_lyrics(self, lyrics): |
593 | + '''Set the lyrics. LyricsDownloader returns None if it can't find |
594 | + anything so ensure that using lyrics is always a string.''' |
595 | + if lyrics is None: |
596 | + self._lyrics = '' |
597 | + else: |
598 | + self._lyrics = lyrics |
599 | + |
600 | + lyrics = property(_get_lyrics, _set_lyrics) |
601 | |
602 | def has_lyrics(self): |
603 | - """ |
604 | - Is there lyrics for this track in music cache |
605 | - @return: Boolean, true if lyrics exists |
606 | - """ |
607 | + '''Test if the track has any lyrics.''' |
608 | if self.lyrics == "": |
609 | return False |
610 | else: |
611 | return True |
612 | |
613 | def fetch_lyrics(self, callback=False): |
614 | - """ |
615 | - Fetch lyrics from the Internet using the LyricsDownloader, use |
616 | + '''Fetch lyrics from the Internet using the LyricsDownloader, use a |
617 | callback function to indicate completion since LyricsDownloader is |
618 | asynchronous. Callback function must take lyrics as only input |
619 | - parameter. |
620 | - @param callback: Function called when fetch_lyrics completes |
621 | - """ |
622 | + parameter.''' |
623 | if not callback: |
624 | callback = self.set_lyrics |
625 | if not self.has_lyrics(): |
626 | - self.ld = LyricsDownloader(self.get_title(), self.get_artist(), |
627 | - callback) |
628 | + self.ld = LyricsDownloader(self.title, self.artist, callback) |
629 | self.ld.search() |
630 | |
631 | - def get_lyrics(self): |
632 | - """ |
633 | - Get lyrics of the track |
634 | - @return: String |
635 | - """ |
636 | - return self.lyrics |
637 | - |
638 | - def set_lyrics(self, lyrics): |
639 | - """ |
640 | - Set lyrics to track object instance, use save lyrics for persistent |
641 | - storage of lyrics |
642 | - @param lyrics: Lyrics of track |
643 | - """ |
644 | - if lyrics is None: |
645 | - self.lyrics = "" |
646 | + def get_album_art_url(self): |
647 | + '''Get the album art location if it exists.''' |
648 | + if self.album.has_album_art(): |
649 | + return self.album.album_art_url |
650 | else: |
651 | - self.lyrics = lyrics |
652 | + return None |
653 | |
654 | # Implement playable interface |
655 | + def get_title(self): |
656 | + '''Get the title.''' |
657 | + return self.title |
658 | + |
659 | def get_type(self): |
660 | - """ |
661 | - Track is an audio stream. |
662 | - @return: Integer |
663 | - """ |
664 | + '''Get the type.''' |
665 | return Playable.AUDIO_STREAM |
666 | |
667 | def get_uri(self): |
668 | - """ |
669 | - Get URI of the audio file |
670 | - @return: String |
671 | - """ |
672 | + '''Get the URI.''' |
673 | return "file://" + self.filename |
674 | |
675 | |
676 | class CompactDisc(object): |
677 | - """ |
678 | - CompactDisc |
679 | - |
680 | - Represents one CD. This object is a simple container that includes CD |
681 | - artist, album name and track listing. |
682 | - """ |
683 | + '''Representation of a CD.''' |
684 | |
685 | def __init__(self, disc_id): |
686 | - """ |
687 | - Create a new CompactDisc object. Initialization queries track |
688 | - information from the Internet. |
689 | + # Assume that no results will be found. |
690 | + self.artist = _("Unknown artist") |
691 | + self.length = 0 |
692 | + self.title = _("Unknown title") |
693 | + self.tracks = [] |
694 | |
695 | - @param disc_id: DiscID |
696 | - """ |
697 | - self.tracks = [] |
698 | try: |
699 | (query_status, query_info) = CDDB.query(disc_id) |
700 | except IOError: |
701 | # Set query_status to 0 to act like an unknown CD. |
702 | query_status = 0 |
703 | |
704 | - #See CDDB documentation for more information. |
705 | - #http://cddb-py.sourceforge.net/CDDB/README |
706 | + # See CDDB documentation for more information. |
707 | + # http://cddb-py.sourceforge.net/CDDB/README |
708 | # query_info variable's type depends on query_status |
709 | |
710 | if query_status == 200: |
711 | @@ -592,11 +286,9 @@ |
712 | self._get_information_from_result_element(query_info[0], disc_id) |
713 | else: |
714 | # No metadata found for this disc |
715 | - self.album = _("Unknown title") |
716 | - self.artist = _("Unknown artist") |
717 | for i in range(disc_id[1]): |
718 | self.tracks.append(CompactDiscTrack(i + 1, |
719 | - _("Unknown track %(num)s.") % {'num': str(i+1)}, 0)) |
720 | + _("Unknown track %(num)s.") % {'num': str(i + 1)}, 0)) |
721 | |
722 | def _get_information_from_result_element(self, result, disc_id): |
723 | """Catch any information from a CDDB result dictionnary""" |
724 | @@ -605,105 +297,46 @@ |
725 | disc = unicode(result['disc_id'], "iso-8859-1") |
726 | |
727 | self.artist = title[:title.index(' / ')] |
728 | - self.album = title[title.index(' / ') + 3:] |
729 | + self.title = title[title.index(' / ') + 3:] |
730 | |
731 | # Get track titles |
732 | info = CDDB.read(category, disc)[1] |
733 | - cumulative_length = 0 |
734 | for i in range(disc_id[1]): |
735 | if i + 4 == len(disc_id): |
736 | - # We must calculate last track length different way |
737 | - length = disc_id[len(disc_id) - 1] - cumulative_length |
738 | + # We must calculate last track length in a different way |
739 | + length = disc_id[len(disc_id) - 1] - self.length |
740 | else: |
741 | # Calculate track length in seconds |
742 | length = (disc_id[i + 3] - disc_id[ i + 2]) / 75 |
743 | - cumulative_length = cumulative_length + length |
744 | |
745 | + self.length += length |
746 | track_title = unicode(info['TTITLE' + str(i)], "iso-8859-1") |
747 | self.tracks.append(CompactDiscTrack(i + 1, track_title, length)) |
748 | |
749 | - def get_artist(self): |
750 | - """ |
751 | - Get the name of the artist |
752 | - @return: Artist name as string |
753 | - """ |
754 | - return self.artist |
755 | - |
756 | - def get_title(self): |
757 | - """ |
758 | - Get name of the album. |
759 | - @return: name as string |
760 | - """ |
761 | - return self.album |
762 | - |
763 | - def get_tracks(self): |
764 | - """ |
765 | - Get a list of track names. |
766 | - @return: Tracknames in a string list |
767 | - """ |
768 | - return self.tracks |
769 | - |
770 | - def get_length(self): |
771 | - """ |
772 | - Get length of the album. This is the sum of the track lengths. |
773 | - @return: Integer, length in seconds |
774 | - """ |
775 | - length = 0 |
776 | - for track in self.tracks: |
777 | - length = length + track.get_length() |
778 | - return length |
779 | - |
780 | |
781 | class CompactDiscTrack(Playable): |
782 | - """ |
783 | - CompactDiscTrack is a Playable object that is a one track of the Audio CD. |
784 | - """ |
785 | + '''Representation of a CD track.''' |
786 | |
787 | - def __init__(self, track_number, title, track_length): |
788 | - """ |
789 | - Create a new CD track. |
790 | - @param track_number: Number of the track on the Audio CD. |
791 | - @param title: Title of the track |
792 | - @param track_length: Track length in seconds (integer) |
793 | - """ |
794 | + def __init__(self, number, title, length): |
795 | self.title = title |
796 | - self.uri = "cdda://" + str(track_number) |
797 | - self.track_length = track_length |
798 | - |
799 | + self.uri = "cdda://" + str(number) |
800 | + self.length = length |
801 | + |
802 | + @property |
803 | + def length_string(self): |
804 | + '''Return length as a human readable string. Example: 2:46.''' |
805 | + return str(self.length / 60) + ":" + str.zfill(str(self.length % 60), 2) |
806 | + |
807 | + # Implement playable interface |
808 | def get_title(self): |
809 | - """ |
810 | - Get title of the track |
811 | - @return: String |
812 | - """ |
813 | + '''Get the title.''' |
814 | return self.title |
815 | |
816 | + def get_type(self): |
817 | + '''Get the type.''' |
818 | + return Playable.AUDIO_STREAM |
819 | + |
820 | def get_uri(self): |
821 | - """ |
822 | - Get URI of the playable stream. |
823 | - @return: String |
824 | - """ |
825 | + '''Get the URI.''' |
826 | return self.uri |
827 | |
828 | - def get_length(self): |
829 | - """ |
830 | - Get track length in seconds |
831 | - @return: Integer, length in seconds |
832 | - """ |
833 | - return self.track_length |
834 | - |
835 | - def get_length_string(self): |
836 | - """ |
837 | - Get length of the track as human readable string. Example: 02:46 |
838 | - @return: Timestamp as string |
839 | - """ |
840 | - return str.zfill(str(self.track_length / 60), 2) + ":" + \ |
841 | - str.zfill(str(self.track_length % 60), 2) |
842 | - |
843 | - def get_type(self): |
844 | - """ |
845 | - Get type of the stream. This is one of the |
846 | - constants defined in Playable class. |
847 | - @return: Integer |
848 | - """ |
849 | - return Playable.AUDIO_STREAM |
850 | - |
851 | |
852 | === modified file 'entertainerlib/client/medialibrary/playable.py' |
853 | --- entertainerlib/client/medialibrary/playable.py 2009-05-06 02:58:08 +0000 |
854 | +++ entertainerlib/client/medialibrary/playable.py 2010-01-03 23:00:32 +0000 |
855 | @@ -1,41 +1,22 @@ |
856 | # Copyright (c) 2009 Entertainer Developers - See COPYING - GPLv2 |
857 | '''Playable - Interface for playable streams. MediaPlayer plays Playables''' |
858 | |
859 | -class Playable: |
860 | - """ |
861 | - Interface for playable media. |
862 | - |
863 | - This is an interface for all of those objects that can be played with the |
864 | - MediaPlayer object. MediaPlayer playes only files that implement this |
865 | - interface. |
866 | - |
867 | - At the moment following classes implement this: |
868 | - - Track |
869 | - - VideoItem |
870 | - """ |
871 | +class Playable(object): |
872 | + '''An interface for all objects that can be played with the MediaPlayer. |
873 | + MediaPlayer playes only files that implement this interface.''' |
874 | |
875 | VIDEO_STREAM = 0 |
876 | AUDIO_STREAM = 1 |
877 | |
878 | def get_uri(self): |
879 | - """ |
880 | - Get URI of the playable stream. |
881 | - @return: String |
882 | - """ |
883 | + '''Get the URI.''' |
884 | return None |
885 | |
886 | def get_type(self): |
887 | - """ |
888 | - Get type of the stream. This is one of the |
889 | - constants defined in Playable class. |
890 | - @return: Integer |
891 | - """ |
892 | + '''Get the type (as defined by the Playable constants.''' |
893 | return None |
894 | |
895 | def get_title(self): |
896 | - """ |
897 | - Gets the title of the stream. |
898 | - @return: String |
899 | - """ |
900 | + '''Get the title.''' |
901 | return None |
902 | |
903 | |
904 | === modified file 'entertainerlib/gui/screens/album.py' |
905 | --- entertainerlib/gui/screens/album.py 2009-07-29 03:09:34 +0000 |
906 | +++ entertainerlib/gui/screens/album.py 2010-01-03 23:00:32 +0000 |
907 | @@ -38,7 +38,7 @@ |
908 | |
909 | #List indicator |
910 | self.li = ListIndicator(0.74, 0.85, 0.2, 0.045, ListIndicator.VERTICAL) |
911 | - self.li.set_maximum(len(self.album.get_tracks())) |
912 | + self.li.set_maximum(len(self.album.tracks)) |
913 | self.add(self.li) |
914 | |
915 | self.track_menu.active = True |
916 | @@ -51,8 +51,7 @@ |
917 | displays album cover art. |
918 | """ |
919 | if(self.album.has_album_art()): |
920 | - pixbuf = gtk.gdk.pixbuf_new_from_file( |
921 | - self.album.get_album_art_url()) |
922 | + pixbuf = gtk.gdk.pixbuf_new_from_file(self.album.album_art_url) |
923 | else: |
924 | pixbuf = gtk.gdk.pixbuf_new_from_file( |
925 | self.theme.getImage("default_album_art")) |
926 | @@ -64,19 +63,19 @@ |
927 | """ |
928 | Create album info labels. |
929 | """ |
930 | - if self.album.get_year() != 0: |
931 | - album_text = self.album.get_title() + ", " + \ |
932 | - str(self.album.get_year()) |
933 | + if self.album.year != 0: |
934 | + album_text = self.album.title + ", " + str(self.album.year) |
935 | else: |
936 | - album_text = self.album.get_title() |
937 | + album_text = self.album.title |
938 | album = Label(0.0416, "text", 0.5, 0.13, album_text, font_weight="bold") |
939 | album.set_ellipsize(pango.ELLIPSIZE_END) |
940 | + album.set_line_wrap(False) |
941 | album.width = 0.45 |
942 | self.add(album) |
943 | |
944 | - length = str(self.album.get_total_length() / 60) |
945 | + length = str(self.album.length / 60) |
946 | num_of_tracks_text = _("%(total)s tracks, %(time)s minutes") % \ |
947 | - {'total': self.album.get_number_of_tracks(), 'time': length} |
948 | + {'total': len(self.album.tracks), 'time': length} |
949 | num_of_tracks = Label(0.028, "subtitle", 0.5, 0.18, |
950 | num_of_tracks_text, font_weight="bold") |
951 | self.add(num_of_tracks) |
952 | @@ -87,8 +86,8 @@ |
953 | """ |
954 | menu = TextMenu(0.4978, 0.2344, 0.4393, 0.0781) |
955 | |
956 | - tracks = self.album.get_tracks() |
957 | - tracks_list = [[track.get_title(), track.get_length_string(), track] \ |
958 | + tracks = self.album.tracks |
959 | + tracks_list = [[track.title, track.length_string, track] \ |
960 | for track in tracks] |
961 | menu.async_add(tracks_list) |
962 | |
963 | @@ -132,6 +131,6 @@ |
964 | '''Update of the list indicator and the screen's title''' |
965 | self.li.set_current(self.track_menu.selected_index + 1) |
966 | track = self.track_menu.selected_userdata |
967 | - self.screen_title.set_text(track.get_artist()) |
968 | + self.screen_title.set_text(track.artist) |
969 | self.screen_title.show() |
970 | |
971 | |
972 | === modified file 'entertainerlib/gui/screens/artist.py' |
973 | --- entertainerlib/gui/screens/artist.py 2009-06-17 02:49:44 +0000 |
974 | +++ entertainerlib/gui/screens/artist.py 2010-01-03 23:00:32 +0000 |
975 | @@ -51,6 +51,6 @@ |
976 | better documentation. |
977 | """ |
978 | album = self.tab_group.tab("albums").selected_album |
979 | - self.media_player.set_playlist(Playlist(album.get_tracks())) |
980 | + self.media_player.set_playlist(Playlist(album.tracks)) |
981 | self.media_player.play() |
982 | |
983 | |
984 | === modified file 'entertainerlib/gui/screens/audio_play.py' |
985 | --- entertainerlib/gui/screens/audio_play.py 2009-07-12 17:02:32 +0000 |
986 | +++ entertainerlib/gui/screens/audio_play.py 2010-01-03 23:00:32 +0000 |
987 | @@ -18,11 +18,11 @@ |
988 | Screen.__init__(self, 'AudioPlay', has_tabs=True) |
989 | |
990 | self.theme = self.config.theme |
991 | - album = track.get_album() |
992 | + album = track.album |
993 | |
994 | # Create album art (this is displayed on all tab pages |
995 | if(album.has_album_art()): |
996 | - pixbuf = gtk.gdk.pixbuf_new_from_file(album.get_album_art_url()) |
997 | + pixbuf = gtk.gdk.pixbuf_new_from_file(album.album_art_url) |
998 | else: |
999 | pixbuf = gtk.gdk.pixbuf_new_from_file( |
1000 | self.theme.getImage("default_album_art")) |
1001 | |
1002 | === modified file 'entertainerlib/gui/screens/disc.py' |
1003 | --- entertainerlib/gui/screens/disc.py 2009-07-29 03:09:34 +0000 |
1004 | +++ entertainerlib/gui/screens/disc.py 2010-01-03 23:00:32 +0000 |
1005 | @@ -60,12 +60,12 @@ |
1006 | try: |
1007 | disc = self.music_library.get_compact_disc_information() |
1008 | |
1009 | - title = disc.get_title() |
1010 | - artist = disc.get_artist() |
1011 | - tracks = disc.get_tracks() |
1012 | + title = disc.title |
1013 | + artist = disc.artist |
1014 | + tracks = disc.tracks |
1015 | |
1016 | self.playlist = Playlist(tracks) |
1017 | - self._create_album_info(title, artist, tracks, disc.get_length()) |
1018 | + self._create_album_info(title, artist, tracks, disc.length) |
1019 | self.track_menu = self._create_track_menu(tracks) |
1020 | self.add(self.track_menu) |
1021 | self._create_album_cover_texture(artist, title) |
1022 | @@ -177,7 +177,7 @@ |
1023 | menu = TextMenu(0.4978, 0.2344, 0.4393, 0.0781) |
1024 | menu.visible_rows = 7 |
1025 | |
1026 | - tracks_list = [[track.get_title(), track.get_length_string(), index] \ |
1027 | + tracks_list = [[track.title, track.length_string, index] \ |
1028 | for index, track in enumerate(tracks)] |
1029 | menu.async_add(tracks_list) |
1030 | |
1031 | |
1032 | === modified file 'entertainerlib/gui/screens/music.py' |
1033 | --- entertainerlib/gui/screens/music.py 2009-06-17 02:49:44 +0000 |
1034 | +++ entertainerlib/gui/screens/music.py 2010-01-03 23:00:32 +0000 |
1035 | @@ -85,7 +85,7 @@ |
1036 | self.media_player.play() |
1037 | elif self.tab_group.tab("albums").active: |
1038 | album = self.tab_group.tab("albums").selected_album |
1039 | - self.media_player.set_playlist(Playlist(album.get_tracks())) |
1040 | + self.media_player.set_playlist(Playlist(album.tracks)) |
1041 | self.media_player.play() |
1042 | |
1043 | def handle_user_event(self, event): |
1044 | |
1045 | === modified file 'entertainerlib/gui/tabs/albums_tab.py' |
1046 | --- entertainerlib/gui/tabs/albums_tab.py 2010-01-03 23:00:30 +0000 |
1047 | +++ entertainerlib/gui/tabs/albums_tab.py 2010-01-03 23:00:32 +0000 |
1048 | @@ -42,7 +42,7 @@ |
1049 | self.menu.items_per_col = self.menu.visible_rows |
1050 | self.add(self.menu) |
1051 | |
1052 | - albums_list = [[album.get_album_art_url(), album] for album in albums] |
1053 | + albums_list = [[album.album_art_url, album] for album in albums] |
1054 | self.menu.async_add_albums(albums_list) |
1055 | |
1056 | self.li = ListIndicator(0.77, 0.8, 0.18, 0.045, |
1057 | @@ -83,10 +83,10 @@ |
1058 | '''Update the album information labels.''' |
1059 | if self.active: |
1060 | album = self.menu.selected_userdata |
1061 | - self.album_title.set_text(album.get_title()) |
1062 | - self.album_artist.set_text(album.get_artist()) |
1063 | + self.album_title.set_text(album.title) |
1064 | + self.album_artist.set_text(album.artist) |
1065 | self.album_tracks.set_text(_("%(total)s tracks") % \ |
1066 | - {'total': album.get_number_of_tracks()}) |
1067 | + {'total': len(album.tracks)}) |
1068 | self.li.show() |
1069 | self.li.set_current(self.menu.selected_index + 1) |
1070 | else: |
1071 | |
1072 | === modified file 'entertainerlib/gui/tabs/lyrics_tab.py' |
1073 | --- entertainerlib/gui/tabs/lyrics_tab.py 2009-08-04 01:09:03 +0000 |
1074 | +++ entertainerlib/gui/tabs/lyrics_tab.py 2010-01-03 23:00:32 +0000 |
1075 | @@ -22,7 +22,7 @@ |
1076 | self.lyrics_text = "" |
1077 | |
1078 | if self.track.has_lyrics(): |
1079 | - self.lyrics_text = self.track.get_lyrics() |
1080 | + self.lyrics_text = self.track.lyrics |
1081 | lyrics = Label(0.037, "subtitle", 0, 0, self.lyrics_text) |
1082 | lyrics.set_line_wrap_mode(pango.WRAP_WORD) |
1083 | lyrics.width = 0.366 |
1084 | |
1085 | === modified file 'entertainerlib/gui/tabs/playing_tab.py' |
1086 | --- entertainerlib/gui/tabs/playing_tab.py 2009-06-17 02:49:44 +0000 |
1087 | +++ entertainerlib/gui/tabs/playing_tab.py 2010-01-03 23:00:32 +0000 |
1088 | @@ -14,14 +14,14 @@ |
1089 | tab_title=_("Currently playing")): |
1090 | Tab.__init__(self, name, tab_title) |
1091 | |
1092 | - album = track.get_album() |
1093 | + album = track.album |
1094 | |
1095 | # Track name |
1096 | - if track.get_tracknumber() == 0: |
1097 | - track_label_text = str(track.get_title()) |
1098 | + if track.number == 0: |
1099 | + track_label_text = track.title |
1100 | else: |
1101 | track_label_text = _("From %(number)d. %(title)s") % \ |
1102 | - {'number':track.get_tracknumber(), 'title': track.get_title()} |
1103 | + {'number': track.number, 'title': track.title} |
1104 | |
1105 | self.track_label = Label(0.05, "text", 0.5, 0.33, track_label_text) |
1106 | self.track_label.set_ellipsize(pango.ELLIPSIZE_END) |
1107 | @@ -29,12 +29,11 @@ |
1108 | self.add(self.track_label) |
1109 | |
1110 | # Album name |
1111 | - if album.get_year() == 0: |
1112 | - album_label_text = _("From %(title)s") % \ |
1113 | - {'title': album.get_title()} |
1114 | + if album.year == 0: |
1115 | + album_label_text = _("From %(title)s") % {'title': album.title} |
1116 | else: |
1117 | album_label_text = _("From %(title)s, %(year)s") % \ |
1118 | - {'title': album.get_title(), 'year': album.get_year()} |
1119 | + {'title': album.title, 'year': album.year} |
1120 | |
1121 | self.album_label = Label(0.042, "subtitle", 0.5, 0.43, album_label_text) |
1122 | self.album_label.set_ellipsize(pango.ELLIPSIZE_END) |
1123 | @@ -42,7 +41,7 @@ |
1124 | self.add(self.album_label) |
1125 | |
1126 | # Artist name |
1127 | - artist_text = _("By %(artist)s") % {'artist': track.get_artist()} |
1128 | + artist_text = _("By %(artist)s") % {'artist': track.artist} |
1129 | self.artist_label = Label(0.042, "subtitle", 0.5, 0.53, artist_text) |
1130 | self.artist_label.set_ellipsize(pango.ELLIPSIZE_END) |
1131 | self.artist_label.width = 0.4 |
1132 | @@ -57,23 +56,21 @@ |
1133 | Called when currently playing changes tracks. The provided track |
1134 | is used to update all the necessary labels. |
1135 | ''' |
1136 | - track = track |
1137 | - album = track.get_album() |
1138 | + album = track.album |
1139 | |
1140 | - if track.get_tracknumber() == 0: |
1141 | - self.track_label.set_text(str(track.get_title())) |
1142 | + if track.number == 0: |
1143 | + self.track_label.set_text(track.title) |
1144 | else: |
1145 | - self.track_label.set_text(str(track.get_tracknumber()) + \ |
1146 | - ". " + track.get_title()) |
1147 | + self.track_label.set_text(str(track.number) + ". " + track.title) |
1148 | |
1149 | - if album.get_year() != 0: |
1150 | + if album.year != 0: |
1151 | self.album_label.set_text(_("From %(title)s, %(year)s") % \ |
1152 | - {'title': album.get_title(), 'year': album.get_year()}) |
1153 | + {'title': album.title, 'year': album.year}) |
1154 | else: |
1155 | self.album_label.set_text(_("From %(album)s") % \ |
1156 | - {'album': album.get_title()}) |
1157 | + {'album': album.title}) |
1158 | self.artist_label.set_text(_("By %(artist)s") % \ |
1159 | - {'artist': track.get_artist()}) |
1160 | + {'artist': track.artist}) |
1161 | |
1162 | def can_activate(self): |
1163 | '''No interaction is available on the PlayingTab.''' |
1164 | |
1165 | === modified file 'entertainerlib/gui/tabs/tracks_tab.py' |
1166 | --- entertainerlib/gui/tabs/tracks_tab.py 2010-01-03 23:00:31 +0000 |
1167 | +++ entertainerlib/gui/tabs/tracks_tab.py 2010-01-03 23:00:33 +0000 |
1168 | @@ -29,7 +29,7 @@ |
1169 | self.menu.cursor = None |
1170 | self.add(self.menu) |
1171 | |
1172 | - tracks_list = [[track.get_title(), None, track] for track in tracks] |
1173 | + tracks_list = [[track.title, None, track] for track in tracks] |
1174 | self.menu.async_add_artists(tracks_list) |
1175 | |
1176 | self.track_title = Label(0.045, "title", 0.22, 0.79, "") |
1177 | @@ -69,12 +69,10 @@ |
1178 | '''Update the track information labels''' |
1179 | if self.active: |
1180 | track = self.menu.selected_userdata |
1181 | - self.track_title.set_text(track.get_title()) |
1182 | - self.track_length.set_text(str(track.get_length() / 60) + ":" + \ |
1183 | - str(track.get_length() % 60).zfill(2)) |
1184 | - self.track_number.set_text(_("Track %(track)s from %(album)s") % \ |
1185 | - {'track': track.get_tracknumber(), |
1186 | - 'album': track.get_album().get_title()}) |
1187 | + self.track_title.set_text(track.title) |
1188 | + self.track_length.set_text(track.length_string) |
1189 | + self.track_number.set_text(_("Track %(track)d from %(album)s") % \ |
1190 | + {'track': track.number, 'album': track.album.title}) |
1191 | self.li.show() |
1192 | self.li.set_current(self.menu.selected_index + 1) |
1193 | else: |
1194 | |
1195 | === modified file 'entertainerlib/tests/mock.py' |
1196 | --- entertainerlib/tests/mock.py 2009-09-08 02:40:16 +0000 |
1197 | +++ entertainerlib/tests/mock.py 2010-01-03 23:00:33 +0000 |
1198 | @@ -23,17 +23,7 @@ |
1199 | if make_track: |
1200 | self.mock_track = MockTrack(make_album=False) |
1201 | |
1202 | - def get_number_of_tracks(self): |
1203 | - '''See `Album.get_number_of_tracks`.''' |
1204 | - return 1 |
1205 | - |
1206 | - def get_tracks(self): |
1207 | - '''See `Album.get_tracks`.''' |
1208 | - return [self.mock_track] |
1209 | - |
1210 | - def get_year(self): |
1211 | - '''See `Album.get_year`.''' |
1212 | - return '2009' |
1213 | + self.tracks = [self.mock_track] |
1214 | |
1215 | def has_album_art(self): |
1216 | '''See `Album.has_album_art`.''' |
1217 | @@ -284,10 +274,6 @@ |
1218 | if make_album: |
1219 | self.album = MockAlbum(make_track=False) |
1220 | |
1221 | - def get_album(self, cursor=False): |
1222 | - '''See `Track.get_album`.''' |
1223 | - return self.album |
1224 | - |
1225 | |
1226 | class MockVideoLibrary(VideoLibrary): |
1227 | '''Mock entertainerlib.client.medialibrary.videos.VideoLibrary''' |
1228 | |
1229 | === modified file 'entertainerlib/tests/test_music.py' |
1230 | --- entertainerlib/tests/test_music.py 2009-09-08 02:40:16 +0000 |
1231 | +++ entertainerlib/tests/test_music.py 2010-01-03 23:00:33 +0000 |
1232 | @@ -6,8 +6,10 @@ |
1233 | from pysqlite2 import dbapi2 as sqlite |
1234 | |
1235 | from entertainerlib.client.medialibrary.music import ( |
1236 | - Album, AlbumHasNoTracks, MusicLibrary, Track, CompactDisc, |
1237 | - TrackRatingOutOfRange, TrackTypeError) |
1238 | + Album, AlbumHasNoTracks, |
1239 | + CompactDisc, CompactDiscTrack, |
1240 | + MusicLibrary, |
1241 | + Track, TrackTypeError) |
1242 | from entertainerlib.client.medialibrary.playable import Playable |
1243 | from entertainerlib.tests import EntertainerTest |
1244 | |
1245 | @@ -16,7 +18,6 @@ |
1246 | classes that need to access the music cache""" |
1247 | |
1248 | def setUp(self): |
1249 | - """See unittest.TestCase""" |
1250 | EntertainerTest.setUp(self) |
1251 | |
1252 | self.debug = False |
1253 | @@ -85,161 +86,83 @@ |
1254 | |
1255 | def setUp(self): |
1256 | TestMusic.setUp(self) |
1257 | + self.music_library = MusicLibrary() |
1258 | self.track = Track('/path/to/track.mp3', # filename |
1259 | 'title', |
1260 | 1, # tracknumber |
1261 | 'artist0', |
1262 | 'album0', |
1263 | - 'genre', |
1264 | - '128', # bitrate |
1265 | 2008, # year |
1266 | - 5, # rating |
1267 | 240, # length |
1268 | - 'comment', |
1269 | - 'lyrics') |
1270 | - |
1271 | - def tearDown(self): |
1272 | - TestMusic.tearDown(self) |
1273 | - |
1274 | - def testTrackConstructor(self): |
1275 | - """testTrackConstructor - Ensures that a Track object is created""" |
1276 | + 'lyrics', |
1277 | + self.music_library._create_album) |
1278 | + |
1279 | + def test_constructor(self): |
1280 | + '''Test that a Track object is created.''' |
1281 | self.assertTrue(isinstance(self.track, Track)) |
1282 | + self.assertEqual(self.track.artist, 'artist0') |
1283 | + self.assertEqual(self.track.filename, '/path/to/track.mp3') |
1284 | + self.assertEqual(self.track.length, 240) |
1285 | + self.assertEqual(self.track.length_string, '4:00') |
1286 | + self.assertEqual(self.track.lyrics, 'lyrics') |
1287 | + self.assertEqual(self.track.number, 1) |
1288 | + self.assertEqual(self.track.title, 'title') |
1289 | + self.assertEqual(self.track.year, 2008) |
1290 | |
1291 | - def testTrackBadConstructor(self): |
1292 | - """testTrackBadConstructor - Ensures that bad track construction |
1293 | - raises an exception for the integer fields""" |
1294 | - for i in [2, 7, 8, 9]: |
1295 | - t = ['a', 'b', 1, 'c', 'd', 'e', 'f', 2, 3, 4, 'g', 'h'] |
1296 | + def test_bad_constructor(self): |
1297 | + '''Test that bad track construction raises an exception for the integer |
1298 | + fields.''' |
1299 | + for i in [2, 5, 6]: |
1300 | + t = ['', '', 1, '', '', 2, 3, ''] |
1301 | t[i] = str(t[i]) |
1302 | self.assertRaises(TrackTypeError, Track, t[0], t[1], t[2], t[3], |
1303 | - t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11]) |
1304 | - |
1305 | - def testTrackRatingInRange(self): |
1306 | - """testTrackRatingInRange - Ensures that the ratings in range create |
1307 | - valid Track objects""" |
1308 | - for i in range(1, 6): |
1309 | - self.track = Track('a', 'b', 1, 'c', 'd', 'e', 'f', 2, i, 3, 'g', |
1310 | - 'h') |
1311 | - self.assertTrue(isinstance(self.track, Track)) |
1312 | - self.assertEqual(self.track.get_rating(), i) |
1313 | - |
1314 | - def testTrackRatingOutOfRange(self): |
1315 | - """testTrackRatingOutOfRange - Ensures that the rating raises an |
1316 | - exception for something out of range in construction""" |
1317 | - for i in [0, 6]: |
1318 | - self.assertRaises(TrackRatingOutOfRange, Track, 'a', 'b', 1, 'c', |
1319 | - 'd', 'e', 'f', 2, i, 3, 'g', 'h') |
1320 | - |
1321 | - def testTrackGetFilename(self): |
1322 | - """testTrackGetFilename - Ensures that the filename is returned""" |
1323 | - result = self.track.get_filename() |
1324 | - self.assertEqual(result, '/path/to/track.mp3') |
1325 | - |
1326 | - def testTrackGetTitle(self): |
1327 | - """testTrackGetTitle - Ensures that the title is returned""" |
1328 | - result = self.track.get_title() |
1329 | - self.assertEqual(result, 'title') |
1330 | - |
1331 | - def testTrackGetTrackNumber(self): |
1332 | - """testTrackGetTrackNumber - Ensures that the tracknumber is |
1333 | - returned""" |
1334 | - result = self.track.get_tracknumber() |
1335 | - self.assertEqual(result, 1) |
1336 | - |
1337 | - def testTrackGetArtist(self): |
1338 | - """testTrackGetArtist - Ensures that the artist is returned""" |
1339 | - result = self.track.get_artist() |
1340 | - self.assertEqual(result, 'artist0') |
1341 | - |
1342 | - def testTrackGetAlbum(self): |
1343 | - """testTrackGetAlbum - Ensures that an album object is returned""" |
1344 | - result = self.track.get_album(self.cursor) |
1345 | + t[4], t[5], t[6], t[7], None) |
1346 | + |
1347 | + def test_album_property(self): |
1348 | + '''Test that an album object is returned.''' |
1349 | + result = self.track.album |
1350 | self.assertTrue(isinstance(result, Album)) |
1351 | - self.assertEqual(result.get_title(), 'album0') |
1352 | - |
1353 | - def testTrackGetAlbumNot(self): |
1354 | - """testTrackGetAlbumNot - Ensures that a bad album in the track |
1355 | - returns AlbumHasNoTracks""" |
1356 | - self.badTrack = Track('path', 'title', 1, 'artist', |
1357 | - 'foo-bar-baz**', # Here is the bad input |
1358 | - 'genre', '128', 2008, 5, 240, 'comment', |
1359 | - 'lyrics') |
1360 | - self.assertRaises(AlbumHasNoTracks, self.badTrack.get_album, |
1361 | - self.cursor) |
1362 | - |
1363 | - def testTrackGetAlbumArtUrlExists(self): |
1364 | - """testTrackGetAlbumArtUrl - Ensures that the album art url is |
1365 | - returned""" |
1366 | + self.assertEqual(result.title, 'album0') |
1367 | + |
1368 | + def test_bad_album(self): |
1369 | + '''Test that a bad album in the track returns AlbumHasNoTracks.''' |
1370 | + bad_track = Track('', '', 1, '', 'foo-bar-baz**', 2, 3, '', |
1371 | + self.music_library._create_album) |
1372 | + try: |
1373 | + album = bad_track.album |
1374 | + self.fail() |
1375 | + except AlbumHasNoTracks: |
1376 | + pass |
1377 | + |
1378 | + def test_get_album_art_url(self): |
1379 | + '''Test that the album art url is returned.''' |
1380 | album_artist = "artist0 - album0" |
1381 | album_artist = album_artist.encode("base64") |
1382 | album_art = os.path.join(self.art_path, album_artist + ".jpg") |
1383 | open(album_art, "wb").close() |
1384 | - result = self.track.get_album_art_url(self.cursor) |
1385 | + result = self.track.get_album_art_url() |
1386 | self.assertEqual(result, album_art) |
1387 | if os.path.exists(album_art): |
1388 | os.remove(album_art) |
1389 | |
1390 | - def testTrackGetAlbumArtUrlNotExists(self): |
1391 | - """testTrackGetAlbumArtUrlNotExists - Ensures that when art does |
1392 | - not exist, None is returned""" |
1393 | - result = self.track.get_album_art_url(self.cursor) |
1394 | + result = self.track.get_album_art_url() |
1395 | self.assertEqual(result, None) |
1396 | |
1397 | - def testTrackGetGenre(self): |
1398 | - """testTrackGetGenre - Ensures that the genre is returned""" |
1399 | - result = self.track.get_genre() |
1400 | - self.assertEqual(result, 'genre') |
1401 | - |
1402 | - def testTrackGetBitrate(self): |
1403 | - """testTrackGetBitrate - Ensures that the bitrate is returned""" |
1404 | - result = self.track.get_bitrate() |
1405 | - self.assertEqual(result, '128') |
1406 | - |
1407 | - def testTrackGetYear(self): |
1408 | - """testTrackGetYear - Ensures that the year is returned""" |
1409 | - result = self.track.get_year() |
1410 | - self.assertEqual(result, 2008) |
1411 | - |
1412 | - def testTrackGetRating(self): |
1413 | - """testTrackGetRating - Ensures that the rating is returned""" |
1414 | - result = self.track.get_rating() |
1415 | - self.assertEqual(result, 5) |
1416 | - |
1417 | - def testTrackGetLength(self): |
1418 | - """testTrackGetLength - Ensures that the length is returned""" |
1419 | - result = self.track.get_length() |
1420 | - self.assertEqual(result, 240) |
1421 | - |
1422 | - def testTrackGetComment(self): |
1423 | - """testTrackGetComment - Ensures that the comment is returned""" |
1424 | - result = self.track.get_comment() |
1425 | - self.assertEqual(result, 'comment') |
1426 | - |
1427 | - def testTrackGetLyrics(self): |
1428 | - """testTrackGetLyrics - Ensures that the lyrics are returned""" |
1429 | - result = self.track.get_lyrics() |
1430 | - self.assertEqual(result, 'lyrics') |
1431 | - |
1432 | - def testTrackSetLyrics(self): |
1433 | - """testTrackSetLyrics - Ensures that lyrics are properly set""" |
1434 | - self.track.set_lyrics('some new lyrics') |
1435 | - self.assertEqual(self.track.get_lyrics(), 'some new lyrics') |
1436 | - |
1437 | - def testTrackSetNoneLyrics(self): |
1438 | - """testTrackSetNoneLyrics - Ensures that lyrics are set to empty |
1439 | - string when None is passed as lyrics input""" |
1440 | - self.track.set_lyrics(None) |
1441 | - self.assertEqual(self.track.get_lyrics(), '') |
1442 | - |
1443 | - def testTrackGetType(self): |
1444 | - """testTrackGetType - Ensures that the type is returned""" |
1445 | - result = self.track.get_type() |
1446 | - self.assertEqual(result, Playable.AUDIO_STREAM) |
1447 | - |
1448 | - def testTrackGetUri(self): |
1449 | - """testTrackGetUri - Ensures that the uri is returned""" |
1450 | - result = self.track.get_uri() |
1451 | - self.assertEqual(result, 'file:///path/to/track.mp3') |
1452 | + def test_lyrics_property(self): |
1453 | + '''Test the lyrics property.''' |
1454 | + self.track.lyrics = 'some new lyrics' |
1455 | + self.assertEqual(self.track.lyrics, 'some new lyrics') |
1456 | + |
1457 | + self.track.lyrics = None |
1458 | + self.assertEqual(self.track.lyrics, '') |
1459 | + |
1460 | + def test_get_type(self): |
1461 | + '''Test that the type is returned.''' |
1462 | + self.assertEqual(self.track.get_type(), Playable.AUDIO_STREAM) |
1463 | + |
1464 | + def test_get_uri(self): |
1465 | + '''Test that the uri is returned.''' |
1466 | + self.assertEqual(self.track.get_uri(), 'file:///path/to/track.mp3') |
1467 | |
1468 | |
1469 | class TestMusicLibrary(TestMusic): |
1470 | @@ -249,9 +172,8 @@ |
1471 | TestMusic.setUp(self) |
1472 | self.musiclibrary = MusicLibrary() |
1473 | |
1474 | - def testMusicLibraryConstructor(self): |
1475 | - """testMusicLibraryContructor - Ensures instantiation of MusicLibrary |
1476 | - class""" |
1477 | + def test_music_library_constructor(self): |
1478 | + '''Test that the music library contructor works.''' |
1479 | self.assertTrue(isinstance(self.musiclibrary, MusicLibrary)) |
1480 | |
1481 | def testGetAllArtists(self): |
1482 | @@ -260,34 +182,13 @@ |
1483 | result = self.musiclibrary.get_all_artists() |
1484 | self.assertEqual(result, ['artist0']) |
1485 | |
1486 | - def testGetAllTracks(self): |
1487 | - """testGetAllTracks - Ensures that all tracks are returned""" |
1488 | - result = self.musiclibrary.get_all_tracks() |
1489 | - for i in result: |
1490 | - self.assertTrue(isinstance(i, Track)) |
1491 | - self.assertEqual(len(result), 8) |
1492 | - |
1493 | - def testGetTracksByGenre(self): |
1494 | - """testGetTracksByGenre - Ensures tracks of a certain genre are |
1495 | - returned""" |
1496 | - result = self.musiclibrary.get_tracks_by_genre('genre0') |
1497 | - self.assertEqual(len(result), 4) |
1498 | - for i in result: |
1499 | - self.assertEqual(i.get_genre(), 'genre0') |
1500 | - |
1501 | - def testGetTracksByMissingGenre(self): |
1502 | - """testGetTracksByMissingGenre - Ensures proper handling of a missing |
1503 | - genre""" |
1504 | - self.assertEquals( |
1505 | - len(self.musiclibrary.get_tracks_by_genre('foo-bar-baz**')), 0) |
1506 | - |
1507 | def testGetTracksByArtist(self): |
1508 | """testGetTracksByArtist - Ensure tracks by a certain artist are |
1509 | returned""" |
1510 | result = self.musiclibrary.get_tracks_by_artist('artist0') |
1511 | self.assertEqual(len(result), 8) |
1512 | for i in result: |
1513 | - self.assertEqual(i.get_artist(), 'artist0') |
1514 | + self.assertEqual(i.artist, 'artist0') |
1515 | |
1516 | def testGetTracksByUnknownArtist(self): |
1517 | """testGetTracksByUnknownArtist - Ensure proper handling of an missing |
1518 | @@ -308,7 +209,7 @@ |
1519 | result = self.musiclibrary.get_albums_by_artist('artist0') |
1520 | self.assertEqual(len(result), 2) |
1521 | for i in result: |
1522 | - self.assertEqual(i.get_artist(), 'artist0') |
1523 | + self.assertEqual(i.artist, 'artist0') |
1524 | |
1525 | def testGetAlbumsByUnknownArtist(self): |
1526 | """testGetAlbumsByUnknownArtist - Ensures proper handling of an |
1527 | @@ -350,42 +251,32 @@ |
1528 | database""" |
1529 | # Only need a filename that matches something in the database, the rest |
1530 | # of the track is for construction purposes only |
1531 | - self.track = Track('/filename/000', '', 0, '', '', '', '', 0, 1, 0, '', |
1532 | - '') |
1533 | - self.musiclibrary.save_lyrics(self.track, 'some lyrics here') |
1534 | - self.assertEqual(self.track.get_lyrics(), 'some lyrics here') |
1535 | + track = Track('/filename/000', '', 0, '', '', 0, 1, '', None) |
1536 | + self.musiclibrary.save_lyrics(track, 'some lyrics here') |
1537 | + self.assertEqual(track.lyrics, 'some lyrics here') |
1538 | |
1539 | |
1540 | class TestAlbum(TestMusic): |
1541 | '''Tests Album''' |
1542 | |
1543 | def setUp(self): |
1544 | - """See unittest.TestCase""" |
1545 | TestMusic.setUp(self) |
1546 | - self.album = Album('album1', self.cursor) |
1547 | - |
1548 | - def tearDown(self): |
1549 | - """Clean up after the test""" |
1550 | - TestMusic.tearDown(self) |
1551 | + self.music_library = MusicLibrary() |
1552 | + self.album = self.music_library._create_album('album1') |
1553 | |
1554 | def testAlbumConstructor(self): |
1555 | """Test that an Album object is properly constructed""" |
1556 | self.assertTrue(isinstance(self.album, Album)) |
1557 | + self.assertEqual(self.album.artist, 'artist0') |
1558 | + self.assertEqual(self.album.length, 8) |
1559 | + self.assertEqual(self.album.title, 'album1') |
1560 | + self.assertEqual(self.album.year, 0) |
1561 | |
1562 | def testAlbumConstructorNot(self): |
1563 | """Test that an AlbumHasNoTracks exception is raised when the created |
1564 | album doesn't exist in the cache""" |
1565 | - self.assertRaises(AlbumHasNoTracks, Album, 'foo', self.cursor) |
1566 | - |
1567 | - def testAlbumStr(self): |
1568 | - """Test that title is returned in string conversion""" |
1569 | - result = str(self.album) |
1570 | - self.assertEqual(result, 'album1') |
1571 | - |
1572 | - def testAlbumGetTitle(self): |
1573 | - """Test that the album title is returned""" |
1574 | - result = self.album.get_title() |
1575 | - self.assertEqual(result, 'album1') |
1576 | + self.assertRaises(AlbumHasNoTracks, self.music_library._create_album, |
1577 | + 'foo') |
1578 | |
1579 | def testAlbumHasAlbumArt(self): |
1580 | """Test that album art exists for the file""" |
1581 | @@ -399,12 +290,12 @@ |
1582 | |
1583 | def testAlbumHasAlbumArtNot(self): |
1584 | """Test that missing album art is reported back""" |
1585 | - otherAlbum = Album('album1', self.cursor) |
1586 | - self.assertFalse(otherAlbum.has_album_art()) |
1587 | + other_album = self.music_library._create_album('album1') |
1588 | + self.assertFalse(other_album.has_album_art()) |
1589 | |
1590 | def testAlbumGetAlbumArtUrl(self): |
1591 | """Test that the path to the album's art is returned""" |
1592 | - result = self.album.get_album_art_url() |
1593 | + result = self.album.album_art_url |
1594 | album_artist = "artist0 - album1" |
1595 | album_artist = album_artist.encode("base64") |
1596 | album_art = os.path.join(self.art_path, album_artist + ".jpg") |
1597 | @@ -412,60 +303,30 @@ |
1598 | |
1599 | def testAlbumGetTracks(self): |
1600 | """Test that all tracks for an album are returned""" |
1601 | - result = self.album.get_tracks() |
1602 | + result = self.album.tracks |
1603 | self.assertEqual(len(result), 4) |
1604 | for i in result: |
1605 | self.assertTrue(isinstance(i, Track)) |
1606 | |
1607 | - def testAlbumGetNumberOfTracks(self): |
1608 | - """Test correct number of tracks from album is returned""" |
1609 | - self.assertEqual(self.album.get_number_of_tracks(), 4) |
1610 | - |
1611 | - def testAlbumGetYear(self): |
1612 | - """Test that year of album is returned""" |
1613 | - self.assertEqual(self.album.get_year(), 0) |
1614 | - |
1615 | - def testAlbumGetGenre(self): |
1616 | - """Test that genre of album is returned""" |
1617 | - self.assertEqual(self.album.get_genre(), 'genre0') |
1618 | - |
1619 | - def testAlbumGetArtist(self): |
1620 | - """Test that artist of album is returned""" |
1621 | - self.assertEqual(self.album.get_artist(), 'artist0') |
1622 | - |
1623 | - def testAlbumGetTotalLength(self): |
1624 | - """Test that total length of album is returned""" |
1625 | - self.assertEqual(self.album.get_total_length(), 8) |
1626 | - |
1627 | |
1628 | class TestCompactDisc(TestMusic): |
1629 | '''Tests CompactDisc''' |
1630 | |
1631 | def setUp(self): |
1632 | - """See unittest.TestCase""" |
1633 | TestMusic.setUp(self) |
1634 | self.cd = CompactDisc([2299253003L, 11, 150, 25433, 46436, 68737, 89292, |
1635 | 108536, 130667, 144099, 160174, 181568, 203695, 3027]) |
1636 | |
1637 | - def tearDown(self): |
1638 | - """Clean up after the test""" |
1639 | - TestMusic.tearDown(self) |
1640 | - |
1641 | - def testCompactDiscConstructor(self): |
1642 | - """Test that a CompactDisc object is properly constructed""" |
1643 | + def test_constructor(self): |
1644 | + '''Test that a CompactDisc object is properly constructed.''' |
1645 | self.assertTrue(isinstance(self.cd, CompactDisc)) |
1646 | - |
1647 | - def testCompactDiscGetTitle(self): |
1648 | - """Test that album title is returned from CDDB""" |
1649 | - self.assertEqual(self.cd.get_title(), 'The Joshua Tree') |
1650 | - |
1651 | - def testCompactDiscGetArtist(self): |
1652 | - """Test that artist is returned from CDDB""" |
1653 | - self.assertEqual(self.cd.get_artist(), 'U2') |
1654 | - |
1655 | - def testCompactDiscGetTracks(self): |
1656 | - """Test that tracks names are returned from CDDB""" |
1657 | - tracks = [track.get_title() for track in self.cd.get_tracks()] |
1658 | + self.assertEqual(self.cd.artist, 'U2') |
1659 | + self.assertEqual(self.cd.length, 3027) |
1660 | + self.assertEqual(self.cd.title, 'The Joshua Tree') |
1661 | + |
1662 | + def test_tracks(self): |
1663 | + '''Test that track names are returned from CDDB.''' |
1664 | + tracks = [track.title for track in self.cd.tracks] |
1665 | |
1666 | self.assertEqual(tracks, ['Where the Streets Have No Name', |
1667 | "I Still haven't Found What I'm Looking For", 'With or Without You', |
1668 | @@ -474,7 +335,24 @@ |
1669 | 'Trip Through Your Wires', 'One Tree Hill', 'Exit', |
1670 | 'Mothers of the Disappeared']) |
1671 | |
1672 | - def testCompactDiscGetLength(self): |
1673 | - """Test that the sum of the track lengths is returned""" |
1674 | - self.assertEqual(self.cd.get_length(), 3027) |
1675 | +class TestCompactDiscTrack(TestMusic): |
1676 | + '''Tests CompactDiscTrack''' |
1677 | + |
1678 | + def setUp(self): |
1679 | + TestMusic.setUp(self) |
1680 | + self.track = CompactDiscTrack(1, 'test', 120) |
1681 | + |
1682 | + def test_constructor(self): |
1683 | + '''Test that a CompactDiscTrack object is properly constructed.''' |
1684 | + self.assertTrue(isinstance(self.track, CompactDiscTrack)) |
1685 | + self.assertEqual(self.track.length, 120) |
1686 | + self.assertEqual(self.track.title, 'test') |
1687 | + |
1688 | + def test_get_uri(self): |
1689 | + '''Test that the URI is in the proper CD format.''' |
1690 | + self.assertEqual(self.track.uri, 'cdda://1') |
1691 | + |
1692 | + def test_length_string_property(self): |
1693 | + '''Test the length_string property.''' |
1694 | + self.assertEqual(self.track.length_string, '2:00') |
1695 |
This is a chunk of work to eliminate some of the Java-ness of the MusicLibrary classes. It cleans up a lot of getters and setters and makes the code look much cleaner.
Here is the diffstat for the curious:
client/client.py | 2 medialibrary/ music.py | 678 +++++++ +------ ------- ------- ------- ----- medialibrary/ playable. py | 31 - album.py | 23 - artist. py | 2 audio_play. py | 4 disc.py | 10 music.py | 2 albums_ tab.py | 8 lyrics_ tab.py | 2 playing_ tab.py | 35 -- tracks_ tab.py | 12 test_music. py | 346 ++++++- ------- ------
client/
client/
gui/screens/
gui/screens/
gui/screens/
gui/screens/
gui/screens/
gui/tabs/
gui/tabs/
gui/tabs/
gui/tabs/
tests/mock.py | 18 -
tests/
14 files changed, 315 insertions(+), 858 deletions(-)