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