forked from mavidser/terminal-twitter
/
app.py
181 lines (162 loc) · 5.41 KB
/
app.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
#!/usr/bin/env python
from keys import *
import webbrowser
import tweepy
import cPickle
import click
import os
USER_FILE = 'user.pkl'
TWEETS_FILE = 'tweets.pkl'
@click.group(invoke_without_command=True)
@click.option('--num','-n', default=25, help='The number of tweets to display (should be less than 200). Defaults to 25.', required = False)
@click.option('--pager/--no-pager', default=True, help='Display tweets via pager (less). Defaults to pager.')
@click.pass_context
def main(context,num,pager):
"""A CLI to Twitter with support to display, open and compose tweeets."""
if context.invoked_subcommand is None:
get_tweets(num,pager)
def login():
"""Authenticate and save the user."""
try:
auth=load_user()
except:
auth = save_user()
return tweepy.API(auth)
def load_user():
"""Load the user authentication details file."""
with open(USER_FILE, 'r') as f:
return cPickle.load(f)
def save_user():
"""Save the user authentication details in a file."""
auth = tweepy.OAuthHandler(API_KEY, API_SECRET)
try:
redirect_url = auth.get_authorization_url()
except tweepy.TweepError:
click.secho('Error - Failed to get request token.', fg="red")
click.echo('Open this link in your web browser:\n'+redirect_url)
verifier = raw_input('Enter the displayed PIN:')
try:
auth.get_access_token(verifier)
with open(USER_FILE, 'wb') as f:
cPickle.dump(auth, f, cPickle.HIGHEST_PROTOCOL)
except tweepy.TweepError:
click.secho('Error - Failed to get access token.', fg="red")
return auth
def load_tweets():
"""Load the last saved tweets details file."""
with open(TWEETS_FILE, 'r') as f:
return cPickle.load(f)
def save_tweets(tweets):
"""Save the user loaded tweets in a file."""
with open(TWEETS_FILE, 'wb') as f:
cPickle.dump(tweets, f, cPickle.HIGHEST_PROTOCOL)
def get_tweet_id(n):
"""Get the twitter id of a tweet, when supplied with the index."""
tweets = load_tweets();
tweet = tweets[n-1]
return {'author':tweet.author.screen_name,'id':tweet.id}
def print_home_timeline(tweets,pager):
"""Print the home timeline of the user."""
s=""
for i,tweet in enumerate(tweets):
s += ((click.style('[%d] ' %(i+1), bold=True, fg="blue") +
click.style('@%s - ' %tweet.author.screen_name, bold=True, fg="cyan") +
click.style('%s' %tweet.text)).encode('utf_8')+'\n\n')
if pager:
click.echo_via_pager(s)
else:
click.echo(s)
def update_status(photo,n=False):
api = login()
try:
if photo:
photo = click.prompt('Enter the photo path').encode('utf_8')
photo = photo.strip(' ')
photo = photo.strip('\'')
x=open(photo,'r')
if n:
reply_to = get_tweet_id(n)
tweet = click.prompt('Enter the text to go along with the photo',default='@%s' %reply_to['author'])
if tweet.find('@%s ' %reply_to['author']) >=0:
pass
else:
tweet = '@%s ' %reply_to['author'] + tweet
api.update_with_media(filename=x.name,status=tweet,file=x,in_reply_to_status_id=reply_to['id'])
else:
tweet = click.prompt('Enter the text to go along with the photo',default='')
api.update_with_media(filename=x.name,status=tweet,file=x)
else:
if n:
reply_to = get_tweet_id(n)
tweet = click.prompt('Enter the reply to @%s'%reply_to['author'])
if tweet.find('@%s ' %reply_to['author']) >=0:
pass
else:
tweet = '@%s ' %reply_to['author'] + tweet
api.update_status(status=tweet,in_reply_to_status_id=reply_to['id'])
else:
tweet = click.prompt('Enter the tweet')
api.update_status(tweet)
click.echo('Your tweet has been published')
except Exception as e:
click.secho('Error - %s' %e, fg="red")
@main.command()
@click.option('--photo', is_flag=True, help="Compose a tweet containing a photo.")
def compose(photo):
"""Composes a tweet."""
update_status(photo,False)
@main.command()
@click.option('--photo', is_flag=True, help="Reply with a tweet containing a photo.")
@click.argument('index',type=int)
def reply(photo,index):
"""Reply to a given tweet."""
update_status(photo,index)
@main.command()
@click.argument('index',type=int)
def rt(index):
"""Retweet a given tweet."""
api = login()
id=get_tweet_id(index)['id']
try:
api.retweet(id)
click.echo('Retweeted')
except Exception as e:
click.secho('Error - %s' %e, fg="red")
@main.command()
@click.argument('index',type=int)
def fav(index):
"""Favorite a tweet."""
api = login()
id=get_tweet_id(index)['id']
try:
api.create_favorite(id)
click.echo('Marked as Favorite')
except Exception as e:
click.secho('Error - %s' %e, fg="red")
@main.command()
@click.argument('index',type=int)
def browse(index):
"""Opens the tweet in web browser."""
details = get_tweet_id(index)
link = 'http://twitter.com/%s/status/%d' %(details['author'], details['id'])
try:
click.launch(link)
click.echo('Opening link %s' %link)
except Exception as e:
click.secho('Error - %s' %e, fg="red")
@main.command()
def logout():
"""Logout from the application."""
os.remove(USER_FILE)
click.echo('The user is logged out')
def get_tweets(n,pager):
"""Display the user's Twiter feed."""
api = login()
try:
tweets = api.home_timeline(count=n)
save_tweets(tweets)
print_home_timeline(tweets,pager)
except Exception as e:
click.secho('Error - %s' %e, fg="red")
if __name__ == '__main__':
main()