jugyo-termtter 1.1.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +115 -0
- data/README.rdoc +25 -10
- data/Rakefile +53 -34
- data/lib/plugins/cool.rb +2 -5
- data/lib/plugins/curry.rb +43 -0
- data/lib/plugins/db.rb +91 -0
- data/lib/plugins/{auto_reload.rb → defaults/auto_reload.rb} +5 -1
- data/lib/plugins/defaults/command_line.rb +111 -0
- data/lib/plugins/{exec.rb → defaults/exec.rb} +2 -7
- data/lib/plugins/{fib.rb → defaults/fib.rb} +1 -4
- data/lib/plugins/defaults/retweet.rb +34 -0
- data/lib/plugins/{standard_commands.rb → defaults/standard_commands.rb} +88 -162
- data/lib/plugins/defaults/standard_completion.rb +67 -0
- data/lib/plugins/defaults/stdout.rb +148 -0
- data/lib/plugins/defaults.rb +14 -0
- data/lib/plugins/en2ja.rb +11 -5
- data/lib/plugins/english.rb +2 -2
- data/lib/plugins/expand-tinyurl.rb +27 -6
- data/lib/plugins/github-issues.rb +192 -0
- data/lib/plugins/group.rb +30 -4
- data/lib/plugins/growl.rb +10 -1
- data/lib/plugins/http_server/favicon.ico +0 -0
- data/lib/plugins/http_server/index.html +117 -0
- data/lib/plugins/http_server.rb +82 -0
- data/lib/plugins/irb.rb +6 -0
- data/lib/plugins/l2.rb +1 -1
- data/lib/plugins/list_with_opts.rb +0 -3
- data/lib/plugins/log.rb +6 -9
- data/lib/plugins/modify_arg_hook_sample.rb +3 -5
- data/lib/plugins/multi_reply.rb +0 -5
- data/lib/plugins/notify-send.rb +1 -1
- data/lib/plugins/notify-send2.rb +1 -1
- data/lib/plugins/notify-send3.rb +11 -3
- data/lib/plugins/open_url.rb +5 -17
- data/lib/plugins/otsune.rb +3 -9
- data/lib/plugins/outputz.rb +1 -1
- data/lib/plugins/pool.rb +30 -0
- data/lib/plugins/protected_filter.rb +9 -0
- data/lib/plugins/quicklook.rb +1 -1
- data/lib/plugins/saykanji.rb +81 -0
- data/lib/plugins/shell.rb +1 -6
- data/lib/plugins/sl.rb +8 -8
- data/lib/plugins/tinyurl.rb +26 -7
- data/lib/plugins/trends.rb +84 -0
- data/lib/plugins/twitpic.rb +46 -0
- data/lib/plugins/uri-open.rb +33 -28
- data/lib/plugins/wassr.rb +0 -3
- data/lib/plugins/whois.rb +45 -0
- data/lib/plugins/yhara.rb +2 -6
- data/lib/termtter/client.rb +91 -103
- data/lib/termtter/command.rb +24 -9
- data/lib/termtter/config.rb +8 -6
- data/lib/termtter/config_setup.rb +1 -1
- data/lib/termtter/config_template.erb +1 -4
- data/lib/termtter/hook.rb +2 -2
- data/lib/termtter/optparse.rb +14 -1
- data/lib/termtter/system_extensions.rb +3 -2
- data/lib/termtter/task_manager.rb +1 -5
- data/lib/termtter/version.rb +1 -1
- data/spec/plugins/cool_spec.rb +1 -1
- data/spec/plugins/curry_spec.rb +13 -0
- data/spec/plugins/db_spec.rb +62 -0
- data/spec/plugins/english_spec.rb +2 -2
- data/spec/plugins/fib_spec.rb +2 -2
- data/spec/plugins/filter_spec.rb +2 -2
- data/spec/plugins/pause_spec.rb +1 -1
- data/spec/plugins/primes_spec.rb +2 -2
- data/spec/plugins/shell_spec.rb +1 -1
- data/spec/plugins/sl_spec.rb +1 -1
- data/spec/plugins/{standard_plugins_spec.rb → standard_commands_spec.rb} +2 -2
- data/spec/plugins/whois_spec.rb +20 -0
- data/spec/termtter/client_spec.rb +151 -33
- data/spec/termtter/command_spec.rb +68 -35
- data/spec/termtter/config_spec.rb +10 -0
- data/spec/termtter/optparse_spec.rb +16 -0
- data/spec/termtter_spec.rb +7 -8
- metadata +48 -19
- data/History.txt +0 -4
- data/lib/plugins/direct_messages.rb +0 -36
- data/lib/plugins/retweet.rb +0 -46
- data/lib/plugins/stdout.rb +0 -77
@@ -7,43 +7,39 @@ config.plugins.standard.set_default(
|
|
7
7
|
:limit_format,
|
8
8
|
'<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=limit.reset_time%> (<%=remaining_time%> remaining)')
|
9
9
|
|
10
|
+
config.set_default(:easy_reply, true)
|
11
|
+
|
10
12
|
module Termtter::Client
|
11
13
|
|
12
14
|
register_command(
|
13
15
|
:name => :reload,
|
14
|
-
:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
unless
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Readline.refresh_line
|
23
|
-
end
|
24
|
-
rescue OpenURI::HTTPError => e
|
25
|
-
if e.message == '401 Unauthorized'
|
26
|
-
puts 'Could not login'
|
27
|
-
puts 'plese check your account settings'
|
28
|
-
exit!
|
29
|
-
end
|
30
|
-
rescue => e
|
31
|
-
handle_error(e)
|
16
|
+
:exec => lambda {|arg|
|
17
|
+
args = @since_id ? [{:since_id => @since_id}] : []
|
18
|
+
statuses = Termtter::API.twitter.friends_timeline(*args)
|
19
|
+
unless statuses.empty?
|
20
|
+
print "\e[1K\e[0G" unless win?
|
21
|
+
@since_id = statuses[0].id
|
22
|
+
output(statuses, :update_friends_timeline)
|
23
|
+
Readline.refresh_line
|
32
24
|
end
|
33
25
|
}
|
34
26
|
)
|
35
27
|
|
36
28
|
register_command(
|
37
|
-
:name => :update, :
|
38
|
-
:
|
29
|
+
:name => :update, :alias => :u,
|
30
|
+
:exec => lambda {|arg|
|
39
31
|
unless arg.empty?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
params =
|
33
|
+
if config.easy_reply && /^\s*(@\w+)/ =~ arg
|
34
|
+
user_name = normalize_as_user_name($1)
|
35
|
+
in_reply_to_status_id = Termtter::API.twitter.user(user_name).status.id rescue nil
|
36
|
+
in_reply_to_status_id ? {:in_reply_to_status_id => in_reply_to_status_id} : {}
|
37
|
+
else
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
|
41
|
+
result = Termtter::API.twitter.update(arg, params)
|
42
|
+
puts "updated => #{result.text}"
|
47
43
|
end
|
48
44
|
},
|
49
45
|
:help => ["update,u TEXT", "Post a new message"]
|
@@ -61,7 +57,7 @@ module Termtter::Client
|
|
61
57
|
end
|
62
58
|
if id
|
63
59
|
result = Termtter::API.twitter.remove_status(id)
|
64
|
-
puts
|
60
|
+
puts "deleted => #{result.text}"
|
65
61
|
end
|
66
62
|
},
|
67
63
|
:help => ['delete,del [STATUS ID]', 'Delete a status']
|
@@ -77,8 +73,8 @@ module Termtter::Client
|
|
77
73
|
:name => :direct, :aliases => [:d],
|
78
74
|
:exec_proc => lambda {|arg|
|
79
75
|
case arg
|
80
|
-
when /^([^\s]+)\s
|
81
|
-
user, text = $1, $2
|
76
|
+
when /^([^\s]+)\s+?(.*)\s*$/
|
77
|
+
user, text = normalize_as_user_name($1), $2
|
82
78
|
Termtter::API.twitter.direct_message(user, text)
|
83
79
|
puts "=> to:#{user} message:#{text}"
|
84
80
|
when 'list'
|
@@ -97,10 +93,6 @@ module Termtter::Client
|
|
97
93
|
)
|
98
94
|
end
|
99
95
|
},
|
100
|
-
:completion_proc => lambda {|cmd, arg|
|
101
|
-
find_user_candidates(arg, "#{cmd} %s") +
|
102
|
-
["list", "sent_list"].grep(/^#{Regexp.quote(arg)}/).map { |i| "#{cmd} #{i}" }
|
103
|
-
},
|
104
96
|
:help => [
|
105
97
|
["direct,d USERNAME TEXT", "Send direct message"],
|
106
98
|
["direct,d list", 'List direct messages'],
|
@@ -111,7 +103,7 @@ module Termtter::Client
|
|
111
103
|
register_command(
|
112
104
|
:name => :profile, :aliases => [:p],
|
113
105
|
:exec_proc => lambda {|arg|
|
114
|
-
user = Termtter::API.twitter.user(arg
|
106
|
+
user = Termtter::API.twitter.user(normalize_as_user_name(arg))
|
115
107
|
attrs = %w[ name screen_name url description profile_image_url location protected following
|
116
108
|
friends_count followers_count statuses_count favourites_count
|
117
109
|
id time_zone created_at utc_offset notifications
|
@@ -122,16 +114,13 @@ module Termtter::Client
|
|
122
114
|
puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
|
123
115
|
end
|
124
116
|
},
|
125
|
-
:completion_proc => lambda {|cmd, arg|
|
126
|
-
find_user_candidates arg, "#{cmd} %s"
|
127
|
-
},
|
128
117
|
:help => ["profile,p USERNAME", "Show user's profile"]
|
129
118
|
)
|
130
119
|
|
131
120
|
register_command(
|
132
121
|
:name => :followers,
|
133
122
|
:exec_proc => lambda {|arg|
|
134
|
-
user_name = arg
|
123
|
+
user_name = normalize_as_user_name(arg)
|
135
124
|
user_name = config.user_name if user_name.empty?
|
136
125
|
|
137
126
|
followers = []
|
@@ -143,9 +132,6 @@ module Termtter::Client
|
|
143
132
|
public_storage[:users] += followers.map(&:screen_name)
|
144
133
|
puts followers.map(&:screen_name).join(' ')
|
145
134
|
},
|
146
|
-
:completion_proc => lambda {|cmd, arg|
|
147
|
-
find_user_candidates arg, "#{cmd} %s"
|
148
|
-
},
|
149
135
|
:help => ["followers", "Show followers"]
|
150
136
|
)
|
151
137
|
|
@@ -157,13 +143,11 @@ module Termtter::Client
|
|
157
143
|
statuses = Termtter::API.twitter.friends_timeline
|
158
144
|
else
|
159
145
|
event = :list_user_timeline
|
160
|
-
|
146
|
+
user_name = normalize_as_user_name(arg)
|
147
|
+
statuses = Termtter::API.twitter.user_timeline(user_name)
|
161
148
|
end
|
162
149
|
output(statuses, event)
|
163
150
|
},
|
164
|
-
:completion_proc => lambda {|cmd, arg|
|
165
|
-
find_user_candidates arg, "#{cmd} %s"
|
166
|
-
},
|
167
151
|
:help => ["list,l [USERNAME]", "List the posts"]
|
168
152
|
)
|
169
153
|
|
@@ -176,7 +160,7 @@ module Termtter::Client
|
|
176
160
|
output(statuses, :search)
|
177
161
|
},
|
178
162
|
:completion_proc => lambda {|cmd, arg|
|
179
|
-
public_storage[:search_keywords].grep(
|
163
|
+
public_storage[:search_keywords].grep(/^#{Regexp.quote(arg)}/).map { |i| "#{cmd} #{i}" }
|
180
164
|
},
|
181
165
|
:help => ["search,s TEXT", "Search for Twitter"]
|
182
166
|
)
|
@@ -184,9 +168,13 @@ module Termtter::Client
|
|
184
168
|
register_command(
|
185
169
|
:name => :replies, :aliases => [:r],
|
186
170
|
:exec_proc => lambda {|arg|
|
187
|
-
|
171
|
+
res = Termtter::API.twitter.replies
|
172
|
+
unless arg.empty?
|
173
|
+
res = res.map {|e| e.user.screen_name == arg ? e : nil }.compact
|
174
|
+
end
|
175
|
+
output(res, :replies)
|
188
176
|
},
|
189
|
-
:help => ["replies,r", "List the
|
177
|
+
:help => ["replies,r", "List the replies"]
|
190
178
|
)
|
191
179
|
|
192
180
|
register_command(
|
@@ -226,14 +214,10 @@ module Termtter::Client
|
|
226
214
|
:name => :follow, :aliases => [],
|
227
215
|
:exec_proc => lambda {|args|
|
228
216
|
args.split(' ').each do |arg|
|
229
|
-
|
230
|
-
|
231
|
-
end
|
217
|
+
user_name = normalize_as_user_name(arg)
|
218
|
+
res = Termtter::API::twitter.follow(user_name)
|
232
219
|
end
|
233
220
|
},
|
234
|
-
:completion_proc => lambda {|cmd, args|
|
235
|
-
find_user_candidates args, "#{cmd} %s"
|
236
|
-
},
|
237
221
|
:help => ['follow USER', 'Follow user']
|
238
222
|
)
|
239
223
|
|
@@ -241,14 +225,10 @@ module Termtter::Client
|
|
241
225
|
:name => :leave, :aliases => [],
|
242
226
|
:exec_proc => lambda {|args|
|
243
227
|
args.split(' ').each do |arg|
|
244
|
-
|
245
|
-
|
246
|
-
end
|
228
|
+
user_name = normalize_as_user_name(arg)
|
229
|
+
res = Termtter::API::twitter.leave(user_name)
|
247
230
|
end
|
248
231
|
},
|
249
|
-
:completion_proc => lambda {|cmd, args|
|
250
|
-
find_user_candidates args, "#{cmd} %s"
|
251
|
-
},
|
252
232
|
:help => ['leave USER', 'Leave user']
|
253
233
|
)
|
254
234
|
|
@@ -260,15 +240,19 @@ module Termtter::Client
|
|
260
240
|
when /^\d+/
|
261
241
|
id = arg.to_i
|
262
242
|
when /^@([A-Za-z0-9_]+)/
|
263
|
-
|
264
|
-
statuses = Termtter::API.twitter.user_timeline(
|
243
|
+
user_name = normalize_as_user_name($1)
|
244
|
+
statuses = Termtter::API.twitter.user_timeline(user_name)
|
265
245
|
return if statuses.empty?
|
266
246
|
id = statuses[0].id
|
267
247
|
when /^\/(.*)$/
|
268
248
|
word = $1
|
269
249
|
raise "Not implemented yet."
|
270
250
|
else
|
271
|
-
|
251
|
+
if public_storage[:typable_id] && typable_id?(arg)
|
252
|
+
id = typable_id_convert(arg)
|
253
|
+
else
|
254
|
+
return
|
255
|
+
end
|
272
256
|
end
|
273
257
|
|
274
258
|
r = Termtter::API.twitter.favorite id
|
@@ -276,15 +260,17 @@ module Termtter::Client
|
|
276
260
|
},
|
277
261
|
:completion_proc => lambda {|cmd, arg|
|
278
262
|
case arg
|
279
|
-
when /@(.*)/
|
280
|
-
find_user_candidates $1, "#{cmd} @%s"
|
281
263
|
when /(\d+)/
|
282
264
|
find_status_ids(arg).map{|id| "#{cmd} #{id}"}
|
283
265
|
else
|
284
|
-
|
266
|
+
if data = Termtter::Client.typable_id_to_data(arg)
|
267
|
+
"#{cmd} #{data}"
|
268
|
+
else
|
269
|
+
%w(favorite).grep(/^#{Regexp.quote arg}/)
|
270
|
+
end
|
285
271
|
end
|
286
272
|
},
|
287
|
-
:help => ['favorite,fav (ID|@USER|/WORD)', 'Mark a status as a favorite']
|
273
|
+
:help => ['favorite,fav (ID|@USER|TYPABLE|/WORD)', 'Mark a status as a favorite']
|
288
274
|
)
|
289
275
|
|
290
276
|
def self.show_settings(conf, level = 0)
|
@@ -339,7 +325,7 @@ module Termtter::Client
|
|
339
325
|
)
|
340
326
|
|
341
327
|
register_command(
|
342
|
-
:name => :exit, :aliases => [:
|
328
|
+
:name => :exit, :aliases => [:quit],
|
343
329
|
:exec_proc => lambda {|arg| exit},
|
344
330
|
:help => ['exit,e', 'Exit']
|
345
331
|
)
|
@@ -358,6 +344,9 @@ module Termtter::Client
|
|
358
344
|
end
|
359
345
|
end
|
360
346
|
helps.compact!
|
347
|
+
unless arg.empty?
|
348
|
+
helps = helps.select {|n, _| /#{arg}/ =~ n }
|
349
|
+
end
|
361
350
|
puts formatted_help(helps)
|
362
351
|
},
|
363
352
|
:help => ["help,h", "Print this help message"]
|
@@ -372,28 +361,6 @@ module Termtter::Client
|
|
372
361
|
}.join("\n")
|
373
362
|
end
|
374
363
|
|
375
|
-
# completion for standard commands
|
376
|
-
|
377
|
-
public_storage[:users] ||= Set.new
|
378
|
-
public_storage[:status_ids] ||= Set.new
|
379
|
-
|
380
|
-
register_hook(
|
381
|
-
:name => :for_completion,
|
382
|
-
:points => [:pre_filter],
|
383
|
-
:exec_proc => lambda {|statuses, event|
|
384
|
-
statuses.each do |s|
|
385
|
-
public_storage[:users].add(s.user.screen_name)
|
386
|
-
public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
|
387
|
-
public_storage[:status_ids].add(s.id)
|
388
|
-
public_storage[:status_ids].add(s.in_reply_to_status_id) if s.in_reply_to_status_id
|
389
|
-
end
|
390
|
-
}
|
391
|
-
)
|
392
|
-
|
393
|
-
public_storage[:plugins] = (Dir["#{File.dirname(__FILE__)}/*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).map do |f|
|
394
|
-
f.match(%r|([^/]+).rb$|)[1]
|
395
|
-
end
|
396
|
-
|
397
364
|
register_command(
|
398
365
|
:name => :plug,
|
399
366
|
:alias => :plugin,
|
@@ -410,22 +377,29 @@ module Termtter::Client
|
|
410
377
|
end
|
411
378
|
},
|
412
379
|
:completion_proc => lambda {|cmd, args|
|
413
|
-
|
414
|
-
unless args.empty?
|
415
|
-
find_plugin_candidates args, "#{cmd} %s"
|
416
|
-
else
|
417
|
-
public_storage[:plugins].sort
|
418
|
-
end
|
380
|
+
plugin_list.grep(/^#{Regexp.quote(args)}/).map{|i| "#{cmd} #{i}"}
|
419
381
|
},
|
420
|
-
:help
|
382
|
+
:help => ['plug FILE', 'Load a plugin']
|
421
383
|
)
|
422
384
|
|
385
|
+
def self.plugin_list
|
386
|
+
(Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
|
387
|
+
map{|f| File.basename(f).sub(/\.rb$/, '')}.
|
388
|
+
sort
|
389
|
+
end
|
390
|
+
|
423
391
|
register_command(
|
424
|
-
:name
|
392
|
+
:name => :plugins,
|
425
393
|
:exec_proc => lambda {|arg|
|
426
|
-
|
427
|
-
|
428
|
-
|
394
|
+
list = plugin_list
|
395
|
+
width = list.map{|i|i.size}.max + 2
|
396
|
+
a = []
|
397
|
+
list.sort.each_slice(4) {|i|
|
398
|
+
a << i.map{|j| j + (" " * (width - j.size))}.join
|
399
|
+
}
|
400
|
+
puts TermColor.parse('<green>' + TermColor.escape(a.join("\n")) + '</green>')
|
401
|
+
},
|
402
|
+
:help => ['plugins', 'Show list of plugins']
|
429
403
|
)
|
430
404
|
|
431
405
|
register_command(
|
@@ -453,19 +427,20 @@ module Termtter::Client
|
|
453
427
|
when /^\s*(\d+)\s+(.+)$/
|
454
428
|
s = Termtter::API.twitter.show($1) rescue nil
|
455
429
|
if s
|
456
|
-
update_with_user_and_id($2, s.user.screen_name, id)
|
430
|
+
update_with_user_and_id($2, s.user.screen_name, s.id)
|
431
|
+
end
|
432
|
+
when /^\s*(@\w+)/
|
433
|
+
user_name = normalize_as_user_name($1)
|
434
|
+
s = Termtter::API.twitter.user(user_name).status
|
435
|
+
if s
|
436
|
+
params = s ? {:in_reply_to_status_id => s.id} : {}
|
437
|
+
Termtter::API.twitter.update(arg, params)
|
438
|
+
puts "=> #{arg}"
|
457
439
|
end
|
458
|
-
when /^\s*@(\w+)/
|
459
|
-
in_reply_to_status_id = Termtter::API.twitter.user($1).status.id rescue nil
|
460
|
-
params = in_reply_to_status_id ? {:in_reply_to_status_id => in_reply_to_status_id} : {}
|
461
|
-
Termtter::API.twitter.update(arg, params)
|
462
|
-
puts "=> #{arg}"
|
463
440
|
end
|
464
441
|
},
|
465
442
|
:completion_proc => lambda {|cmd, arg|
|
466
443
|
case arg
|
467
|
-
when /(.*)@([^\s]*)$/
|
468
|
-
find_user_candidates $2, "#{cmd} #{$1}@%s"
|
469
444
|
when /(\d+)/
|
470
445
|
find_status_ids(arg).map{|id| "#{cmd} #{id}"}
|
471
446
|
end
|
@@ -500,50 +475,11 @@ module Termtter::Client
|
|
500
475
|
def self.update_with_user_and_id(text, username, id)
|
501
476
|
text = "@#{username} #{text}"
|
502
477
|
result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id})
|
503
|
-
puts
|
478
|
+
puts "replied => #{result.text}"
|
504
479
|
end
|
505
480
|
|
506
|
-
|
507
|
-
|
508
|
-
== Usage
|
509
|
-
=== list
|
510
|
-
* ステータスリストを連番と一緒に出す。
|
511
|
-
> reply [list|ls]
|
512
|
-
0: foo: foo's message
|
513
|
-
1: bar: bar's message
|
514
|
-
..
|
515
|
-
|
516
|
-
* ユーザ指定してリスト作成。
|
517
|
-
> reply [list|ls] foo
|
518
|
-
0: foo: foo's message0
|
519
|
-
1: foo: foo's message1
|
520
|
-
|
521
|
-
=== reply
|
522
|
-
メッセージ送信の際、@usernameが自動的に付与される。
|
523
|
-
|
524
|
-
* status_idを自分で入力してreply送信
|
525
|
-
> reply 1234567890 message to status_id
|
526
|
-
=> @foo message to status_id (reply to 1234567890)
|
527
|
-
|
528
|
-
* reply listコマンドで出したステータス番号に対してreply送信
|
529
|
-
> reply up 0 message to status no
|
530
|
-
=> @foo message to status_no
|
531
|
-
|
532
|
-
* 対象ユーザの最後の発言に対してreply
|
533
|
-
> reply @foo message to foo
|
534
|
-
=> @foo message to foo
|
535
|
-
|
536
|
-
== Todo
|
537
|
-
* 英語で説明 => ヘルプを設定する
|
538
|
-
* リファクタ
|
539
|
-
* 補完
|
540
|
-
* 確認画面を出したい
|
541
|
-
=end
|
542
|
-
|
543
|
-
def self.find_plugin_candidates(a, b)
|
544
|
-
public_storage[:plugins].
|
545
|
-
grep(/^#{Regexp.quote a}/i).
|
546
|
-
map {|u| b % u }
|
481
|
+
def self.normalize_as_user_name(text)
|
482
|
+
text.strip.sub(/^@/, '')
|
547
483
|
end
|
548
484
|
|
549
485
|
def self.find_status_ids(text)
|
@@ -553,14 +489,4 @@ module Termtter::Client
|
|
553
489
|
def self.find_users(text)
|
554
490
|
public_storage[:users].select {|user| /^#{Regexp.quote(text)}/ =~ user}
|
555
491
|
end
|
556
|
-
|
557
|
-
def self.find_user_candidates(a, b)
|
558
|
-
users =
|
559
|
-
if a.nil? || a.empty?
|
560
|
-
public_storage[:users].to_a
|
561
|
-
else
|
562
|
-
public_storage[:users].grep(/^#{Regexp.quote a}/i)
|
563
|
-
end
|
564
|
-
users.map {|u| b % u }
|
565
|
-
end
|
566
492
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Termtter::Client
|
6
|
+
|
7
|
+
#
|
8
|
+
# completion for status ids
|
9
|
+
# (I want to delete)
|
10
|
+
#
|
11
|
+
|
12
|
+
public_storage[:status_ids] ||= Set.new
|
13
|
+
|
14
|
+
register_hook(:collect_status_ids, :point => :pre_filter) do |statuses, event|
|
15
|
+
statuses.each do |s|
|
16
|
+
public_storage[:status_ids].add(s.id)
|
17
|
+
public_storage[:status_ids].add(s.in_reply_to_status_id) if s.in_reply_to_status_id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# completion for user names
|
23
|
+
#
|
24
|
+
|
25
|
+
public_storage[:users] ||= Set.new
|
26
|
+
|
27
|
+
register_hook(:collect_user_names, :point => :pre_filter) do |statuses, event|
|
28
|
+
statuses.each do |s|
|
29
|
+
public_storage[:users].add(s.user.screen_name)
|
30
|
+
public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
register_hook(:user_names_completion, :point => :completion) do |input|
|
35
|
+
if /(.*)@([^\s]*)$/ =~ input
|
36
|
+
command_str = $1
|
37
|
+
part_of_user_name = $2
|
38
|
+
|
39
|
+
users =
|
40
|
+
if part_of_user_name.nil? || part_of_user_name.empty?
|
41
|
+
public_storage[:users].to_a
|
42
|
+
else
|
43
|
+
public_storage[:users].grep(/^#{Regexp.quote(part_of_user_name)}/)
|
44
|
+
end
|
45
|
+
|
46
|
+
users.map {|u| "#{command_str}@%s" % u }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# completion for hashtags
|
52
|
+
#
|
53
|
+
|
54
|
+
public_storage[:hashtag] ||= Set.new
|
55
|
+
|
56
|
+
register_hook(:collect_hashtags, :point => /^post_exec_/) do |cmd, arg, result|
|
57
|
+
public_storage[:hashtag] += arg.scan(/\s+#([^\s]+)/).flatten if arg
|
58
|
+
end
|
59
|
+
|
60
|
+
register_hook(:hashtags_completion, :point => :completion) do |input|
|
61
|
+
if /(.*)#([^\s]*)$/ =~ input
|
62
|
+
command_str = $1
|
63
|
+
part_of_hashtag = $2
|
64
|
+
public_storage[:hashtag].grep(/^#{Regexp.quote(part_of_hashtag)}/i).map { |i| "#{command_str}##{i}" }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'termcolor'
|
4
|
+
require 'erb'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
config.plugins.stdout.set_default(:colors, (31..36).to_a + (91..96).to_a)
|
8
|
+
config.plugins.stdout.set_default(
|
9
|
+
:timeline_format,
|
10
|
+
'<90><%=time%> [<%=status_id%>]</90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
|
11
|
+
'<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%></90>'
|
12
|
+
)
|
13
|
+
config.plugins.stdout.set_default(:enable_pager, true)
|
14
|
+
config.plugins.stdout.set_default(:pager, 'less -R -f +G')
|
15
|
+
config.plugins.stdout.set_default(:window_height, 50)
|
16
|
+
config.plugins.stdout.set_default(:typable_ids, ('aa'..'zz').to_a)
|
17
|
+
config.plugins.stdout.set_default(:typable_id_prefix, '$')
|
18
|
+
config.plugins.stdout.set_default(:show_as_thread, false)
|
19
|
+
|
20
|
+
module Termtter
|
21
|
+
class TypableIdGenerator
|
22
|
+
def initialize(ids)
|
23
|
+
if not ids.kind_of?(Array)
|
24
|
+
raise ArgumentError, 'ids should be an Array'
|
25
|
+
elsif ids.empty?
|
26
|
+
raise ArgumentError, 'ids should not be empty'
|
27
|
+
end
|
28
|
+
@ids = ids
|
29
|
+
@table = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def next(data)
|
33
|
+
id = @ids.shift
|
34
|
+
@ids.push id
|
35
|
+
@table[id] = data
|
36
|
+
id
|
37
|
+
end
|
38
|
+
|
39
|
+
def get(id)
|
40
|
+
@table[id]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Client
|
45
|
+
@typable_id_generator = TypableIdGenerator.new(config.plugins.stdout.typable_ids)
|
46
|
+
|
47
|
+
def self.data_to_typable_id(data)
|
48
|
+
id = config.plugins.stdout.typable_id_prefix + @typable_id_generator.next(data)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.typable_id_to_data(id)
|
52
|
+
@typable_id_generator.get(id)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class StdOut < Hook
|
57
|
+
def initialize
|
58
|
+
super(:name => :stdout, :points => [:output])
|
59
|
+
end
|
60
|
+
|
61
|
+
def call(statuses, event)
|
62
|
+
print_statuses(statuses)
|
63
|
+
end
|
64
|
+
|
65
|
+
def print_statuses(statuses, sort = true, time_format = nil)
|
66
|
+
return unless statuses and statuses.first
|
67
|
+
unless time_format
|
68
|
+
t0 = Time.now
|
69
|
+
t1 = Time.parse(statuses.first[:created_at])
|
70
|
+
t2 = Time.parse(statuses.last[:created_at])
|
71
|
+
time_format =
|
72
|
+
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
73
|
+
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
74
|
+
'%H:%M:%S'
|
75
|
+
else
|
76
|
+
'%y/%m/%d %H:%M'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
output_text = ''
|
81
|
+
statuses.each do |s|
|
82
|
+
output_text << status_line(s, time_format)
|
83
|
+
end
|
84
|
+
|
85
|
+
if config.plugins.stdout.enable_pager && ENV['LINES'] && statuses.size > ENV['LINES'].to_i
|
86
|
+
file = Tempfile.new('termtter')
|
87
|
+
file.print output_text
|
88
|
+
file.close
|
89
|
+
system "#{config.plugins.stdout.pager} #{file.path}"
|
90
|
+
file.close(true)
|
91
|
+
else
|
92
|
+
print output_text
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def status_line(s, time_format, indent = 0)
|
97
|
+
return '' unless s
|
98
|
+
text = TermColor.escape(s.text)
|
99
|
+
color = config.plugins.stdout.colors[s.user.id.to_i % config.plugins.stdout.colors.size]
|
100
|
+
status_id = Termtter::Client.data_to_typable_id(s.id)
|
101
|
+
reply_to_status_id =
|
102
|
+
if s.in_reply_to_status_id.nil?
|
103
|
+
nil
|
104
|
+
else
|
105
|
+
Termtter::Client.data_to_typable_id(s.in_reply_to_status_id)
|
106
|
+
end
|
107
|
+
|
108
|
+
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
109
|
+
source =
|
110
|
+
case s.source
|
111
|
+
when />(.*?)</ then $1
|
112
|
+
when 'web' then 'web'
|
113
|
+
end
|
114
|
+
|
115
|
+
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
116
|
+
indent_text = indent > 0 ? "#{' ' * (indent - 1)} ┗ " : ''
|
117
|
+
text = TermColor.parse(indent_text + erbed_text) + "\n"
|
118
|
+
if config.plugins.stdout.show_as_thread && s.in_reply_to_status_id
|
119
|
+
text << status_line(Status[s.in_reply_to_status_id], time_format, indent + 1)
|
120
|
+
end
|
121
|
+
text
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Client.register_hook(StdOut.new)
|
126
|
+
|
127
|
+
Client.register_hook(
|
128
|
+
:name => :stdout_typable_id,
|
129
|
+
:point => /^modify_arg_for_.*/,
|
130
|
+
:exec => lambda { |cmd, arg|
|
131
|
+
if arg
|
132
|
+
prefix = config.plugins.stdout.typable_id_prefix
|
133
|
+
arg.gsub(/#{Regexp.quote(prefix)}\w+/) do |id|
|
134
|
+
Termtter::Client.typable_id_to_data(id[1..-1]) || id
|
135
|
+
end
|
136
|
+
else
|
137
|
+
arg
|
138
|
+
end
|
139
|
+
}
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
# stdout.rb
|
144
|
+
# output statuses to stdout
|
145
|
+
# example config
|
146
|
+
# config.plugins.stdout.colors = [:none, :red, :green, :yellow, :blue, :magenta, :cyan]
|
147
|
+
# config.plugins.stdout.timeline_format = '<90><%=time%> [<%=status_id%>]</90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
|
148
|
+
# '<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%></90>'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
config.set_default(:stdout, true)
|
5
|
+
config.set_default(:standard_commands, true)
|
6
|
+
config.set_default(:standard_completion, true)
|
7
|
+
config.set_default(:auto_reload, true)
|
8
|
+
|
9
|
+
defaults = Dir[File.dirname(__FILE__) + '/defaults/*.rb'].map { |f|
|
10
|
+
f.match(%r|defaults/(.*?).rb$|)[1]
|
11
|
+
}.each { |plugin|
|
12
|
+
plug "defaults/#{plugin}" if config.__refer__(plugin.to_sym)
|
13
|
+
}
|
14
|
+
end
|
data/lib/plugins/en2ja.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
|
3
|
+
module Termtter::Client
|
4
|
+
plug 'translation'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
register_hook(:en2ja, :point => :filter_for_output) do |statuses, event|
|
7
|
+
statuses.each do |s|
|
8
|
+
if english?(s.text)
|
9
|
+
s.text = translate(s.text, 'en|ja')
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
13
|
+
|
14
|
+
def self.english?(text)
|
15
|
+
/[一-龠]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+/ !~ text
|
16
|
+
end
|
11
17
|
end
|