55d95cada2161d58bdaa91402c67e30224d14347
[plugin.video.netflix.git] / resources / lib / NetflixHttpSubRessourceHandler.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # Module: NetflixHttpSubRessourceHandler
4 # Created on: 07.03.2017
5
6 class NetflixHttpSubRessourceHandler:
7     """ Represents the callable internal server routes & translates/executes them to requests for Netflix"""
8
9     def __init__ (self, kodi_helper, netflix_session):
10         """Sets up credentials & video_list_cache cache
11         Assigns the netflix_session/kodi_helper instacnes
12         Does the initial login if we have user data
13
14         Parameters
15         ----------
16         kodi_helper : :obj:`KodiHelper`
17             instance of the KodiHelper class
18
19         netflix_session : :obj:`NetflixSession`
20             instance of the NetflixSession class
21         """
22         self.kodi_helper = kodi_helper
23         self.netflix_session = netflix_session
24         self.credentials = self.kodi_helper.get_credentials()
25         self.profiles = []
26         self.video_list_cache = {}
27         self.prefetch_login()
28
29     def prefetch_login (self):
30         """Check if we have stored credentials.
31         If so, do the login before the user requests it
32         If that is done, we cache the profiles
33         """
34         if self.credentials['email'] != '' and self.credentials['password'] != '':
35             if self.netflix_session.is_logged_in(account=self.credentials):
36                 self.netflix_session.refresh_session_data(account=self.credentials)
37                 self.profiles = self.netflix_session.profiles
38             else:
39                 self.netflix_session.login(account=self.credentials)
40                 self.profiles = self.netflix_session.profiles
41         else:
42             self.profiles = []
43         self.kodi_helper.set_esn(self.netflix_session.esn)
44
45     def is_logged_in (self, params):
46         """Existing login proxy function
47
48         Parameters
49         ----------
50         params : :obj:`dict` of :obj:`str`
51             Request params
52
53         Returns
54         -------
55         :obj:`Requests.Response`
56             Response of the remote call
57         """
58         if self.credentials['email'] == '' or self.credentials['password'] == '':
59             return False
60         return self.netflix_session.is_logged_in(account=self.credentials)
61
62     def logout (self, params):
63         """Logout proxy function
64
65         Parameters
66         ----------
67         params : :obj:`dict` of :obj:`str`
68             Request params
69
70         Returns
71         -------
72         :obj:`Requests.Response`
73             Response of the remote call
74         """
75         self.profiles = []
76         self.credentials = {'email': '', 'password': ''}
77         return self.netflix_session.logout()
78
79     def login (self, params):
80         """Logout proxy function
81
82         Parameters
83         ----------
84         params : :obj:`dict` of :obj:`str`
85             Request params
86
87         Returns
88         -------
89         :obj:`Requests.Response`
90             Response of the remote call
91         """
92         email = params.get('email', [''])[0]
93         password = params.get('password', [''])[0]
94         if email != '' and password != '':
95             self.credentials = {'email': email, 'password': password}
96             _ret = self.netflix_session.login(account=self.credentials)
97             self.profiles = self.netflix_session.profiles
98             return _ret
99         return None
100
101     def list_profiles (self, params):
102         """Returns the cached list of profiles
103
104         Parameters
105         ----------
106         params : :obj:`dict` of :obj:`str`
107             Request params
108
109         Returns
110         -------
111         :obj:`dict` of :obj:`str`
112             List of profiles
113         """
114         return self.profiles
115
116     def get_esn (self, params):
117         """ESN getter function
118
119         Parameters
120         ----------
121         params : :obj:`dict` of :obj:`str`
122             Request params
123
124         Returns
125         -------
126         :obj:`str`
127             Exracted ESN
128         """
129         return self.netflix_session.esn
130
131     def fetch_video_list_ids (self, params):
132         """Video list ids proxy function (caches video lists)
133
134         Parameters
135         ----------
136         params : :obj:`dict` of :obj:`str`
137             Request params
138
139         Returns
140         -------
141         :obj:`list`
142             Transformed response of the remote call
143         """
144         cached_list = self.video_list_cache.get(self.netflix_session.user_data['guid'], None)
145         if cached_list != None:
146             self.kodi_helper.log('Serving cached list for user: ' + self.netflix_session.user_data['guid'])
147             return cached_list
148         video_list_ids_raw = self.netflix_session.fetch_video_list_ids()
149
150         if 'error' in video_list_ids_raw:
151             return video_list_ids_raw
152         return self.netflix_session.parse_video_list_ids(response_data=video_list_ids_raw)
153
154     def fetch_video_list (self, params):
155         """Video list proxy function
156
157         Parameters
158         ----------
159         params : :obj:`dict` of :obj:`str`
160             Request params
161
162         Returns
163         -------
164         :obj:`list`
165             Transformed response of the remote call
166         """
167         list_id = params.get('list_id', [''])[0]
168         raw_video_list = self.netflix_session.fetch_video_list(list_id=list_id)
169         if 'error' in raw_video_list:
170             return raw_video_list
171         # parse the video list ids
172         if 'videos' in raw_video_list.get('value', {}).keys():
173             return self.netflix_session.parse_video_list(response_data=raw_video_list)
174         return []
175
176     def fetch_episodes_by_season (self, params):
177         """Episodes for season proxy function
178
179         Parameters
180         ----------
181         params : :obj:`dict` of :obj:`str`
182             Request params
183
184         Returns
185         -------
186         :obj:`list`
187             Transformed response of the remote call
188         """
189         raw_episode_list = self.netflix_session.fetch_episodes_by_season(season_id=params.get('season_id')[0])
190         if 'error' in raw_episode_list:
191             return raw_episode_list
192         return self.netflix_session.parse_episodes_by_season(response_data=raw_episode_list)
193
194     def fetch_seasons_for_show (self, params):
195         """Season for show proxy function
196
197         Parameters
198         ----------
199         params : :obj:`dict` of :obj:`str`
200             Request params
201
202         Returns
203         -------
204         :obj:`list`
205             Transformed response of the remote call
206         """
207         show_id = params.get('show_id', [''])[0]
208         raw_season_list = self.netflix_session.fetch_seasons_for_show(id=show_id)
209         if 'error' in raw_season_list:
210             return raw_season_list
211         # check if we have sesons, announced shows that are not available yet have none
212         if 'seasons' not in raw_season_list.get('value', {}):
213               return []
214         return self.netflix_session.parse_seasons(id=show_id, response_data=raw_season_list)
215
216     def rate_video (self, params):
217         """Video rating proxy function
218
219         Parameters
220         ----------
221         params : :obj:`dict` of :obj:`str`
222             Request params
223
224         Returns
225         -------
226         :obj:`Requests.Response`
227             Response of the remote call
228         """
229         video_id = params.get('video_id', [''])[0]
230         rating = params.get('rating', [''])[0]
231         return self.netflix_session.rate_video(video_id=video_id, rating=rating)
232
233     def remove_from_list (self, params):
234         """Remove from my list proxy function
235
236         Parameters
237         ----------
238         params : :obj:`dict` of :obj:`str`
239             Request params
240
241         Returns
242         -------
243         :obj:`Requests.Response`
244             Response of the remote call
245         """
246         video_id = params.get('video_id', [''])[0]
247         return self.netflix_session.remove_from_list(video_id=video_id)
248
249     def add_to_list (self, params):
250         """Add to my list proxy function
251
252         Parameters
253         ----------
254         params : :obj:`dict` of :obj:`str`
255             Request params
256
257         Returns
258         -------
259         :obj:`Requests.Response`
260             Response of the remote call
261         """
262         video_id = params.get('video_id', [''])[0]
263         return self.netflix_session.add_to_list(video_id=video_id)
264
265     def fetch_metadata (self, params):
266         """Metadata proxy function
267
268         Parameters
269         ----------
270         params : :obj:`dict` of :obj:`str`
271             Request params
272
273         Returns
274         -------
275         :obj:`Requests.Response`
276             Response of the remote call
277         """
278         video_id = params.get('video_id', [''])[0]
279         return self.netflix_session.fetch_metadata(id=video_id)
280
281     def switch_profile (self, params):
282         """Switch profile proxy function
283
284         Parameters
285         ----------
286         params : :obj:`dict` of :obj:`str`
287             Request params
288
289         Returns
290         -------
291         :obj:`Requests.Response`
292             Response of the remote call
293         """
294         profile_id = params.get('profile_id', [''])[0]
295         return self.netflix_session.switch_profile(profile_id=profile_id, account=self.credentials)
296
297     def get_user_data (self, params):
298         """User data getter function
299
300         Parameters
301         ----------
302         params : :obj:`dict` of :obj:`str`
303             Request params
304
305         Returns
306         -------
307         :obj:`str`
308             Exracted User Data
309         """
310         return self.netflix_session.user_data
311
312     def search (self, params):
313         """Search proxy function
314
315         Parameters
316         ----------
317         params : :obj:`dict` of :obj:`str`
318             Request params
319
320         Returns
321         -------
322         :obj:`list`
323             Transformed response of the remote call
324         """
325         term = params.get('term', [''])[0]
326         has_search_results = False
327         raw_search_results = self.netflix_session.fetch_search_results(search_str=term)
328         # check for any errors
329         if 'error' in raw_search_results:
330             return raw_search_results
331
332         # determine if we found something
333         if 'search' in raw_search_results['value']:
334             for key in raw_search_results['value']['search'].keys():
335                 if self.netflix_session._is_size_key(key=key) == False:
336                     has_search_results = raw_search_results['value']['search'][key]['titles']['length'] > 0
337                     if has_search_results == False:
338                         if raw_search_results['value']['search'][key].get('suggestions', False) != False:
339                             for entry in raw_search_results['value']['search'][key]['suggestions']:
340                                 if self.netflix_session._is_size_key(key=entry) == False:
341                                     if raw_search_results['value']['search'][key]['suggestions'][entry]['relatedvideos']['length'] > 0:
342                                         has_search_results = True
343
344         # display that we haven't found a thing
345         if has_search_results == False:
346             return []
347
348         # list the search results
349         search_results = self.netflix_session.parse_search_results(response_data=raw_search_results)
350         # add more menaingful data to the search results
351         raw_search_contents = self.netflix_session.fetch_video_list_information(video_ids=search_results.keys())
352         # check for any errors
353         if 'error' in raw_search_contents:
354             return raw_search_contents
355         return self.netflix_session.parse_video_list(response_data=raw_search_contents)