GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 3d112a...bb5fc0 )
by Bastien
42s
created

TwitterBot._push_job_offers_to_twitter()   B

Complexity

Conditions 6

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
c 0
b 0
f 0
dl 0
loc 35
rs 7.5384
1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import
3
4
import twitter
5
import logging
6
7
from pyjobsweb.model import JobAlchemy
8
from pyjobsweb.lib.helpers import get_job_url
9
from pyjobsweb.lib.lock import acquire_inter_process_lock
10
11
12
class TwitterBot(object):
13
    MAX_TWEET_LENGTH = 140
14
    MAX_URL_LENGTH = 23
15
    MAX_TWEETS_TO_PUSH = 250
16
17
    def __init__(self, credentials):
18
        err_msg = ''
19
        exception = None
20
21
        self._logger = logging.getLogger(__name__)
22
23
        try:
24
            self._twitter_api = twitter.Api(
25
                consumer_key=credentials['consumer_key'],
26
                consumer_secret=credentials['consumer_secret'],
27
                access_token_key=credentials['access_token_key'],
28
                access_token_secret=credentials['access_token_secret']
29
            )
30
        except twitter.TwitterError as exc:
31
            err_msg = 'The following error: %s, occurred while connecting ' \
32
                      'to the twitter API.' % exc.message
33
            exception = exc
34
        except KeyError as exc:
35
            err_msg = 'Malformed credentials dictionary: %s.' % exc.message
36
            exception = exc
37
        except Exception as exc:
38
            err_msg = 'An unhandled error: %s, occurred while connecting ' \
39
                      'to the twitter API.' % exc
40
            exception = exc
41
42
        if err_msg:
43
            logging.getLogger(__name__).log(logging.ERROR, err_msg)
44
            raise exception
45
46
    def _logging(self, logging_level, message):
47
        self._logger.log(logging_level, message)
48
49
    def _format_tweet(self, job_id, job_title):
50
        self._logging(logging.INFO, 'Formatting tweet.')
51
        # The Twitter API automatically shrinks URLs to 23 characters
52
        url = get_job_url(job_id, job_title, absolute=True)
53
54
        # Tweet format string
55
        tweet_format = u'%s. %s'
56
57
        # The number of punctuation characters in the tweet string format
58
        punctuation = len(tweet_format.replace(u'%s', u''))
59
60
        total_length = len(job_title) + self.MAX_URL_LENGTH + punctuation
61
62
        # Make sure our tweet doesn't exceed max_length
63
        if total_length > self.MAX_TWEET_LENGTH:
64
            diff = total_length - self.MAX_TWEET_LENGTH
65
            job_title = job_title[:-diff]
66
67
        # Return the formatted tweet
68
        return tweet_format % (job_title, url)
69
70
    def _push_job_offers_to_twitter(self, num_tweets_to_push):
71
        # Do not push every job offer at once. The Twitter API won't allow it.
72
        # We thus push them num_offers_to_push at a time.
73
        if num_tweets_to_push > self.MAX_TWEETS_TO_PUSH:
74
            err_msg = 'Cannot push %s tweets at once, pushing %s tweets ' \
75
                      'instead.' % (num_tweets_to_push, self.MAX_TWEETS_TO_PUSH)
76
            self._logging(logging.WARNING, err_msg)
77
78
            num_tweets_to_push = self.MAX_TWEETS_TO_PUSH
79
80
        self._logging(logging.INFO, 'Acquiring unpublished job offers.')
81
        to_push = JobAlchemy.get_not_pushed_on_twitter(num_tweets_to_push)
82
83
        for job_offer in to_push:
84
            tweet = self._format_tweet(job_offer.id, job_offer.title)
85
86
            try:
87
                self._logging(logging.INFO, 'Publishing to Twitter.')
88
                self._twitter_api.PostUpdate(tweet)
89
            except twitter.TwitterError as exc:
90
                err_msg = '[Job offer id: %s] The following error: %s, ' \
91
                          'occurred while pushing the following tweet: %s.' \
92
                          % (job_offer.id, exc.message, tweet)
93
                self._logging(logging.WARNING, err_msg)
94
            except Exception as exc:
95
                err_msg = '[Job offer id: %s] An unhandled error: %s, ' \
96
                          'occurred while pushing the following tweet: %s.' \
97
                          % (job_offer.id, exc, tweet)
98
                self._logging(logging.ERROR, err_msg)
99
            else:
100
                # The tweet has been pushed successfully. Mark the job offer as
101
                # pushed on Twitter in the Postgresql database, so we don't push
102
                # it again on Twitter later on.
103
                self._logging(logging.INFO, 'Marking as published on Twitter.')
104
                JobAlchemy.set_pushed_on_twitter(job_offer.id, True)
105
106
    def run(self, num_tweets_to_push):
107
        self._logging(logging.INFO, 'Starting the Twitter bot.')
108
109
        with acquire_inter_process_lock('twitter_bot') as acquired:
110
            if not acquired:
111
                err_msg = 'Another instance of the Twitter bot is already ' \
112
                          'running, aborting now.'
113
                self._logging(logging.WARNING, err_msg)
114
            else:
115
                self._push_job_offers_to_twitter(num_tweets_to_push)
116