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 get_full_text(t
):
179 """Handle RTs and extended tweets to always display all the available text"""
181 if t
.get('retweeted_status'):
182 rt_status
= t
['retweeted_status']
183 if rt_status
.get('extended_tweet'):
184 elem
= rt_status
['extended_tweet']
187 rt_text
= elem
.get('full_text', elem
.get('text'))
188 t
['full_text'] = 'RT @' + rt_status
['user']['screen_name'] + ': ' + rt_text
189 elif t
.get('extended_tweet'):
190 t
['full_text'] = t
['extended_tweet']['full_text']
192 return t
.get('full_text', t
.get('text'))
195 def draw(t
, keyword
=None, humanize
=True, noti
=False, fil
=[], ig
=[]):
205 text
= get_full_text(t
)
206 screen_name
= t
['user']['screen_name']
207 name
= t
['user']['name']
208 created_at
= t
['created_at']
209 favorited
= t
['favorited']
210 retweet_count
= t
['retweet_count']
211 favorite_count
= t
['favorite_count']
213 date
= parser
.parse(created_at
)
215 clock_format
= c
['FORMAT']['TWEET']['CLOCK_FORMAT']
217 clock_format
= '%Y/%m/%d %H:%M:%S'
218 clock
= fallback_humanize(date
, clock_format
, not humanize
)
220 # Pull extended retweet text
222 # Display as a notification
223 target
= t
['retweeted_status']['user']['screen_name']
224 if all([target
== c
['original_name'], not noti
]):
225 # Add to evens for 'notification' command
226 t
['event'] = 'retweet'
227 c
['events'].append(t
)
233 # Unescape HTML character
234 text
= unescape(text
)
238 client
= client
.split('>')[-2].split('<')[0]
246 urls
= t
['entities']['urls']
248 expanded_url
.append(u
['expanded_url'])
257 media
= t
['entities']['media']
259 media_url
.append(m
['media_url'])
264 mytweet
= screen_name
== c
['original_name']
265 screen_name
= '@' + screen_name
266 fil
= list(set((fil
or []) + c
['ONLY_LIST']))
267 ig
= list(set((ig
or []) + c
['IGNORE_LIST']))
268 if fil
and screen_name
not in fil
:
270 if ig
and screen_name
in ig
:
274 if tid
not in c
['tweet_dict']:
275 c
['tweet_dict'].append(tid
)
276 rid
= len(c
['tweet_dict']) - 1
278 rid
= c
['tweet_dict'].index(tid
)
281 name
= cycle_color(name
)
283 nick
= color_func(c
['TWEET']['mynick'])(screen_name
)
285 nick
= color_func(c
['TWEET']['nick'])(screen_name
)
290 fav
= color_func(c
['TWEET']['favorited'])(u
'\u2605')
292 tweet
= text
.split(' ')
293 tweet
= [x
for x
in tweet
if x
!= '']
296 for index
in xrange(len(expanded_url
)):
298 lambda x
: expanded_url
[index
]
304 lambda x
: color_func(c
['TWEET']['rt'])(x
)
308 # Highlight screen_name
310 lambda x
: cycle_color(x
) if x
.lstrip().startswith('@') else x
, tweet
)
313 lambda x
: color_func(c
['TWEET']['link'])(x
)
314 if x
.lstrip().startswith('http')
319 lambda x
: color_func(c
['TWEET']['hashtag'])(x
)
320 if x
.lstrip().startswith('#')
325 tweet
= [color_func(c
['TWEET']['mytweet'])(x
)
329 x
.lstrip().startswith('http'),
330 x
.lstrip().startswith('#')])
333 tweet
= ' '.join(tweet
)
334 tweet
= '\n '.join(tweet
.split('\n'))
336 roj
= re
.search(keyword
, tweet
, re
.IGNORECASE
)
339 ary
= tweet
.split(occur
)
340 delimiter
= color_func(c
['TWEET']['keyword'])(occur
)
341 tweet
= delimiter
.join(ary
)
343 # Load config formater
346 formater
= c
['FORMAT']['TWEET']['DISPLAY']
347 formater
= name
.join(formater
.split('#name'))
348 formater
= nick
.join(formater
.split('#nick'))
349 formater
= fav
.join(formater
.split('#fav'))
350 formater
= tweet
.join(formater
.split('#tweet'))
351 formater
= emojize(formater
)
353 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
354 delimiter
= color_func(c
['TWEET']['clock'])(
355 clock
.join(word
.split('#clock')))
356 formater
= delimiter
.join(formater
.split(word
))
358 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
359 delimiter
= color_func(c
['TWEET']['id'])(id.join(word
.split('#id')))
360 formater
= delimiter
.join(formater
.split(word
))
361 # Change retweet count word
362 word
= [wo
for wo
in formater
.split() if '#rt_count' in wo
][0]
363 delimiter
= color_func(c
['TWEET']['retweet_count'])(
364 str(retweet_count
).join(word
.split('#rt_count')))
365 formater
= delimiter
.join(formater
.split(word
))
366 # Change favorites count word
367 word
= [wo
for wo
in formater
.split() if '#fa_count' in wo
][0]
368 delimiter
= color_func(c
['TWEET']['favorite_count'])(
369 str(favorite_count
).join(word
.split('#fa_count')))
370 formater
= delimiter
.join(formater
.split(word
))
372 word
= [wo
for wo
in formater
.split() if '#client' in wo
][0]
373 delimiter
= color_func(c
['TWEET']['client'])(
374 client
.join(word
.split('#client')))
375 formater
= delimiter
.join(formater
.split(word
))
379 # Add spaces in begining of line if this is inside a notification
381 formater
= '\n '.join(formater
.split('\n'))
383 if formater
.startswith('\n'):
384 formater
= formater
[1:]
387 printNicely(formater
)
390 if c
['IMAGE_ON_TERM'] and media_url
:
393 response
= requests
.get(mu
)
394 image_to_display(BytesIO(response
.content
))
396 printNicely(red('Sorry, image link is broken'))
399 def print_threads(d
):
401 Print threads of messages
406 messages
= d
[partner
]
407 count
= len(messages
)
408 screen_name
= '@' + partner
[0]
410 screen_name
= color_func(c
['MESSAGE']['partner'])(screen_name
)
411 name
= cycle_color(name
)
412 thread_id
= color_func(c
['MESSAGE']['id'])('thread_id:' + str(id))
413 line
= ' ' * 2 + name
+ ' ' + screen_name
+ \
414 ' (' + str(count
) + ' message) ' + thread_id
422 def print_thread(partner
, me_nick
, me_name
):
424 Print a thread of messages
426 # Sort messages by time
427 messages
= dg
['thread'][partner
]
428 messages
.sort(key
=lambda x
: parser
.parse(x
['created_at']))
429 # Use legacy display on non-ascii text message
430 ms
= [m
['text'] for m
in messages
]
431 ums
= [m
for m
in ms
if not all(ord(c
) < 128 for c
in m
)]
437 # Print the first line
438 dg
['frame_margin'] = margin
= 2
439 partner_nick
= partner
[0]
440 partner_name
= partner
[1]
441 left_size
= len(partner_nick
) + len(partner_name
) + 2
442 right_size
= len(me_nick
) + len(me_name
) + 2
443 partner_nick
= color_func(c
['MESSAGE']['partner'])('@' + partner_nick
)
444 partner_name
= cycle_color(partner_name
)
445 me_screen_name
= color_func(c
['MESSAGE']['me'])('@' + me_nick
)
446 me_name
= cycle_color(me_name
)
447 left
= ' ' * margin
+ partner_name
+ ' ' + partner_nick
448 right
= me_name
+ ' ' + me_screen_name
+ ' ' * margin
449 h
, w
= os
.popen('stty size', 'r').read().split()
451 line
= '{}{}{}'.format(
452 left
, ' ' * (w
- left_size
- right_size
- 2 * margin
), right
)
458 if m
['sender_screen_name'] == me_nick
:
459 print_right_message(m
)
460 elif m
['recipient_screen_name'] == me_nick
:
461 print_left_message(m
)
464 def print_right_message(m
):
466 Print a message on the right of screen
468 h
, w
= os
.popen('stty size', 'r').read().split()
470 frame_width
= w
// 3 - dg
['frame_margin']
471 frame_width
= max(c
['THREAD_MIN_WIDTH'], frame_width
)
472 step
= frame_width
- 2 * dg
['frame_margin']
473 slicing
= textwrap
.wrap(m
['text'], step
)
474 spaces
= w
- frame_width
- dg
['frame_margin']
475 dotline
= ' ' * spaces
+ '-' * frame_width
476 dotline
= color_func(c
['MESSAGE']['me_frame'])(dotline
)
480 fill
= step
- len(line
)
481 screen_line
= ' ' * spaces
+ '| ' + line
+ ' ' * fill
+ ' '
482 if slicing
[-1] == line
:
483 screen_line
= screen_line
+ ' >'
485 screen_line
= screen_line
+ '|'
486 screen_line
= color_func(c
['MESSAGE']['me_frame'])(screen_line
)
487 printNicely(screen_line
)
490 date
= parser
.parse(m
['created_at'])
491 date
= arrow
.get(date
).to('local').datetime
492 clock_format
= '%Y/%m/%d %H:%M:%S'
494 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
497 clock
= date
.strftime(clock_format
)
499 if m
['id'] not in c
['message_dict']:
500 c
['message_dict'].append(m
['id'])
501 rid
= len(c
['message_dict']) - 1
503 rid
= c
['message_dict'].index(m
['id'])
508 virtual_meta
= formater
= c
['THREAD_META_RIGHT']
509 virtual_meta
= clock
.join(virtual_meta
.split('#clock'))
510 virtual_meta
= id.join(virtual_meta
.split('#id'))
512 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
513 delimiter
= color_func(c
['MESSAGE']['clock'])(
514 clock
.join(word
.split('#clock')))
515 formater
= delimiter
.join(formater
.split(word
))
517 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
518 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
519 formater
= delimiter
.join(formater
.split(word
))
520 formater
= emojize(formater
)
522 printNicely(red('Wrong format in config.'))
525 line
= ' ' * (w
- len(virtual_meta
) - dg
['frame_margin']) + meta
529 def print_left_message(m
):
531 Print a message on the left of screen
533 h
, w
= os
.popen('stty size', 'r').read().split()
535 frame_width
= w
// 3 - dg
['frame_margin']
536 frame_width
= max(c
['THREAD_MIN_WIDTH'], frame_width
)
537 step
= frame_width
- 2 * dg
['frame_margin']
538 slicing
= textwrap
.wrap(m
['text'], step
)
539 spaces
= dg
['frame_margin']
540 dotline
= ' ' * spaces
+ '-' * frame_width
541 dotline
= color_func(c
['MESSAGE']['partner_frame'])(dotline
)
545 fill
= step
- len(line
)
546 screen_line
= ' ' + line
+ ' ' * fill
+ ' |'
547 if slicing
[-1] == line
:
548 screen_line
= ' ' * (spaces
- 1) + '< ' + screen_line
550 screen_line
= ' ' * spaces
+ '|' + screen_line
551 screen_line
= color_func(c
['MESSAGE']['partner_frame'])(screen_line
)
552 printNicely(screen_line
)
555 date
= parser
.parse(m
['created_at'])
556 date
= arrow
.get(date
).to('local').datetime
557 clock_format
= '%Y/%m/%d %H:%M:%S'
559 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
562 clock
= date
.strftime(clock_format
)
564 if m
['id'] not in c
['message_dict']:
565 c
['message_dict'].append(m
['id'])
566 rid
= len(c
['message_dict']) - 1
568 rid
= c
['message_dict'].index(m
['id'])
573 virtual_meta
= formater
= c
['THREAD_META_LEFT']
574 virtual_meta
= clock
.join(virtual_meta
.split('#clock'))
575 virtual_meta
= id.join(virtual_meta
.split('#id'))
577 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
578 delimiter
= color_func(c
['MESSAGE']['clock'])(
579 clock
.join(word
.split('#clock')))
580 formater
= delimiter
.join(formater
.split(word
))
582 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
583 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
584 formater
= delimiter
.join(formater
.split(word
))
585 formater
= emojize(formater
)
587 printNicely(red('Wrong format in config.'))
590 line
= ' ' * dg
['frame_margin'] + meta
594 def print_message(m
):
599 sender_screen_name
= '@' + m
['sender_screen_name']
600 sender_name
= m
['sender']['name']
601 text
= unescape(m
['text'])
602 recipient_screen_name
= '@' + m
['recipient_screen_name']
603 recipient_name
= m
['recipient']['name']
605 date
= parser
.parse(m
['created_at'])
606 date
= arrow
.get(date
).to('local').datetime
607 clock_format
= '%Y/%m/%d %H:%M:%S'
609 clock_format
= c
['FORMAT']['MESSAGE']['CLOCK_FORMAT']
612 clock
= date
.strftime(clock_format
)
615 if mid
not in c
['message_dict']:
616 c
['message_dict'].append(mid
)
617 rid
= len(c
['message_dict']) - 1
619 rid
= c
['message_dict'].index(mid
)
622 sender_name
= cycle_color(sender_name
)
623 sender_nick
= color_func(c
['MESSAGE']['sender'])(sender_screen_name
)
624 recipient_name
= cycle_color(recipient_name
)
625 recipient_nick
= color_func(
626 c
['MESSAGE']['recipient'])(recipient_screen_name
)
627 to
= color_func(c
['MESSAGE']['to'])('>>>')
631 text
= ''.join(lmap(lambda x
: x
+ ' ' if x
== '\n' else x
, text
))
633 # Load config formater
635 formater
= c
['FORMAT']['MESSAGE']['DISPLAY']
636 formater
= sender_name
.join(formater
.split("#sender_name"))
637 formater
= sender_nick
.join(formater
.split("#sender_nick"))
638 formater
= to
.join(formater
.split("#to"))
639 formater
= recipient_name
.join(formater
.split("#recipient_name"))
640 formater
= recipient_nick
.join(formater
.split("#recipient_nick"))
641 formater
= text
.join(formater
.split("#message"))
643 word
= [wo
for wo
in formater
.split() if '#clock' in wo
][0]
644 delimiter
= color_func(c
['MESSAGE']['clock'])(
645 clock
.join(word
.split('#clock')))
646 formater
= delimiter
.join(formater
.split(word
))
648 word
= [wo
for wo
in formater
.split() if '#id' in wo
][0]
649 delimiter
= color_func(c
['MESSAGE']['id'])(id.join(word
.split('#id')))
650 formater
= delimiter
.join(formater
.split(word
))
651 formater
= emojize(formater
)
653 printNicely(red('Wrong format in config.'))
657 printNicely(formater
)
660 def notify_retweet(t
):
665 created_at
= t
['created_at']
667 source_user
= cycle_color(source
['name']) + \
668 color_func(c
['NOTIFICATION']['source_nick'])(
669 ' @' + source
['screen_name'])
670 notify
= color_func(c
['NOTIFICATION']['notify'])(
671 'retweeted your tweet')
672 date
= parser
.parse(created_at
)
673 clock
= fallback_humanize(date
)
674 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
675 meta
= c
['NOTIFY_FORMAT']
676 meta
= source_user
.join(meta
.split('#source_user'))
677 meta
= notify
.join(meta
.split('#notify'))
678 meta
= clock
.join(meta
.split('#clock'))
683 draw(t
=t
['retweeted_status'], noti
=True)
686 def notify_favorite(e
):
688 Notify a favorite event
692 if target
['screen_name'] != c
['original_name']:
695 target_object
= e
['target_object']
696 created_at
= e
['created_at']
698 source_user
= cycle_color(source
['name']) + \
699 color_func(c
['NOTIFICATION']['source_nick'])(
700 ' @' + source
['screen_name'])
701 notify
= color_func(c
['NOTIFICATION']['notify'])(
702 'favorited your tweet')
703 date
= parser
.parse(created_at
)
704 clock
= fallback_humanize(date
)
705 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
706 meta
= c
['NOTIFY_FORMAT']
707 meta
= source_user
.join(meta
.split('#source_user'))
708 meta
= notify
.join(meta
.split('#notify'))
709 meta
= clock
.join(meta
.split('#clock'))
714 draw(t
=target_object
, noti
=True)
717 def notify_unfavorite(e
):
719 Notify a unfavorite event
723 if target
['screen_name'] != c
['original_name']:
726 target_object
= e
['target_object']
727 created_at
= e
['created_at']
729 source_user
= cycle_color(source
['name']) + \
730 color_func(c
['NOTIFICATION']['source_nick'])(
731 ' @' + source
['screen_name'])
732 notify
= color_func(c
['NOTIFICATION']['notify'])(
733 'unfavorited your tweet')
734 date
= parser
.parse(created_at
)
735 clock
= fallback_humanize(date
)
736 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
737 meta
= c
['NOTIFY_FORMAT']
738 meta
= source_user
.join(meta
.split('#source_user'))
739 meta
= notify
.join(meta
.split('#notify'))
740 meta
= clock
.join(meta
.split('#clock'))
745 draw(t
=target_object
, noti
=True)
748 def notify_follow(e
):
750 Notify a follow event
754 if target
['screen_name'] != c
['original_name']:
757 created_at
= e
['created_at']
759 source_user
= cycle_color(source
['name']) + \
760 color_func(c
['NOTIFICATION']['source_nick'])(
761 ' @' + source
['screen_name'])
762 notify
= color_func(c
['NOTIFICATION']['notify'])(
764 date
= parser
.parse(created_at
)
765 clock
= fallback_humanize(date
)
766 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
767 meta
= c
['NOTIFY_FORMAT']
768 meta
= source_user
.join(meta
.split('#source_user'))
769 meta
= notify
.join(meta
.split('#notify'))
770 meta
= clock
.join(meta
.split('#clock'))
777 def notify_list_member_added(e
):
779 Notify a list_member_added event
783 if target
['screen_name'] != c
['original_name']:
786 target_object
= [e
['target_object']] # list of Twitter list
787 created_at
= e
['created_at']
789 source_user
= cycle_color(source
['name']) + \
790 color_func(c
['NOTIFICATION']['source_nick'])(
791 ' @' + source
['screen_name'])
792 notify
= color_func(c
['NOTIFICATION']['notify'])(
793 'added you to a list')
794 date
= parser
.parse(created_at
)
795 clock
= fallback_humanize(date
)
796 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
797 meta
= c
['NOTIFY_FORMAT']
798 meta
= source_user
.join(meta
.split('#source_user'))
799 meta
= notify
.join(meta
.split('#notify'))
800 meta
= clock
.join(meta
.split('#clock'))
805 print_list(target_object
, noti
=True)
808 def notify_list_member_removed(e
):
810 Notify a list_member_removed event
814 if target
['screen_name'] != c
['original_name']:
817 target_object
= [e
['target_object']] # list of Twitter list
818 created_at
= e
['created_at']
820 source_user
= cycle_color(source
['name']) + \
821 color_func(c
['NOTIFICATION']['source_nick'])(
822 ' @' + source
['screen_name'])
823 notify
= color_func(c
['NOTIFICATION']['notify'])(
824 'removed you from a list')
825 date
= parser
.parse(created_at
)
826 clock
= fallback_humanize(date
)
827 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
828 meta
= c
['NOTIFY_FORMAT']
829 meta
= source_user
.join(meta
.split('#source_user'))
830 meta
= notify
.join(meta
.split('#notify'))
831 meta
= clock
.join(meta
.split('#clock'))
836 print_list(target_object
, noti
=True)
839 def notify_list_user_subscribed(e
):
841 Notify a list_user_subscribed event
845 if target
['screen_name'] != c
['original_name']:
848 target_object
= [e
['target_object']] # list of Twitter list
849 created_at
= e
['created_at']
851 source_user
= cycle_color(source
['name']) + \
852 color_func(c
['NOTIFICATION']['source_nick'])(
853 ' @' + source
['screen_name'])
854 notify
= color_func(c
['NOTIFICATION']['notify'])(
855 'subscribed to your list')
856 date
= parser
.parse(created_at
)
857 clock
= fallback_humanize(date
)
858 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
859 meta
= c
['NOTIFY_FORMAT']
860 meta
= source_user
.join(meta
.split('#source_user'))
861 meta
= notify
.join(meta
.split('#notify'))
862 meta
= clock
.join(meta
.split('#clock'))
867 print_list(target_object
, noti
=True)
870 def notify_list_user_unsubscribed(e
):
872 Notify a list_user_unsubscribed event
876 if target
['screen_name'] != c
['original_name']:
879 target_object
= [e
['target_object']] # list of Twitter list
880 created_at
= e
['created_at']
882 source_user
= cycle_color(source
['name']) + \
883 color_func(c
['NOTIFICATION']['source_nick'])(
884 ' @' + source
['screen_name'])
885 notify
= color_func(c
['NOTIFICATION']['notify'])(
886 'unsubscribed from your list')
887 date
= parser
.parse(created_at
)
888 clock
= fallback_humanize(date
)
889 clock
= color_func(c
['NOTIFICATION']['clock'])(clock
)
890 meta
= c
['NOTIFY_FORMAT']
891 meta
= source_user
.join(meta
.split('#source_user'))
892 meta
= notify
.join(meta
.split('#notify'))
893 meta
= clock
.join(meta
.split('#clock'))
898 print_list(target_object
, noti
=True)
906 'retweet': notify_retweet
,
907 'favorite': notify_favorite
,
908 'unfavorite': notify_unfavorite
,
909 'follow': notify_follow
,
910 'list_member_added': notify_list_member_added
,
911 'list_member_removed': notify_list_member_removed
,
912 'list_user_subscribed': notify_list_user_subscribed
,
913 'list_user_unsubscribed': notify_list_user_unsubscribed
,
915 event_dict
.get(e
['event'], lambda *args
: None)(e
)
924 screen_name
= u
['screen_name']
925 description
= u
['description']
926 profile_image_url
= u
['profile_image_url']
927 location
= u
['location']
929 created_at
= u
['created_at']
930 statuses_count
= u
['statuses_count']
931 friends_count
= u
['friends_count']
932 followers_count
= u
['followers_count']
935 statuses_count
= color_func(
936 c
['PROFILE']['statuses_count'])(
937 str(statuses_count
) +
939 friends_count
= color_func(
940 c
['PROFILE']['friends_count'])(
943 followers_count
= color_func(
944 c
['PROFILE']['followers_count'])(
945 str(followers_count
) +
947 count
= statuses_count
+ ' ' + friends_count
+ ' ' + followers_count
949 name
) + color_func(c
['PROFILE']['nick'])(' @' + screen_name
+ ' : ') + count
950 profile_image_raw_url
= 'Profile photo: ' + \
951 color_func(c
['PROFILE']['profile_image_url'])(profile_image_url
)
952 description
= ''.join(
953 lmap(lambda x
: x
+ ' ' * 4 if x
== '\n' else x
, description
))
954 description
= color_func(c
['PROFILE']['description'])(description
)
955 location
= 'Location : ' + color_func(c
['PROFILE']['location'])(location
)
956 url
= 'URL : ' + (color_func(c
['PROFILE']['url'])(url
) if url
else '')
957 date
= parser
.parse(created_at
)
958 clock
= fallback_humanize(date
)
959 clock
= 'Joined ' + color_func(c
['PROFILE']['clock'])(clock
)
962 line1
= u
"{u:>{uw}}".format(
966 line2
= u
"{p:>{pw}}".format(
967 p
=profile_image_raw_url
,
968 pw
=len(profile_image_raw_url
) + 4,
970 line3
= u
"{d:>{dw}}".format(
972 dw
=len(description
) + 4,
974 line4
= u
"{l:>{lw}}".format(
976 lw
=len(location
) + 4,
978 line5
= u
"{u:>{uw}}".format(
982 line6
= u
"{c:>{cw}}".format(
990 if c
['IMAGE_ON_TERM']:
992 response
= requests
.get(profile_image_url
)
993 image_to_display(BytesIO(response
.content
))
998 for line
in [line3
, line4
, line5
, line6
]:
1003 def print_trends(trends
):
1007 for topic
in trends
[:c
['TREND_MAX']]:
1008 name
= topic
['name']
1010 line
= cycle_color(name
) + ': ' + color_func(c
['TREND']['url'])(url
)
1015 def print_list(group
, noti
=False):
1021 name
= grp
['full_name']
1022 name
= color_func(c
['GROUP']['name'])(name
+ ' : ')
1023 member
= str(grp
['member_count'])
1024 member
= color_func(c
['GROUP']['member'])(member
+ ' member')
1025 subscriber
= str(grp
['subscriber_count'])
1026 subscriber
= color_func(
1027 c
['GROUP']['subscriber'])(
1030 description
= grp
['description'].strip()
1031 description
= color_func(c
['GROUP']['description'])(description
)
1033 mode
= color_func(c
['GROUP']['mode'])('Type: ' + mode
)
1034 created_at
= grp
['created_at']
1035 date
= parser
.parse(created_at
)
1036 clock
= fallback_humanize(date
)
1037 clock
= 'Created at ' + color_func(c
['GROUP']['clock'])(clock
)
1040 # Add spaces in begining of line if this is inside a notification
1042 prefix
= ' ' * 2 + prefix
1044 line1
= prefix
+ name
+ member
+ ' ' + subscriber
1045 line2
= prefix
+ ' ' * 2 + description
1046 line3
= prefix
+ ' ' * 2 + mode
1047 line4
= prefix
+ ' ' * 2 + clock
1060 def show_calendar(month
, date
, rel
):
1062 Show the calendar in rainbow mode
1064 month
= random_rainbow(month
)
1065 date
= ' '.join([cycle_color(i
) for i
in date
.split(' ')])
1066 today
= str(int(os
.popen('date +\'%d\'').read().strip()))
1071 ary
= line
.split(' ')
1073 lambda x
: color_func(c
['CAL']['today'])(x
)
1075 else color_func(c
['CAL']['days'])(x
),
1077 printNicely(' '.join(ary
))
1080 def format_quote(tweet
):
1085 screen_name
= tweet
['user']['screen_name']
1086 text
= get_full_text(tweet
)
1087 tid
= str( tweet
['id'] )
1089 # Validate quote format
1090 if '#owner' not in c
['QUOTE_FORMAT']:
1091 printNicely(light_magenta('Quote should contains #owner'))
1093 if '#comment' not in c
['QUOTE_FORMAT']:
1094 printNicely(light_magenta('Quote format should have #comment'))
1100 formater
= c
['QUOTE_FORMAT']
1102 formater
= formater
.replace('#owner', screen_name
)
1103 formater
= formater
.replace('#tweet', text
)
1104 formater
= formater
.replace('#tid', tid
)
1106 formater
= emojize(formater
)
1109 # Highlight like a tweet
1110 notice
= formater
.split()
1112 lambda x
: light_green(x
)
1117 lambda x
: color_func(c
['TWEET']['rt'])(x
)
1121 notice
= lmap(lambda x
: cycle_color(x
) if x
[0] == '@' else x
, notice
)
1123 lambda x
: color_func(c
['TWEET']['link'])(x
)
1128 lambda x
: color_func(c
['TWEET']['hashtag'])(x
)
1129 if x
.startswith('#')
1132 notice
= ' '.join(notice
)
1134 notice
= light_magenta('Quoting: "') + notice
+ light_magenta('"')
1139 # Start the color cycle