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