ui: Added support for displaying WATC service results
[maevies] / ui / maeviesui / util / moviemanager.py
1 # -*- coding: utf-8 -*-
2
3 ###########################################################################
4 #    Maevies
5 #    Copyright (C) 2010 Simón Pena <spenap@gmail.com>
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU General Public License as published by
9 #    the Free Software Foundation, either version 3 of the License, or
10 #    (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU General Public License for more details.
16 #
17 #    You should have received a copy of the GNU General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 ###########################################################################
20
21 import dbus
22 import gobject
23 from dbus import glib
24 import gtk
25 from dbus.exceptions import DBusException
26
27 gobject.threads_init()
28 glib.init_threads()
29
30 MINFO_PROVIDER_INTERFACE = 'com.simonpena.maevies.minfoprovider'
31 MINFO_PROVIDER_BUS_NAME = 'com.simonpena.maevies.minfoprovider'
32 TMDB_MOVIE_INTERFACE = 'com.simonpena.maevies.tmdbmovie'
33 TMDB_MOVIE_BUS_NAME = 'com.simonpena.maevies.tmdbmovie'
34 WATC_MOVIE_INTERFACE = 'com.simonpena.maevies.watcmovie'
35 WATC_MOVIE_BUS_NAME = 'com.simonpena.maevies.watcmovie'
36 TMDB = 0
37 WATC = 1
38
39 class MovieManager:
40
41     def __init__(self, response_received_cb=None):
42         self.response_received_cb = response_received_cb
43         self._bus = None
44         self._provider = None
45
46         self._bus = dbus.SessionBus()
47
48     def _get_provider(self):
49         if not self._provider:
50             self._provider = self._create_minfo_provider()
51         return self._provider
52
53     def _create_minfo_provider(self):
54         provider_proxy = self._bus.get_object(MINFO_PROVIDER_BUS_NAME,
55                                              '/MInfoProvider')
56         provider_interface = dbus.Interface(provider_proxy,
57                                             dbus_interface=MINFO_PROVIDER_INTERFACE)
58         provider_interface.connect_to_signal('ResponseReceived',
59                                              self._on_response_received)
60         return provider_interface
61
62     def query(self, movie_name='', query_type=TMDB):
63         try:
64             self._get_provider().Query(query_type, movie_name)
65         except DBusException:
66             self._on_response_received([])
67
68     def _on_response_received(self, interface, object_paths):
69         movies = []
70
71         if interface == TMDB_MOVIE_INTERFACE:
72             for path in object_paths:
73                 movies.append(TmdbMovie(self._bus, path))
74         elif interface == WATC_MOVIE_INTERFACE:
75             for path in object_paths:
76                 movies.append(WatcMovie(self._bus, path))
77
78         if self.response_received_cb:
79             self.response_received_cb(movies)
80
81 class TmdbMovieImage:
82     def __init__(self, image_struct):
83         self._type, self._url, self._size, self._id = image_struct
84
85     def get_url(self):
86         return self._url
87
88     def get_id(self):
89         return self._id
90
91     def get_size(self):
92         return self._size
93
94     def get_type(self):
95         return self._type
96
97     def __str__(self):
98         str = ''
99         for field in [self._id, self._url, self._type, self._size]:
100             str += '\t%s\n' % field
101         return str
102
103 class GenericMovie(object):
104
105     def __init__(self, bus):
106         self._bus = bus
107         pass
108
109     def _create_interface(self, bus_name, bus_interface, object_path):
110         proxy = self._bus.get_object(bus_name,
111                                      object_path)
112         interface = dbus.Interface(proxy,
113                                    dbus_interface=bus_interface)
114         return interface
115
116     def get_title(self):
117         return ''
118
119     def get_info(self):
120         return ''
121
122     def get_value(self, field):
123         return ''
124
125     def get_image(self, type=None, size=None):
126         return self.get_placeholder_image()
127
128     def get_placeholder_image(self):
129         return self._get_placeholder_pixbuf()
130
131     def _get_placeholder_pixbuf(self):
132         pixbuf = gtk.IconTheme().load_icon('general_video_file', 48, 0)
133         return pixbuf
134
135 class WatcMovie(GenericMovie):
136
137     def __init__(self, bus, object_path):
138         super(WatcMovie, self).__init__(bus)
139         self.interface = self._create_interface(WATC_MOVIE_BUS_NAME,
140                                                 WATC_MOVIE_INTERFACE,
141                                                 object_path)
142         self.fields = ['Name', 'Year', 'Stingers']
143
144     def get_value(self, field):
145         if field == 'Name':
146             return self.get_title()
147         elif field == 'Year':
148             return self.get_year()
149         elif field == 'Stingers':
150             return self.get_stingers()
151         super(WatcMovie, self).get_value()
152
153     def get_title(self):
154         return self.interface.GetName()
155
156     def get_year(self):
157         return self.interface.GetYear()
158
159     def get_stingers(self):
160         return self.interface.GetStingers()
161
162     def get_info(self):
163         stingers = self.get_stingers()
164         has_stingers = ''
165         if stingers == 0:
166             has_stingers = 'Unknown'
167         elif stingers == 1:
168             has_stingers = 'Yes'
169         elif stingers == 2:
170             has_stingers = 'No'
171
172         return ('<b>%(title)s</b>\n<small><i>Year: </i>%(year)s'
173                 '    <i>Has stingers: </i>%(stingers)s</small>' %
174                 {'title' : self.get_title(),
175                  'year' : self.get_year(),
176                  'stingers' : has_stingers})
177
178 class TmdbMovie(GenericMovie):
179
180     def __init__(self, bus, object_path):
181         super(TmdbMovie, self).__init__(bus)
182         self.interface = self._create_interface(TMDB_MOVIE_BUS_NAME,
183                                                 TMDB_MOVIE_INTERFACE,
184                                                 object_path)
185         self.fields = ['Title', 'Release date', 'Rating', 'Popularity']
186         self._images = self._retrieve_images()
187
188     def _retrieve_images(self):
189         images = { }
190         dbus_images = self.interface.GetImages()
191         for dbus_image in dbus_images:
192             image = TmdbMovieImage(dbus_image)
193             if not images.has_key(image.get_type()):
194                 images[image.get_type()] = {}
195             images[image.get_type()][image.get_size()] = image
196         return images
197
198     def get_value(self, field):
199         if field == 'Title':
200             return self.get_title()
201         elif field == 'Release date':
202             return self.get_released()
203         elif field == 'Rating':
204             return self.get_rating()
205         elif field == 'Popularity':
206             return self.get_popularity()
207         super(TmdbMovie, self).get_value()
208
209     def get_title(self):
210         return self.interface.GetTitle()
211
212     def get_popularity(self):
213         return self.interface.GetPopularity()
214
215     def get_rating(self):
216         return self.interface.GetRating()
217
218     def get_image(self, type, size):
219         if self._images.has_key(type) and self._images[type].has_key(size):
220             return self._images[type][size]
221         else:
222             return None
223
224     def get_released(self):
225         return self.interface.GetReleased()
226
227     def get_info(self):
228         return ('<b>%(title)s</b>\n<small><i>Popularity: </i>%(popularity)s'
229                 '    <i>Rating: </i>%(rating)s    <i>Released: </i>'
230                 '%(released)s</small>' %
231                 {'title' : self.get_title(),
232                  'popularity' : self.get_popularity(),
233                  'rating' : self.get_rating(),
234                  'released' : self.get_released()})
235
236     def get_overview(self):
237         return self.interface.GetOverview()