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 ( 1c10bc...271fb1 )
by PyJobs
01:14
created

TwitterBot._format_tweet()   B

Complexity

Conditions 3

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
c 1
b 0
f 1
dl 0
loc 26
rs 8.8571
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
        job_title = job_title.lower()
55
        job_title = job_title.replace('adminsys', '#sysadmin')
56
        job_title = job_title.replace('administrateur', '#sysadmin')
57
        for hashword in ('devops', 'developpeur', 'developpeuse', 'startup', 'cdd', 'cdi', 'stage', 'sysadmin', 'django', 'flask', 'python') :
58
            job_title = job_title.replace(hashword, '#%s' % hashword)
59
60
        # Tweet format string
61
        tweet_format = u'Recrutement %s %s #emploi'
62
63
        # The number of punctuation characters in the tweet string format
64
        punctuation = len(tweet_format.replace(u'%s', u''))
65
66
        total_length = len(job_title) + self.MAX_URL_LENGTH + punctuation
67
68
        # Make sure our tweet doesn't exceed max_length
69
        if total_length > self.MAX_TWEET_LENGTH:
70
            diff = total_length - self.MAX_TWEET_LENGTH
71
            job_title = job_title[:-diff]
72
73
        # Return the formatted tweet
74
        return tweet_format % (job_title, url)
75
76
    def _push_job_offers_to_twitter(self, num_tweets_to_push):
77
        # Do not push every job offer at once. The Twitter API won't allow it.
78
        # We thus push them num_offers_to_push at a time.
79
        if num_tweets_to_push > self.MAX_TWEETS_TO_PUSH:
80
            err_msg = 'Cannot push %s tweets at once, pushing %s tweets ' \
81
                      'instead.' % (num_tweets_to_push, self.MAX_TWEETS_TO_PUSH)
82
            self._logging(logging.WARNING, err_msg)
83
84
            num_tweets_to_push = self.MAX_TWEETS_TO_PUSH
85
86
        self._logging(logging.INFO, 'Acquiring unpublished job offers.')
87
        to_push = JobAlchemy.get_not_pushed_on_twitter(num_tweets_to_push)
88
89
        for job_offer in to_push:
90
            tweet = self._format_tweet(job_offer.id, job_offer.title)
91
92
            try:
93
                self._logging(logging.INFO, 'Publishing to Twitter.')
94
                self._twitter_api.PostUpdate(tweet)
95
            except twitter.TwitterError as exc:
96
                err_msg = '[Job offer id: %s] The following error: %s, ' \
97
                          'occurred while pushing the following tweet: %s.' \
98
                          % (job_offer.id, exc.message, tweet)
99
                self._logging(logging.WARNING, err_msg)
100
            except Exception as exc:
101
                err_msg = '[Job offer id: %s] An unhandled error: %s, ' \
102
                          'occurred while pushing the following tweet: %s.' \
103
                          % (job_offer.id, exc, tweet)
104
                self._logging(logging.ERROR, err_msg)
105
            else:
106
                # The tweet has been pushed successfully. Mark the job offer as
107
                # pushed on Twitter in the Postgresql database, so we don't push
108
                # it again on Twitter later on.
109
                self._logging(logging.INFO, 'Marking as published on Twitter.')
110
                JobAlchemy.set_pushed_on_twitter(job_offer.id, True)
111
112
    def run(self, num_tweets_to_push):
113
        self._logging(logging.INFO, 'Starting the Twitter bot.')
114
115
        with acquire_inter_process_lock('twitter_bot') as acquired:
116
            if not acquired:
117
                err_msg = 'Another instance of the Twitter bot is already ' \
118
                          'running, aborting now.'
119
                self._logging(logging.WARNING, err_msg)
120
            else:
121
                self._push_job_offers_to_twitter(num_tweets_to_push)
122