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