jugyo-termtter 1.1.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|