def extract_parental_control_data(content, current_maturity): """Extract the content of parental control data""" try: react_context = extract_json(content, 'reactContext') # Extract country max maturity value max_maturity = common.get_path(['models', 'parentalControls', 'data', 'accountProps', 'countryMaxMaturity'], react_context) # Extract rating levels rc_rating_levels = common.get_path(['models', 'memberContext', 'data', 'userInfo', 'ratingLevels'], react_context) rating_levels = [] levels_count = len(rc_rating_levels) - 1 current_level_index = levels_count for index, rating_level in enumerate(rc_rating_levels): if index == levels_count: # Last level must use the country max maturity level level_value = max_maturity else: level_value = int(rating_level['level']) rating_levels.append({'level': index, 'value': level_value, 'label': rating_level['labels'][0]['label'], 'description': parse_html(rating_level['labels'][0]['description'])}) if level_value == current_maturity: current_level_index = index except KeyError as exc: raise_from(WebsiteParsingError('Unable to get path in to reactContext data'), exc) if not rating_levels: raise WebsiteParsingError('Unable to get maturity rating levels') return {'rating_levels': rating_levels, 'current_level_index': current_level_index}
def validate_login(content): react_context = extract_json(content, 'reactContext') path_code_list = [ path_item for path_item in PAGE_ITEM_ERROR_CODE_LIST.split('\\') ] path_error_code = [ path_item for path_item in PAGE_ITEM_ERROR_CODE.split('/') ] if common.check_path_exists(path_error_code, react_context): # If the path exists, a login error occurs try: error_code_list = common.get_path(path_code_list, react_context) error_code = common.get_path(path_error_code, react_context) common.debug('Login not valid, error code {}'.format(error_code)) error_description = common.get_local_string(30102) + error_code if error_code in error_code_list: error_description = error_code_list[error_code] if 'email_' + error_code in error_code_list: error_description = error_code_list['email_' + error_code] if 'login_' + error_code in error_code_list: error_description = error_code_list['login_' + error_code] return common.remove_html_tags(error_description) except (AttributeError, KeyError): common.error( 'Something is wrong in PAGE_ITEM_ERROR_CODE or PAGE_ITEM_ERROR_CODE_LIST paths.' 'react_context data may have changed.') raise LoginValidateError return None
def validate_login(react_context): path_code_list = PAGE_ITEM_ERROR_CODE_LIST.split('\\') path_error_code = PAGE_ITEM_ERROR_CODE.split('/') if common.check_path_exists(path_error_code, react_context): # If the path exists, a login error occurs try: error_code_list = common.get_path(path_code_list, react_context) error_code = common.get_path(path_error_code, react_context) common.error('Login not valid, error code {}', error_code) error_description = common.get_local_string(30102) + error_code if error_code in error_code_list: error_description = error_code_list[error_code] if 'email_' + error_code in error_code_list: error_description = error_code_list['email_' + error_code] if 'login_' + error_code in error_code_list: error_description = error_code_list['login_' + error_code] if 'incorrect_password' in error_code: raise LoginValidateErrorIncorrectPassword(common.remove_html_tags(error_description)) raise LoginValidateError(common.remove_html_tags(error_description)) except (AttributeError, KeyError): import traceback common.error(traceback.format_exc()) error_msg = ( 'Something is wrong in PAGE_ITEM_ERROR_CODE or PAGE_ITEM_ERROR_CODE_LIST paths.' 'react_context data may have changed.') common.error(error_msg) raise LoginValidateError(error_msg)
def validate_login(react_context): path_code_list = PAGE_ITEM_ERROR_CODE_LIST.split('\\') path_error_code = PAGE_ITEM_ERROR_CODE.split('/') if common.check_path_exists(path_error_code, react_context): # If the path exists, a login error occurs try: error_code_list = common.get_path(path_code_list, react_context) error_code = common.get_path(path_error_code, react_context) LOG.error('Login not valid, error code {}', error_code) error_description = common.get_local_string(30102) + error_code if error_code in error_code_list: error_description = error_code_list[error_code] if 'email_' + error_code in error_code_list: error_description = error_code_list['email_' + error_code] if 'login_' + error_code in error_code_list: error_description = error_code_list['login_' + error_code] raise LoginValidateError(common.remove_html_tags(error_description)) except (AttributeError, KeyError) as exc: import traceback LOG.error(G.py2_decode(traceback.format_exc(), 'latin-1')) error_msg = ( 'Something is wrong in PAGE_ITEM_ERROR_CODE or PAGE_ITEM_ERROR_CODE_LIST paths.' 'react_context data may have changed.') LOG.error(error_msg) raise_from(WebsiteParsingError(error_msg), exc)
def _get_avatar(profiles_list_data, profile): try: return common.get_path(profile['avatar'] + AVATAR_SUBPATH, profiles_list_data) except (KeyError, TypeError): common.warn('Cannot find avatar for profile {}', profile['summary']['guid']) common.debug('Profile list data: {}', profiles_list_data) return g.ICON
def _get_avatar(falkor_cache, profile): try: profile['avatar']['value'].extend(AVATAR_SUBPATH) return common.get_path(profile['avatar']['value'], falkor_cache) except KeyError: common.warn('Cannot find avatar for profile {guid}'.format( guid=profile['summary']['value']['guid'])) return ''
def extract_api_data(react_context): """Extract api urls from the reactContext of the webpage""" common.debug('Extracting api urls from webpage') api_data = {} for key, value in PAGE_ITEMS_API_URL.items(): path = [path_item for path_item in value.split('/')] try: extracted_value = {key: common.get_path(path, react_context)} api_data.update(extracted_value) common.debug('Extracted {}'.format(extracted_value)) except (AttributeError, KeyError): common.debug('Could not extract {}'.format(path)) return assert_valid_auth_url(api_data)
def extract_userdata(react_context): """Extract essential userdata from the reactContext of the webpage""" common.debug('Extracting userdata from webpage') user_data = {} for path in ([path_item for path_item in path.split('/')] for path in PAGE_ITEMS_INFO): try: extracted_value = {path[-1]: common.get_path(path, react_context)} user_data.update(extracted_value) common.debug('Extracted {}'.format(extracted_value)) except (AttributeError, KeyError): common.debug('Could not extract {}'.format(path)) return user_data
def extract_api_data(react_context, debug_log=True): """Extract api urls from the reactContext of the webpage""" common.debug('Extracting api urls from webpage') api_data = {} for key, value in list(PAGE_ITEMS_API_URL.items()): path = value.split('/') try: extracted_value = {key: common.get_path(path, react_context)} api_data.update(extracted_value) if debug_log: common.debug('Extracted {}', extracted_value) except (AttributeError, KeyError): common.error('Could not extract {}', path) return assert_valid_auth_url(api_data)
def extract_userdata(react_context, debug_log=True): """Extract essential userdata from the reactContext of the webpage""" common.debug('Extracting userdata from webpage') user_data = {} for path in (path.split('/') for path in PAGE_ITEMS_INFO): try: extracted_value = {path[-1]: common.get_path(path, react_context)} user_data.update(extracted_value) if 'esn' not in path and debug_log: common.debug('Extracted {}', extracted_value) except (AttributeError, KeyError): common.error('Could not extract {}', path) return user_data
def extract_userdata(content): """Extract essential userdata from the reactContext of the webpage""" common.debug('Extracting userdata from webpage') user_data = {} react_context = extract_json(content, 'reactContext') for path in ([path_item for path_item in path.split('/')] for path in PAGE_ITEMS): try: user_data.update({path[-1]: common.get_path(path, react_context)}) common.debug('Extracted {}'.format(path)) except (AttributeError, KeyError): common.debug('Could not extract {}'.format(path)) return assert_valid_auth_url(user_data)
def _get_library_entry(videoid): """Get the first leaf-entry for videoid from the library. For shows and seasons this will return the first contained episode""" if videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE]: return (common.get_path(videoid.to_list(), g.library()), videoid.mediatype) elif videoid.mediatype == common.VideoId.SHOW: return (_any_child_library_entry( _any_child_library_entry(g.library()[videoid.tvshowid])), common.VideoId.EPISODE) elif videoid.mediatype == common.VideoId.SEASON: return (_any_child_library_entry( g.library()[videoid.tvshowid][videoid.seasonid]), common.VideoId.EPISODE) else: # Items of other mediatype are never in library raise ItemNotFound
def remove_item(item_task, library_home=None): """Remove an item from the library and delete if from disk""" # pylint: disable=unused-argument, broad-except if item_task[ 'is_strm']: # We don't take care of a tvshow.nfo task if we are running an update common.debug('Removing {} from library'.format(item_task['title'])) if not is_in_library(item_task['videoid']): common.warn('cannot remove {}, item not in library'.format( item_task['title'])) return id_path = item_task['videoid'].to_list() exported_filename = xbmc.translatePath( common.get_path(id_path, g.library())['file']).decode("utf-8") parent_folder = os.path.dirname(exported_filename) try: xbmcvfs.delete( xbmc.translatePath(exported_filename).decode("utf-8")) # Remove the NFO files if exists nfo_file = os.path.splitext( xbmc.translatePath(exported_filename).decode( "utf-8"))[0] + '.nfo' if xbmcvfs.exists(nfo_file): xbmcvfs.delete(nfo_file) dirs, files = xbmcvfs.listdir( xbmc.translatePath(parent_folder).decode("utf-8")) tvshow_nfo_file = xbmc.makeLegalFilename( os.path.join( xbmc.translatePath(parent_folder).decode("utf-8"), 'tvshow.nfo')) # Remove tvshow_nfo_file only when is the last file (users have the option of removing even single seasons) if xbmcvfs.exists(tvshow_nfo_file) and not dirs and len( files) == 1: xbmcvfs.delete(tvshow_nfo_file) # Delete parent folder xbmcvfs.rmdir( xbmc.translatePath(parent_folder).decode("utf-8")) # Delete parent folder when empty if not dirs and not files: xbmcvfs.rmdir( xbmc.translatePath(parent_folder).decode("utf-8")) except Exception: common.debug('Cannot delete {}, file does not exist'.format( exported_filename)) common.remove_path(id_path, g.library(), lambda e: e.keys() == ['videoid']) g.save_library()
def remove_item(item_task, library_home=None): """Remove an item from the library and delete if from disk""" # pylint: disable=unused-argument, broad-except common.debug('Removing {} from library'.format(item_task['title'])) if not is_in_library(item_task['videoid']): common.warn('cannot remove {}, item not in library'.format( item_task['title'])) return id_path = item_task['videoid'].to_list() exported_filename = xbmc.translatePath( common.get_path(id_path, g.library())['file']).decode("utf-8") parent_folder = os.path.dirname(exported_filename) try: xbmcvfs.delete(xbmc.translatePath(exported_filename).decode("utf-8")) if not os.listdir(parent_folder): os.rmdir(parent_folder) except Exception: common.debug( 'Cannot delete {}, file does not exist'.format(exported_filename)) common.remove_path(id_path, g.library(), lambda e: e.keys() == ['videoid']) g.save_library()
def resolve_refs(references, targets): """Return a generator expression that returns the objects in targets by resolving the references in sorted order""" return (common.get_path(ref, targets, include_key=True) for index, ref in iterate_references(references))