fix bug
[rainbowstream.git] / rainbowstream / draw.py
1 """
2 Draw
3 """
4 import requests
5 import datetime
6 import time
7
8 from twitter.util import printNicely
9 from StringIO import StringIO
10 from dateutil import parser
11 from .c_image import *
12 from .colors import *
13 from .config import *
14 from .db import *
15
16 db = RainbowDB()
17 cur_theme = None
18
19 def check_theme():
20 """
21 Check current theme and update if necessary
22 """
23 exists = db.theme_query()
24 themes = [t.theme_name for t in exists]
25 if cur_theme != themes[0]:
26 cur_theme = themes[0]
27 # Determine path
28 if cur_theme == 'user':
29 config = os.environ.get(
30 'HOME',
31 os.environ.get(
32 'USERPROFILE',
33 '')) + os.sep + '.rainbow_config.json'
34 else:
35 config = 'rainbowstream/colorset/'+cur_theme+'.json'
36 # Load new config
37 data = load_config(config)
38 if data:
39 for d in data:
40 c[d] = data[d]
41
42
43 def color_func(func_name):
44 """
45 Call color function base on name
46 """
47 pure = func_name.encode('utf8')
48 if pure.startswith('RGB_') and pure[4:].isdigit():
49 return RGB(int(pure[4:]))
50 return globals()[pure]
51
52
53 def draw(t, iot=False, keyword=None, fil=[], ig=[]):
54 """
55 Draw the rainbow
56 """
57
58 check_theme()
59 # Retrieve tweet
60 tid = t['id']
61 text = t['text']
62 screen_name = t['user']['screen_name']
63 name = t['user']['name']
64 created_at = t['created_at']
65 favorited = t['favorited']
66 date = parser.parse(created_at)
67 date = date - datetime.timedelta(seconds=time.timezone)
68 clock = date.strftime('%Y/%m/%d %H:%M:%S')
69
70 # Get expanded url
71 try:
72 expanded_url = []
73 url = []
74 urls = t['entities']['urls']
75 for u in urls:
76 expanded_url.append(u['expanded_url'])
77 url.append(u['url'])
78 except:
79 expanded_url = None
80 url = None
81
82 # Get media
83 try:
84 media_url = []
85 media = t['entities']['media']
86 for m in media:
87 media_url.append(m['media_url'])
88 except:
89 media_url = None
90
91 # Filter and ignore
92 screen_name = '@' + screen_name
93 if fil and screen_name not in fil:
94 return
95 if ig and screen_name in ig:
96 return
97
98 # Get rainbow id
99 res = db.tweet_to_rainbow_query(tid)
100 if not res:
101 db.tweet_store(tid)
102 res = db.tweet_to_rainbow_query(tid)
103 rid = res[0].rainbow_id
104
105 # Format info
106 user = cycle_color(
107 name) + color_func(c['TWEET']['nick'])(' ' + screen_name + ' ')
108 meta = color_func(c['TWEET']['clock'])(
109 '[' + clock + '] ') + color_func(c['TWEET']['id'])('[id=' + str(rid) + '] ')
110 if favorited:
111 meta = meta + color_func(c['TWEET']['favorite'])(u'\u2605')
112 tweet = text.split()
113 # Replace url
114 if expanded_url:
115 for index in range(len(expanded_url)):
116 tweet = map(
117 lambda x: expanded_url[index] if x == url[index] else x,
118 tweet)
119 # Highlight RT
120 tweet = map(
121 lambda x: color_func(
122 c['TWEET']['rt'])(x) if x == 'RT' else x,
123 tweet)
124 # Highlight screen_name
125 tweet = map(lambda x: cycle_color(x) if x[0] == '@' else x, tweet)
126 # Highlight link
127 tweet = map(
128 lambda x: color_func(
129 c['TWEET']['link'])(x) if x[
130 0:4] == 'http' else x,
131 tweet)
132 # Highlight search keyword
133 if keyword:
134 tweet = map(
135 lambda x: color_func(c['TWEET']['keyword'])(x) if
136 ''.join(c for c in x if c.isalnum()).lower() == keyword.lower()
137 else x,
138 tweet
139 )
140 # Recreate tweet
141 tweet = ' '.join(tweet)
142
143 # Draw rainbow
144 line1 = u"{u:>{uw}}:".format(
145 u=user,
146 uw=len(user) + 2,
147 )
148 line2 = u"{c:>{cw}}".format(
149 c=meta,
150 cw=len(meta) + 2,
151 )
152 line3 = ' ' + tweet
153
154 printNicely('')
155 printNicely(line1)
156 printNicely(line2)
157 printNicely(line3)
158
159 # Display Image
160 if iot and media_url:
161 for mu in media_url:
162 response = requests.get(mu)
163 image_to_display(StringIO(response.content))
164
165
166 def print_message(m):
167 """
168 Print direct message
169 """
170 sender_screen_name = '@' + m['sender_screen_name']
171 sender_name = m['sender']['name']
172 text = m['text']
173 recipient_screen_name = '@' + m['recipient_screen_name']
174 recipient_name = m['recipient']['name']
175 mid = m['id']
176 date = parser.parse(m['created_at'])
177 date = date - datetime.timedelta(seconds=time.timezone)
178 clock = date.strftime('%Y/%m/%d %H:%M:%S')
179
180 # Get rainbow id
181 res = db.message_to_rainbow_query(mid)
182 if not res:
183 db.message_store(mid)
184 res = db.message_to_rainbow_query(mid)
185 rid = res[0].rainbow_id
186
187 # Draw
188 sender = cycle_color(
189 sender_name) + color_func(c['MESSAGE']['sender'])(' ' + sender_screen_name + ' ')
190 recipient = cycle_color(recipient_name) + color_func(
191 c['MESSAGE']['recipient'])(
192 ' ' + recipient_screen_name + ' ')
193 user = sender + color_func(c['MESSAGE']['to'])(' >>> ') + recipient
194 meta = color_func(
195 c['MESSAGE']['clock'])(
196 '[' + clock + ']') + color_func(
197 c['MESSAGE']['id'])(
198 ' [message_id=' + str(rid) + '] ')
199 text = ''.join(map(lambda x: x + ' ' if x == '\n' else x, text))
200
201 line1 = u"{u:>{uw}}:".format(
202 u=user,
203 uw=len(user) + 2,
204 )
205 line2 = u"{c:>{cw}}".format(
206 c=meta,
207 cw=len(meta) + 2,
208 )
209
210 line3 = ' ' + text
211
212 printNicely('')
213 printNicely(line1)
214 printNicely(line2)
215 printNicely(line3)
216
217
218 def show_profile(u, iot=False):
219 """
220 Show a profile
221 """
222 # Retrieve info
223 name = u['name']
224 screen_name = u['screen_name']
225 description = u['description']
226 profile_image_url = u['profile_image_url']
227 location = u['location']
228 url = u['url']
229 created_at = u['created_at']
230 statuses_count = u['statuses_count']
231 friends_count = u['friends_count']
232 followers_count = u['followers_count']
233
234 # Create content
235 statuses_count = color_func(
236 c['PROFILE']['statuses_count'])(
237 str(statuses_count) +
238 ' tweets')
239 friends_count = color_func(
240 c['PROFILE']['friends_count'])(
241 str(friends_count) +
242 ' following')
243 followers_count = color_func(
244 c['PROFILE']['followers_count'])(
245 str(followers_count) +
246 ' followers')
247 count = statuses_count + ' ' + friends_count + ' ' + followers_count
248 user = cycle_color(
249 name) + color_func(c['PROFILE']['nick'])(' @' + screen_name + ' : ') + count
250 profile_image_raw_url = 'Profile photo: ' + \
251 color_func(c['PROFILE']['profile_image_url'])(profile_image_url)
252 description = ''.join(
253 map(lambda x: x + ' ' * 4 if x == '\n' else x, description))
254 description = color_func(c['PROFILE']['description'])(description)
255 location = 'Location : ' + color_func(c['PROFILE']['location'])(location)
256 url = 'URL : ' + (color_func(c['PROFILE']['url'])(url) if url else '')
257 date = parser.parse(created_at)
258 date = date - datetime.timedelta(seconds=time.timezone)
259 clock = date.strftime('%Y/%m/%d %H:%M:%S')
260 clock = 'Join at ' + color_func(c['PROFILE']['clock'])(clock)
261
262 # Format
263 line1 = u"{u:>{uw}}".format(
264 u=user,
265 uw=len(user) + 2,
266 )
267 line2 = u"{p:>{pw}}".format(
268 p=profile_image_raw_url,
269 pw=len(profile_image_raw_url) + 4,
270 )
271 line3 = u"{d:>{dw}}".format(
272 d=description,
273 dw=len(description) + 4,
274 )
275 line4 = u"{l:>{lw}}".format(
276 l=location,
277 lw=len(location) + 4,
278 )
279 line5 = u"{u:>{uw}}".format(
280 u=url,
281 uw=len(url) + 4,
282 )
283 line6 = u"{c:>{cw}}".format(
284 c=clock,
285 cw=len(clock) + 4,
286 )
287
288 # Display
289 printNicely('')
290 printNicely(line1)
291 if iot:
292 response = requests.get(profile_image_url)
293 image_to_display(StringIO(response.content), 2, 20)
294 else:
295 printNicely(line2)
296 for line in [line3, line4, line5, line6]:
297 printNicely(line)
298 printNicely('')
299
300
301 def print_trends(trends):
302 """
303 Display topics
304 """
305 for topic in trends[:c['TREND_MAX']]:
306 name = topic['name']
307 url = topic['url']
308 line = cycle_color(name) + ': ' + color_func(c['TREND']['url'])(url)
309 printNicely(line)
310 printNicely('')