예제 #1
0
    def __init__(self):
        """
        Create a `Configuration` taking into account the arguments
        from the command line interface (if any).
        """
        # load defaults
        self.twitter = TWITTER
        self.key_bindings = KEY_BINDINGS
        self.palette = PALETTE
        self.styles = STYLES
        self.logging_level = LOGGING_LEVEL
        self.session = DEFAULT_SESSION

        # config and token files
        self.config_file = DEFAULT_CONFIG_FILE
        self.token_file = DEFAULT_TOKEN_FILE

        # debug mode
        self.debug = False

        # create the config directory if it does not exist
        if not path.isdir(CONFIG_PATH):
            try:
                mkdir(CONFIG_PATH)
            except:
                print encode(
                    _('Error creating config directory in %s' % CONFIG_DIR))
                self.exit_with_code(3)
예제 #2
0
    def __init__(self):
        """
        Create a `Configuration` taking into account the arguments
        from the command line interface (if any).
        """
        # load defaults
        self.twitter = TWITTER
        self.key_bindings = KEY_BINDINGS
        self.palette = PALETTE
        self.styles = STYLES
        self.logging_level = LOGGING_LEVEL
        self.session = DEFAULT_SESSION

        # config and token files
        self.config_file = DEFAULT_CONFIG_FILE
        self.token_file = DEFAULT_TOKEN_FILE

        # debug mode
        self.debug = False

        # create the config directory if it does not exist
        if not path.isdir(CONFIG_PATH):
            try:
                mkdir(CONFIG_PATH)
            except:
                print encode(_('Error creating config directory in %s' % CONFIG_DIR))
                self.exit_with_code(3)
예제 #3
0
파일: config.py 프로젝트: gigigi/turses
    def __init__(self, cli_args=None):
        """
        Create a `Configuration` taking into account the arguments
        from the command line interface (if any).
        """
        self.load_defaults()

        self.browser = BROWSER

        # create the config directory if it does not exist
        if not path.isdir(CONFIG_PATH):
            try:
                mkdir(CONFIG_PATH)
            except:
                print encode(_('Error creating config directory in %s' % CONFIG_DIR))
                exit(3)

        # generate config file and exit
        if cli_args and cli_args.generate_config:
            self.generate_config_file(config_file=cli_args.generate_config,)
            exit(0)

        if cli_args and cli_args.config:
            config_file = cli_args.config
        else:
            config_file = DEFAULT_CONFIG_FILE
        self.config_file = config_file

        if cli_args and cli_args.account:
            token_file = path.join(CONFIG_PATH, '%s.token' % cli_args.account)
        else:
            # loads the default `token' if no account was specified 
            token_file = DEFAULT_TOKEN_FILE
        self.token_file = token_file
예제 #4
0
    def __init__(self):
        """
        Create a `Configuration` taking into account the arguments
        from the command line interface (if any).
        """
        # load defaults
        self.default_timelines = DEFAULT_TIMELINES
        self.update_frequency = UPDATE_FREQUENCY
        self.key_bindings = KEY_BINDINGS
        self.palette = PALETTE
        self.styles = STYLES
        self.logging_level = LOGGING_LEVEL

        # config and token files
        self.config_file = DEFAULT_CONFIG_FILE
        self.token_file = DEFAULT_TOKEN_FILE

        # debug mode
        self.debug = False

        # create the config directory if it does not exist
        if not path.isdir(CONFIG_PATH):
            try:
                mkdir(CONFIG_PATH)
            except:
                print encode(
                    _('Error creating config directory in %s' % CONFIG_DIR))
                exit(3)
예제 #5
0
파일: config.py 프로젝트: msabramo/turses
    def __init__(self):
        """
        Create a `Configuration` taking into account the arguments
        from the command line interface (if any).
        """
        # load defaults
        self.default_timelines = DEFAULT_TIMELINES
        self.update_frequency = UPDATE_FREQUENCY
        self.key_bindings = KEY_BINDINGS
        self.palette = PALETTE
        self.styles = STYLES
        self.logging_level = LOGGING_LEVEL

        # config and token files
        self.config_file = DEFAULT_CONFIG_FILE
        self.token_file = DEFAULT_TOKEN_FILE

        # debug mode
        self.debug = False

        # create the config directory if it does not exist
        if not path.isdir(CONFIG_PATH):
            try:
                mkdir(CONFIG_PATH)
            except:
                print encode(_('Error creating config directory in %s' % CONFIG_DIR))
                exit(3)
예제 #6
0
    def generate_token_file(self, token_file, oauth_token, oauth_token_secret):
        self.oauth_token = oauth_token
        self.oauth_token_secret = oauth_token_secret

        conf = RawConfigParser()
        conf.add_section(SECTION_TOKEN)
        conf.set(SECTION_TOKEN, 'oauth_token', oauth_token)
        conf.set(SECTION_TOKEN, 'oauth_token_secret', oauth_token_secret)

        with open(token_file, 'wb') as tokens:
            conf.write(tokens)

        print encode(_('your account has been saved'))
예제 #7
0
파일: config.py 프로젝트: msabramo/turses
    def generate_token_file(self,
                            token_file,
                            oauth_token,
                            oauth_token_secret):
        self.oauth_token = oauth_token
        self.oauth_token_secret = oauth_token_secret

        conf = RawConfigParser()
        conf.add_section(SECTION_TOKEN)
        conf.set(SECTION_TOKEN, 'oauth_token', oauth_token)
        conf.set(SECTION_TOKEN, 'oauth_token_secret', oauth_token_secret)

        with open(token_file, 'wb') as tokens:
            conf.write(tokens)

        print encode(_('your account has been saved'))
예제 #8
0
    def _dm_header(self, dm):
        dm_template = ''.join([' ', configuration.styles['dm_template'], ' '])
        relative_created_at = dm.relative_created_at
        header = str(dm_template).format(
            sender_screen_name=dm.sender_screen_name,
            recipient_screen_name=dm.recipient_screen_name,
            time=relative_created_at,
        )

        return encode(header)
예제 #9
0
파일: ui.py 프로젝트: ivanov/turses
    def _dm_header(self, dm):
        dm_template = " " + self.configuration.styles["dm_template"] + " "
        relative_created_at = dm.relative_created_at
        header = unicode(dm_template).format(
            sender_screen_name=dm.sender_screen_name,
            recipient_screen_name=dm.recipient_screen_name,
            time=relative_created_at,
        )

        return encode(header)
예제 #10
0
파일: ui.py 프로젝트: Erik-k/turses
    def _dm_header(self, dm):
        dm_template = ''.join([' ', configuration.styles['dm_template'], ' '])
        relative_created_at = dm.relative_created_at
        header = unicode(dm_template).format(
            sender_screen_name=dm.sender_screen_name,
            recipient_screen_name=dm.recipient_screen_name,
            time=relative_created_at,
        )

        return encode(header)
예제 #11
0
파일: ui.py 프로젝트: gigigi/turses
    def _dm_header(self, dm):
        dm_template = ' ' + self.configuration.styles['dm_template'] + ' '
        relative_created_at = dm.get_relative_created_at()
        header = unicode(dm_template).format(
            sender_screen_name=dm.sender_screen_name,
            recipient_screen_name=dm.recipient_screen_name,
            time = relative_created_at,
        )

        return encode(header)
예제 #12
0
def get_authorization_tokens():
    """
    Authorize `turses` to use a Twitter account.

    Return a dictionary with `oauth_token` and `oauth_token_secret` keys
    if succesfull, `None` otherwise.
    """

    oauth_client = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY,
                                       TWITTER_CONSUMER_SECRET)

    print _('Requesting temporary token from Twitter')

    try:
        authorization_url_with_token = oauth_client.get_authorization_url()
    except tweepy.TweepError:
        print 'Error! Failed to get request token.'
        return None

    print
    print _('Please visit the following page to retrieve the pin code needed '
            'to obtain an Authorization Token:')
    print
    print authorization_url_with_token
    print

    verifier = raw_input(_('Pin code? '))

    print
    print encode(_('Generating and signing request for an access token'))
    print

    # Use the "pin code"/verifier to authorize to access to the account
    try:
        oauth_client.get_access_token(verifier)
        access_tokens = {}
        access_tokens['oauth_token'] = oauth_client.access_token
        access_tokens['oauth_token_secret'] = oauth_client.access_token_secret
        return access_tokens
    except tweepy.TweepError:
        print 'Error! Failed to get access token.'
        return None
예제 #13
0
파일: base.py 프로젝트: battlemidget/turses
def get_authorization_tokens():
    """
    Authorize `turses` to use a Twitter account.

    Return a dictionary with `oauth_token` and `oauth_token_secret` keys
    if succesfull, `None` otherwise.
    """

    oauth_client = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY,
                                       TWITTER_CONSUMER_SECRET)

    print _('Requesting temporary token from Twitter')

    try:
        authorization_url_with_token = oauth_client.get_authorization_url()
    except tweepy.TweepError:
        print 'Error! Failed to get request token.'
        return None

    print
    print _('Please visit the following page to retrieve the pin code needed '
            'to obtain an Authorization Token:')
    print
    print authorization_url_with_token
    print

    verifier = raw_input(_('Pin code? '))

    print
    print encode(_('Generating and signing request for an access token'))
    print

    # Use the "pin code"/verifier to authorize to access to the account
    try:
        oauth_client.get_access_token(verifier)
        access_tokens = {}
        access_tokens['oauth_token'] = oauth_client.access_token
        access_tokens['oauth_token_secret'] = oauth_client.access_token_secret
        return access_tokens
    except tweepy.TweepError:
        print 'Error! Failed to get access token.'
        return None
예제 #14
0
파일: config.py 프로젝트: ripperbone/turses
    def generate_token_file(self, token_file, oauth_token, oauth_token_secret):
        self.oauth_token = oauth_token
        self.oauth_token_secret = oauth_token_secret

        conf = RawConfigParser()
        conf.add_section(SECTION_TOKEN)
        conf.set(SECTION_TOKEN, "oauth_token", oauth_token)
        conf.set(SECTION_TOKEN, "oauth_token_secret", oauth_token_secret)

        with open(token_file, "w") as tokens:
            conf.write(tokens)

        print(encode(_("your account has been saved")))
예제 #15
0
파일: ui.py 프로젝트: ripperbone/turses
    def _create_header(self, status):
        """
        Return the header text for the status associated with this widget.
        """
        if is_DM(status):
            return self._dm_header(status)

        reply = ''
        retweeted = ''
        retweet_count = ''
        retweeter = ''
        username = status.user
        relative_created_at = status.relative_created_at

        # reply
        if status.is_reply:
            reply = surround_with_spaces(
                configuration.styles['reply_indicator'])

        # retweet
        if status.is_retweet:
            retweeted = surround_with_spaces(
                configuration.styles['retweet_indicator'])
            # `username` is the author of the original tweet
            username = status.author
            # `retweeter` is the user who made the RT
            retweeter = status.user
            retweet_count = str(status.retweet_count)

        # create header
        styles = configuration.styles
        header_template = ' ' + styles.get('header_template') + ' '
        header = str(header_template).format(
            username=username,
            retweeted=retweeted,
            retweeter=retweeter,
            time=relative_created_at,
            reply=reply,
            retweet_count=retweet_count,
        )

        return encode(header)
예제 #16
0
    def _create_header(self, status):
        """
        Return the header text for the status associated with this widget.
        """
        if is_DM(status):
            return self._dm_header(status)

        reply = ''
        retweeted = ''
        retweet_count = ''
        retweeter = ''
        username = status.user
        relative_created_at = status.relative_created_at

        # reply
        if status.is_reply:
            reply = surround_with_spaces(
                configuration.styles['reply_indicator'])

        # retweet
        if status.is_retweet:
            retweeted = surround_with_spaces(
                configuration.styles['retweet_indicator'])
            # `username` is the author of the original tweet
            username = status.author
            # `retweeter` is the user who made the RT
            retweeter = status.user
            retweet_count = str(status.retweet_count)

        # create header
        styles = configuration.styles
        header_template = ' ' + styles.get('header_template') + ' '
        header = str(header_template).format(
            username=username,
            retweeted=retweeted,
            retweeter=retweeter,
            time=relative_created_at,
            reply=reply,
            retweet_count=retweet_count,
        )

        return encode(header)
예제 #17
0
파일: ui.py 프로젝트: ivanov/turses
    def _create_header(self, status):
        """
        Return the header text for the status associated with this widget.
        """
        if is_DM(status):
            return self._dm_header(status)

        reply = ""
        retweeted = ""
        retweet_count = ""
        retweeter = ""
        username = status.user
        relative_created_at = status.relative_created_at

        # reply
        if status.is_reply:
            reply = u" \u2709"

        # retweet
        if status.is_retweet:
            retweeted = u" \u267b "
            # `username` is the author of the original tweet
            username = status.author
            # `retweeter` is the user who made the RT
            retweeter = status.user
            retweet_count = str(status.retweet_count)

        # create header
        styles = self.configuration.styles
        header_template = " " + styles.get("header_template") + " "
        header = unicode(header_template).format(
            username=username,
            retweeted=retweeted,
            retweeter=retweeter,
            time=relative_created_at,
            reply=reply,
            retweet_count=retweet_count,
        )

        return encode(header)
예제 #18
0
파일: ui.py 프로젝트: apg/turses
    def _create_header(self, status):
        """Return the header text for the status associated with this widget."""
        if is_DM(status):
            return self._dm_header(status)

        # tweet or retweet
        reply = ''
        retweeted = ''
        retweet_count = ''
        retweeter = ''
        username = status.user
        relative_created_at = status.get_relative_created_at()

        # reply
        if status.is_reply:
            reply = u' \u2709'

        # retweet
        if status.is_retweet:
            retweeted = u" \u267b "
            # `username` is the author of the original tweet
            username = status.author
            # `retweeter` is the user who made the RT
            retweeter = status.user
            retweet_count = str(status.retweet_count)

        # create header
        header_template = ' ' + self.configuration.styles['header_template'] + ' '
        header = unicode(header_template).format(
            username=username,
            retweeted=retweeted,
            retweeter=retweeter,
            time=relative_created_at,
            reply=reply,
            retweet_count=retweet_count,
        )

        return encode(header)
예제 #19
0
 def _config_generation_success(self, config_file):
     print encode(_('Generated configuration file in %s')) % config_file
예제 #20
0
def get_authorization_tokens():
    """
    Authorize `turses` to use a Twitter account.

    Return a dictionary with `oauth_token` and `oauth_token_secret` keys
    if succesfull, `None` otherwise.
    """
    # This function was borrowed from python-twitter developers and experienced
    # an important refactoring
    #
    # Copyright 2007 The Python-Twitter Developers
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    oauth_consumer = oauth.Consumer(key=TWITTER_CONSUMER_KEY,
                                    secret=TWITTER_CONSUMER_SECRET)
    oauth_client = oauth.Client(oauth_consumer)

    print _('Requesting temporary token from Twitter')

    try:
        oauth_token, oauth_token_secret = get_temporary_tokens(oauth_client)
    except SSLError:
        print _("""There was an SSL certificate error, your user may not have
                   permission to access SSL. Try executing `turses` as a
                   privileged user.""")
        return None
    except Exception as e:
        print e
        return None

    authorization_url = urljoin(BASE_URL, '/oauth/authorize')
    authorization_url_with_token = urljoin(authorization_url,
                                           '?oauth_token=%s' % oauth_token)
    print
    print _('Please visit the following page to retrieve the pin code needed '
            'to obtain an Authorization Token:')
    print
    print authorization_url_with_token
    print

    pin_code = raw_input(_('Pin code? '))

    print
    print encode(_('Generating and signing request for an access token'))
    print

    # Generate an OAuth token that verifies the identity of the user
    token = oauth.Token(oauth_token, oauth_token_secret)
    token.set_verifier(pin_code)

    # Re-create the OAuth client with the corresponding token
    oauth_client = oauth.Client(oauth_consumer, token)

    try:
        access_tokens = get_access_tokens(oauth_client, pin_code)
        return access_tokens
    except Exception as e:
        print e
        return None
예제 #21
0
파일: config.py 프로젝트: msabramo/turses
 def _config_generation_error(self, config_file):
     print encode(_('Unable to generate configuration file in %s')) % config_file
     exit(2)
예제 #22
0
파일: config.py 프로젝트: msabramo/turses
 def _config_generation_success(self, config_file):
     print encode(_('Generated configuration file in %s')) % config_file
예제 #23
0
def authorization():
    """
    Authorize `turses` to use a Twitter account.

    Return a dictionary with `oauth_token` and `oauth_token_secret`
    if succesfull, `None` otherwise.
    """
    # This function is borrowed from python-twitter developers

    # Copyright 2007 The Python-Twitter Developers
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    print 'base_url:{0}'.format(BASE_URL)

    REQUEST_TOKEN_URL = BASE_URL + '/oauth/request_token'
    ACCESS_TOKEN_URL = BASE_URL + '/oauth/access_token'
    AUTHORIZATION_URL = BASE_URL + '/oauth/authorize'

    consumer_key = TWITTER_CONSUMER_KEY
    consumer_secret = TWITTER_CONSUMER_SECRET
    oauth_consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
    oauth_client = oauth.Client(oauth_consumer)

    print encode(_('Requesting temp token from Twitter'))

    resp, content = oauth_client.request(REQUEST_TOKEN_URL, 'GET')

    if resp['status'] != '200':
        response = str(resp['status'])
        message = _('Invalid respond, requesting temp token: %s') % response
        print encode(message)
        return

    request_token = dict(parse_qsl(content))

    print
    message = _('Please visit the following page to retrieve needed pin code'
                'to obtain an Authentication Token:')
    print encode(message)
    print
    print '%s?oauth_token=%s' % (AUTHORIZATION_URL,
                                 request_token['oauth_token'])
    print

    pincode = raw_input('Pin code? ')

    token = oauth.Token(request_token['oauth_token'],
                        request_token['oauth_token_secret'])
    token.set_verifier(pincode)

    print ''
    print encode(_('Generating and signing request for an access token'))
    print ''

    oauth_client = oauth.Client(oauth_consumer, token)
    resp, content = oauth_client.request(ACCESS_TOKEN_URL,
                                         method='POST',
                                         body='oauth_verifier=%s' % pincode)
    access_token = dict(parse_qsl(content))

    if resp['status'] == '200':
        return access_token
    else:
        print 'response:{0}'.format(resp['status'])
        print encode(_('Request for access token failed: %s')) % resp['status']
        return None
예제 #24
0
파일: config.py 프로젝트: ryanprior/turses
 def _config_generation_error(self, config_file):
     print(encode(_('Unable to generate configuration file in %s')) % (
         config_file))
     self.exit_with_code(2)
예제 #25
0
파일: base.py 프로젝트: floppym/turses
def get_authorization_tokens():
    """
    Authorize `turses` to use a Twitter account.

    Return a dictionary with `oauth_token` and `oauth_token_secret` keys
    if succesfull, `None` otherwise.
    """
    # This function was borrowed from python-twitter developers and experienced
    # an important refactoring
    #
    # Copyright 2007 The Python-Twitter Developers
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    oauth_consumer = oauth.Consumer(key=TWITTER_CONSUMER_KEY,
                                    secret=TWITTER_CONSUMER_SECRET)
    oauth_client = oauth.Client(oauth_consumer)

    print _('Requesting temporary token from Twitter')

    try:
        oauth_token, oauth_token_secret = get_temporary_tokens(oauth_client)
    except SSLError:
        print _("""There was an SSL certificate error, your user may not have
                   permission to access SSL. Try executing `turses` as a
                   privileged user.""")
        return None
    except Exception as e:
        print e
        return None


    authorization_url = urljoin(BASE_URL, '/oauth/authorize')
    authorization_url_with_token = urljoin(authorization_url,
                                           '?oauth_token=%s' % oauth_token)
    print
    print  _('Please visit the following page to retrieve the pin code needed '
             'to obtain an Authorization Token:')
    print
    print authorization_url_with_token
    print

    pin_code = raw_input(_('Pin code? '))

    print
    print encode(_('Generating and signing request for an access token'))
    print

    # Generate an OAuth token that verifies the identity of the user
    token = oauth.Token(oauth_token, oauth_token_secret)
    token.set_verifier(pin_code)

    # Re-create the OAuth client with the corresponding token
    oauth_client = oauth.Client(oauth_consumer, token)

    try:
        access_tokens = get_access_tokens(oauth_client, pin_code)
        return access_tokens
    except Exception as e:
        print e
        return None
예제 #26
0
파일: base.py 프로젝트: gigigi/turses
def authorization():
    """
    Authorize `turses` to use a Twitter account. 

    Return a dictionary with `oauth_token` and `oauth_token_secret`
    if succesfull, `None` otherwise.
    """
    # This function is borrowed from python-twitter developers 

    # Copyright 2007 The Python-Twitter Developers
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    print 'base_url:{0}'.format(BASE_URL)


    REQUEST_TOKEN_URL = BASE_URL + '/oauth/request_token'
    ACCESS_TOKEN_URL  = BASE_URL + '/oauth/access_token'
    AUTHORIZATION_URL = BASE_URL + '/oauth/authorize'
    consumer_key      = TWITTER_CONSUMER_KEY
    consumer_secret   = TWITTER_CONSUMER_SECRET
    oauth_consumer    = oauth.Consumer(key=consumer_key, secret=consumer_secret)
    oauth_client      = oauth.Client(oauth_consumer)

    print encode(_('Requesting temp token from Twitter'))

    resp, content = oauth_client.request(REQUEST_TOKEN_URL, 'GET')

    if resp['status'] != '200':
        print encode(_('Invalid respond, requesting temp token: %s')) % str(resp['status'])
        return

    request_token = dict(parse_qsl(content))

    print ''
    print encode(_('Please visit the following page to retrieve needed pin code'))
    print encode(_('to obtain an Authentication Token:'))
    print ''
    print '%s?oauth_token=%s' % (AUTHORIZATION_URL, request_token['oauth_token'])
    print ''

    pincode = raw_input('Pin code? ')

    token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
    token.set_verifier(pincode)

    print ''
    print encode(_('Generating and signing request for an access token'))
    print ''

    oauth_client  = oauth.Client(oauth_consumer, token)
    resp, content = oauth_client.request(ACCESS_TOKEN_URL, method='POST', body='oauth_verifier=%s' % pincode)
    access_token  = dict(parse_qsl(content))

    if resp['status'] == '200':
        return access_token
    else:
        print 'response:{0}'.format(resp['status'])
        print encode(_('Request for access token failed: %s')) % resp['status']
        return None
예제 #27
0
 def _config_generation_error(self, config_file):
     print encode(
         _('Unable to generate configuration file in %s')) % config_file
     self.exit_with_code(2)