forked from dper/pumptweet
/
PumpTweet.py
152 lines (123 loc) · 4.2 KB
/
PumpTweet.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
# coding=utf-8
from PumpLogin import PumpTweetParser
from pypump import PyPump
from MLStripper import strip_tags
from shorturl import shorten
from unicodedata import normalize
import argparse
# Connect to servers.
def connect_to_servers():
# Run the parser and grab useful values.
global __ptp__
global __pump_me__
global __pump_username__
global __twitter_api__
__ptp__ = PumpTweetParser()
__pump_me__ = __ptp__.get_pump_me()
__pump_username__ = __ptp__.get_pump_username()
__twitter_api__ = __ptp__.get_twitter_api()
# Returns recent outbox activities.
# If testing, don't stop at recent activity.
def get_new_activities(testing=False):
print 'Looking at Pump outbox activity...'
# Some of this can be replaced by 'since' if later implemented by PyPump.
published = __ptp__.get_published()
recent = __ptp__.get_recent()
outbox = __pump_me__.outbox
history = __ptp__.get_history()
# Users with a lot of non-note activity might raise this.
count = 20
# The maximum number of notes to post at a time.
# Posting too frequently might lead to errors on Twitter.
# If this number is too small, consider a more frequent cronjob.
allowable_posts = 3
notes = []
for activity in outbox.major[:count]:
print '> ' + activity.obj.objectType + ' (' + str(activity.published) + ')'
# Stop looking at the outbox upon finding old activity.
if history and not testing:
if recent == activity.id: break
if published >= activity.published: break
# Only post several notes. Others are forgotten.
if len(notes) >= allowable_posts: break
obj = activity.obj
# Only post notes to Twitter.
if obj.objectType != 'note': break
# Skip deleted notes.
if obj.deleted: break
# Omit posts written by others and then shared.
note_author = obj.author.id.lstrip('acct:')
if note_author != __pump_username__: break
notes.append(obj)
return notes
# Make the text for a tweet that includes the contest of the note.
def make_tweet(note):
max_length = 136
content = note.content
# Convert or remove HTML.
content = strip_tags(content)
# If the note fits in a tweet, post it as-is.
# Tweets of notes this short don't need to link to their source.
if len(content.splitlines()) == 1 and len(content) <= max_length:
return content
# Make a short URL pointing to the original note.
private_url = note.id
public_url = private_url.replace('/api/note/', '/dper/note/')
short_url = shorten(public_url)
# Make room for the ellipsis and URL at the end of the tweet.
cropped_length = max_length - len(short_url) - 2
# Keep only the first line.
content = content.splitlines()[0]
content = content[:cropped_length]
content = content.rstrip()
tweet = content + u'… ' + short_url
return tweet
# Converts posts to tweets.
def make_tweets(notes):
tweets = []
for note in notes:
tweets.append(make_tweet(note))
return tweets
# Prints a list of tweets.
def print_tweets(tweets):
print 'Printing tweets...'
for tweet in tweets:
normal = normalize('NFKD', tweet).encode('ascii', 'ignore')
print '> ' + normal
# Posts a list of tweets.
def post_tweets(tweets):
print 'Posting to Twitter...'
print 'New tweet count: ' + str(len(tweets)) + '.'
for tweet in tweets:
__twitter_api__.PostUpdate(tweet)
# Updates the ini file with the most recent entry.
def update_recent():
print 'Updating history...'
activity = __pump_me__.outbox.major[0]
latest = activity.id
published = activity.published
__ptp__.update_recent(latest, published)
# Pulls from Pump and produces text for some tweets.
# Nothing is sent to Twitter. This is for testing.
def pull_and_test():
print 'Testing PumpTweet...'
connect_to_servers()
notes = get_new_activities(testing=True)
tweets = make_tweets(notes)
print_tweets(tweets)
# Pulls from Pump and pushes to Twitter.
def pull_and_push():
connect_to_servers()
notes = get_new_activities()
tweets = make_tweets(notes)
print_tweets(tweets)
post_tweets(tweets)
update_recent()
description = 'Cross-post from pump to twitter. Call with no options for normal use.'
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-t', '--test', help='do a test-run without actually tweeting', action='store_true')
args = parser.parse_args()
if args.test:
pull_and_test()
else:
pull_and_push()