-
Notifications
You must be signed in to change notification settings - Fork 0
/
twitbot.py
228 lines (193 loc) · 9.06 KB
/
twitbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
import time, configparser
from sys import exit
from rauth import OAuth1Service
from multiprocessing import Process, Queue
from os.path import isfile
def make_session(strConsumer_key, strConsumer_secret,
strRequest_token, strRequest_secret, intPin):
twitter = OAuth1Service(
name='twitter',
consumer_key = strConsumer_key,
consumer_secret = strConsumer_secret,
request_token_url='https://api.twitter.com/oauth/request_token',
access_token_url='https://api.twitter.com/oauth/access_token',
authorize_url='https://api.twitter.com/oauth/authorize',
base_url='https://api.twitter.com/1.1/')
if not (strRequest_token or strRequest_secret or intPin):
strRequest_token, strRequest_secret = twitter.get_request_token()
authorize_url = twitter.get_authorize_url(strRequest_token)
while(True):
print 'Visit this URL in your browser: ' + authorize_url + '\n'
intPin = raw_input('Enter PIN from browser: ')
try:
session = twitter.get_auth_session(strRequest_token,
strRequest_secret, method='POST',
data={'oath_verifier':intPin})
break
except KeyError:
print "You need to enter a PIN!"
else:
print strRequest_token
print strRequest_secret
print intPin
session = twitter.get_auth_session(strRequest_token,
strRequest_secret, method='POST',
data={'oath_verifier':intPin})
intStatus_code = session.get('account/verify_credentials.json').status_code
if intStatus_code == 200:
print 'Account successfully verified'
else:
print 'Something went wrong, status code: {0}'.format(intStatus_code)
#ipdb.set_trace()
return (session, strRequest_token, strRequest_secret, intPin)
def dictTweet(session, data):
r = session.post('statuses/update.json',
data={'status':data['status'],
'in_reply_to_status_id':`data['in_reply_to_status_id']`})
if r.status_code == 200:
print 'dictTweet: Successfully posted {0}'.format(data)
else:
print 'dictTweet: Something went wrong! Status code is {0}'.format(r.status_code)
print 'dictTweet: dumping the body of the return {0}'.format(r.text)
def initializeProcesses(tsScraper, twWriter):
# set up the two processes and return a tuple containing them
q = Queue()
p1 = Process(target = tsScraper.run, args=(q,))
p2 = Process(target = twWriter.run, args=(q,))
p2.start()
p1.start()
return (p1, p2)
class TweetGeneric(object):
def __init__(self, strConsumer_key, strConsumer_secret,
strRequest_token = '', strRequest_secret = '', intPin = ''):
ret = make_session(strConsumer_key, strConsumer_secret, strRequest_token,
strRequest_secret, intPin)
print ret
self.strConsumer_key = strConsumer_key
self.strConsumer_secret = strConsumer_secret
self.session = ret[0]
self.strRequest_token = ret[1]
self.strRequest_secret = ret[2]
self.intPin = ret[3]
return
class TweetScraper(TweetGeneric):
def __init__(self, strConsumer_key, strConsumer_secret,
strRequest_token = '', strRequest_secret = '', intPin = ''):
print "TweetScraper: Initializing an account to scrape tweets on."
TweetGeneric.__init__(self, strConsumer_key, strConsumer_secret,
strRequest_token, strRequest_secret, intPin)
self.strSn = ''
self.strSince_id = ''
self.strFilter = '' #exclude tweets containing the given string
self.intMax_tweets = 0 #maximum number of tweets to go back
return
def __getstate__(self)
def configure(self):
print "Settings for the scraping account\n-----------"
self.strSn = raw_input("What screenname do you want to retweet? ")
self.strSince_id = raw_input("What is the id of the most recent tweet you'd like to scrape? [1] ")
self.intMax_tweets = raw_input("How many old tweets should be processed? [20] ")
if not self.strSince_id:
self.strSince_id = '1'
if not self.intMax_tweets :
self.intMax_tweets = 0
return
def run(self, q):
while True:
print 'scrape_tweets: Scraping tweets in an infinite loop'
posts = self.session.get('statuses/user_timeline.json',
params = {'screen_name':self.strSn,
'since_id':self.strSince_id,
'count':20,
'exclude_replies':'false'}).json()
for post in reversed(posts):
print type(post)
passed = {'status':post['text'],
'in_reply_to_status_id':post['in_reply_to_status_id'],
'place_id':post['geo']}
if not self.strFilter in passed['status']:
q.put(passed)
self.strSince_id = post['id']
#fix timing: the API rate limits requests more frequent than every 5 seconds
time.sleep(6)
#take a break if ther aren't any new posts coming in
if not posts:
time.sleep(180)
return
class TweetWriter(TweetGeneric):
def __init__(self, strConsumer_key, strConsumer_secret,
strRequest_token = '', strRequest_secret = '', intPin = ''):
print "TweetWriter: Initializing an account to write tweets from."
TweetGeneric.__init__(self, strConsumer_key, strConsumer_secret,
strRequest_token, strRequest_secret, intPin)
self.strAppend = ''
return
def configure(self):
print "Settings for the tweeting account\n-----------"
self.strAppend = raw_input("Is there anything you want me to append" +
" to these tweets? [blank for nothing] ")
return
def run(self, q):
while True:
print "write_tweets: Blocking to get a new tweet."
data = q.get(True, None)
data['status'] = ' '.join([data['status'], self.strAppend])
print "write_tweets: Tweeting the following: {0}".format(data)
dictTweet(self.session, data)
def main():
config = configparser.ConfigParser()
if not isfile('.config'):
open('.config', 'w').close()
config.read('.config')
#TODO: SPLIT THIS OFF INTO SUBROUTINES
if config.sections():
# def localAssign(strType):
#TODO: find a way to pickle an OAuth1Session object
# return TweetScraper(config[strType]['strConsumer_key'],
# config[strType]['strConsumer_secret'],
# config[strType]['strRequest_token'],
# config[strType]['strRequest_secret'],
# config[strType]['intPin'])
# tsScraper = localAssign('SCRAPER')
tsScraper = TweetScraper('juKgzsgl5LYnBKocnq4mg',
'vIw1vUec4bMkyL5hQpCISe3svTf767suzXyVh6YKA')
tsScraper.strSn = config['SCRAPER']['strSn']
tsScraper.strSince_id = config['SCRAPER']['strSince_id']
tsScraper.strFilter = config['SCRAPER']['strFilter']
tsScraper.intMax_tweets = config['SCRAPER']['intMax_tweets']
# tsWriter = localAssign('WRITER')
twWriter = TweetWriter('C2XWyJSzHpVx8iT7Bbabsw',
'uoxWh9wj4pDExn1GoQ5P4e5NdVAFATdAnYdao1Musw')
tsWriter.strAppend = config['WRITER']['strAppend']
else:
tsScraper = TweetScraper('juKgzsgl5LYnBKocnq4mg',
'vIw1vUec4bMkyL5hQpCISe3svTf767suzXyVh6YKA')
tsScraper.configure()
twWriter = TweetWriter('C2XWyJSzHpVx8iT7Bbabsw',
'uoxWh9wj4pDExn1GoQ5P4e5NdVAFATdAnYdao1Musw')
twWriter.configure()
tsScraper.strFilter = twWriter.strAppend
p1, p2 = initializeProcesses(tsScraper, twWriter)
while True:
print "Available commands: [h]elp [q]uit [s]ave [m]odify."
input = raw_input('? ')
if input == 'h':
print "Implement me."
if input == 'q':
p1.terminate()
p2.terminate()
exit(0)
if input == 's':
config['SCRAPER'] = tsScraper.__dict__
config['WRITER'] = twWriter.__dict__
with open('.config', 'w') as configfile:
config.write(configfile)
if input == 'm':
c = raw_input('Modify [s]craper or [w]riter? ')
if c == 's':
tsScraper.configure()
if c == 'w':
twWriter.configure()
return
if __name__ == '__main__':
main()