Merge lp:~mblayman/entertainer/videolibz into lp:entertainer

Proposed by Matt Layman
Status: Merged
Approved by: Matt Layman
Approved revision: 478
Merged at revision: not available
Proposed branch: lp:~mblayman/entertainer/videolibz
Merge into: lp:entertainer
Diff against target: 1557 lines (+290/-836)
12 files modified
entertainerlib/client/media_player.py (+4/-11)
entertainerlib/client/medialibrary/videos.py (+216/-704)
entertainerlib/gui/screens/factory.py (+1/-0)
entertainerlib/gui/screens/movie.py (+12/-13)
entertainerlib/gui/screens/tv_episodes.py (+13/-19)
entertainerlib/gui/screens/tv_series.py (+9/-8)
entertainerlib/gui/tabs/movies_tab.py (+6/-6)
entertainerlib/gui/tabs/series_tab.py (+3/-4)
entertainerlib/gui/tabs/video_clips_tab.py (+2/-2)
entertainerlib/tests/mock.py (+21/-66)
entertainerlib/tests/test_mediaplayer.py (+1/-2)
entertainerlib/tests/test_screenfactory.py (+2/-1)
To merge this branch: bzr merge lp:~mblayman/entertainer/videolibz
Reviewer Review Type Date Requested Status
Matt Layman Approve
Review via email: mp+22770@code.launchpad.net

Commit message

Video classes are now more Pythonic and do not talk directly to the database anymore.

Description of the change

I did the same clean up to the video library as I did early to the music library. Now all the video classes are just plain Python objects. Any method that talks to the database has been pushed into some factory methods in the VideoLibrary. This leaves only the VideoLibrary to work with when we move away from directly using the database directly (first to Storm, then to Twisted probably).

To post a comment you must log in.
Revision history for this message
Matt Layman (mblayman) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'entertainerlib/client/media_player.py'
2--- entertainerlib/client/media_player.py 2009-12-21 22:21:55 +0000
3+++ entertainerlib/client/media_player.py 2010-04-03 23:02:16 +0000
4@@ -15,17 +15,10 @@
5 from entertainerlib.logger import Logger
6
7 class MediaPlayer(gobject.GObject, object):
8- '''
9- MediaPlayer class for Entertainer
10-
11- MediaPlayer uses Gstreamer backend and is able to play all video and audio
12- files that gstreamer supports. Entertainer has only one MediaPlayer object
13- at runtime.
14-
15- MediaPlayer can play objects that implement Playable interface. These
16- classes are Track, Movie, TVEpisode, Movie, VideoClip and CompactDiscTrack.
17- (and Channel in the future)
18- '''
19+ '''MediaPlayer uses Gstreamer to play all video and audio files. Entertainer
20+ has only one MediaPlayer object at runtime. MediaPlayer can play objects
21+ that implement Playable interface.'''
22+
23 __gsignals__ = {
24 'play' : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ),
25 'pause' : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ),
26
27=== modified file 'entertainerlib/client/medialibrary/videos.py'
28--- entertainerlib/client/medialibrary/videos.py 2010-04-03 14:33:37 +0000
29+++ entertainerlib/client/medialibrary/videos.py 2010-04-03 23:02:16 +0000
30@@ -2,15 +2,14 @@
31 '''Video Library - Interface for Entertainer video library cache'''
32
33 import os
34+
35 from pysqlite2 import dbapi2 as sqlite
36
37 from entertainerlib.client.medialibrary.playable import Playable
38 from entertainerlib.configuration import Configuration
39-from entertainerlib.logger import Logger
40-
41-
42-class VideoLibrary:
43- """Interface for Entertainer's video cache."""
44+
45+class VideoLibrary(object):
46+ '''Interface for Entertainer's video cache.'''
47
48 def __init__(self):
49 self.config = Configuration()
50@@ -18,778 +17,291 @@
51 if not os.path.exists(self.config.VIDEO_DB):
52 raise Exception("Video database doesn't exist!")
53
54+ self.connection = sqlite.connect(self.config.VIDEO_DB)
55+ self.cursor = self.connection.cursor()
56+
57+ def __del__(self):
58+ '''Close the db connection when this object is deleted.'''
59+ self.connection.close()
60+
61 def get_movies(self):
62- """
63- Get all movies
64- @return: List of Movie objects
65- """
66- connection = sqlite.connect(self.config.VIDEO_DB)
67- cursor = connection.cursor()
68- cursor.execute("""SELECT videofile.filename
69+ '''Get all the movies.'''
70+ self.cursor.execute("""SELECT videofile.filename
71 FROM videofile, metadata
72 WHERE type='MOVIE'
73 AND videofile.filename=metadata.filename
74 ORDER BY title""")
75 movies = []
76- for row in cursor:
77- movies.append(Movie(row[0]))
78- connection.close()
79+ for row in self.cursor.fetchall():
80+ movies.append(self._create_movie(row[0]))
81 return movies
82
83+ def _create_movie(self, filename):
84+ '''Factory method to create a movie.'''
85+ self.cursor.execute(
86+ """SELECT metadata.filename, hash, length, resolution,
87+ title, runtime, genres, rating, year,
88+ plot_outline, plot, actor_1, actor_2,
89+ actor_3, actor_4, actor_5, writer_1,
90+ writer_2, director_1, director_2
91+ FROM videofile, metadata
92+ WHERE metadata.filename=:fn
93+ AND videofile.filename=metadata.filename
94+ ORDER BY title""", { "fn" : filename })
95+ result = self.cursor.fetchall()
96+ db_movie = result[0]
97+
98+ movie = Movie()
99+ movie.filename = db_movie[0]
100+ movie.art_hash = db_movie[1]
101+ movie.title = db_movie[4]
102+ movie.runtime = db_movie[5]
103+ movie.genres = db_movie[6].split(',')
104+ movie.plot = db_movie[10]
105+ movie.rating = db_movie[7]
106+ movie.short_plot = db_movie[9]
107+ movie.year = db_movie[8]
108+
109+ for i in range(11, 16):
110+ if len(db_movie[i]) > 0:
111+ movie.actors.append(db_movie[i])
112+
113+ for i in [16, 17]:
114+ if len(db_movie[i]) > 0:
115+ movie.writers.append(db_movie[i])
116+
117+ for i in [18, 19]:
118+ if len(db_movie[i]) > 0:
119+ movie.directors.append(db_movie[i])
120+
121+ return movie
122+
123 def get_tv_series(self):
124- """
125- Get all TV-series.
126- @return: List of TV-series titles (strings)
127- """
128- connection = sqlite.connect(self.config.VIDEO_DB)
129- cursor = connection.cursor()
130- cursor.execute("""SELECT DISTINCT series_title
131+ '''Get all the TV series.'''
132+ self.cursor.execute("""SELECT DISTINCT series_title
133 FROM metadata
134 WHERE type='TV-SERIES'
135 ORDER BY title""")
136 series = []
137- for row in cursor:
138- series.append(TVSeries(row[0]))
139- connection.close()
140+ for row in self.cursor.fetchall():
141+ series.append(self._create_tv_series(row[0]))
142 return series
143
144+ def _create_tv_series(self, title):
145+ '''Factory method to create a TV series.'''
146+ tv_series = TVSeries(title)
147+
148+ self.cursor.execute(
149+ "SELECT DISTINCT season FROM metadata WHERE series_title=:title",
150+ { "title" : title })
151+ for row in self.cursor.fetchall():
152+ tv_series.seasons.append(row[0])
153+
154+ self.cursor.execute(
155+ "SELECT COUNT(filename) FROM metadata WHERE series_title=:title",
156+ { "title" : title })
157+ result = self.cursor.fetchall()
158+ tv_series.number_of_episodes = result[0][0]
159+
160+ return tv_series
161+
162 def get_video_clips(self):
163- """
164- Get List of videos that or not movies or tv-series episodes.
165- @return: List of VideoClip objects
166- """
167- connection = sqlite.connect(self.config.VIDEO_DB)
168- cursor = connection.cursor()
169- cursor.execute("""SELECT filename
170+ '''Get all the video clips.'''
171+ self.cursor.execute("""SELECT filename
172 FROM metadata
173 WHERE type='CLIP'
174 ORDER BY title""")
175 clips = []
176- for row in cursor:
177- clips.append(VideoClip(row[0]))
178- connection.close()
179+ for row in self.cursor.fetchall():
180+ clips.append(self._create_video_clip(row[0]))
181 return clips
182
183+ def _create_video_clip(self, filename):
184+ '''Factory method to create a video clip.'''
185+ self.cursor.execute(
186+ """SELECT videofile.filename, hash, title
187+ FROM videofile, metadata
188+ WHERE videofile.filename=:fn
189+ AND videofile.filename=metadata.filename
190+ ORDER BY title""", { "fn" : filename })
191+ result = self.cursor.fetchall()
192+
193+ video_item = VideoItem()
194+ video_item.filename = result[0][0]
195+ video_item.art_hash = result[0][1]
196+ video_item.title = result[0][2]
197+ return video_item
198+
199 def get_number_of_movies(self):
200- """
201- Get number of movies in the video library
202- @return: Integer
203- """
204- connection = sqlite.connect(self.config.VIDEO_DB)
205- cursor = connection.cursor()
206- cursor.execute("""SELECT COUNT(filename)
207- FROM metadata
208- WHERE type='MOVIE'""")
209- result = cursor.fetchall()
210- connection.close()
211+ '''Get the number of movies.'''
212+ self.cursor.execute(
213+ """SELECT COUNT(filename) FROM metadata WHERE type='MOVIE'""")
214+ result = self.cursor.fetchall()
215 return result[0][0]
216
217 def get_number_of_tv_series(self):
218- """
219- Get number of TV-series in the video library
220- @return: Integer
221- """
222- connection = sqlite.connect(self.config.VIDEO_DB)
223- cursor = connection.cursor()
224- cursor.execute("""SELECT DISTINCT COUNT(series_title)
225+ '''Get the number of TV series.'''
226+ self.cursor.execute("""SELECT DISTINCT COUNT(series_title)
227 FROM metadata
228 WHERE type='TV-SERIES'""")
229- result = cursor.fetchall()
230- connection.close()
231+ result = self.cursor.fetchall()
232 return result[0][0]
233
234 def get_number_of_video_clips(self):
235- """
236- Get number of misc. VideoClips in the video library
237- @return: Integer
238- """
239- connection = sqlite.connect(self.config.VIDEO_DB)
240- cursor = connection.cursor()
241- cursor.execute("""SELECT COUNT(filename)
242+ '''Get the number of video clips.'''
243+ self.cursor.execute(
244+ """SELECT COUNT(filename) FROM metadata WHERE type='CLIP'""")
245+ result = self.cursor.fetchall()
246+ return result[0][0]
247+
248+ def get_episodes_from_season(self, series_title, season_number):
249+ '''Get TV episodes from the series' season.'''
250+ self.cursor.execute("""SELECT filename
251 FROM metadata
252- WHERE type='CLIP'""")
253- result = cursor.fetchall()
254- connection.close()
255- return result[0][0]
256+ WHERE series_title=:title
257+ AND season=:season
258+ ORDER BY episode""",
259+ { "title" : series_title, "season" : season_number })
260+ episodes = []
261+ for row in self.cursor.fetchall():
262+ episodes.append(self._create_tv_episode(row[0]))
263+ return episodes
264+
265+ def _create_tv_episode(self, filename):
266+ '''Factory method to create a TV episode.'''
267+ self.cursor.execute(
268+ """SELECT videofile.filename, hash, title, plot, episode
269+ FROM videofile, metadata
270+ WHERE videofile.filename=:fn
271+ AND videofile.filename=metadata.filename
272+ ORDER BY title""", { "fn" : filename })
273+ result = self.cursor.fetchall()
274+ db_episode = result[0]
275+
276+ tv_episode = TVEpisode()
277+ tv_episode.filename = db_episode[0]
278+ tv_episode.art_hash = db_episode[1]
279+ tv_episode.title = db_episode[2]
280+ tv_episode.plot = db_episode[3]
281+ tv_episode.number = db_episode[4]
282+
283+ return tv_episode
284
285
286 class VideoItem(Playable):
287- """
288- Objects from this class represents video items
289- """
290+ '''Representation of a playable video item.'''
291
292 def __init__(self):
293- """Initialize the VideoItem object"""
294+ # XXX: laymansterms - VideoItem should really have a few mandatory
295+ # parameters. title, filename, maybe more.
296 Playable.__init__(self)
297 self.config = Configuration()
298
299- #Setting default values
300- self.logger = Logger().getLogger(
301- 'client.medialibrary.videos.VideoItem')
302- self.__title = ""
303- self.__filename = ""
304- self.__length = 0
305- self.__resolution = ""
306- self.__art_hash = ""
307-
308- def get_cover_art_url(self):
309- """
310- Get absolute filename of the cover art image file.
311- @return: String
312- """
313- return os.path.join(self.config.MOVIE_ART_DIR,
314- self.get_title() + ".jpg")
315-
316- def get_filename(self):
317- """
318- Get filename (abs path) of the VideoItem
319- @return: String
320- """
321- return self.__filename
322-
323- def set_filename(self, filename):
324- """
325- Sets the filename of the VideoItem
326- @param filename String
327- """
328- self.__filename = filename
329-
330- def get_title(self):
331- """
332- Get title of the VideoItem
333- @return: String
334- """
335- if (self.__title == "") or (self.__title == None):
336- return self.get_filename()
337- else:
338- return self.__title
339-
340- def set_title(self, title):
341- """
342- Sets the title of the VideoItem
343- @param title String
344- """
345- self.__title = title
346-
347- def get_length(self):
348- """
349- Get length of the VideoItem
350- @return: Integer
351- """
352- return self.__length
353-
354- def set_length(self, length):
355- """
356- Sets the length of the VideoItem
357- @param length Integer
358- """
359- self.__length = length
360-
361- def get_resolution(self):
362- """
363- Get resolution of the VideoItem
364- @return: String
365- """
366- return self.__resolution
367-
368- def set_resolution(self, res):
369- """
370- Sets the resolution of the VideoItem
371- @param res String
372- """
373- self.__resolution = res
374-
375- def get_thumbnail_url(self):
376- """
377- Get absolute path of the thumbnail image file.
378- @return: String
379- """
380- if self.get_art_hash() is not None:
381- thumb = os.path.join(self.config.VIDEO_THUMB_DIR,
382- self.get_art_hash() + ".jpg")
383- if os.path.exists(thumb):
384- return thumb
385- else:
386- self.logger.error("Thumbnail does not exist for " + \
387- self.get_filename() + ", using default art instead")
388- return os.path.join(self.config.theme_path,
389- "images/default_movie_art.png")
390- else:
391- self.logger.error("Thumbnail does not exist for " + \
392- self.get_filename() + ", using default art instead")
393- return os.path.join(self.config.theme_path,
394- "images/default_movie_art.png")
395+ self._title = ""
396+ self.filename = ""
397+ self.art_hash = ""
398+
399+ def _get_title(self):
400+ '''Get the title.'''
401+ if (self._title == "") or (self._title == None):
402+ return self.filename
403+ else:
404+ return self._title
405+
406+ def _set_title(self, title):
407+ '''Set the title.'''
408+ self._title = title
409+
410+ title = property(_get_title, _set_title)
411
412 def has_thumbnail(self):
413- """
414- Is there a thumbnail for this VideoItem
415- @return Boolean
416- """
417+ '''Test if there is a thumbnail.'''
418 thumb_path = os.path.join(self.config.VIDEO_THUMB_DIR,
419- self.get_art_hash() + ".jpg")
420+ self.art_hash + ".jpg")
421 return os.path.exists(thumb_path)
422
423- def get_art_hash(self):
424- """
425- Gets the art hash
426- @return String
427- """
428- return self.__art_hash
429-
430- def set_art_hash(self, arthash):
431- """
432- Sets the art hash
433- @param arthash String
434- """
435- self.__art_hash = arthash
436-
437- def has_cover_art(self):
438- """
439- Is there cover art file for this VideoItem
440- @return: Boolean
441- """
442- art_path = os.path.join(self.config.MOVIE_ART_DIR,
443- self.get_title() + ".jpg")
444- return os.path.exists(art_path)
445+ @property
446+ def thumbnail_url(self):
447+ '''Get the path to the thumbnail or a default.'''
448+ thumb = os.path.join(self.config.VIDEO_THUMB_DIR,
449+ self.art_hash + ".jpg")
450+ if os.path.exists(thumb):
451+ return thumb
452+ else:
453+ return os.path.join(self.config.theme_path,
454+ "images/default_movie_art.png")
455
456 # Implement playable interface
457+ def get_title(self):
458+ '''Get the title.'''
459+ return self.title
460+
461 def get_type(self):
462- """
463- Track is an video stream.
464- @return: Integer
465- """
466+ '''Get the type.'''
467 return Playable.VIDEO_STREAM
468
469 def get_uri(self):
470- """
471- Get URI of the video file
472- @return: String
473- """
474- return "file://" + self.get_filename()
475+ '''Get the URI.'''
476+ return "file://" + self.filename
477
478
479 class VideoFilm(VideoItem):
480- '''Objects from this class represents video films'''
481+ '''Generic representation of a film.'''
482+
483 def __init__(self):
484 VideoItem.__init__(self)
485- #initialise values
486- self.__plot_outline = ""
487- self.__plot = ""
488- self.__actors = []
489- self.__writers = []
490- self.__directors = []
491- self.__runtime = ""
492- self.__genres = []
493- self.__rating = 0.0
494- self.__year = 2000
495-
496- def get_short_plot(self):
497- """
498- Get plot outline text.
499- @return: String
500- """
501- return self.__plot_outline
502-
503- def set_short_plot(self, plot):
504- """
505- Set plot outline
506- @param plot String
507- """
508- self.__plot_outline = plot
509-
510- def get_plot(self):
511- """
512- Get long plot text.
513- @return: String
514- """
515- return self.__plot
516-
517- def set_plot(self, plot):
518- """
519- Sets the long plot
520- @param plot String
521- """
522- self.__plot = plot
523-
524- def get_actors(self):
525- """
526- Get list of actors
527- @return: List of strings
528- """
529- return self.__actors
530-
531- def set_actors(self, actors):
532- """
533- Sets list of actors
534- @param actors List of Strings
535- """
536- self.__actors = actors
537-
538- def get_writers(self):
539- """
540- Get list of writers
541- @return: List of strings
542- """
543- return self.__writers
544-
545- def set_writers(self, writers):
546- """
547- Sets list of writers
548- @param writers List of Strings
549- """
550- self.__writers = writers
551-
552- def get_directors(self):
553- """
554- Get list of directors
555- @return: List of strings
556- """
557- return self.__directors
558-
559- def set_directors(self, directors):
560- """
561- Sets list of directors
562- @param directors List of Strings
563- """
564- self.__directors = directors
565-
566- def get_runtime(self):
567- """
568- Get runtime of the VideoFilm
569- @return: String
570- """
571- return self.__runtime
572-
573- def set_runtime(self, run):
574- """
575- Set runtime of the VideoFilm
576- @param run String
577- """
578- self.__runtime = run
579-
580- def get_genres(self):
581- """
582- Get list of genre strings
583- @return: List of strings
584- """
585- return self.__genres
586-
587- def set_genres(self, genres):
588- """
589- Sets list of genres
590- @param genres List of Strings
591- """
592- self.__genres = genres
593-
594- def get_rating(self):
595- """
596- Get rating of the VideoFilm (1-5)
597- @return: Integer
598- """
599- return int(self.__rating)
600-
601- def set_rating(self, rating):
602- """
603- Sets rating of the VideoFilm (1-5)
604- @param rating Integer
605- """
606- self.__rating = int(rating)
607-
608- def get_year(self):
609- """
610- Get release year of the VideoFilm.
611- @return: String
612- """
613- return int(self.__year)
614-
615- def set_year(self, year):
616- """
617- Sets the year of the VideoFilm
618- @param year String
619- """
620- try:
621- self.__year = int(year)
622- except ValueError:
623- self.__year = 0
624- print "Year for Video should be an integer, not: ", year
625-
626-
627-class VideoClip(VideoItem):
628- """
629- Objects from this class represents video files.
630- """
631-
632- def __init__(self, filename):
633- """
634- Initialize Clip information
635- @param filename: Absolute path of the video clip file
636- """
637- VideoItem.__init__(self)
638- connection = sqlite.connect(self.config.VIDEO_DB)
639- cursor = connection.cursor()
640- cursor.execute(
641- """SELECT videofile.filename, hash, length, resolution, title
642- FROM videofile, metadata
643- WHERE videofile.filename=:fn
644- AND videofile.filename=metadata.filename
645- ORDER BY title""", { "fn" : filename })
646- result = cursor.fetchall()
647- self.set_filename(result[0][0]) # Filename of the clip
648- self.set_art_hash(result[0][1]) # Cover art hash
649- self.set_length(result[0][2]) # Lenght of the movie
650- self.set_resolution(result[0][3]) # Video resolution
651- self.set_title(result[0][4]) # Clip title
652- connection.close()
653+ self.actors = []
654+ self.directors = []
655+ self.genres = []
656+ self.plot = ''
657+ self.runtime = ''
658+ self.short_plot = ''
659+ self.writers = []
660+ self.rating = 0
661+ self.year = 2000
662
663
664 class Movie(VideoFilm):
665- """
666- Objects from this class represents movie.
667- """
668-
669-
670- def __init__(self, filename):
671- """
672- Initialize Movie information
673- @param filename: Absolute path of the Movie file
674- """
675- VideoFilm.__init__(self)
676- connection = sqlite.connect(self.config.VIDEO_DB)
677- cursor = connection.cursor()
678- cursor.execute("""SELECT metadata.filename, hash, length, resolution,
679- title, runtime, genres, rating, year,
680- plot_outline, plot, actor_1, actor_2,
681- actor_3, actor_4, actor_5, writer_1,
682- writer_2, director_1, director_2
683- FROM videofile, metadata
684- WHERE metadata.filename=:fn
685- AND videofile.filename=metadata.filename
686- ORDER BY title""", { "fn" : filename })
687- result = cursor.fetchall()
688- self.set_filename(result[0][0])
689- self.set_art_hash(result[0][1])
690- self.set_length(result[0][2])
691- self.set_resolution(result[0][3])
692- self.set_title(result[0][4])
693- self.set_runtime(result[0][5])
694- self.set_genres(result[0][6].split(','))
695- self.set_rating(result[0][7])
696- self.set_year(result[0][8])
697- self.set_short_plot(result[0][9])
698- self.set_plot(result[0][10])
699- self.set_actors([])
700- self.set_art_hash([])
701- self.set_directors([])
702-
703- # Actors
704- if len(result[0][11]) > 0:
705- self.get_actors().append(result[0][11])
706- if len(result[0][12]) > 0:
707- self.get_actors().append(result[0][12])
708- if len(result[0][13]) > 0:
709- self.get_actors().append(result[0][13])
710- if len(result[0][14]) > 0:
711- self.get_actors().append(result[0][14])
712- if len(result[0][15]) > 0:
713- self.get_actors().append(result[0][15])
714-
715- # Writers
716- if len(result[0][16]) > 0:
717- self.get_writers().append(result[0][16])
718- if len(result[0][17]) > 0:
719- self.get_writers().append(result[0][17])
720-
721- # Directors
722- if len(result[0][18]) > 0:
723- self.get_directors().append(result[0][18])
724- if len(result[0][19]) > 0:
725- self.get_directors().append(result[0][19])
726-
727- connection.close()
728+ '''Representation of a movie.'''
729+
730+ def has_cover_art(self):
731+ '''Test if there is cover art in the cache.'''
732+ art_path = os.path.join(self.config.MOVIE_ART_DIR, self.title + ".jpg")
733+ return os.path.exists(art_path)
734+
735+ @property
736+ def cover_art_url(self):
737+ '''Get the URL to the cover art.'''
738+ return os.path.join(self.config.MOVIE_ART_DIR, self.title + ".jpg")
739
740
741 class TVSeries(object):
742- """
743- TV Series
744-
745- TV Series contains TVEpisodes organized by seasons.
746- """
747+ '''TV Series contains TVEpisodes organized by seasons.'''
748
749 def __init__(self, title):
750- """
751- Initialize TV-Series
752- @param title: Series title
753- """
754 self.config = Configuration()
755
756- connection = sqlite.connect(self.config.VIDEO_DB)
757- cursor = connection.cursor()
758- cursor.execute("""SELECT DISTINCT series_title
759- FROM metadata
760- WHERE series_title=:title""", { "title" : title })
761- result = cursor.fetchall()
762- self.__title = None
763- if len(result) == 0:
764- raise Exception("No such TV-series as " + title)
765- else:
766- self.__title = title
767- connection.close()
768-
769- def get_title(self):
770- """
771- Get title of the series
772- @return: String
773- """
774- return self.__title
775-
776- def set_title(self, title):
777- """
778- Sets title of the series
779- @param title String
780- """
781- self.__title = title
782+ self.number_of_episodes = 0
783+ # Season list of numbers. For example [1,2,3,5] in case that user
784+ # doesn't have episodes from season 4.
785+ self.seasons = []
786+ self.title = title
787
788 def has_cover_art(self):
789- """
790- Is there cover art file for this TV-serie
791- @return: String
792- """
793- art_path = os.path.join(self.config.MOVIE_ART_DIR,
794- self.get_title() + ".jpg")
795+ '''Test if there is cover art in the cache.'''
796+ art_path = os.path.join(self.config.MOVIE_ART_DIR, self.title + ".jpg")
797 return os.path.exists(art_path)
798
799- def get_cover_art_url(self):
800- """
801- Get absolute filename of the cover art image file.
802- @return: String
803- """
804- return os.path.join(self.config.MOVIE_ART_DIR,
805- self.get_title() + ".jpg")
806-
807- def get_seasons(self):
808- """
809- Return list of numbers. For example [1,2,3,5] in case that user
810- doesn't have episodes from season 4.
811- @return: List of Integers
812- """
813- seasons = []
814- connection = sqlite.connect(self.config.VIDEO_DB)
815- cursor = connection.cursor()
816- cursor.execute("""SELECT DISTINCT season
817- FROM metadata
818- WHERE series_title=:title""",
819- { "title" : self.get_title() })
820- for row in cursor:
821- seasons.append(row[0])
822- connection.close()
823- return seasons
824-
825- def get_number_of_episodes(self):
826- """
827- Get number of episodes available on this series
828- @return: Integer
829- """
830- connection = sqlite.connect(self.config.VIDEO_DB)
831- cursor = connection.cursor()
832- cursor.execute("""SELECT COUNT(filename)
833- FROM metadata
834- WHERE series_title=:title""",
835- { "title" : self.get_title() })
836- result = cursor.fetchall()
837- connection.close()
838- return result[0][0]
839-
840- def get_number_of_seasons(self):
841- """
842- Get number of seasons available on this series
843- @return: Integer
844- """
845- connection = sqlite.connect(self.config.VIDEO_DB)
846- cursor = connection.cursor()
847- cursor.execute("""SELECT COUNT(DISTINCT season)
848- FROM metadata
849- WHERE series_title=:title""",
850- { "title" : self.get_title() })
851- result = cursor.fetchall()
852- connection.close()
853- return result[0][0]
854-
855- def get_episodes_from_season(self, season):
856- """
857- Get all episodes of the season.
858- @param season: Season number (Integer)
859- """
860- episodes = []
861- connection = sqlite.connect(self.config.VIDEO_DB)
862- cursor = connection.cursor()
863- cursor.execute("""SELECT filename, episode
864- FROM metadata
865- WHERE series_title=:title
866- AND season=:season
867- ORDER BY episode""",
868- { "title" : self.get_title(), "season" : season })
869- for row in cursor:
870- episodes.append(TVEpisode(row[0], self))
871- connection.close()
872- return episodes
873-
874- def get_episode_from_season(self, season, episode):
875- """
876- Get specific episode from this series.
877- @param season: Season number (Integer)
878- @param episode: Episode number (Integer)
879- @return TVEpisode object
880- """
881- connection = sqlite.connect(self.config.VIDEO_DB)
882- cursor = connection.cursor()
883- cursor.execute("""SELECT filename
884- FROM metadata
885- WHERE series_title=:title
886- AND episode=:episode
887- AND season=:season""",
888- { "title" : self.get_title(),
889- "season" : season,
890- "episode" : episode })
891- result = cursor.fetchall()
892- episode = TVEpisode(result[0][0], self)
893- connection.close()
894- return episode
895-
896- def get_episodes(self):
897- """
898- Get all episodes of this series.
899- @return: List of TVEpisode objects
900- """
901- episodes = []
902- connection = sqlite.connect(self.config.VIDEO_DB)
903- cursor = connection.cursor()
904- cursor.execute("""SELECT filename, season, episode
905- FROM metadata
906- WHERE series_title=:title
907- ORDER BY season, episode""",
908- { "title" : self.get_title() })
909- for row in cursor:
910- episodes.append(TVEpisode(row[0], self))
911- connection.close()
912- return episodes
913+ @property
914+ def cover_art_url(self):
915+ '''Get the URL to the cover art.'''
916+ return os.path.join(self.config.MOVIE_ART_DIR, self.title + ".jpg")
917
918
919 class TVEpisode(VideoFilm):
920- """
921- Objects from this class represents TV-Episode video file.
922- """
923+ '''Representation of a TV show episode.'''
924
925- def __init__(self, filename, series):
926- """
927- Initialize episode information.
928- @param filename: Name of the video file
929- @param series: TVSeries object
930- """
931+ def __init__(self):
932 VideoFilm.__init__(self)
933- connection = sqlite.connect(self.config.VIDEO_DB)
934- cursor = connection.cursor()
935- cursor.execute("""SELECT videofile.filename, hash, length, resolution,
936- title, runtime, genres, rating, year,
937- plot_outline, plot, actor_1, actor_2,
938- actor_3, actor_4, actor_5, writer_1,
939- writer_2, director_1, director_2,
940- series_title, season, episode
941- FROM videofile, metadata
942- WHERE videofile.filename=:fn
943- AND videofile.filename=metadata.filename
944- ORDER BY title""", { "fn" : filename })
945- result = cursor.fetchall()
946- self.set_filename(result[0][0])
947- self.set_art_hash(result[0][1])
948- self.set_length(result[0][2])
949- self.set_resolution(result[0][3])
950- self.set_title(result[0][4])
951- self.set_runtime(result[0][5])
952- self.set_genres(result[0][6].split(','))
953- self.set_rating(result[0][7])
954- self.set_year(result[0][8])
955- self.set_short_plot(result[0][9])
956- self.set_plot(result[0][10])
957-
958- # Actors
959- self.set_actors([])
960- if len(result[0][11]) > 0:
961- self.get_actors().append(result[0][11])
962- if len(result[0][12]) > 0:
963- self.get_actors().append(result[0][12])
964- if len(result[0][13]) > 0:
965- self.get_actors().append(result[0][13])
966- if len(result[0][14]) > 0:
967- self.get_actors().append(result[0][14])
968- if len(result[0][15]) > 0:
969- self.get_actors().append(result[0][15])
970-
971- # Writers
972- self.set_writers([])
973- if len(result[0][16]) > 0:
974- self.get_writers().append(result[0][16])
975- if len(result[0][17]) > 0:
976- self.get_writers().append(result[0][17])
977-
978- # Directors
979- self.set_directors([])
980- if len(result[0][18]) > 0:
981- self.get_directors().append(result[0][18])
982- if len(result[0][19]) > 0:
983- self.get_directors().append(result[0][19])
984-
985- self.__series = series
986- self.__season = result[0][21]
987- self.__episode_number = result[0][22]
988- connection.close()
989-
990- def get_cover_art_url(self):
991- """
992- Get absolute filename of the cover art image file.
993- @return: String
994- """
995- return os.path.join(self.config.MOVIE_ART_DIR,
996- self.get_series() + ".jpg")
997-
998- def get_series(self):
999- """
1000- Get TV-series
1001- @return: TVSeries objects
1002- """
1003- return self.__series
1004-
1005- def set_series(self, series):
1006- """
1007- Sets TV-Series
1008- @param series TVSeries
1009- """
1010- self.__series = series
1011-
1012- def get_episode_number(self):
1013- """
1014- Get number of the episode
1015- @return: Integer
1016- """
1017- return int(self.__episode_number)
1018-
1019- def set_episode_number(self, num):
1020- """
1021- Sets the number of the episode
1022- @param num Integer
1023- """
1024- self.__episode_number = int(num)
1025-
1026- def get_season(self):
1027- """
1028- Get number of the season
1029- @return: Interger
1030- """
1031- return int(self.__season)
1032-
1033- def set_season(self, season):
1034- """
1035- Sets number of the season
1036- @param season Integer
1037- """
1038- self.__season = int(season)
1039+ self.number = 0
1040
1041
1042=== modified file 'entertainerlib/gui/screens/factory.py'
1043--- entertainerlib/gui/screens/factory.py 2010-04-02 22:28:04 +0000
1044+++ entertainerlib/gui/screens/factory.py 2010-04-03 23:02:16 +0000
1045@@ -135,6 +135,7 @@
1046 def _generate_tv_series(self, kwargs):
1047 '''Generate a TvSeries screen.'''
1048 kwargs['move_to_new_screen_callback'] = self.move_to_new_screen_callback
1049+ kwargs['video_library'] = self.video_library
1050 return TvSeries(**kwargs)
1051
1052 def _generate_tv_episodes(self, kwargs):
1053
1054=== modified file 'entertainerlib/gui/screens/movie.py'
1055--- entertainerlib/gui/screens/movie.py 2009-12-22 00:07:29 +0000
1056+++ entertainerlib/gui/screens/movie.py 2010-04-03 23:02:16 +0000
1057@@ -45,8 +45,7 @@
1058
1059 # Movie art texture
1060 if self.movie.has_cover_art():
1061- pixbuf = gtk.gdk.pixbuf_new_from_file(
1062- self.movie.get_cover_art_url())
1063+ pixbuf = gtk.gdk.pixbuf_new_from_file(self.movie.cover_art_url)
1064 else:
1065 pixbuf = gtk.gdk.pixbuf_new_from_file(
1066 self.theme.getImage("default_movie_art"))
1067@@ -54,21 +53,21 @@
1068 self.add(movie_art)
1069
1070 # Movie title
1071- title = Label(0.04, "title", 0.47, 0.1, self.movie.get_title(),
1072+ title = Label(0.04, "title", 0.47, 0.1, self.movie.title,
1073 font_weight="bold")
1074 title.set_ellipsize(pango.ELLIPSIZE_END)
1075 title.set_size(0.5124, 0.05208)
1076 self.add(title)
1077
1078 # Movie release year
1079- year_text = _("Released in %(year)s") % {'year': self.movie.get_year()}
1080+ year_text = _("Released in %(year)s") % {'year': self.movie.year}
1081 year = Label(0.032, "subtitle", 0.47, 0.3, year_text)
1082 year.set_ellipsize(pango.ELLIPSIZE_END)
1083 year.set_size(0.5124, 0.05208)
1084 self.add(year)
1085
1086 # Show only 2 genres (or one if there is only one)
1087- genres_list = self.movie.get_genres()
1088+ genres_list = self.movie.genres
1089 if len(genres_list) == 0:
1090 genres_text = _("Unknown")
1091 else:
1092@@ -76,7 +75,7 @@
1093
1094 # Runtime and genres
1095 info_text = _("%(runtime)s min, %(genre)s") % \
1096- {'runtime': self.movie.get_runtime(), 'genre': genres_text}
1097+ {'runtime': self.movie.runtime, 'genre': genres_text}
1098 info = Label(0.032, "subtitle", 0.47, 0.24, info_text)
1099 info.set_ellipsize(pango.ELLIPSIZE_END)
1100 info.set_size(0.5124, 0.05208)
1101@@ -90,7 +89,7 @@
1102 star2.hide()
1103 self.add(star2)
1104
1105- for i in range(self.movie.get_rating()):
1106+ for i in range(self.movie.rating):
1107 tex = clutter.Clone(star)
1108 tex.set_position(
1109 self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * i),
1110@@ -98,16 +97,16 @@
1111 tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04))
1112 self.add(tex)
1113
1114- dark_star = 5 - self.movie.get_rating()
1115+ dark_star = 5 - self.movie.rating
1116 for i in range(dark_star):
1117 tex = clutter.Clone(star2)
1118 tex.set_position(self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * \
1119- (i+ self.movie.get_rating())), self.get_abs_y(0.17))
1120+ (i + self.movie.rating)), self.get_abs_y(0.17))
1121 tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04))
1122 self.add(tex)
1123
1124 # Plot
1125- plot = Label(0.029, "subtitle", 0, 0, self.movie.get_plot())
1126+ plot = Label(0.029, "subtitle", 0, 0, self.movie.plot)
1127 plot.set_justify(True)
1128 plot.set_line_wrap_mode(pango.WRAP_WORD)
1129 plot.set_line_wrap(True)
1130@@ -118,7 +117,7 @@
1131 # Actors
1132 self.add(Label(0.032, "title", 0.33, 0.8, _("Starring")))
1133
1134- actors_list = self.movie.get_actors()
1135+ actors_list = self.movie.actors
1136 if len(actors_list) == 0:
1137 actors_text = _("Unknown")
1138 else:
1139@@ -131,7 +130,7 @@
1140 # Directors
1141 self.add(Label(0.032, "title", 0.33, 0.86, _("Directed by")))
1142
1143- directors_list = self.movie.get_directors()
1144+ directors_list = self.movie.directors
1145 if len(directors_list) == 0:
1146 directors_text = _("Unknown")
1147 else:
1148@@ -144,7 +143,7 @@
1149 # Writers
1150 self.add(Label(0.032, "title", 0.33, 0.92, _("Written by")))
1151
1152- writers_list = self.movie.get_writers()
1153+ writers_list = self.movie.writers
1154 if len(directors_list) == 0:
1155 writers_text = _("Unknown")
1156 else:
1157
1158=== modified file 'entertainerlib/gui/screens/tv_episodes.py'
1159--- entertainerlib/gui/screens/tv_episodes.py 2009-12-22 00:34:27 +0000
1160+++ entertainerlib/gui/screens/tv_episodes.py 2010-04-03 23:02:16 +0000
1161@@ -14,18 +14,17 @@
1162 class TvEpisodes(Screen):
1163 '''Screen contains list of all episodes of one specific season.'''
1164
1165- def __init__(self, media_player, move_to_new_screen_callback,
1166- season_number, tv_series):
1167+ def __init__(self, media_player, move_to_new_screen_callback, episodes,
1168+ tv_series):
1169 Screen.__init__(self, 'TvEpisodes', move_to_new_screen_callback)
1170
1171+ self.episodes = episodes
1172 self.media_player = media_player
1173 self.theme = self.config.theme
1174 self.tv_series = tv_series
1175- self.season_number = season_number
1176
1177 # Screen Title (Displayed at the bottom left corner)
1178- screen_title = Label(0.13, "screentitle", 0, 0.87,
1179- self.tv_series.get_title())
1180+ screen_title = Label(0.13, "screentitle", 0, 0.87, self.tv_series.title)
1181 self.add(screen_title)
1182
1183 self.scroll_area = None
1184@@ -37,8 +36,7 @@
1185
1186 #List indicator
1187 self.li = ListIndicator(0.8, 0.9, 0.2, 0.045, ListIndicator.VERTICAL)
1188- self.li.set_maximum(
1189- len(self.tv_series.get_episodes_from_season(self.season_number)))
1190+ self.li.set_maximum(len(self.episodes))
1191 self.add(self.li)
1192
1193 self.menu.connect("moved", self._update_episode_info)
1194@@ -49,10 +47,9 @@
1195 """Create a list of available seasons."""
1196 menu = TextMenu(0.4978, 0.1563, 0.4393, 0.0781)
1197
1198- episodes = self.tv_series.get_episodes_from_season(self.season_number)
1199 episodes_list = [[_("%(num)d. %(title)s") % \
1200- {'num': episode.get_episode_number(), 'title': episode.get_title()},
1201- None, episode] for episode in episodes]
1202+ {'num': episode.number, 'title': episode.title},
1203+ None, episode] for episode in self.episodes]
1204 menu.async_add(episodes_list)
1205
1206 menu.active = True
1207@@ -65,7 +62,7 @@
1208 self.thumb.hide()
1209
1210 # Thumbnail. Use cover art if thumbnail doesn't exist
1211- thumbnail = self.menu.selected_userdata.get_thumbnail_url()
1212+ thumbnail = self.menu.selected_userdata.thumbnail_url
1213 if(thumbnail is not None):
1214 pixbuf = gtk.gdk.pixbuf_new_from_file(thumbnail)
1215 thumb_width = 0.2928
1216@@ -79,7 +76,7 @@
1217 thumb_y = 0.15
1218 if(self.tv_series.has_cover_art()):
1219 pixbuf = gtk.gdk.pixbuf_new_from_file(
1220- self.tv_series.get_cover_art_url())
1221+ self.tv_series.cover_art_url)
1222 else:
1223 pixbuf = gtk.gdk.pixbuf_new_from_file(
1224 self.theme.getImage("default_movie_art"))
1225@@ -97,16 +94,14 @@
1226
1227 # Title
1228 self.title = Label(0.04, "title", 0.05, 0.55,
1229- self.menu.selected_userdata.get_title(),
1230- font_weight="bold")
1231+ self.menu.selected_userdata.title, font_weight="bold")
1232 self.title.set_ellipsize(pango.ELLIPSIZE_END)
1233 self.title.set_line_wrap(False)
1234 self.title.width = 0.4
1235 self.add(self.title)
1236
1237 # Plot
1238- plot = Label(0.029, "subtitle", 0, 0,
1239- self.menu.selected_userdata.get_plot())
1240+ plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot)
1241 plot.width = 0.4
1242
1243 self.scroll_area = ScrollArea(0.05, 0.63, 0.4, 0.15, plot)
1244@@ -118,11 +113,10 @@
1245 self.li.set_current(self.menu.selected_index + 1)
1246
1247 self._create_thumbnail_texture()
1248- self.title.set_text(self.menu.selected_userdata.get_title())
1249+ self.title.set_text(self.menu.selected_userdata.title)
1250 self.title.width = 0.4
1251
1252- plot = Label(0.029, "subtitle", 0, 0,
1253- self.menu.selected_userdata.get_plot())
1254+ plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot)
1255 plot.width = 0.4
1256 self.scroll_area.set_content(plot)
1257
1258
1259=== modified file 'entertainerlib/gui/screens/tv_series.py'
1260--- entertainerlib/gui/screens/tv_series.py 2009-07-29 03:09:34 +0000
1261+++ entertainerlib/gui/screens/tv_series.py 2010-04-03 23:02:16 +0000
1262@@ -12,15 +12,15 @@
1263 class TvSeries(Screen):
1264 '''Screen that contains all seasons of one TV series.'''
1265
1266- def __init__(self, move_to_new_screen_callback, tv_series):
1267+ def __init__(self, video_library, move_to_new_screen_callback, tv_series):
1268 Screen.__init__(self, 'TvSeries', move_to_new_screen_callback)
1269
1270 self.theme = self.config.theme
1271 self.tv_series = tv_series
1272+ self.video_library = video_library
1273
1274 # Screen Title (Displayed at the bottom left corner)
1275- screen_title = Label(0.13, "screentitle", 0, 0.87,
1276- self.tv_series.get_title())
1277+ screen_title = Label(0.13, "screentitle", 0, 0.87, self.tv_series.title)
1278 self.add(screen_title)
1279
1280 self.art = None
1281@@ -31,7 +31,7 @@
1282
1283 #List indicator
1284 self.li = ListIndicator(0.8, 0.9, 0.2, 0.045, ListIndicator.VERTICAL)
1285- self.li.set_maximum(len(self.tv_series.get_seasons()))
1286+ self.li.set_maximum(len(self.tv_series.seasons))
1287 self.add(self.li)
1288
1289 self.menu.connect("moved", self._update_season_info)
1290@@ -43,7 +43,7 @@
1291 """
1292 menu = TextMenu(0.4978, 0.1563, 0.4393, 0.0781)
1293
1294- seasons = self.tv_series.get_seasons()
1295+ seasons = self.tv_series.seasons
1296 seasons.sort()
1297
1298 seasons_list = [[_("Season %(num)s") % {'num': season}, None, season] \
1299@@ -60,8 +60,7 @@
1300 displays album cover art.
1301 """
1302 if(self.tv_series.has_cover_art()):
1303- pixbuf = gtk.gdk.pixbuf_new_from_file(
1304- self.tv_series.get_cover_art_url())
1305+ pixbuf = gtk.gdk.pixbuf_new_from_file(self.tv_series.cover_art_url)
1306 else:
1307 pixbuf = gtk.gdk.pixbuf_new_from_file(
1308 self.theme.getImage("default_movie_art"))
1309@@ -83,6 +82,8 @@
1310 def _handle_select(self, event=None):
1311 '''Handle UserEvent.NAVIGATE_SELECT.'''
1312 season = self.menu.selected_userdata
1313- kwargs = { 'tv_series' : self.tv_series, 'season_number' : season }
1314+ episodes = self.video_library.get_episodes_from_season(
1315+ self.tv_series.title, season)
1316+ kwargs = { 'episodes' : episodes, 'tv_series' : self.tv_series }
1317 self.callback("tv_episodes", kwargs)
1318
1319
1320=== modified file 'entertainerlib/gui/tabs/movies_tab.py'
1321--- entertainerlib/gui/tabs/movies_tab.py 2009-12-21 17:22:33 +0000
1322+++ entertainerlib/gui/tabs/movies_tab.py 2010-04-03 23:02:16 +0000
1323@@ -80,7 +80,7 @@
1324 menu.visible_cols = 7
1325
1326 movies = self.video_library.get_movies()
1327- movies_list = [[movie.get_cover_art_url(), movie] for movie in movies]
1328+ movies_list = [[movie.cover_art_url, movie] for movie in movies]
1329 menu.async_add_videos(movies_list)
1330
1331 # Create list indicator
1332@@ -114,17 +114,17 @@
1333 '''Update the movie information labels.'''
1334 if self.active:
1335 movie = self.menu.selected_userdata
1336- genres = movie.get_genres()
1337+ genres = movie.genres
1338 if len(genres) > 1:
1339 genre = genres[0] + "/" + genres[1]
1340 else:
1341 genre = genres[0]
1342
1343- self.movie_title.set_text(_("%(title)s (%(year)d)") % \
1344- {'title': movie.get_title(), 'year': movie.get_year()})
1345+ self.movie_title.set_text(_("%(title)s (%(year)s)") % \
1346+ {'title': movie.title, 'year': movie.year})
1347 self.movie_info.set_text(_("%(min)d min, (%(genre)s)") % \
1348- {'min': movie.get_runtime(), 'genre': genre})
1349- self.movie_plot.set_text(movie.get_short_plot())
1350+ {'min': movie.runtime, 'genre': genre})
1351+ self.movie_plot.set_text(movie.short_plot)
1352 self.list_indicator.show()
1353 self.list_indicator.set_current(self.menu.selected_index + 1)
1354 else:
1355
1356=== modified file 'entertainerlib/gui/tabs/series_tab.py'
1357--- entertainerlib/gui/tabs/series_tab.py 2009-12-21 17:22:33 +0000
1358+++ entertainerlib/gui/tabs/series_tab.py 2010-04-03 23:02:16 +0000
1359@@ -79,7 +79,7 @@
1360 menu.visible_cols = 7
1361
1362 series = self.video_library.get_tv_series()
1363- series_list = [[serie.get_cover_art_url(), serie] for serie in series]
1364+ series_list = [[serie.cover_art_url, serie] for serie in series]
1365 menu.async_add_videos(series_list)
1366
1367 # Create list indicator
1368@@ -107,11 +107,10 @@
1369 if self.active:
1370 series = self.menu.selected_userdata
1371 info = _("%(season)d Seasons\n%(episode)d Episodes") % {'season':
1372- series.get_number_of_seasons(), 'episode':
1373- series.get_number_of_episodes()}
1374+ len(series.seasons), 'episode': series.number_of_episodes}
1375
1376 self.series_info.set_text(info)
1377- self.series_title.set_text(series.get_title())
1378+ self.series_title.set_text(series.title)
1379 self.list_indicator.show()
1380 self.list_indicator.set_current(self.menu.selected_index + 1)
1381 else:
1382
1383=== modified file 'entertainerlib/gui/tabs/video_clips_tab.py'
1384--- entertainerlib/gui/tabs/video_clips_tab.py 2009-12-21 17:22:33 +0000
1385+++ entertainerlib/gui/tabs/video_clips_tab.py 2010-04-03 23:02:16 +0000
1386@@ -79,7 +79,7 @@
1387 menu.visible_cols = 4
1388
1389 clips = self.video_library.get_video_clips()
1390- clips_list = [[clip.get_thumbnail_url(), clip] for clip in clips]
1391+ clips_list = [[clip.thumbnail_url, clip] for clip in clips]
1392 menu.async_add_clips(clips_list)
1393
1394 # Create list indicator
1395@@ -109,7 +109,7 @@
1396 '''Update the VideoClip information labels.'''
1397 if self.active:
1398 clip = self.menu.selected_userdata
1399- (folder, filename) = os.path.split(clip.get_filename())
1400+ (folder, filename) = os.path.split(clip.filename)
1401 self.clip_title.set_text(filename)
1402 self.clip_info.set_text(folder)
1403 self.list_indicator.show()
1404
1405=== modified file 'entertainerlib/tests/mock.py'
1406--- entertainerlib/tests/mock.py 2010-04-02 23:13:48 +0000
1407+++ entertainerlib/tests/mock.py 2010-04-03 23:02:16 +0000
1408@@ -84,43 +84,15 @@
1409 '''Mock entertainerlib.client.medialibrary.videos.Movie'''
1410
1411 def __init__(self, filename=None):
1412- '''Override init to prevent a database connection'''
1413-
1414- def get_actors(self):
1415- '''See `Movie.get_actors`.'''
1416- return ['Tim Robbins']
1417-
1418- def get_directors(self):
1419- '''See `Movie.get_directors`.'''
1420- return ['Frank Darabont']
1421-
1422- def get_genres(self):
1423- '''See `Movie.get_genres`.'''
1424- return ['Drama']
1425-
1426- def get_plot(self):
1427- '''See `Movie.get_plot`.'''
1428- return 'An innocent man is sent to prison'
1429-
1430- def get_rating(self):
1431- '''See `Movie.get_rating`.'''
1432- return 5
1433-
1434- def get_runtime(self):
1435- '''See `Movie.get_runtime`.'''
1436- return ""
1437-
1438- def get_title(self):
1439- '''See `Movie.get_title`.'''
1440- return 'The Shawshank Redemption'
1441-
1442- def get_writers(self):
1443- '''See `Movie.get_writers`.'''
1444- return ['Frank Darabont']
1445-
1446- def get_year(self):
1447- '''See `Movie.get_year`.'''
1448- return 1994
1449+ self.actors = ['Tim Robbins']
1450+ self.directors = ['Frank Darabont']
1451+ self.genres = ['Drama']
1452+ self.plot = 'An innocent man is sent to prison'
1453+ self.rating = 5
1454+ self.runtime = ''
1455+ self.title = 'The Shawshank Redemption'
1456+ self.writers = ['Frank Darabont']
1457+ self.year = 1994
1458
1459 def has_cover_art(self):
1460 '''See `Movie.has_cover_art`.'''
1461@@ -158,42 +130,22 @@
1462
1463 def __init__(self, title=None):
1464 '''Override init to prevent a database connection'''
1465-
1466- def get_episode_number(self):
1467- '''See `TVEpisode.get_episode_number`.'''
1468- return 1
1469-
1470- def get_plot(self):
1471- '''See `TVEpisode.get_plot`.'''
1472- return 'Dr. House continues to be a jerk'
1473-
1474- def get_thumbnail_url(self):
1475- '''See `TVEpisode.get_thumbnail_url`.'''
1476+ self.number = 1
1477+ self.title = 'Something clever'
1478+ self.plot = 'Dr. House continues to be a jerk'
1479+
1480+ @property
1481+ def thumbnail_url(self):
1482+ '''Thumbnail URL getter.'''
1483 return None
1484
1485- def get_title(self):
1486- '''See `TVEpisode.get_title`.'''
1487- return 'Something clever'
1488-
1489-
1490 class MockTVSeries(TVSeries):
1491 '''Mock entertainerlib.client.medialibrary.videos.TVSeries'''
1492
1493 def __init__(self, title=None):
1494 '''Override init to prevent a database connection'''
1495-
1496- def get_episodes_from_season(self, season_number=1):
1497- '''See `TVSeries.get_episodes_from_season`.'''
1498- mock_episode = MockTVEpisode()
1499- return [mock_episode]
1500-
1501- def get_seasons(self):
1502- '''See `TVSeries.get_seasons`.'''
1503- return []
1504-
1505- def get_title(self):
1506- '''See `TVSeries.get_title`.'''
1507- return 'House'
1508+ self.seasons = []
1509+ self.title = 'House'
1510
1511 def has_cover_art(self):
1512 '''See `TVSeries.has_cover_art`.'''
1513@@ -205,6 +157,9 @@
1514 def __init__(self):
1515 '''Override the intial behavior.'''
1516
1517+ def __del__(self):
1518+ '''Override the delete behavior.'''
1519+
1520 def get_number_of_movies(self):
1521 '''See `VideoLibrary.get_number_of_movies`.'''
1522 return 0
1523
1524=== modified file 'entertainerlib/tests/test_mediaplayer.py'
1525--- entertainerlib/tests/test_mediaplayer.py 2009-07-14 04:56:55 +0000
1526+++ entertainerlib/tests/test_mediaplayer.py 2010-04-03 23:02:16 +0000
1527@@ -19,8 +19,7 @@
1528
1529 self.player = MediaPlayer(clutter.Stage(), 100, 100)
1530 self.video_item = VideoItem()
1531- self.video_item.set_filename(
1532- THIS_DIR + '/data/VideoThumbnailer/test.avi')
1533+ self.video_item.filename = THIS_DIR + '/data/VideoThumbnailer/test.avi'
1534 self.player.set_media(self.video_item)
1535
1536 def test_create(self):
1537
1538=== modified file 'entertainerlib/tests/test_screenfactory.py'
1539--- entertainerlib/tests/test_screenfactory.py 2010-04-02 23:13:48 +0000
1540+++ entertainerlib/tests/test_screenfactory.py 2010-04-03 23:02:16 +0000
1541@@ -28,6 +28,7 @@
1542 from entertainerlib.tests.mock import MockMediaPlayer
1543 from entertainerlib.tests.mock import MockMovie
1544 from entertainerlib.tests.mock import MockMusicLibrary
1545+from entertainerlib.tests.mock import MockTVEpisode
1546 from entertainerlib.tests.mock import MockTVSeries
1547 from entertainerlib.tests.mock import MockVideoLibrary
1548
1549@@ -129,7 +130,7 @@
1550
1551 def test__generate_tv_episodes(self):
1552 '''Test _generate_tv_episodes returns a TvEpisodes screen'''
1553- self.kwargs['season_number'] = 1
1554+ self.kwargs['episodes'] = [MockTVEpisode()]
1555 self.kwargs['tv_series'] = MockTVSeries()
1556 screen = self.factory._generate_tv_episodes(self.kwargs)
1557 self.assertTrue(isinstance(screen, TvEpisodes))

Subscribers

People subscribed via source and target branches