fix help
[rainbowstream.git] / rainbowstream / draw.py
CommitLineData
e9f5200b
VNM
1import random
2import itertools
7500d90b
VNM
3import requests
4import datetime
5import time
6
2da50cc4 7from twitter.util import printNicely
e9f5200b
VNM
8from functools import wraps
9from pyfiglet import figlet_format
7500d90b 10from dateutil import parser
2da50cc4 11from .c_image import *
7500d90b
VNM
12from .colors import *
13from .config import *
14from .db import *
c3bab4ef 15from .py3patch import *
16
7500d90b
VNM
17
18db = RainbowDB()
1fdd6a5c
VNM
19g = {}
20
e9f5200b
VNM
21def init_cycle():
22 """
23 Init the cycle
24 """
25 colors_shuffle = [globals()[i.encode('utf8')]
37ae740e 26 if not i.startswith('term_')
8124f3a8 27 else term_color(int(i[5:]))
e9f5200b 28 for i in c['CYCLE_COLOR']]
5f22104f 29 return itertools.cycle(colors_shuffle)
30g['cyc'] = init_cycle()
e43ebfa6 31g['cache'] = {}
1fdd6a5c 32
e9f5200b 33
e43ebfa6 34def reset_cycle():
2359c276
VNM
35 """
36 Notify from rainbow
37 """
5f22104f 38 g['cyc'] = init_cycle()
e43ebfa6 39 g['cache'] = {}
2359c276
VNM
40
41
e9f5200b
VNM
42def order_rainbow(s):
43 """
44 Print a string with ordered color with each character
45 """
5f22104f 46 colors_shuffle = [globals()[i.encode('utf8')]
47 if not i.startswith('term_')
48 else term_color(int(i[5:]))
49 for i in c['CYCLE_COLOR']]
50 colored = [colors_shuffle[i % 7](s[i]) for i in xrange(len(s))]
c3bab4ef 51 return ''.join(colored)
e9f5200b
VNM
52
53
54def random_rainbow(s):
55 """
56 Print a string with random color with each character
57 """
5f22104f 58 colors_shuffle = [globals()[i.encode('utf8')]
59 if not i.startswith('term_')
60 else term_color(int(i[5:]))
61 for i in c['CYCLE_COLOR']]
62 colored = [random.choice(colors_shuffle)(i) for i in s]
c3bab4ef 63 return ''.join(colored)
e9f5200b
VNM
64
65
66def Memoize(func):
67 """
68 Memoize decorator
69 """
e9f5200b
VNM
70 @wraps(func)
71 def wrapper(*args):
e43ebfa6 72 if args not in g['cache']:
73 g['cache'][args] = func(*args)
74 return g['cache'][args]
e9f5200b
VNM
75 return wrapper
76
77
78@Memoize
79def cycle_color(s):
80 """
81 Cycle the colors_shuffle
82 """
1fdd6a5c 83 return next(g['cyc'])(s)
e9f5200b
VNM
84
85
86def ascii_art(text):
87 """
88 Draw the Ascii Art
89 """
90 fi = figlet_format(text, font='doom')
91 print('\n'.join(
1fdd6a5c 92 [next(g['cyc'])(i) for i in fi.split('\n')]
e9f5200b
VNM
93 ))
94
95
2a0cabee
O
96def show_calendar(month, date, rel):
97 """
98 Show the calendar in rainbow mode
99 """
100 month = random_rainbow(month)
101 date = ' '.join([cycle_color(i) for i in date.split(' ')])
102 today = str(int(os.popen('date +\'%d\'').read().strip()))
103 # Display
104 printNicely(month)
105 printNicely(date)
106 for line in rel:
107 ary = line.split(' ')
c3bab4ef 108 ary = lmap(lambda x: color_func(c['CAL']['today'])(x)
2a0cabee
O
109 if x == today
110 else color_func(c['CAL']['days'])(x)
111 , ary)
112 printNicely(' '.join(ary))
113
114
4cf86720
VNM
115def check_theme():
116 """
117 Check current theme and update if necessary
118 """
119 exists = db.theme_query()
120 themes = [t.theme_name for t in exists]
ddb1e615
VNM
121 if c['theme'] != themes[0]:
122 c['theme'] = themes[0]
4cf86720 123 # Determine path
ddb1e615 124 if c['theme'] == 'custom':
4cf86720
VNM
125 config = os.environ.get(
126 'HOME',
9c7342ca 127 os.environ.get('USERPROFILE',
4cf86720
VNM
128 '')) + os.sep + '.rainbow_config.json'
129 else:
15f3e155 130 config = os.path.dirname(__file__) + '/colorset/'+c['theme']+'.json'
4cf86720
VNM
131 # Load new config
132 data = load_config(config)
a5301bc0
VNM
133 if data:
134 for d in data:
135 c[d] = data[d]
9c7342ca 136 # Re-init color cycle
1fdd6a5c 137 g['cyc'] = init_cycle()
7500d90b 138
fe08f905
VNM
139
140def color_func(func_name):
141 """
142 Call color function base on name
143 """
c3bab4ef 144 if func_name.startswith('term_') and func_name[5:].isdigit():
145 return term_color(int(func_name[5:]))
146 return globals()[func_name]
fe08f905
VNM
147
148
7500d90b
VNM
149def draw(t, iot=False, keyword=None, fil=[], ig=[]):
150 """
151 Draw the rainbow
152 """
153
4cf86720 154 check_theme()
7500d90b
VNM
155 # Retrieve tweet
156 tid = t['id']
157 text = t['text']
158 screen_name = t['user']['screen_name']
159 name = t['user']['name']
160 created_at = t['created_at']
161 favorited = t['favorited']
162 date = parser.parse(created_at)
163 date = date - datetime.timedelta(seconds=time.timezone)
164 clock = date.strftime('%Y/%m/%d %H:%M:%S')
165
166 # Get expanded url
167 try:
168 expanded_url = []
169 url = []
170 urls = t['entities']['urls']
171 for u in urls:
172 expanded_url.append(u['expanded_url'])
173 url.append(u['url'])
174 except:
175 expanded_url = None
176 url = None
177
178 # Get media
179 try:
180 media_url = []
181 media = t['entities']['media']
182 for m in media:
183 media_url.append(m['media_url'])
184 except:
185 media_url = None
186
187 # Filter and ignore
188 screen_name = '@' + screen_name
189 if fil and screen_name not in fil:
190 return
191 if ig and screen_name in ig:
192 return
193
194 # Get rainbow id
195 res = db.tweet_to_rainbow_query(tid)
196 if not res:
197 db.tweet_store(tid)
198 res = db.tweet_to_rainbow_query(tid)
199 rid = res[0].rainbow_id
200
201 # Format info
c075e6dc
O
202 user = cycle_color(
203 name) + color_func(c['TWEET']['nick'])(' ' + screen_name + ' ')
204 meta = color_func(c['TWEET']['clock'])(
205 '[' + clock + '] ') + color_func(c['TWEET']['id'])('[id=' + str(rid) + '] ')
7500d90b 206 if favorited:
1a0ac1b8 207 meta = meta + color_func(c['TWEET']['favorited'])(u'\u2605')
7500d90b
VNM
208 tweet = text.split()
209 # Replace url
210 if expanded_url:
211 for index in range(len(expanded_url)):
c3bab4ef 212 tweet = lmap(
7500d90b
VNM
213 lambda x: expanded_url[index] if x == url[index] else x,
214 tweet)
215 # Highlight RT
c3bab4ef 216 tweet = lmap(
c075e6dc
O
217 lambda x: color_func(
218 c['TWEET']['rt'])(x) if x == 'RT' else x,
219 tweet)
7500d90b 220 # Highlight screen_name
c3bab4ef 221 tweet = lmap(lambda x: cycle_color(x) if x[0] == '@' else x, tweet)
7500d90b 222 # Highlight link
c3bab4ef 223 tweet = lmap(
c075e6dc
O
224 lambda x: color_func(
225 c['TWEET']['link'])(x) if x[
226 0:4] == 'http' else x,
227 tweet)
7500d90b
VNM
228 # Highlight search keyword
229 if keyword:
c3bab4ef 230 tweet = lmap(
632c6fa5 231 lambda x: color_func(c['TWEET']['keyword'])(x) if
7500d90b
VNM
232 ''.join(c for c in x if c.isalnum()).lower() == keyword.lower()
233 else x,
234 tweet
235 )
236 # Recreate tweet
237 tweet = ' '.join(tweet)
238
239 # Draw rainbow
240 line1 = u"{u:>{uw}}:".format(
241 u=user,
242 uw=len(user) + 2,
243 )
244 line2 = u"{c:>{cw}}".format(
245 c=meta,
246 cw=len(meta) + 2,
247 )
248 line3 = ' ' + tweet
249
250 printNicely('')
251 printNicely(line1)
252 printNicely(line2)
253 printNicely(line3)
254
255 # Display Image
256 if iot and media_url:
257 for mu in media_url:
17bc529d 258 try:
259 response = requests.get(mu)
77f1d210 260 image_to_display(BytesIO(response.content))
261 except Exception:
17bc529d 262 printNicely(red('Sorry, image link is broken'))
7500d90b
VNM
263
264
265def print_message(m):
266 """
267 Print direct message
268 """
269 sender_screen_name = '@' + m['sender_screen_name']
270 sender_name = m['sender']['name']
271 text = m['text']
272 recipient_screen_name = '@' + m['recipient_screen_name']
273 recipient_name = m['recipient']['name']
274 mid = m['id']
275 date = parser.parse(m['created_at'])
276 date = date - datetime.timedelta(seconds=time.timezone)
277 clock = date.strftime('%Y/%m/%d %H:%M:%S')
278
279 # Get rainbow id
280 res = db.message_to_rainbow_query(mid)
281 if not res:
282 db.message_store(mid)
283 res = db.message_to_rainbow_query(mid)
284 rid = res[0].rainbow_id
285
6fa09c14 286 # Draw
c075e6dc
O
287 sender = cycle_color(
288 sender_name) + color_func(c['MESSAGE']['sender'])(' ' + sender_screen_name + ' ')
289 recipient = cycle_color(recipient_name) + color_func(
290 c['MESSAGE']['recipient'])(
291 ' ' + recipient_screen_name + ' ')
632c6fa5 292 user = sender + color_func(c['MESSAGE']['to'])(' >>> ') + recipient
c075e6dc
O
293 meta = color_func(
294 c['MESSAGE']['clock'])(
295 '[' + clock + ']') + color_func(
296 c['MESSAGE']['id'])(
297 ' [message_id=' + str(rid) + '] ')
c3bab4ef 298 text = ''.join(lmap(lambda x: x + ' ' if x == '\n' else x, text))
7500d90b
VNM
299
300 line1 = u"{u:>{uw}}:".format(
301 u=user,
302 uw=len(user) + 2,
303 )
304 line2 = u"{c:>{cw}}".format(
305 c=meta,
306 cw=len(meta) + 2,
307 )
308
309 line3 = ' ' + text
310
311 printNicely('')
312 printNicely(line1)
313 printNicely(line2)
314 printNicely(line3)
315
316
317def show_profile(u, iot=False):
318 """
319 Show a profile
320 """
321 # Retrieve info
322 name = u['name']
323 screen_name = u['screen_name']
324 description = u['description']
325 profile_image_url = u['profile_image_url']
326 location = u['location']
327 url = u['url']
328 created_at = u['created_at']
329 statuses_count = u['statuses_count']
330 friends_count = u['friends_count']
331 followers_count = u['followers_count']
6fa09c14 332
7500d90b 333 # Create content
c075e6dc
O
334 statuses_count = color_func(
335 c['PROFILE']['statuses_count'])(
336 str(statuses_count) +
337 ' tweets')
338 friends_count = color_func(
339 c['PROFILE']['friends_count'])(
340 str(friends_count) +
341 ' following')
342 followers_count = color_func(
343 c['PROFILE']['followers_count'])(
344 str(followers_count) +
345 ' followers')
7500d90b 346 count = statuses_count + ' ' + friends_count + ' ' + followers_count
c075e6dc
O
347 user = cycle_color(
348 name) + color_func(c['PROFILE']['nick'])(' @' + screen_name + ' : ') + count
349 profile_image_raw_url = 'Profile photo: ' + \
350 color_func(c['PROFILE']['profile_image_url'])(profile_image_url)
7500d90b 351 description = ''.join(
c3bab4ef 352 lmap(lambda x: x + ' ' * 4 if x == '\n' else x, description))
632c6fa5
O
353 description = color_func(c['PROFILE']['description'])(description)
354 location = 'Location : ' + color_func(c['PROFILE']['location'])(location)
355 url = 'URL : ' + (color_func(c['PROFILE']['url'])(url) if url else '')
7500d90b
VNM
356 date = parser.parse(created_at)
357 date = date - datetime.timedelta(seconds=time.timezone)
358 clock = date.strftime('%Y/%m/%d %H:%M:%S')
632c6fa5 359 clock = 'Join at ' + color_func(c['PROFILE']['clock'])(clock)
6fa09c14 360
7500d90b
VNM
361 # Format
362 line1 = u"{u:>{uw}}".format(
363 u=user,
364 uw=len(user) + 2,
365 )
366 line2 = u"{p:>{pw}}".format(
367 p=profile_image_raw_url,
368 pw=len(profile_image_raw_url) + 4,
369 )
370 line3 = u"{d:>{dw}}".format(
371 d=description,
372 dw=len(description) + 4,
373 )
374 line4 = u"{l:>{lw}}".format(
375 l=location,
376 lw=len(location) + 4,
377 )
378 line5 = u"{u:>{uw}}".format(
379 u=url,
380 uw=len(url) + 4,
381 )
382 line6 = u"{c:>{cw}}".format(
383 c=clock,
384 cw=len(clock) + 4,
385 )
6fa09c14 386
7500d90b
VNM
387 # Display
388 printNicely('')
389 printNicely(line1)
390 if iot:
17bc529d 391 try:
392 response = requests.get(profile_image_url)
77f1d210 393 image_to_display(BytesIO(response.content), 2, 20)
17bc529d 394 except:
395 pass
7500d90b
VNM
396 else:
397 printNicely(line2)
398 for line in [line3, line4, line5, line6]:
399 printNicely(line)
400 printNicely('')
401
402
403def print_trends(trends):
404 """
405 Display topics
406 """
632c6fa5 407 for topic in trends[:c['TREND_MAX']]:
7500d90b
VNM
408 name = topic['name']
409 url = topic['url']
8394e34b 410 line = cycle_color(name) + ': ' + color_func(c['TREND']['url'])(url)
7500d90b
VNM
411 printNicely(line)
412 printNicely('')
2d341029
O
413
414
415def print_list(group):
416 """
417 Display a list
418 """
419 for g in group:
420 # Format
421 name = g['name']
422 name = color_func(c['GROUP']['name'])(name + ' : ')
423 member = str(g['member_count'])
424 member = color_func(c['GROUP']['member'])(member+' member')
425 subscriber = str(g['subscriber_count'])
426 subscriber = color_func(c['GROUP']['subscriber'])(subscriber+' subscriber')
427 description = g['description'].strip()
428 description = color_func(c['GROUP']['description'])(description)
429 mode = g['mode']
430 mode = color_func(c['GROUP']['mode'])('Type: '+mode)
431 created_at = g['created_at']
432 date = parser.parse(created_at)
433 date = date - datetime.timedelta(seconds=time.timezone)
434 clock = date.strftime('%Y/%m/%d %H:%M:%S')
435 clock = 'Created at ' + color_func(c['GROUP']['clock'])(clock)
436
437 # Save to db
438 db.list_store(g['id'],g['name'])
439
440 # Create lines
441 line1 = ' '*2 + name + member + ' ' + subscriber
442 line2 = ' '*4 + description
443 line3 = ' '*4 + mode
444 line4 = ' '*4 + clock
445
446 # Display
447 printNicely('')
448 printNicely(line1)
449 printNicely(line2)
450 printNicely(line3)
451 printNicely(line4)
452
453 printNicely('')
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490