1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
import json |
3
|
|
|
import logging |
4
|
|
|
|
5
|
|
|
from pyjobsweb.bot.github import GitHubBot |
6
|
|
|
from pyjobsweb.bot.twitter import TwitterBot |
7
|
|
|
from pyjobsweb.commands import AppContextCommand |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
class BotsCommand(AppContextCommand): |
11
|
|
|
""" |
12
|
|
|
Run pyjobs' publication bots |
13
|
|
|
""" |
14
|
|
|
def __init__(self, *args, **kwargs): |
15
|
|
|
super(BotsCommand, self).__init__(args, kwargs) |
16
|
|
|
self._logger = logging.getLogger(__name__) |
17
|
|
|
|
18
|
|
|
def get_parser(self, prog_name): |
19
|
|
|
parser = super(BotsCommand, self).get_parser(prog_name) |
20
|
|
|
|
21
|
|
|
bot_parser = parser.add_subparsers( |
22
|
|
|
title='Choose your bot', |
23
|
|
|
description='Use one of these commands to setup and start the ' |
24
|
|
|
'corresponding bot.', |
25
|
|
|
help='You must choose between one of these subcommands.', |
26
|
|
|
dest='bot_command' |
27
|
|
|
) |
28
|
|
|
|
29
|
|
|
twitter_parser = bot_parser.add_parser( |
30
|
|
|
'twitter', |
31
|
|
|
description='Starts the Twitter bot.', |
32
|
|
|
help="Use this command to start and customize the Twitter bot." |
33
|
|
|
"For this command to work, you have to specify the path to " |
34
|
|
|
"the file containing your Twitter API credentials using the " |
35
|
|
|
"-c (or --credentials-file) argument. For more details about " |
36
|
|
|
"the Twitter API credentials file format, please refer to the " |
37
|
|
|
"following command: 'gearbox bots twitter -h'." |
38
|
|
|
) |
39
|
|
|
twitter_parser.add_argument( |
40
|
|
|
'-n', '--number-of-tweets', type=int, |
41
|
|
|
dest='number_of_tweets', default=TwitterBot.MAX_TWEETS_TO_PUSH, |
42
|
|
|
help='Sets a custom number of tweets to push on twitter, instead ' |
43
|
|
|
'of default: %s. Beware though, your value cannot be bigger ' |
44
|
|
|
'than the default one, only smaller.' |
45
|
|
|
% TwitterBot.MAX_TWEETS_TO_PUSH |
46
|
|
|
) |
47
|
|
|
twitter_parser.add_argument( |
48
|
|
|
'-cf', '--credentials-file', type=str, |
49
|
|
|
dest='twitter_credentials_file', required=True, |
50
|
|
|
help="This file must contain the your Twitter API " |
51
|
|
|
"credentials in the following json format: " |
52
|
|
|
"{" |
53
|
|
|
"'consumer_key':'YOUR_CONSUMER_KEY', " |
54
|
|
|
"'consumer_secret':'YOUR_CONSUMER_SECRET', " |
55
|
|
|
"'access_token_key':'YOUR_ACCESS_TOKEN_KEY', " |
56
|
|
|
"'access_token_secret':'YOUR_ACCESS_TOKEN_SECRET'" |
57
|
|
|
"} " |
58
|
|
|
"Each element of this file must be on a separate line, and " |
59
|
|
|
"each line must end with an \\n character." |
60
|
|
|
) |
61
|
|
|
|
62
|
|
|
# TODO: Fix broken help display (gearbox bots twitter -h displays the |
63
|
|
|
# TODO: same help message as gearbox bots, which shouldn't be the case) |
64
|
|
|
|
65
|
|
|
bot_parser.add_parser('github', |
66
|
|
|
description='Starts the Github bot.', |
67
|
|
|
help='Starts the Github bot.') |
68
|
|
|
|
69
|
|
|
return parser |
70
|
|
|
|
71
|
|
|
def _logging(self, logging_level, message): |
72
|
|
|
self._logger.log(logging_level, message) |
73
|
|
|
|
74
|
|
|
def _get_twitter_credentials(self, credentials_path): |
75
|
|
|
err_msg = '' |
76
|
|
|
exception = None |
77
|
|
|
|
78
|
|
|
credentials = None |
79
|
|
|
|
80
|
|
|
try: |
81
|
|
|
with open(credentials_path) as credentials_file: |
82
|
|
|
credentials_json = credentials_file.read() |
83
|
|
|
credentials = json.loads(credentials_json) |
84
|
|
|
except ValueError as exc: |
85
|
|
|
err_msg = u'Malformed credentials file: %s.' % exc |
86
|
|
|
exception = exc |
87
|
|
|
except Exception as exc: |
88
|
|
|
err_msg = u'An error occurred while parsing credentials: %s.' % exc |
89
|
|
|
exception = exc |
90
|
|
|
|
91
|
|
|
if err_msg: |
92
|
|
|
self._logging(logging.ERROR, err_msg) |
93
|
|
|
raise exception |
94
|
|
|
|
95
|
|
|
return credentials |
96
|
|
|
|
97
|
|
|
def _run_twitter_bot(self, num_tweets, twitter_credentials_file): |
98
|
|
|
try: |
99
|
|
|
credentials_path = twitter_credentials_file |
100
|
|
|
credentials = self._get_twitter_credentials(credentials_path) |
101
|
|
|
twitter_bot = TwitterBot(credentials) |
102
|
|
|
twitter_bot.run(num_tweets) |
103
|
|
|
except Exception as e: |
104
|
|
|
err_msg = u'A critical error occurred while ' \ |
105
|
|
|
u'configuring/running the Twitter bot. Aborting now. ' \ |
106
|
|
|
u'The error is %s' % e.__str__() |
107
|
|
|
self._logging(logging.ERROR, err_msg) |
108
|
|
|
|
109
|
|
|
return |
110
|
|
|
|
111
|
|
|
@staticmethod |
112
|
|
|
def _run_github_bot(): |
113
|
|
|
github_bot = GitHubBot() |
114
|
|
|
github_bot.run() |
115
|
|
|
|
116
|
|
|
def take_action(self, parsed_args): |
117
|
|
|
super(BotsCommand, self).take_action(parsed_args) |
118
|
|
|
|
119
|
|
|
if parsed_args.bot_command == 'twitter': |
120
|
|
|
num_tweets = parsed_args.number_of_tweets |
121
|
|
|
credentials_path = parsed_args.twitter_credentials_file |
122
|
|
|
self._run_twitter_bot(num_tweets, credentials_path) |
123
|
|
|
|
124
|
|
|
if parsed_args.bot_command == 'github': |
125
|
|
|
self._run_github_bot() |
126
|
|
|
|