Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from resources.lib.utils.api_paths import (VIDEO_LIST_PARTIAL_PATHS, RANGE_PLACEHOLDER, VIDEO_LIST_BASIC_PARTIAL_PATHS,
SEASONS_PARTIAL_PATHS, EPISODES_PARTIAL_PATHS, ART_PARTIAL_PATHS,
TRAILER_PARTIAL_PATHS, PATH_REQUEST_SIZE_STD, build_paths,
PATH_REQUEST_SIZE_MAX)
PATH_REQUEST_SIZE_MAX, jgraph_get)
from resources.lib.common import cache_utils
from resources.lib.globals import G
from resources.lib.utils.logging import LOG
Expand Down Expand Up @@ -55,16 +55,26 @@ def req_loco_list_root(self):
# - To get items for the main menu
# (when 'loco_known'==True and loco_contexts is set, see MAIN_MENU_ITEMS in globals.py)
# - To get list items for menus that have multiple contexts set to 'loco_contexts' like 'recommendations' menu
LOG.debug('Requesting LoCo root lists')
paths = ([['loco', 'componentSummary'],
['loco', {'from': 0, 'to': 50}, 'componentSummary'],
# Titles of first 4 videos in each video list (needed only to show titles in the plot description)
['loco', {'from': 0, 'to': 50}, {'from': 0, 'to': 3}, 'reference', ['title', 'summary']]] +
# Art for the first video of each context list (needed only to add art to the menu item)
build_paths(['loco', {'from': 0, 'to': 50}, 0, 'reference'], ART_PARTIAL_PATHS))
LOG.debug('Requesting LoCo\'s root ID')
paths = ([['loco', 'componentSummary']])
call_args = {'paths': paths}
path_response = self.nfsession.path_request(**call_args)
return LoCo(path_response)
loco_response = self.nfsession.path_request(**call_args)
loco_data = jgraph_get('loco', loco_response)
comp_data = jgraph_get('componentSummary', loco_data)
loco_id = comp_data.get('id')
if loco_id:
LOG.debug('Requesting LoCo root lists')
paths = ([['locos', loco_id, {'from': 0, 'to': 50}, 'componentSummary'],
# Titles of first 4 videos in each video list (needed only to show titles in the plot description)
['locos', loco_id, {'from': 0, 'to': 50}, {'from': 0, 'to': 3}, 'reference', ['title', 'summary']]])
# Art for the first video of each context list (needed only to add art to the menu item)
# + build_paths(['locos', loco_id, {'from': 0, 'to': 50}, 0, 'reference'], ART_PARTIAL_PATHS))
call_args = {'paths': paths}
path_response = self.nfsession.path_request(**call_args)
return LoCo(path_response)
else:
LOG.error('Cannot get the LoCo\'s root ID, response data: {}', loco_response)
return LoCo({})

@cache_utils.cache_output(cache_utils.CACHE_GENRES, identify_from_kwarg_name='genre_id', ignore_self_class=True)
def req_loco_list_genre(self, genre_id):
Expand Down Expand Up @@ -113,9 +123,9 @@ def req_seasons(self, videoid, perpetual_range_start):
raise InvalidVideoId(f'Cannot request season list for {videoid}')
LOG.debug('Requesting the seasons list for show {}', videoid)
call_args = {
'paths': (build_paths(['videos', videoid.tvshowid], SEASONS_PARTIAL_PATHS) +
build_paths(['videos', videoid.tvshowid], ART_PARTIAL_PATHS) +
[['videos', videoid.tvshowid, 'componentSummary']]),
'paths': (build_paths(['videos', videoid.tvshowid], SEASONS_PARTIAL_PATHS)),
#+ build_paths(['videos', videoid.tvshowid], ART_PARTIAL_PATHS) +
#[['videos', videoid.tvshowid, 'componentSummary']]),
'length_params': ['stdlist_wid', ['videos', videoid.tvshowid, 'seasonList']],
'perpetual_range_start': perpetual_range_start
}
Expand All @@ -130,9 +140,10 @@ def req_episodes(self, videoid, perpetual_range_start=None):
raise InvalidVideoId(f'Cannot request episode list for {videoid}')
LOG.debug('Requesting episode list for {}', videoid)
paths = ([['seasons', videoid.seasonid, 'summary']] +
[['seasons', videoid.seasonid, 'componentSummary']] +
build_paths(['seasons', videoid.seasonid, 'episodes', RANGE_PLACEHOLDER], EPISODES_PARTIAL_PATHS) +
build_paths(['videos', videoid.tvshowid], ART_PARTIAL_PATHS + [[['title', 'delivery']]]))
[['videos', videoid.tvshowid, ['title', 'delivery']]] +
#[['seasons', videoid.seasonid, 'componentSummary']] +
build_paths(['seasons', videoid.seasonid, 'episodes', RANGE_PLACEHOLDER], EPISODES_PARTIAL_PATHS))
# + build_paths(['videos', videoid.tvshowid], ART_PARTIAL_PATHS + [[['title', 'delivery']]]))
call_args = {
'paths': paths,
'length_params': ['stdlist_wid', ['seasons', videoid.seasonid, 'episodes']],
Expand Down
35 changes: 18 additions & 17 deletions resources/lib/services/nfsession/nfsession_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,28 @@ def activate_profile(self, guid):
# Change the current profile while a video is playing can cause problems with outgoing HTTP requests
# (MSL/NFSession) causing a failure in the HTTP request or sending data on the wrong profile
raise ErrorMsgNoReport('It is not possible select a profile while a video is playing.')
timestamp = time.time()
LOG.info('Activating profile {}', guid)
# 20/05/2020 - The method 1 not more working for switching PIN locked profiles

# INIT Method 1 - HTTP mode
# response = self._get('switch_profile', params={'tkn': guid})
# self.nfsession.auth_url = self.website_extract_session_data(response)['auth_url']
response = self.get_safe('switch_profile', params={'tkn': guid})
self.auth_url = self.website_extract_session_data(response)['auth_url']
# END Method 1
# INIT Method 2 - API mode
try:
response = self.get_safe(endpoint='activate_profile',
params={'switchProfileGuid': guid,
'_': int(timestamp * 1000),
'authURL': self.auth_url})
if response.get('status') != 'success':
raise InvalidProfilesError('Unable to access to the selected profile.')
except HttpError401 as exc:
# Profile guid not more valid
raise InvalidProfilesError('Unable to access to the selected profile.') from exc

# INIT Method 2 - API mode **** 07/2026 not working anymore ****
# try:
# timestamp = time.time()
# response = self.get_safe(endpoint='activate_profile',
# params={'switchProfileGuid': guid,
# '_': int(timestamp * 1000),
# 'authURL': self.auth_url})
# if response.get('status') != 'success':
# raise InvalidProfilesError('Unable to access to the selected profile.')
# except HttpError401 as exc:
# # Profile guid not more valid
# raise InvalidProfilesError('Unable to access to the selected profile.') from exc
# Retrieve browse page to update authURL
response = self.get_safe('browse')
self.auth_url = website.extract_session_data(response)['auth_url']
# response = self.get_safe('browse')
# self.auth_url = website.extract_session_data(response)['auth_url']
# END Method 2

G.LOCAL_DB.switch_active_profile(guid)
Expand Down
13 changes: 7 additions & 6 deletions resources/lib/services/nfsession/session/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,13 @@
'use_default_params': False,
'add_auth_url': None,
'accept': '*/*'},
'activate_profile':
{'address': '/api/shakti/mre/profiles/switch',
'is_api_call': False,
'use_default_params': False,
'add_auth_url': None,
'accept': '*/*'},
# **** 07/2026 not working anymore ****
# 'activate_profile':
# {'address': '/api/shakti/mre/profiles/switch',
# 'is_api_call': False,
# 'use_default_params': False,
# 'add_auth_url': None,
# 'accept': '*/*'},
'profile_lock':
{'address': '/api/shakti/mre/profileLock',
'is_api_call': False,
Expand Down
3 changes: 0 additions & 3 deletions resources/lib/services/nfsession/session/http_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ def _prepare_request_properties(self, endpoint_conf, kwargs):
'falcor_server': '0.1.0',
'withSize': 'false',
'materialize': 'false',
'routeAPIRequestsThroughFTL': 'false',
'isVolatileBillboardsEnabled': 'true',
'isTop10Supported': 'true',
'original_path': '/shakti/mre/pathEvaluator'
}
if endpoint_conf['add_auth_url'] == 'to_params':
Expand Down
32 changes: 16 additions & 16 deletions resources/lib/utils/api_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
LENGTH_ATTRIBUTES = {
'stdlist': lambda r, context, key: jgrapgh_len(r[context][key]),
'stdlist_wid': lambda r, context, uid, key: jgrapgh_len(r[context][uid][key]),
'searchlist': lambda r, context, key: len(list(r[context][key].values())[0]),

Check warning on line 32 in resources/lib/utils/api_paths.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLr3d5Z0uswiLj_ER&open=AZ9MLr3d5Z0uswiLj_ER&pullRequest=1796
'videoslist': lambda r, list_name: jgrapgh_len(r[list_name])
}

"""Predefined lambda expressions that return the number of video results within a path response dict"""

ART_PARTIAL_PATHS = [
ART_PARTIAL_PATHS = [ # art moved to graphql endpoint
['boxarts', [ART_SIZE_SD, ART_SIZE_FHD, ART_SIZE_POSTER], 'jpg', 'value'],
['interestingMoment', [ART_SIZE_SD, ART_SIZE_FHD], 'jpg', 'value'],
['artWorkByType', 'LOGO_BRANDED_HORIZONTAL', '_550x124', 'png', 'value'], # 11/05/2020 same img of bb2OGLogo
Expand All @@ -48,16 +48,16 @@


VIDEO_LIST_PARTIAL_PATHS = [
[['requestId', 'summary', 'title', 'synopsis', 'regularSynopsis', 'evidence', 'queue', 'inRemindMeList',
'episodeCount', 'info', 'maturity', 'runtime', 'seasonCount', 'availability', 'trackIds',
[['summary', 'title', 'synopsis', 'queue', 'inRemindMeList',
'episodeCount', 'maturity', 'runtime', 'seasonCount', 'availability', 'trackIds',
'releaseYear', 'userRating', 'numSeasonsLabel', 'bookmarkPosition', 'creditsOffset',
'dpSupplementalMessage', 'watched', 'delivery', 'sequiturEvidence', 'promoVideo', 'availability', 'itemSummary']],
[['genres', 'tags', 'creators', 'directors', 'cast'],
{'from': 0, 'to': 10}, ['id', 'name']]
] + ART_PARTIAL_PATHS
'delivery', 'availability', 'itemSummary']]
#,[['genres', 'tags', 'creators', 'directors', 'cast'],
# {'from': 0, 'to': 10}, ['id', 'name']]
]# + ART_PARTIAL_PATHS

VIDEO_LIST_BASIC_PARTIAL_PATHS = [
[['title', 'queue', 'watched', 'summary', 'type', 'id']]
[['queue', 'summary']]
]

GENRE_PARTIAL_PATHS = [
Expand All @@ -70,20 +70,20 @@
SEASONS_PARTIAL_PATHS = [
['seasonList', RANGE_PLACEHOLDER, 'summary'],
['title']
] + ART_PARTIAL_PATHS
]# + ART_PARTIAL_PATHS

EPISODES_PARTIAL_PATHS = [
[['requestId', 'summary', 'synopsis', 'regularSynopsis', 'title', 'runtime', 'releaseYear', 'queue',
'info', 'maturity', 'userRating', 'bookmarkPosition', 'creditsOffset',
'watched', 'delivery', 'trackIds', 'availability']],
[['genres', 'tags', 'creators', 'directors', 'cast'],
[['summary', 'synopsis', 'title', 'runtime', 'releaseYear', 'queue',
'maturity', 'userRating', 'bookmarkPosition', 'creditsOffset',
'delivery', 'trackIds', 'availability']],
[['genres', 'creators', 'directors', 'cast'],
{'from': 0, 'to': 10}, ['id', 'name']]
] + ART_PARTIAL_PATHS
]# + ART_PARTIAL_PATHS

TRAILER_PARTIAL_PATHS = [
[['availability', 'summary', 'synopsis', 'regularSynopsis', 'title', 'trackIds', 'delivery', 'runtime',
[['availability', 'summary', 'synopsis', 'title', 'trackIds', 'delivery', 'runtime',
'bookmarkPosition', 'creditsOffset']]
] + ART_PARTIAL_PATHS
]# + ART_PARTIAL_PATHS

EVENT_PATHS = [
[['requestId', 'title', 'runtime', 'queue', 'bookmarkPosition', 'watched', 'trackIds']]
Expand Down
14 changes: 7 additions & 7 deletions resources/lib/utils/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
# Set first videos titles (special handling for menus see parse_info in infolabels.py)
self.contained_titles = _get_titles(self.videos)
# Set art data of first video (special handling for menus see parse_info in infolabels.py)
self.artitem = list(self.videos.values())[0]

Check warning on line 90 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EI&open=AZ9MLryX5Z0uswiLj_EI&pullRequest=1796
self.component_summary = {}

def __getitem__(self, key):
Expand Down Expand Up @@ -120,7 +120,7 @@
self.videos = OrderedDict(resolve_refs(self.data['lists'][self.videoid.value], self.data))
if self.videos:
# self.artitem = next(self.videos.values())
self.artitem = list(self.videos.values())[0]

Check warning on line 123 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EJ&open=AZ9MLryX5Z0uswiLj_EJ&pullRequest=1796
self.contained_titles = _get_titles(self.videos)

def __getitem__(self, key):
Expand Down Expand Up @@ -157,7 +157,7 @@
self.videos = OrderedDict(resolve_refs(self.data_lists, self.data))
if self.videos:
# self.artitem = next(self.videos.values())
self.artitem = list(self.videos.values())[0]

Check warning on line 160 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EK&open=AZ9MLryX5Z0uswiLj_EK&pullRequest=1796
self.contained_titles = _get_titles(self.videos)

def __getitem__(self, key):
Expand Down Expand Up @@ -189,10 +189,10 @@
first_list_id = next(iter(self.data['search']['byReference']))
self.component_summary = {
'trackIds': self.data['search']['byReference'][first_list_id]['trackIds'].get('value', {})}
self.title = common.get_local_string(30100).format(list(self.data['search']['byTerm'])[0][1:])

Check warning on line 192 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EL&open=AZ9MLryX5Z0uswiLj_EL&pullRequest=1796
self.videos = OrderedDict(resolve_refs(self.data['search']['byReference'][first_list_id], self.data))
# self.artitem = next(self.videos.values(), None)
self.artitem = list(self.videos.values())[0] if self.videos else None

Check warning on line 195 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EM&open=AZ9MLryX5Z0uswiLj_EM&pullRequest=1796
self.contained_titles = _get_titles(self.videos)

def __getitem__(self, key):
Expand All @@ -210,7 +210,7 @@
self.data = path_response
self.videos = OrderedDict(self.data.get('videos', {}))
# self.artitem = next(self.videos.values())
self.artitem = list(self.videos.values())[0] if self.videos else None

Check warning on line 213 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EN&open=AZ9MLryX5Z0uswiLj_EN&pullRequest=1796
self.contained_titles = _get_titles(self.videos)

def __getitem__(self, key):
Expand All @@ -228,7 +228,7 @@
self.perpetual_range_selector = path_response.get('_perpetual_range_selector')
self.data = path_response
self.videos = OrderedDict(self.data.get('videos', {}))
self.artitem = list(self.videos.values())[0] if self.videos else None

Check warning on line 231 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "list(...)[0]" with "next(iter(...))" to avoid materializing the entire iterable.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EO&open=AZ9MLryX5Z0uswiLj_EO&pullRequest=1796
self.contained_titles = _get_titles(self.videos)

track_ids = common.get_path_safe(list_info_path, path_response, False, {}).get('trackIds')
Expand Down Expand Up @@ -333,12 +333,12 @@
if _get_title(video)]


def _filterout_loco_contexts(root_id, data, contexts):

Check warning on line 336 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "root_id".

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EP&open=AZ9MLryX5Z0uswiLj_EP&pullRequest=1796
"""Deletes from the data all records related to the specified contexts"""
total_items = data['locos'][root_id]['componentSummary'].get('value', {}).get('length', 0)
for index in range(total_items - 1, -1, -1):
list_id = data['locos'][root_id][str(index)]['value'][1]
if not data['lists'][list_id]['componentSummary'].get('value', {}).get('context') in contexts:
continue
del data['lists'][list_id]
del data['locos'][root_id][str(index)]
if not data:
return
lists = data['lists']
for key in list(lists.keys()):

Check warning on line 341 in resources/lib/utils/data_types.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unnecessary `list()` call on an already iterable object.

See more on https://sonarcloud.io/project/issues?id=CastagnaIT_plugin.video.netflix&issues=AZ9MLryX5Z0uswiLj_EQ&open=AZ9MLryX5Z0uswiLj_EQ&pullRequest=1796
context = lists[key].get('componentSummary', {}).get('value', {}).get('context')
if context in contexts:
del lists[key]
Loading