keyword None
[rainbowstream.git] / rainbowstream / rainbow.py
CommitLineData
91476ec3
O
1"""
2Colorful user's timeline stream
3"""
4
5from __future__ import print_function
54277114 6from multiprocessing import Process
91476ec3 7
f405a7d0 8import os, os.path, argparse, sys, time, signal
91476ec3
O
9
10from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
54277114 11from twitter.api import *
91476ec3 12from twitter.oauth import OAuth, read_token_file
8c840a83 13from twitter.oauth_dance import oauth_dance
91476ec3
O
14from twitter.util import printNicely
15from dateutil import parser
91476ec3 16
2a6238f5
O
17from .colors import *
18from .config import *
19
f405a7d0 20g = {}
91476ec3 21
b8dda704 22def draw(t,keyword=None):
91476ec3
O
23 """
24 Draw the rainbow
25 """
26 # Retrieve tweet
27 text = t['text']
28 screen_name = t['user']['screen_name']
29 name = t['user']['name']
30 created_at = t['created_at']
31 date = parser.parse(created_at)
32 time = date.strftime('%Y/%m/%d %H:%M:%S')
33
34 # Format info
54277114 35 user = cycle_color(name) + grey(' ' + '@' + screen_name + ' ')
2a6238f5 36 clock = grey('[' + time + ']')
8c840a83 37 tweet = text.split()
b8dda704 38 # Highlight RT
2a6238f5 39 tweet = map(lambda x: grey(x) if x == 'RT' else x, tweet)
b8dda704 40 # Highlight screen_name
2a6238f5 41 tweet = map(lambda x: cycle_color(x) if x[0] == '@' else x, tweet)
b8dda704 42 # Highlight link
2a6238f5 43 tweet = map(lambda x: cyan(x) if x[0:7] == 'http://' else x, tweet)
b8dda704 44 # Highlight search keyword
7a431249
O
45 if keyword:
46 tweet = map(lambda x: on_yellow(x) if ''.join(c for c in x if c.isalnum()).lower() == keyword.lower() else x, tweet)
8c840a83 47 tweet = ' '.join(tweet)
91476ec3
O
48
49 # Draw rainbow
06773ffe 50 line1 = u"{u:>{uw}}:".format(
2a6238f5
O
51 u=user,
52 uw=len(user) + 2,
91476ec3 53 )
06773ffe 54 line2 = u"{c:>{cw}}".format(
2a6238f5
O
55 c=clock,
56 cw=len(clock) + 2,
06773ffe
O
57 )
58 line3 = ' ' + tweet
59 line4 = '\n'
91476ec3 60
f405a7d0
O
61 printNicely(line1)
62 printNicely(line2)
63 printNicely(line3)
64 printNicely(line4)
91476ec3
O
65
66
67def parse_arguments():
68 """
69 Parse the arguments
70 """
71
72 parser = argparse.ArgumentParser(description=__doc__ or "")
73
2a6238f5
O
74 parser.add_argument(
75 '-to',
76 '--timeout',
77 help='Timeout for the stream (seconds).')
78 parser.add_argument(
79 '-ht',
80 '--heartbeat-timeout',
81 help='Set heartbeat timeout.',
82 default=90)
83 parser.add_argument(
84 '-nb',
85 '--no-block',
86 action='store_true',
87 help='Set stream to non-blocking.')
88 parser.add_argument(
89 '-tt',
90 '--track-keywords',
91 help='Search the stream for specific text.')
91476ec3
O
92 return parser.parse_args()
93
94
54277114
O
95def authen():
96 """
97 authenticate with Twitter OAuth
98 """
8c840a83 99 # When using rainbow stream you must authorize.
2a6238f5
O
100 twitter_credential = os.environ.get(
101 'HOME',
102 os.environ.get(
103 'USERPROFILE',
104 '')) + os.sep + '.rainbow_oauth'
8c840a83
O
105 if not os.path.exists(twitter_credential):
106 oauth_dance("Rainbow Stream",
107 CONSUMER_KEY,
108 CONSUMER_SECRET,
109 twitter_credential)
110 oauth_token, oauth_token_secret = read_token_file(twitter_credential)
54277114 111 return OAuth(
2a6238f5
O
112 oauth_token,
113 oauth_token_secret,
114 CONSUMER_KEY,
115 CONSUMER_SECRET)
91476ec3 116
54277114
O
117
118def get_decorated_name():
119 """
120 Beginning of every line
121 """
122 t = Twitter(auth=authen())
123 name = '@' + t.statuses.user_timeline()[-1]['user']['screen_name']
f405a7d0 124 g['decorated_name'] = grey('[') + grey(name) + grey(']: ')
54277114 125
f405a7d0
O
126
127def tweet():
54277114
O
128 """
129 Authen and tweet
130 """
131 t = Twitter(auth=authen())
f405a7d0
O
132 t.statuses.update(status=g['stuff'])
133
134
135def search():
136 """
137 Authen and search
138 """
139 t = Twitter(auth=authen())
140 rel = t.search.tweets(q='#' + g['stuff'])['statuses']
141 printNicely(grey('**************************************************************************************\n'))
05105565 142 print('Newest',SEARCH_MAX_RECORD, 'tweet: \n')
f405a7d0 143 for i in xrange(5):
b8dda704 144 draw(t=rel[i],keyword=g['stuff'].strip())
f405a7d0
O
145 printNicely(grey('**************************************************************************************\n'))
146
147
148def help():
149 """
150 Print help
151 """
152 usage = '''
153 Hi boss! I'm ready to serve you right now!
154 ----------------------------------------------------
155 "!" at the beginning will start to tweet immediately
8c234c44 156 "/" at the beginning will search for 5 newest tweet
b8dda704
O
157 "?" or "h" will print this help once again
158 "c" will clear the terminal
f405a7d0
O
159 "q" will exit
160 ----------------------------------------------------
161 Hvae fun and hang tight!
162 '''
163 printNicely(usage)
164 sys.stdout.write(g['decorated_name'])
165
166
167def quit():
168 """
169 Exit all
170 """
171 os.kill(g['stream_pid'], signal.SIGKILL)
172 sys.exit()
173
174
b8dda704
O
175def clear():
176 """
177 Exit all
178 """
179 os.system('clear')
180
181
f405a7d0
O
182def process(line):
183 """
184 Process switch by start of line
185 """
186 return {
187 '!' : tweet,
188 '/' : search,
189 '?' : help,
b8dda704
O
190 'h' : help,
191 'c' : clear,
f405a7d0
O
192 'q' : quit,
193 }.get(line[0],lambda: sys.stdout.write(g['decorated_name']))
54277114
O
194
195
196def listen(stdin):
197 """
198 Listen to user's input
199 """
200 for line in iter(stdin.readline, ''):
f405a7d0
O
201 # Save cmd to global variable and call process
202 g['stuff'] = line[1:]
203 process(line)()
54277114
O
204 stdin.close()
205
206
207def stream():
208 """
f405a7d0 209 Track the stream
54277114
O
210 """
211 args = parse_arguments()
212
213 # The Logo
214 ascii_art()
91476ec3
O
215 # These arguments are optional:
216 stream_args = dict(
217 timeout=args.timeout,
218 block=not args.no_block,
219 heartbeat_timeout=args.heartbeat_timeout)
220
221 # Track keyword
222 query_args = dict()
223 if args.track_keywords:
224 query_args['track'] = args.track_keywords
225
226 # Get stream
2a6238f5 227 stream = TwitterStream(
54277114
O
228 auth = authen(),
229 domain = 'userstream.twitter.com',
2a6238f5 230 **stream_args)
91476ec3
O
231 tweet_iter = stream.user(**query_args)
232
233 # Iterate over the sample stream.
234 for tweet in tweet_iter:
235 if tweet is None:
236 printNicely("-- None --")
237 elif tweet is Timeout:
238 printNicely("-- Timeout --")
239 elif tweet is HeartbeatTimeout:
240 printNicely("-- Heartbeat Timeout --")
241 elif tweet is Hangup:
242 printNicely("-- Hangup --")
243 elif tweet.get('text'):
f405a7d0 244 draw(t=tweet)
54277114
O
245
246
247def fly():
248 """
249 Main function
250 """
251 get_decorated_name()
252 p = Process(target = stream)
253 p.start()
f405a7d0 254 g['stream_pid'] = p.pid
54277114
O
255 listen(sys.stdin)
256