-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathReddit2Twitter.py
209 lines (186 loc) · 6.46 KB
/
Reddit2Twitter.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
import praw
import json
import requests
import tweepy
import time
import sys
def setupConnection(subreddit):
print "[r2t] setting up connection with Reddit"
try:
r = praw.Reddit('zakagan and yasoob_python\'s Reddit2Twitter app, monitoring %s' %(subreddit))
except:
print "[r2t] Error accessing subreddit via Praw"
sys.exit()
subreddit = r.get_subreddit(subreddit)
try:
assert subreddit.id #if subreddit doesn't exist, it will have no id on reddit & throw an error
print "[r2t] Connected to /r/%s" %(subreddit.display_name)
return subreddit
except:
print "[r2t] subreddit could not be found, check name in config file"
sys.exit()
def collectPosts(subreddit):
print "[r2t] Collecting current top posts"
for index, submission in enumerate(subreddit.get_hot(limit=25)):
found = duplicateCheck(submission.id)
if found == 0:
print "[r2t] Post #%d selected" %(index+1)
return submission
else:
print "[r2t] Post #%d: ID already collected" %(index+1)
def tweetComposer(post):
char_remaining=140
content_list=[]
num_content=config_dict['include_karma'] + config_dict['include_nsfw_check'] + config_dict['include_title'] \
+ config_dict['include_author'] + config_dict['include_num_comments'] + config_dict['include_link']
char_remaining-=num_content-1
if config_dict['include_karma']==1:
score=u"%d\u2B06:" %(post.score)
if char_remaining-len(score) >= 0:
content_list.append(score)
char_remaining-=len(score)
del score
if config_dict['include_nsfw_check']==1 and post.over_18==True:
nsfw_warning="[NSFW]"
if char_remaining-len(nsfw_warning) >= 0:
content_list.append(nsfw_warning)
char_remaining-=len(nsfw_warning)
del nsfw_warning
if config_dict['include_title']==1:
title=post.title
title_index=len(content_list)
content_list.append(title)
# the post title's length is updated last
del title
if config_dict['include_author']==1:
author="- u/" + post.author.name
if char_remaining-len(author) >= 0:
content_list.append(author)
char_remaining-=len(author)
del author
if config_dict['include_num_comments']==1:
num_comments="%d comments" %(post.num_comments)
if char_remaining-len(num_comments) >= 0:
content_list.append(num_comments)
char_remaining-=len(num_comments)
del num_comments
if config_dict['include_link']==1:
if config_dict['use_permalink_url']==1:
post_link=post.permalink
else:
post_link=post.url
if config_dict['use_google_shortener']==1:
post_link=googleShortener(post_link)
shortened_link_len=24 #For now twitter reserves 24 characters for all links and media, this may change
if char_remaining-shortened_link_len >=0:
content_list.append(post_link)
char_remaining-=shortened_link_len
del post_link, shortened_link_len
if config_dict['include_title']==1: #The post title is revisted to see if it must be truncated
title=content_list[title_index]
if config_dict['use_quotes_around_title']==1:
char_remaining-=2
if char_remaining-len(title) < 0 and char_remaining >0:
title=(title[:char_remaining-len(title)-1]+ u'\u2026')
if char_remaining-len(title) >= 0 and char_remaining >0:
if config_dict['use_quotes_around_title']==1:
title="\""+title+"\""
else:
title=''
content_list[title_index]=title
if config_dict['use_quotes_around_title']==1:
char_remaining-=len(title)-2 #in this surrounding quotation marks have been already factored
else:
char_remaining-=len(title)
del title
tweet_content= " ".join(content_list)
print tweet_content.encode("utf-8")
print "[r2t] Characters remaining = %d" %(char_remaining)
return tweet_content
def googleShortener(url):
try:
headers = {'content-type': 'application/json'}
payload = {"longUrl": url}
googl_url = "https://www.googleapis.com/urlshortener/v1/url?key=%s" %(config_dict['google_api_key'])
r = requests.post(googl_url, data=json.dumps(payload), headers=headers)
url = json.loads(r.text)['id']
except:
print "[r2t] Google shortner could not be accessed, check google api key"
print "[r2t] Defaulting to twitter's t.co shortner"
return url
def tweetSender(tweet):
try:
auth = tweepy.OAuthHandler(config_dict['consumer_key'], config_dict['consumer_secret'])
auth.set_access_token(config_dict['access_token'], config_dict['access_token_secret'])
api = tweepy.API(auth)
api.update_status(tweet)
print "[r2t] Tweet sucessfully sent to twitter"
except Exception, e:
print "[r2t] Error triggered when sending tweet content to twitter:"
try:
print "[Twitter] "+ e.args[0][0]['message']
except:
print "[r2t] Error outside of communication with Twitter"
sys.exit()
def addPostID(post):
with open('posted_posts.txt', 'a') as file:
file.write(str(post.id) + "\n")
file.close()
def duplicateCheck(post_id):
found = 0
with open('posted_posts.txt', 'r') as file:
for line in file.read().splitlines():
if post_id == line:
found = 1
file.close()
return found
def main():
while True:
subreddit = setupConnection(config_dict['subreddit_name'])
reddit_post = collectPosts(subreddit)
tweet_content = tweetComposer(reddit_post)
addPostID(reddit_post)
tweetSender(tweet_content)
#addPostID(reddit_post)
time.sleep(config_dict['tweet_delay']*60)
if __name__ == '__main__':
config_dict = {'access_token': "", #defining what we expect to gt from the config file
'access_token_secret':"",
'consumer_key': "",
'consumer_secret' : "",
'google_api_key' : "",
'subreddit_name' : "",
'include_karma' : 0, #Note that boolean values will default to 0
'include_nsfw_check' : 0,
'include_title' : 0,
'include_author' : 0,
'include_num_comments' :0,
'include_link' : 0,
'use_permalink_url' : 0,
'use_google_shortener': 0,
'use_quotes_around_title': 0,
'tweet_delay' : 0}
with open("r2t_config.txt") as f: #Read from config file and save to global dictionary
for line in f:
line=line.replace(':', " ")
line=line.replace('#', " ")
line=line.split()
if len(line) >=2:
key=line[0]
val=line[1]
try:
val=int(val)
except:
pass
config_dict[key] = val
f.close()
for key in ['include_karma', 'include_nsfw_check', 'include_title',
'include_author','include_num_comments', 'include_link',
'use_permalink_url', 'use_google_shortener',
'use_quotes_around_title', 'tweet_delay']:
#Check if required int values really are ints
if isinstance(config_dict[key],int)==False:
config_dict[key]=0
if key=='tweet_delay' and config_dict[key]<3:
config_dict[key]=3
main()