10 from io
import BytesIO
11 from twitter
.util
import printNicely
12 from functools
import wraps
13 from pyfiglet
import figlet_format
14 from dateutil
import parser
15 from .c_image
import *
18 from .py3patch
import *
21 # Draw global variables
29 colors_shuffle
= [globals()[i
.encode('utf8')]
30 if not str(i
).isdigit()
31 else term_color(int(i
))
32 for i
in c
['CYCLE_COLOR']]
33 return itertools
.cycle(colors_shuffle
)
40 dg
['cyc'] = init_cycle()
42 dg
['humanize_unsupported'] = False
47 Print a string with ordered color with each character
49 colors_shuffle
= [globals()[i
.encode('utf8')]
50 if not str(i
).isdigit()
51 else term_color(int(i
))
52 for i
in c
['CYCLE_COLOR']]
53 colored
= [colors_shuffle
[i
% 7](s
[i
]) for i
in xrange(len(s
))]
54 return ''.join(colored
)
57 def random_rainbow(s
):
59 Print a string with random color with each character
61 colors_shuffle
= [globals()[i
.encode('utf8')]
62 if not str(i
).isdigit()
63 else term_color(int(i
))
64 for i
in c
['CYCLE_COLOR']]
65 colored
= [random
.choice(colors_shuffle
)(i
) for i
in s
]
66 return ''.join(colored
)
75 if args
not in dg
['cache']:
76 dg
['cache'][args
] = func(*args
)
77 return dg
['cache'][args
]
84 Cycle the colors_shuffle
86 return next(dg
['cyc'])(s
)
93 fi
= figlet_format(text
, font
='doom')
95 [next(dg
['cyc'])(i
) for i
in fi
.split('\n')]
101 Check if config is changed
104 data
= get_all_config()
107 if data
[key
] != c
[key
]:
113 def validate_theme(theme
):
115 Validate a theme exists or not
117 # Theme changed check
118 files
= os
.listdir(os
.path
.dirname(__file__
) + '/colorset')
119 themes
= [f
.split('.')[0] for f
in files
if f
.split('.')[-1] == 'json']
120 return theme
in themes
123 def reload_theme(value
, prev
):
125 Check current theme and update if necessary
128 config
= os
.path
.dirname(
129 __file__
) + '/colorset/' + value
+ '.json'
131 data
= load_config(config
)
135 # Restart color cycle and update config
137 set_config('THEME', value
)
142 def color_func(func_name
):
144 Call color function base on name
146 if str(func_name
).isdigit():
147 return term_color(int(func_name
))
148 return globals()[func_name
]
151 def fallback_humanize(date
, fallback_format
=None, use_fallback
=False):
153 Format date with arrow and a fallback format
155 # Convert to local timezone
156 date
= arrow
.get(date
).to('local')
157 # Set default fallback format
158 if not fallback_format
:
159 fallback_format
= '%Y/%m/%d %H:%M:%S'
160 # Determine using fallback format or not by a variable
162 return date
.datetime
.strftime(fallback_format
)
164 # Use Arrow's humanize function
165 lang
, encode
= locale
.getdefaultlocale()
166 clock
= date
.humanize(locale
=lang
)
168 # Notice at the 1st time only
169 if not dg
['humanize_unsupported']:
170 dg
['humanize_unsupported'] = True
172 light_magenta('Humanized date display method does not support your $LC_ALL.'))
173 # Fallback when LC_ALL is not supported
174 clock
= date
.datetime
.strftime(fallback_format
)
178 def draw(t
, keyword
=None, humanize
=True, noti
=False, fil
=[], ig
=[]):
187 text
= t
.get('full_text', t
.get('text'))
188 screen_name
= t
['user']['screen_name']
189 name
= t
['user']['name']
190 created_at
= t
['created_at']
191 favorited
= t
['favorited']
192 retweet_count
= t
['retweet_count']
193 favorite_count
= t
['favorite_count']
195 date
= parser
.parse(created_at
)
197 clock_format
= c
['FORMAT']['TWEET']['CLOCK_FORMAT']
199 clock_format
= '%Y/%m/%d %H:%M:%S'
200 clock
= fallback_humanize(date
, clock_format
, not humanize
)
202 # Pull extended retweet text
204 text
= 'RT @' + t
['retweeted_status']['user']['screen_name'] + ': ' +\
205 t
['retweeted_status']['text']
206 # Display as a notification
207 target
= t
['retweeted_status']['user']['screen_name']
208 if all([target
== c
['original_name'], not noti
]):
209 # Add to evens for 'notification' command
210 t
['event'] = 'retweet'
211 c
['events'].append(t
)
217 # Unescape HTML character
218 text
= unescape(text
)
222 client
= client
.split('>')[-2].split('<')[0]
230 urls
= t
['entities']['urls']
232 expanded_url
.append(u
['expanded_url'])
241 media
= t
['entities']['media']
243 media_url
.append(m
['media_url'])
248 mytweet
= screen_name
== c
['original_name']
249 screen_name
= '@' + screen_name
250 fil
= list(set((fil
or []) + c
['ONLY_LIST']))
251 ig
= list(set((ig
or []) + c
['IGNORE_LIST']))
252 if fil
and screen_name
not in fil
:
254 if ig
and screen_name
in ig
:
258 if tid
not in c
['tweet_dict']:
259 c
['tweet_dict'].append(tid
)
260 rid
= len(c
['tweet_dict']) - 1
262 rid
= c
['tweet_dict'].index(tid
)
265 name
= cycle_color(name
)
267 nick
= color_func(c
['TWEET']['mynick'])(screen_name
)
269 nick
= color_func(c
['TWEET']['nick'])(screen_name
)
274 fav
= color_func(c
['TWEET']['favorited'])(u
'\u2605')
276 tweet
= text
.split(' ')
277 tweet
= [x
for x
in tweet
if x
!= '']
280 for index
in xrange(len(expanded_url
)):
282 lambda x
: expanded_url
[index
]
288 lambda x
: color_func(c
['TWEET']['rt'])(x
)
292 # Highlight screen_name
294 lambda x
: cycle_color(x
) if x
.lstrip().startswith('@') else x
, tweet
)
297 lambda x
: color_func(c
['TWEET']['link'])(x
)
298 if x
.lstrip().startswith('http')
303 lambda x
: color_func(c
['TWEET']['hashtag'])(x
)
304 if x
.lstrip().startswith('#')
309 tweet
= [color_func(c
['TWEET']['mytweet'])(x
)
313 x
.lstrip().startswith('http'),
314 x
.lstrip().startswith('#')])
317 tweet
= ' '.join(tweet
)
318 tweet
= '\n '.join(tweet
.split('\n'))
320 roj
= re
.search(keyword
, tweet
, re
.IGNORECASE
)
323 ary
= tweet
.split(occur
)
324 delimiter
= color_func(c
['TWEET']['keyword'])(occur
)
325 tweet
= delimiter
.join(ary
)
327 # Load config formater
330 formater
= c
['FORMAT']['TWEET']['DISPLAY']
331 formater
= name
.join(formater
.split('#name'))
332 formater
= nick
.join(formater
.split('#nick'))
333 formater
= fav
.join(formater
.split('#fav'))
334 formater
= tweet
.join(formater
.split('#tweet'))
335 formater
= emojize(formater
)
337 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
338 delimiter
= color_func(c
['TWEET']['clock'])(
339 clock
.join(word
.split('#clock')))
340 formater
= delimiter
.join(formater
.split(word
))
342 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
343 delimiter
= color_func(c
['TWEET']['id'])(id.join(word
.split('#id')))
344 formater
= delimiter
.join(formater
.split(word
))
345 # Change retweet count word
346 word
= [wo
for wo
in formater
.split() if '#rt_count' in wo
][0]
347 delimiter
= color_func(c
['TWEET']['retweet_count'])(
348 str(retweet_count
).join(word
.split('#rt_count')))
349 formater
= delimiter
.join(formater
.split(word
))
350 # Change favorites count word
351 word
= [wo
for wo
in formater
.split() if '#fa_count' in wo
][0]
352 delimiter
= color_func(c
['TWEET']['favorite_count'])(
353 str(favorite_count
).join(word
.split('#fa_count')))
354 formater
= delimiter
.join(formater
.split(word
))
356 word
= [wo
for wo
in formater
.split() if '#client' in wo
][0]
357 delimiter
= color_func(c
['TWEET']['client'])(
358 client
.join(word
.split('#client')))
359 formater
= delimiter
.join(formater
.split(word
))
363 # Add spaces in begining of line if this is inside a notification
365 formater
= '\n '.join(formater
.split('\n'))
367 if formater
.startswith('\n'):
368 formater
= formater
[1:]
371 printNicely(formater
)
374 if c
['IMAGE_ON_TERM'] and media_url
:
377 response
= requests
.get(mu
)
378 image_to_display(BytesIO(response
.content
))
380 printNicely(red('Sorry, image link is broken'))
383 def print_threads(d
):
385 Print threads of messages
390 messages
= d
[partner
]
391 count
= len(messages
)
392 screen_name
= '@' + partner
[0]
394 screen_name
= color_func(c
['MESSAGE']['partner'])(screen_name
)
395 name
= cycle_color(name
)
396 thread_id
= color_func(c
['MESSAGE']['id'])('thread_id:' + str(id))
397 line
= ' ' * 2 + name
+ ' ' + screen_name
+ \
398 ' (' + str(count
) + ' message) ' + thread_id
406 def print_thread(partner
, me_nick
, me_name
):
408 Print a thread of messages
410 # Sort messages by time
411 messages
= dg
['thread'][partner
]
412 messages
.sort(key
=lambda x
: parser
.parse(x
['created_at']))
413 # Use legacy display on non-ascii text message
414 ms
= [m
['text'] for m
in messages
]
415 ums
= [m
for m
in ms
if not all(ord(c
) < 128 for c
in m
)]
421 # Print the first line
422 dg
['frame_margin'] = margin
= 2
423 partner_nick
= partner
[0]
424 partner_name
= partner
[1]
425 left_size
= len(partner_nick
) + len(partner_name
) + 2
426 right_size
= len(me_nick
) + len(me_name
) + 2
427 partner_nick
= color_func(c
['MESSAGE']['partner'])('@' + partner_nick
)
428 partner_name
= cycle_color(partner_name
)
429 me_screen_name
= color_func(c
['MESSAGE']['me'])('@' + me_nick
)
430 me_name
= cycle_color(me_name
)
431 left
= ' ' * margin
+ partner_name
+ ' ' + partner_nick
432 right
= me_name
+ ' ' + me_screen_name
+ ' ' * margin
433 h
, w
= os
.popen('stty size', 'r').read().split()
435 line
= '{}{}{}'.format(
436 left
, ' ' * (w
- left_size
- right_size
- 2 * margin
), right
)
442 if m
['sender_screen_name'] == me_nick
:
443 print_right_message(m
)
444 elif m
['recipient_screen_name'] == me_nick
:
445 print_left_message(m
)
448 def print_right_message(m
):
450 Print a message on the right of screen
452 h
, w
= os
.popen('stty size', 'r').read().split()
454 frame_width
= w
// 3 - dg
['frame_margin']
455 frame_width
= max(c
['THREAD_MIN_WIDTH'], frame_width
)
456 step
= frame_width
- 2 * dg
['frame_margin']
457 slicing
= textwrap
.wrap(m
['text'], step
)
458 spaces
= w
- frame_width
- dg
['frame_margin']
459 dotline
= ' ' * spaces
+ '-' * frame_width
460 dotline
= color_func(c
['MESSAGE']['me_frame'])(dotline
)
464 fill
= step
- len(line
)
465 screen_line
= ' ' * spaces
+ '| ' + line
+ ' ' * fill
+ ' '
466 if slicing
[-1] == line
:
467 screen_line
= screen_line
+ ' >'
469 screen_line
= screen_line
+ '|'
470 screen_line
= color_func(c
['MESSAGE']['me_frame'])(screen_line
)
471 printNicely(screen_line
)
474 date
= parser
.parse(m
['created_at'])
475 date
= arrow
.get(date
).to('local').datetime
476 clock_format
= '%Y/%m/%d %H:%M:%S'
478 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
481 clock
= date
.strftime(clock_format
)
483 if m
['id'] not in c
['message_dict']:
484 c
['message_dict'].append(m
['id'])
485 rid
= len(c
['message_dict']) - 1
487 rid
= c
['message_dict'].index(m
['id'])
492 virtual_meta
= formater
= c
['THREAD_META_RIGHT']
493 virtual_meta
= clock
.join(virtual_meta
.split('#clock'))
494 virtual_meta
= id.join(virtual_meta
.split('#id'))
496 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
497 delimiter
= color_func(c
['MESSAGE']['clock'])(
498 clock
.join(word
.split('#clock')))
499 formater
= delimiter
.join(formater
.split(word
))
501 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
502 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
503 formater
= delimiter
.join(formater
.split(word
))
504 formater
= emojize(formater
)
506 printNicely(red('Wrong format in config.'))
509 line
= ' ' * (w
- len(virtual_meta
) - dg
['frame_margin']) + meta
513 def print_left_message(m
):
515 Print a message on the left of screen
517 h
, w
= os
.popen('stty size', 'r').read().split()
519 frame_width
= w
// 3 - dg
['frame_margin']
520 frame_width
= max(c
['THREAD_MIN_WIDTH'], frame_width
)
521 step
= frame_width
- 2 * dg
['frame_margin']
522 slicing
= textwrap
.wrap(m
['text'], step
)
523 spaces
= dg
['frame_margin']
524 dotline
= ' ' * spaces
+ '-' * frame_width
525 dotline
= color_func(c
['MESSAGE']['partner_frame'])(dotline
)
529 fill
= step
- len(line
)
530 screen_line
= ' ' + line
+ ' ' * fill
+ ' |'
531 if slicing
[-1] == line
:
532 screen_line
= ' ' * (spaces
- 1) + '< ' + screen_line
534 screen_line
= ' ' * spaces
+ '|' + screen_line
535 screen_line
= color_func(c
['MESSAGE']['partner_frame'])(screen_line
)
536 printNicely(screen_line
)
539 date
= parser
.parse(m
['created_at'])
540 date
= arrow
.get(date
).to('local').datetime
541 clock_format
= '%Y/%m/%d %H:%M:%S'
543 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
546 clock
= date
.strftime(clock_format
)
548 if m
['id'] not in c
['message_dict']:
549 c
['message_dict'].append(m
['id'])
550 rid
= len(c
['message_dict']) - 1
552 rid
= c
['message_dict'].index(m
['id'])
557 virtual_meta
= formater
= c
['THREAD_META_LEFT']
558 virtual_meta
= clock
.join(virtual_meta
.split('#clock'))
559 virtual_meta
= id.join(virtual_meta
.split('#id'))
561 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
562 delimiter
= color_func(c
['MESSAGE']['clock'])(
563 clock
.join(word
.split('#clock')))
564 formater
= delimiter
.join(formater
.split(word
))
566 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
567 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
568 formater
= delimiter
.join(formater
.split(word
))
569 formater
= emojize(formater
)
571 printNicely(red('Wrong format in config.'))
574 line
= ' ' * dg
['frame_margin'] + meta
578 def print_message(m
):
583 sender_screen_name
= '@' + m
['sender_screen_name']
584 sender_name
= m
['sender']['name']
585 text
= unescape(m
['text'])
586 recipient_screen_name
= '@' + m
['recipient_screen_name']
587 recipient_name
= m
['recipient']['name']
589 date
= parser
.parse(m
['created_at'])
590 date
= arrow
.get(date
).to('local').datetime
591 clock_format
= '%Y/%m/%d %H:%M:%S'
593 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
596 clock
= date
.strftime(clock_format
)
599 if mid
not in c
['message_dict']:
600 c
['message_dict'].append(mid
)
601 rid
= len(c
['message_dict']) - 1
603 rid
= c
['message_dict'].index(mid
)
606 sender_name
= cycle_color(sender_name
)
607 sender_nick
= color_func(c
['MESSAGE']['sender'])(sender_screen_name
)
608 recipient_name
= cycle_color(recipient_name
)
609 recipient_nick
= color_func(
610 c
['MESSAGE']['recipient'])(recipient_screen_name
)
611 to
= color_func(c
['MESSAGE']['to'])('>>>')
615 text
= ''.join(lmap(lambda x
: x
+ ' ' if x
== '\n' else x
, text
))
617 # Load config formater
619 formater
= c
['FORMAT']['MESSAGE']['DISPLAY']
620 formater
= sender_name
.join(formater
.split("#sender_name"))
621 formater
= sender_nick
.join(formater
.split("#sender_nick"))
622 formater
= to
.join(formater
.split("#to"))
623 formater
= recipient_name
.join(formater
.split("#recipient_name"))
624 formater
= recipient_nick
.join(formater
.split("#recipient_nick"))
625 formater
= text
.join(formater
.split("#message"))
627 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
628 delimiter
= color_func(c
['MESSAGE']['clock'])(
629 clock
.join(word
.split('#clock')))
630 formater
= delimiter
.join(formater
.split(word
))
632 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
633 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
634 formater
= delimiter
.join(formater
.split(word
))
635 formater
= emojize(formater
)
637 printNicely(red('Wrong format in config.'))
641 printNicely(formater
)
644 def notify_retweet(t
):
649 created_at
= t
['created_at']
651 source_user
= cycle_color(source
['name']) + \
652 color_func(c
['NOTIFICATION']['source_nick'])(
653 ' @' + source
['screen_name'])
654 notify
= color_func(c
['NOTIFICATION']['notify'])(
655 'retweeted your tweet')
656 date
= parser
.parse(created_at
)
657 clock
= fallback_humanize(date
)
658 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
659 meta
= c
['NOTIFY_FORMAT']
660 meta
= source_user
.join(meta
.split('#source_user'))
661 meta
= notify
.join(meta
.split('#notify'))
662 meta
= clock
.join(meta
.split('#clock'))
667 draw(t
=t
['retweeted_status'], noti
=True)
670 def notify_favorite(e
):
672 Notify a favorite event
676 if target
['screen_name'] != c
['original_name']:
679 target_object
= e
['target_object']
680 created_at
= e
['created_at']
682 source_user
= cycle_color(source
['name']) + \
683 color_func(c
['NOTIFICATION']['source_nick'])(
684 ' @' + source
['screen_name'])
685 notify
= color_func(c
['NOTIFICATION']['notify'])(
686 'favorited your tweet')
687 date
= parser
.parse(created_at
)
688 clock
= fallback_humanize(date
)
689 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
690 meta
= c
['NOTIFY_FORMAT']
691 meta
= source_user
.join(meta
.split('#source_user'))
692 meta
= notify
.join(meta
.split('#notify'))
693 meta
= clock
.join(meta
.split('#clock'))
698 draw(t
=target_object
, noti
=True)
701 def notify_unfavorite(e
):
703 Notify a unfavorite event
707 if target
['screen_name'] != c
['original_name']:
710 target_object
= e
['target_object']
711 created_at
= e
['created_at']
713 source_user
= cycle_color(source
['name']) + \
714 color_func(c
['NOTIFICATION']['source_nick'])(
715 ' @' + source
['screen_name'])
716 notify
= color_func(c
['NOTIFICATION']['notify'])(
717 'unfavorited your tweet')
718 date
= parser
.parse(created_at
)
719 clock
= fallback_humanize(date
)
720 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
721 meta
= c
['NOTIFY_FORMAT']
722 meta
= source_user
.join(meta
.split('#source_user'))
723 meta
= notify
.join(meta
.split('#notify'))
724 meta
= clock
.join(meta
.split('#clock'))
729 draw(t
=target_object
, noti
=True)
732 def notify_follow(e
):
734 Notify a follow event
738 if target
['screen_name'] != c
['original_name']:
741 created_at
= e
['created_at']
743 source_user
= cycle_color(source
['name']) + \
744 color_func(c
['NOTIFICATION']['source_nick'])(
745 ' @' + source
['screen_name'])
746 notify
= color_func(c
['NOTIFICATION']['notify'])(
748 date
= parser
.parse(created_at
)
749 clock
= fallback_humanize(date
)
750 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
751 meta
= c
['NOTIFY_FORMAT']
752 meta
= source_user
.join(meta
.split('#source_user'))
753 meta
= notify
.join(meta
.split('#notify'))
754 meta
= clock
.join(meta
.split('#clock'))
761 def notify_list_member_added(e
):
763 Notify a list_member_added event
767 if target
['screen_name'] != c
['original_name']:
770 target_object
= [e
['target_object']] # list of Twitter list
771 created_at
= e
['created_at']
773 source_user
= cycle_color(source
['name']) + \
774 color_func(c
['NOTIFICATION']['source_nick'])(
775 ' @' + source
['screen_name'])
776 notify
= color_func(c
['NOTIFICATION']['notify'])(
777 'added you to a list')
778 date
= parser
.parse(created_at
)
779 clock
= fallback_humanize(date
)
780 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
781 meta
= c
['NOTIFY_FORMAT']
782 meta
= source_user
.join(meta
.split('#source_user'))
783 meta
= notify
.join(meta
.split('#notify'))
784 meta
= clock
.join(meta
.split('#clock'))
789 print_list(target_object
, noti
=True)
792 def notify_list_member_removed(e
):
794 Notify a list_member_removed event
798 if target
['screen_name'] != c
['original_name']:
801 target_object
= [e
['target_object']] # list of Twitter list
802 created_at
= e
['created_at']
804 source_user
= cycle_color(source
['name']) + \
805 color_func(c
['NOTIFICATION']['source_nick'])(
806 ' @' + source
['screen_name'])
807 notify
= color_func(c
['NOTIFICATION']['notify'])(
808 'removed you from a list')
809 date
= parser
.parse(created_at
)
810 clock
= fallback_humanize(date
)
811 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
812 meta
= c
['NOTIFY_FORMAT']
813 meta
= source_user
.join(meta
.split('#source_user'))
814 meta
= notify
.join(meta
.split('#notify'))
815 meta
= clock
.join(meta
.split('#clock'))
820 print_list(target_object
, noti
=True)
823 def notify_list_user_subscribed(e
):
825 Notify a list_user_subscribed event
829 if target
['screen_name'] != c
['original_name']:
832 target_object
= [e
['target_object']] # list of Twitter list
833 created_at
= e
['created_at']
835 source_user
= cycle_color(source
['name']) + \
836 color_func(c
['NOTIFICATION']['source_nick'])(
837 ' @' + source
['screen_name'])
838 notify
= color_func(c
['NOTIFICATION']['notify'])(
839 'subscribed to your list')
840 date
= parser
.parse(created_at
)
841 clock
= fallback_humanize(date
)
842 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
843 meta
= c
['NOTIFY_FORMAT']
844 meta
= source_user
.join(meta
.split('#source_user'))
845 meta
= notify
.join(meta
.split('#notify'))
846 meta
= clock
.join(meta
.split('#clock'))
851 print_list(target_object
, noti
=True)
854 def notify_list_user_unsubscribed(e
):
856 Notify a list_user_unsubscribed event
860 if target
['screen_name'] != c
['original_name']:
863 target_object
= [e
['target_object']] # list of Twitter list
864 created_at
= e
['created_at']
866 source_user
= cycle_color(source
['name']) + \
867 color_func(c
['NOTIFICATION']['source_nick'])(
868 ' @' + source
['screen_name'])
869 notify
= color_func(c
['NOTIFICATION']['notify'])(
870 'unsubscribed from your list')
871 date
= parser
.parse(created_at
)
872 clock
= fallback_humanize(date
)
873 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
874 meta
= c
['NOTIFY_FORMAT']
875 meta
= source_user
.join(meta
.split('#source_user'))
876 meta
= notify
.join(meta
.split('#notify'))
877 meta
= clock
.join(meta
.split('#clock'))
882 print_list(target_object
, noti
=True)
890 'retweet': notify_retweet
,
891 'favorite': notify_favorite
,
892 'unfavorite': notify_unfavorite
,
893 'follow': notify_follow
,
894 'list_member_added': notify_list_member_added
,
895 'list_member_removed': notify_list_member_removed
,
896 'list_user_subscribed': notify_list_user_subscribed
,
897 'list_user_unsubscribed': notify_list_user_unsubscribed
,
899 event_dict
.get(e
['event'], lambda *args
: None)(e
)
908 screen_name
= u
['screen_name']
909 description
= u
['description']
910 profile_image_url
= u
['profile_image_url']
911 location
= u
['location']
913 created_at
= u
['created_at']
914 statuses_count
= u
['statuses_count']
915 friends_count
= u
['friends_count']
916 followers_count
= u
['followers_count']
919 statuses_count
= color_func(
920 c
['PROFILE']['statuses_count'])(
921 str(statuses_count
) +
923 friends_count
= color_func(
924 c
['PROFILE']['friends_count'])(
927 followers_count
= color_func(
928 c
['PROFILE']['followers_count'])(
929 str(followers_count
) +
931 count
= statuses_count
+ ' ' + friends_count
+ ' ' + followers_count
933 name
) + color_func(c
['PROFILE']['nick'])(' @' + screen_name
+ ' : ') + count
934 profile_image_raw_url
= 'Profile photo: ' + \
935 color_func(c
['PROFILE']['profile_image_url'])(profile_image_url
)
936 description
= ''.join(
937 lmap(lambda x
: x
+ ' ' * 4 if x
== '\n' else x
, description
))
938 description
= color_func(c
['PROFILE']['description'])(description
)
939 location
= 'Location : ' + color_func(c
['PROFILE']['location'])(location
)
940 url
= 'URL : ' + (color_func(c
['PROFILE']['url'])(url
) if url
else '')
941 date
= parser
.parse(created_at
)
942 clock
= fallback_humanize(date
)
943 clock
= 'Joined ' + color_func(c
['PROFILE']['clock'])(clock
)
946 line1
= u
"{u:>{uw}}".format(
950 line2
= u
"{p:>{pw}}".format(
951 p
=profile_image_raw_url
,
952 pw
=len(profile_image_raw_url
) + 4,
954 line3
= u
"{d:>{dw}}".format(
956 dw
=len(description
) + 4,
958 line4
= u
"{l:>{lw}}".format(
960 lw
=len(location
) + 4,
962 line5
= u
"{u:>{uw}}".format(
966 line6
= u
"{c:>{cw}}".format(
974 if c
['IMAGE_ON_TERM']:
976 response
= requests
.get(profile_image_url
)
977 image_to_display(BytesIO(response
.content
))
982 for line
in [line3
, line4
, line5
, line6
]:
987 def print_trends(trends
):
991 for topic
in trends
[:c
['TREND_MAX']]:
994 line
= cycle_color(name
) + ': ' + color_func(c
['TREND']['url'])(url
)
999 def print_list(group
, noti
=False):
1005 name
= grp
['full_name']
1006 name
= color_func(c
['GROUP']['name'])(name
+ ' : ')
1007 member
= str(grp
['member_count'])
1008 member
= color_func(c
['GROUP']['member'])(member
+ ' member')
1009 subscriber
= str(grp
['subscriber_count'])
1010 subscriber
= color_func(
1011 c
['GROUP']['subscriber'])(
1014 description
= grp
['description'].strip()
1015 description
= color_func(c
['GROUP']['description'])(description
)
1017 mode
= color_func(c
['GROUP']['mode'])('Type: ' + mode
)
1018 created_at
= grp
['created_at']
1019 date
= parser
.parse(created_at
)
1020 clock
= fallback_humanize(date
)
1021 clock
= 'Created at ' + color_func(c
['GROUP']['clock'])(clock
)
1024 # Add spaces in begining of line if this is inside a notification
1026 prefix
= ' ' * 2 + prefix
1028 line1
= prefix
+ name
+ member
+ ' ' + subscriber
1029 line2
= prefix
+ ' ' * 2 + description
1030 line3
= prefix
+ ' ' * 2 + mode
1031 line4
= prefix
+ ' ' * 2 + clock
1044 def show_calendar(month
, date
, rel
):
1046 Show the calendar in rainbow mode
1048 month
= random_rainbow(month
)
1049 date
= ' '.join([cycle_color(i
) for i
in date
.split(' ')])
1050 today
= str(int(os
.popen('date +\'%d\'').read().strip()))
1055 ary
= line
.split(' ')
1057 lambda x
: color_func(c
['CAL']['today'])(x
)
1059 else color_func(c
['CAL']['days'])(x
),
1061 printNicely(' '.join(ary
))
1064 def format_quote(tweet
):
1069 screen_name
= tweet
['user']['screen_name']
1070 text
= tweet
['text']
1071 tid
= str( tweet
['id'] )
1073 # Validate quote format
1074 if '#owner' not in c
['QUOTE_FORMAT']:
1075 printNicely(light_magenta('Quote should contains #owner'))
1077 if '#comment' not in c
['QUOTE_FORMAT']:
1078 printNicely(light_magenta('Quote format should have #comment'))
1084 formater
= c
['QUOTE_FORMAT']
1086 formater
= formater
.replace('#owner', screen_name
)
1087 formater
= formater
.replace('#tweet', text
)
1088 formater
= formater
.replace('#tid', tid
)
1090 formater
= emojize(formater
)
1093 # Highlight like a tweet
1094 notice
= formater
.split()
1096 lambda x
: light_green(x
)
1101 lambda x
: color_func(c
['TWEET']['rt'])(x
)
1105 notice
= lmap(lambda x
: cycle_color(x
) if x
[0] == '@' else x
, notice
)
1107 lambda x
: color_func(c
['TWEET']['link'])(x
)
1112 lambda x
: color_func(c
['TWEET']['hashtag'])(x
)
1113 if x
.startswith('#')
1116 notice
= ' '.join(notice
)
1118 notice
= light_magenta('Quoting: "') + notice
+ light_magenta('"')
1123 # Start the color cycle