|
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 = 'Malformed credentials file: %s.' % exc |
|
86
|
|
|
exception = exc |
|
87
|
|
|
except Exception as exc: |
|
88
|
|
|
err_msg = '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: |
|
104
|
|
|
err_msg = 'A critical error occurred while ' \ |
|
105
|
|
|
'configuring/running the Twitter bot. Aborting now.' |
|
106
|
|
|
self._logging(logging.ERROR, err_msg) |
|
107
|
|
|
return |
|
108
|
|
|
|
|
109
|
|
|
@staticmethod |
|
110
|
|
|
def _run_github_bot(): |
|
111
|
|
|
github_bot = GitHubBot() |
|
112
|
|
|
github_bot.run() |
|
113
|
|
|
|
|
114
|
|
|
def take_action(self, parsed_args): |
|
115
|
|
|
super(BotsCommand, self).take_action(parsed_args) |
|
116
|
|
|
|
|
117
|
|
|
if parsed_args.bot_command == 'twitter': |
|
118
|
|
|
num_tweets = parsed_args.number_of_tweets |
|
119
|
|
|
credentials_path = parsed_args.twitter_credentials_file |
|
120
|
|
|
self._run_twitter_bot(num_tweets, credentials_path) |
|
121
|
|
|
|
|
122
|
|
|
if parsed_args.bot_command == 'github': |
|
123
|
|
|
self._run_github_bot() |
|
124
|
|
|
|