def extract_session_data(content, validate=False, update_profiles=False): """ Call all the parsers we need to extract all the session relevant data from the HTML page """ common.debug('Extracting session data...') react_context = extract_json(content, 'reactContext') if validate: validate_login(react_context) user_data = extract_userdata(react_context) _check_membership_status(user_data.get('membershipStatus')) api_data = extract_api_data(react_context) # Note: Falcor cache does not exist if membershipStatus is not CURRENT_MEMBER falcor_cache = extract_json(content, 'falcorCache') if update_profiles: parse_profiles(falcor_cache) # 21/05/2020 - Netflix has introduced a new paging type called "loco" similar to the old "lolomo" # Extract loco root id loco_root = falcor_cache['loco']['value'][1] G.LOCAL_DB.set_value('loco_root_id', loco_root, TABLE_SESSION) # Save only some info of the current profile from user data G.LOCAL_DB.set_value('build_identifier', user_data.get('BUILD_IDENTIFIER'), TABLE_SESSION) if not G.LOCAL_DB.get_value('esn', table=TABLE_SESSION): G.LOCAL_DB.set_value('esn', common.generate_android_esn() or user_data['esn'], TABLE_SESSION) G.LOCAL_DB.set_value('locale_id', user_data.get('preferredLocale').get('id', 'en-US')) # Extract the client version from assets core result = search(r'-([0-9\.]+)\.js$', api_data.pop('asset_core')) if not result: common.error('It was not possible to extract the client version!') api_data['client_version'] = '6.0023.976.011' else: api_data['client_version'] = result.groups()[0] # Save api urls for key, path in list(api_data.items()): G.LOCAL_DB.set_value(key, path, TABLE_SESSION) return api_data
def _esn_checks(): # Check if the custom esn is changed custom_esn = g.ADDON.getSetting('esn') custom_esn_old = g.LOCAL_DB.get_value('custom_esn', '', TABLE_SETTINGS_MONITOR) if custom_esn != custom_esn_old: g.LOCAL_DB.set_value('custom_esn', custom_esn, TABLE_SETTINGS_MONITOR) common.send_signal(signal=common.Signals.ESN_CHANGED) if not custom_esn: # Check if "Force identification as L3 Widevine device" is changed (ANDROID ONLY) is_l3_forced = bool(g.ADDON.getSettingBool('force_widevine_l3')) is_l3_forced_old = g.LOCAL_DB.get_value('force_widevine_l3', False, TABLE_SETTINGS_MONITOR) if is_l3_forced != is_l3_forced_old: g.LOCAL_DB.set_value('force_widevine_l3', is_l3_forced, TABLE_SETTINGS_MONITOR) # If user has changed setting is needed clear previous ESN and perform a new handshake with the new one g.LOCAL_DB.set_value('esn', common.generate_android_esn() or '', TABLE_SESSION) common.send_signal(signal=common.Signals.ESN_CHANGED)
def extract_session_data(content, validate=False, update_profiles=False): """ Call all the parsers we need to extract all the session relevant data from the HTML page """ common.debug('Extracting session data...') react_context = extract_json(content, 'reactContext') if validate: validate_login(react_context) user_data = extract_userdata(react_context) if user_data.get('membershipStatus') == 'ANONYMOUS': # Possible known causes: # -Login password has been changed # -In the login request, 'Content-Type' specified is not compliant with data passed or no more supported # -Expired profiles cookies!? (not verified) # In these cases it is mandatory to login again raise InvalidMembershipStatusAnonymous if user_data.get('membershipStatus') != 'CURRENT_MEMBER': # When NEVER_MEMBER it is possible that the account has not been confirmed or renewed common.error('Can not login, the Membership status is {}', user_data.get('membershipStatus')) raise InvalidMembershipStatusError(user_data.get('membershipStatus')) api_data = extract_api_data(react_context) # Note: Falcor cache does not exist if membershipStatus is not CURRENT_MEMBER falcor_cache = extract_json(content, 'falcorCache') if update_profiles: parse_profiles(falcor_cache) if common.is_debug_verbose(): # Only for debug purpose not sure if can be useful try: common.debug( 'ReactContext profileGateState {} ({})', PROFILE_GATE_STATES[ react_context['models']['profileGateState']['data']], react_context['models']['profileGateState']['data']) except KeyError: common.error('ReactContext unknown profileGateState {}', react_context['models']['profileGateState']['data']) # Profile idle timeout (not sure if will be useful, to now for documentation purpose) # NOTE: On the website this value is used to update the profilesNewSession cookie expiration after a profile switch # and also to update the expiration of this cookie on each website interaction. # When the session is expired the 'profileGateState' will be 0 and the website return auto. to profiles page # g.LOCAL_DB.set_value('profile_gate_idle_timer', user_data.get('idle_timer', 30), TABLE_SESSION) # 21/05/2020 - Netflix has introduced a new paging type called "loco" similar to the old "lolomo" # Extract loco root id loco_root = falcor_cache['loco']['value'][1] g.LOCAL_DB.set_value('loco_root_id', loco_root, TABLE_SESSION) # Check if the profile session is still active # (when a session expire in the website, the screen return automatically to the profiles page) is_profile_session_active = 'componentSummary' in falcor_cache['locos'][ loco_root] # Extract loco root request id if is_profile_session_active: component_summary = falcor_cache['locos'][loco_root][ 'componentSummary']['value'] # Note: 18/06/2020 now the request id is the equal to reactContext models/serverDefs/data/requestId g.LOCAL_DB.set_value('loco_root_requestid', component_summary['requestId'], TABLE_SESSION) else: g.LOCAL_DB.set_value('loco_root_requestid', '', TABLE_SESSION) # Extract loco continueWatching id and index # The following commented code was needed for update_loco_context in api_requests.py, but currently # seem not more required to update the continueWatching list then we keep this in case of future nf changes # -- INIT -- # cw_list_data = jgraph_get('continueWatching', falcor_cache['locos'][loco_root], falcor_cache) # if cw_list_data: # context_index = falcor_cache['locos'][loco_root]['continueWatching']['value'][2] # g.LOCAL_DB.set_value('loco_continuewatching_index', context_index, TABLE_SESSION) # g.LOCAL_DB.set_value('loco_continuewatching_id', # jgraph_get('componentSummary', cw_list_data)['id'], TABLE_SESSION) # elif is_profile_session_active: # # Todo: In the new profiles, there is no 'continueWatching' context # # How get or generate the continueWatching context? # # NOTE: it was needed for update_loco_context in api_requests.py # cur_profile = jgraph_get_path(['profilesList', 'current'], falcor_cache) # common.warn('Context continueWatching not found in locos for profile guid {}.', # jgraph_get('summary', cur_profile)['guid']) # g.LOCAL_DB.set_value('loco_continuewatching_index', '', TABLE_SESSION) # g.LOCAL_DB.set_value('loco_continuewatching_id', '', TABLE_SESSION) # else: # common.warn('Is not possible to find the context continueWatching, the profile session is no more active') # g.LOCAL_DB.set_value('loco_continuewatching_index', '', TABLE_SESSION) # g.LOCAL_DB.set_value('loco_continuewatching_id', '', TABLE_SESSION) # -- END -- # Save only some info of the current profile from user data g.LOCAL_DB.set_value('build_identifier', user_data.get('BUILD_IDENTIFIER'), TABLE_SESSION) if not g.LOCAL_DB.get_value('esn', table=TABLE_SESSION): g.LOCAL_DB.set_value('esn', common.generate_android_esn() or user_data['esn'], TABLE_SESSION) g.LOCAL_DB.set_value('locale_id', user_data.get('preferredLocale').get('id', 'en-US')) # Save api urls for key, path in list(api_data.items()): g.LOCAL_DB.set_value(key, path, TABLE_SESSION) api_data['is_profile_session_active'] = is_profile_session_active return api_data
def extract_session_data(content, validate=False, update_profiles=False): """ Call all the parsers we need to extract all the session relevant data from the HTML page """ common.debug('Extracting session data...') react_context = extract_json(content, 'reactContext') if validate: validate_login(react_context) user_data = extract_userdata(react_context) if user_data.get('membershipStatus') == 'ANONYMOUS': # Possible known causes: # -Login password has been changed # -In the login request, 'Content-Type' specified is not compliant with data passed or no more supported # -Expired profiles cookies!? (not verified) # In these cases it is mandatory to login again raise InvalidMembershipStatusAnonymous if user_data.get('membershipStatus') != 'CURRENT_MEMBER': # When NEVER_MEMBER it is possible that the account has not been confirmed or renewed common.error('Can not login, the Membership status is {}', user_data.get('membershipStatus')) raise InvalidMembershipStatusError(user_data.get('membershipStatus')) api_data = extract_api_data(react_context) # Note: Falcor cache does not exist if membershipStatus is not CURRENT_MEMBER falcor_cache = extract_json(content, 'falcorCache') if update_profiles: parse_profiles(falcor_cache) g.LOCAL_DB.set_value('is_loco_supported', user_data.get('isLocoSupported'), TABLE_SESSION) if user_data.get('isLocoSupported'): # 21/05/2020 - Netflix is introducing a new paging type called "loco", it is similar to "lolomo" # The lolomo data here is obtained by a separated request from update_lolomo_data in nfsession.py # Extract loco root id # NOTE: loco root ID is not same of lolomo root id loco_root = falcor_cache['loco']['value'][1] # g.LOCAL_DB.set_value('lolomo_root_id', loco_root, TABLE_SESSION) # Check if current 'profile session' is still active # Todo: 25/05/2020 - This not works, currently the "locos" list is always empty is_profile_session_active = 'componentSummary' in falcor_cache['locos'][loco_root] # Extract loco continueWatching id and index # Todo: 25/05/2020 - Without the "locos" list is not possible get this data here # g.LOCAL_DB.set_value('lolomo_continuewatching_index', '', TABLE_SESSION) # g.LOCAL_DB.set_value('lolomo_continuewatching_id', '', TABLE_SESSION) else: # Extract lolomo root id lolomo_root = falcor_cache['lolomo']['value'][1] g.LOCAL_DB.set_value('lolomo_root_id', lolomo_root, TABLE_SESSION) # Check if current 'profile session' is still active # What means 'profile session': # In web browser, after you select a profile and then you close the browse page, # when you reopen it you will not be asked to select a profile again, this means that the same profile session # still active, and the lolomo root id (and child contexts id's) are still the same. # Here one way to understand this, is checking if there is an 'summary' entry in the lolomos dictionary. is_profile_session_active = 'summary' in falcor_cache['lolomos'][lolomo_root] # Extract lolomo continueWatching id and index cw_list_data = jgraph_get('continueWatching', falcor_cache['lolomos'][lolomo_root], falcor_cache) if cw_list_data: context_index = falcor_cache['lolomos'][lolomo_root]['continueWatching']['value'][2] g.LOCAL_DB.set_value('lolomo_continuewatching_index', context_index, TABLE_SESSION) g.LOCAL_DB.set_value('lolomo_continuewatching_id', jgraph_get('id', cw_list_data), TABLE_SESSION) elif is_profile_session_active: # Todo: In the new profiles, there is no 'continueWatching' context # How get or generate the continueWatching context? # (needed to update lolomo list for watched state sync, see update_lolomo_context in api_requests.py) cur_profile = jgraph_get_path(['profilesList', 'current'], falcor_cache) common.warn('Context continueWatching not found in lolomos for profile guid {}.', jgraph_get('summary', cur_profile)['guid']) g.LOCAL_DB.set_value('lolomo_continuewatching_index', '', TABLE_SESSION) g.LOCAL_DB.set_value('lolomo_continuewatching_id', '', TABLE_SESSION) else: common.warn('Is not possible to find the context continueWatching, the profile session is no more active') # Save only some info of the current profile from user data g.LOCAL_DB.set_value('build_identifier', user_data.get('BUILD_IDENTIFIER'), TABLE_SESSION) if not g.LOCAL_DB.get_value('esn', table=TABLE_SESSION): g.LOCAL_DB.set_value('esn', common.generate_android_esn() or user_data['esn'], TABLE_SESSION) g.LOCAL_DB.set_value('locale_id', user_data.get('preferredLocale').get('id', 'en-US')) # Save api urls for key, path in list(api_data.items()): g.LOCAL_DB.set_value(key, path, TABLE_SESSION) api_data['is_profile_session_active'] = is_profile_session_active return api_data