Beispiel #1
0
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}
Beispiel #2
0
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)
Beispiel #3
0
def extract_json(content, name):
    """Extract json from netflix content page"""
    LOG.debug('Extracting {} JSON', name)
    json_str = None
    try:
        json_array = recompile(JSON_REGEX.format(name),
                               DOTALL).findall(content.decode('utf-8'))
        json_str = json_array[0]
        json_str_replace = json_str.replace(r'\"', r'\\"')  # Escape \"
        json_str_replace = json_str_replace.replace(
            r'\s', r'\\s')  # Escape whitespace
        json_str_replace = json_str_replace.replace(r'\r',
                                                    r'\\r')  # Escape return
        json_str_replace = json_str_replace.replace(r'\n',
                                                    r'\\n')  # Escape line feed
        json_str_replace = json_str_replace.replace(r'\t',
                                                    r'\\t')  # Escape tab
        json_str_replace = json_str_replace.encode().decode(
            'unicode_escape')  # Decode the string as unicode
        json_str_replace = sub(
            r'\\(?!["])', r'\\\\', json_str_replace
        )  # Escape backslash (only when is not followed by double quotation marks \")
        return json.loads(json_str_replace)
    except Exception as exc:  # pylint: disable=broad-except
        if json_str:
            # For testing purposes remember to add raw prefix to the string to test: json_str = r'string to test'
            LOG.error('JSON string trying to load: {}', json_str)
        import traceback
        LOG.error(traceback.format_exc())
        raise WebsiteParsingError('Unable to extract {}'.format(name)) from exc
def extract_json(content, name):
    """Extract json from netflix content page"""
    LOG.debug('Extracting {} JSON', name)
    json_str = None
    try:
        json_array = recompile(JSON_REGEX.format(name),
                               DOTALL).findall(content.decode('utf-8'))
        json_str = json_array[0]
        json_str_replace = json_str.replace('\\"',
                                            '\\\\"')  # Escape double-quotes
        json_str_replace = json_str_replace.replace('\\s',
                                                    '\\\\s')  # Escape \s
        json_str_replace = json_str_replace.replace(
            '\\n', '\\\\n')  # Escape line feed
        json_str_replace = json_str_replace.replace('\\t',
                                                    '\\\\t')  # Escape tab
        json_str_replace = json_str_replace.encode().decode(
            'unicode_escape')  # Decode the string as unicode
        json_str_replace = sub(
            r'\\(?!["])', r'\\\\', json_str_replace
        )  # Escape backslash (only when is not followed by double quotation marks \")
        return json.loads(json_str_replace)
    except Exception as exc:  # pylint: disable=broad-except
        if json_str:
            LOG.error('JSON string trying to load: {}', json_str)
        import traceback
        LOG.error(G.py2_decode(traceback.format_exc(), 'latin-1'))
        raise_from(WebsiteParsingError('Unable to extract {}'.format(name)),
                   exc)
 def login_auth_data(self, data=None, password=None):
     """Perform account login with authentication data"""
     from requests import exceptions
     LOG.debug('Logging in with authentication data')
     # Add the cookies to the session
     self.session.cookies.clear()
     for cookie in data['cookies']:
         self.session.cookies.set(cookie[0], cookie[1], **cookie[2])
     cookies.log_cookie(self.session.cookies)
     # Try access to website
     try:
         website.extract_session_data(self.get('browse'),
                                      validate=True,
                                      update_profiles=True)
     except MbrStatusAnonymousError:
         # Access not valid
         return False
     # Get the account e-mail
     page_response = self.get('your_account').decode('utf-8')
     email_match = re.search(r'account-email[^<]+>([^<]+@[^</]+)</',
                             page_response)
     email = email_match.group(1).strip() if email_match else None
     if not email:
         raise WebsiteParsingError('E-mail field not found')
     # Verify the password (with parental control api)
     try:
         response = self.post_safe('profile_hub',
                                   data={
                                       'destination':
                                       'contentRestrictions',
                                       'guid':
                                       G.LOCAL_DB.get_active_profile_guid(),
                                       'password':
                                       password,
                                       'task':
                                       'auth'
                                   })
         if response.get('status') != 'ok':
             raise LoginError(common.get_local_string(
                 12344))  # 12344=Passwords entered did not match.
     except exceptions.HTTPError as exc:
         if exc.response.status_code == 500:
             # This endpoint raise HTTP error 500 when the password is wrong
             raise LoginError(common.get_local_string(12344)) from exc
         raise
     common.set_credentials({'email': email, 'password': password})
     LOG.info('Login successful')
     ui.show_notification(common.get_local_string(30109))
     cookies.save(self.session.cookies)
     return True
Beispiel #6
0
 def login_auth_data(self, data=None, password=None):
     """Perform account login with authentication data"""
     LOG.debug('Logging in with authentication data')
     # Add the cookies to the session
     self.session.cookies.clear()
     for cookie in data['cookies']:
         # The code below has been adapted from httpx.Cookies.set() method
         kwargs = {
             'version': 0,
             'name': cookie['name'],
             'value': cookie['value'],
             'port': None,
             'port_specified': False,
             'domain': cookie['domain'],
             'domain_specified': bool(cookie['domain']),
             'domain_initial_dot': cookie['domain'].startswith('.'),
             'path': cookie['path'],
             'path_specified': bool(cookie['path']),
             'secure': cookie['secure'],
             'expires': cookie['expires'],
             'discard': True,
             'comment': None,
             'comment_url': None,
             'rest': cookie['rest'],
             'rfc2109': False,
         }
         cookie = Cookie(**kwargs)
         self.session.cookies.jar.set_cookie(cookie)
     cookies.log_cookie(self.session.cookies.jar)
     # Try access to website
     try:
         website.extract_session_data(self.get('browse'),
                                      validate=True,
                                      update_profiles=True)
     except MbrStatusAnonymousError:
         # Access not valid
         return False
     # Get the account e-mail
     page_response = self.get('your_account').decode('utf-8')
     email_match = re.search(r'account-email[^<]+>([^<]+@[^</]+)</',
                             page_response)
     email = email_match.group(1).strip() if email_match else None
     if not email:
         raise WebsiteParsingError('E-mail field not found')
     # Verify the password (with parental control api)
     try:
         response = self.post_safe('profile_hub',
                                   data={
                                       'destination':
                                       'contentRestrictions',
                                       'guid':
                                       G.LOCAL_DB.get_active_profile_guid(),
                                       'password':
                                       password,
                                       'task':
                                       'auth'
                                   })
         if response.get('status') != 'ok':
             raise LoginError(common.get_local_string(
                 12344))  # 12344=Passwords entered did not match.
     except httpx.HTTPStatusError as exc:
         if exc.response.status_code == 500:
             # This endpoint raise HTTP error 500 when the password is wrong
             raise LoginError(common.get_local_string(12344)) from exc
         raise
     common.set_credentials({'email': email, 'password': password})
     LOG.info('Login successful')
     ui.show_notification(common.get_local_string(30109))
     cookies.save(self.session.cookies.jar)
     return True