Skip to content

Commit

Permalink
Merge pull request #19 from asciidisco/feat/list-performance-api-compat
Browse files Browse the repository at this point in the history
chore(performance): Speeds up display of main menu, genre and recomme…
  • Loading branch information
asciidisco authored Mar 17, 2017
2 parents 0aec910 + 4992e07 commit 8181622
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 80 deletions.
6 changes: 3 additions & 3 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.netflix" name="Netflix" version="0.11.5" provider-name="libdev + jojo + asciidisco">
<addon id="plugin.video.netflix" name="Netflix" version="0.11.6" provider-name="libdev + jojo + asciidisco">
<requires>
<import addon="xbmc.python" version="2.24.0"/>
<import addon="script.module.beautifulsoup4" version="4.3.2"/>
Expand Down Expand Up @@ -28,7 +28,7 @@
<license>MIT</license>
<forum>http://www.kodinerds.net/index.php/Thread/55607-Inputstream-Agile-Betatest-Netflix/</forum>
<source>https://github.com/asciidisco/plugin.video.netflix</source>
<news>v0.11.5 (2017-3-16)
- Remove flawed debugging code</news>
<news>v0.11.5 (2017-3-17)
- Speed up display of main menu, genre and recommendation list</news>
</extension>
</addon>
2 changes: 1 addition & 1 deletion resources/language/English/strings.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
# Addon version: 0.11.5
# Addon version: 0.11.6
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
Expand Down
2 changes: 1 addition & 1 deletion resources/language/German/strings.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
# Addon version: 0.11.5
# Addon version: 0.11.6
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
Expand Down
2 changes: 1 addition & 1 deletion resources/language/Slovak/strings.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
# Addon version: 0.11.5
# Addon version: 0.11.6
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
Expand Down
2 changes: 1 addition & 1 deletion resources/language/Spanish/strings.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
# Addon version: 0.11.5
# Addon version: 0.11.6
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
Expand Down
18 changes: 2 additions & 16 deletions resources/lib/Navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,7 @@ def show_user_list (self, type):
"""
# determine if we´re in kids mode
user_data = self.call_netflix_service({'method': 'get_user_data'})
profiles = self.call_netflix_service({'method': 'list_profiles'})
is_kids = profiles.get(user_data['guid']).get('isKids', False)
# fetch video lists
if is_kids == True:
video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids_for_kids'})
else:
video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids', 'type': type})
video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids', 'guid': user_data['guid'], 'cache': True})
# check for any errors
if self._is_dirty_response(response=video_list_ids):
return False
Expand Down Expand Up @@ -246,16 +240,8 @@ def show_video_list (self, video_list_id, type):

def show_video_lists (self):
"""List the users video lists (recommendations, my list, etc.)"""
# determine if we´re in Kids profile mode
user_data = self.call_netflix_service({'method': 'get_user_data'})
profiles = self.call_netflix_service({'method': 'list_profiles'})
is_kids = profiles.get(user_data['guid']).get('isKids', False)
# fetch video lists
if is_kids == True:
video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids_for_kids', 'guid': user_data['guid'], 'cache': True})
else:
video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids', 'guid': user_data['guid'], 'cache': True})

video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids', 'guid': user_data['guid'], 'cache': True})
# check for any errors
if self._is_dirty_response(response=video_list_ids):
return False
Expand Down
19 changes: 1 addition & 18 deletions resources/lib/NetflixHttpSubRessourceHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,28 +154,11 @@ def fetch_video_list_ids (self, params):
self.kodi_helper.log('Serving cached list for user: ' + self.netflix_session.user_data['guid'])
return cached_list
video_list_ids_raw = self.netflix_session.fetch_video_list_ids()

if 'error' in video_list_ids_raw:
return video_list_ids_raw
return self.netflix_session.parse_video_list_ids(response_data=video_list_ids_raw)

def fetch_video_list_ids_for_kids (self, params):
"""Video list ids proxy function (thanks to Netflix that we need to use a different API for Kids profiles)
Parameters
----------
params : :obj:`dict` of :obj:`str`
Request params
Returns
-------
:obj:`list`
Transformed response of the remote call
"""
if self.lolomo == None:
self.lolomo = self.netflix_session.get_lolomo_for_kids()
response = self.netflix_session.fetch_lists_for_kids(lolomo=self.lolomo)
return response

def fetch_video_list (self, params):
"""Video list proxy function
Expand Down
65 changes: 26 additions & 39 deletions resources/lib/NetflixSession.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,11 @@ def parse_video_list_ids (self, response_data):
for key in self.video_list_keys:
video_list_ids[key] = {}

# check if the list items are hidden behind a `value` sub key
# this is the case when we fetch the lists via POST, not via a GET preflight request
if 'value' in response_data.keys():
response_data = response_data['value']

# subcatogorize the lists by their context
video_lists = response_data['lists']
for video_list_id in video_lists.keys():
Expand Down Expand Up @@ -1270,8 +1275,9 @@ def fetch_browse_list_contents (self):
response = self._session_get(component='browse')
return BeautifulSoup(response.text, 'html.parser')

def fetch_video_list_ids (self, list_from=0, list_to=50):
def fetch_video_list_ids_via_preflight (self, list_from=0, list_to=50):
"""Fetches the JSON with detailed information based on the lists on the landing page (browse page) of Netflix
via the preflight (GET) request
Parameters
----------
Expand All @@ -1298,14 +1304,11 @@ def fetch_video_list_ids (self, list_from=0, list_to=50):
response = self._session_get(component='video_list_ids', params=payload, type='api')
return self._process_response(response=response, component=self._get_api_url_for(component='video_list_ids'))

def fetch_search_results (self, search_str, list_from=0, list_to=10):
"""Fetches the JSON which contains the results for the given search query
def fetch_video_list_ids (self, list_from=0, list_to=50):
"""Fetches the JSON with detailed information based on the lists on the landing page (browse page) of Netflix
Parameters
----------
search_str : :obj:`str`
String to query Netflix search for
list_from : :obj:`int`
Start entry for pagination
Expand All @@ -1317,42 +1320,20 @@ def fetch_search_results (self, search_str, list_from=0, list_to=10):
:obj:`dict` of :obj:`dict` of :obj:`str`
Raw Netflix API call response or api call error
"""
# properly encode the search string
encoded_search_string = quote(search_str)

paths = [
['search', encoded_search_string, 'titles', {'from': list_from, 'to': list_to}, ['summary', 'title']],
['search', encoded_search_string, 'titles', {'from': list_from, 'to': list_to}, 'boxarts', '_342x192', 'jpg'],
['search', encoded_search_string, 'titles', ['id', 'length', 'name', 'trackIds', 'requestId']],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', {'from': list_from, 'to': list_to}, ['summary', 'title']],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', {'from': list_from, 'to': list_to}, 'boxarts', '_342x192', 'jpg'],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', ['id', 'length', 'name', 'trackIds', 'requestId']]
['lolomo', {'from': list_from, 'to': list_to}, ['displayName', 'context', 'id', 'index', 'length']]
]
response = self._path_request(paths=paths)
return self._process_response(response=response, component='Search results')

def get_lolomo_for_kids (self):
"""Fetches the lolomo ID for Kids profiles

Returns
-------
:obj:`str`
Kids Lolomo ID
"""
response = self._session_get(component='kids')
for cookie in response.cookies:
if cookie.name.find('lhpuuidh-browse-' + self.user_data['guid']) != -1 and cookie.name.rfind('-T') == -1:
start = unquote(cookie.value).rfind(':')
return unquote(cookie.value)[start+1:]
return None
response = self._path_request(paths=paths)
return self._process_response(response=response, component='Video list ids')

def fetch_lists_for_kids (self, lolomo, list_from=0, list_to=50):
"""Fetches the JSON which contains the contents of a the video list for kids users
def fetch_search_results (self, search_str, list_from=0, list_to=10):
"""Fetches the JSON which contains the results for the given search query
Parameters
----------
lolomo : :obj:`str`
Lolomo ID for the Kids profile
search_str : :obj:`str`
String to query Netflix search for
list_from : :obj:`int`
Start entry for pagination
Expand All @@ -1365,13 +1346,19 @@ def fetch_lists_for_kids (self, lolomo, list_from=0, list_to=50):
:obj:`dict` of :obj:`dict` of :obj:`str`
Raw Netflix API call response or api call error
"""
# properly encode the search string
encoded_search_string = quote(search_str)

paths = [
['lists', lolomo, {'from': list_from, 'to': list_to}, ['displayName', 'context', 'genreId', 'id', 'index', 'length']]
['search', encoded_search_string, 'titles', {'from': list_from, 'to': list_to}, ['summary', 'title']],
['search', encoded_search_string, 'titles', {'from': list_from, 'to': list_to}, 'boxarts', '_342x192', 'jpg'],
['search', encoded_search_string, 'titles', ['id', 'length', 'name', 'trackIds', 'requestId']],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', {'from': list_from, 'to': list_to}, ['summary', 'title']],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', {'from': list_from, 'to': list_to}, 'boxarts', '_342x192', 'jpg'],
['search', encoded_search_string, 'suggestions', 0, 'relatedvideos', ['id', 'length', 'name', 'trackIds', 'requestId']]
]

response = self._path_request(paths=paths)
res = self._process_response(response=response, component='Kids lists')
return self.parse_video_list_ids(response_data=res['value'])
return self._process_response(response=response, component='Search results')

def fetch_video_list (self, list_id, list_from=0, list_to=20):
"""Fetches the JSON which contains the contents of a given video list
Expand Down

0 comments on commit 8181622

Please sign in to comment.