draftcode-termtter 1.1.0 → 1.1.3
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/README.rdoc +8 -0
- data/Rakefile +1 -1
- data/lib/plugins/auto_reload.rb +8 -0
- data/lib/plugins/hatebu_and_update.rb +2 -2
- data/lib/plugins/history.rb +0 -2
- data/lib/plugins/ignore.rb +13 -7
- data/lib/plugins/irc_gw.rb +83 -0
- data/lib/plugins/list_with_opts.rb +32 -0
- data/lib/plugins/mark.rb +11 -0
- data/lib/plugins/multi_post.rb +32 -0
- data/lib/plugins/notify-send3.rb +8 -3
- data/lib/plugins/{standard_plugins.rb → standard_commands.rb} +64 -19
- data/lib/plugins/stdout.rb +14 -122
- data/lib/plugins/wassr.rb +97 -0
- data/lib/termtter/client.rb +83 -33
- data/lib/termtter/config_setup.rb +13 -21
- data/lib/termtter/config_template.erb +18 -0
- data/lib/termtter/optparse.rb +5 -0
- data/lib/termtter/system_extensions.rb +3 -18
- data/lib/termtter/version.rb +1 -1
- data/spec/plugins/standard_plugins_spec.rb +1 -1
- data/spec/termtter/client_spec.rb +38 -4
- metadata +9 -3
- data/lib/plugins/update_timeline.rb +0 -32
data/README.rdoc
CHANGED
@@ -59,6 +59,14 @@ If you would like to use proxy server, add configurations like this:
|
|
59
59
|
config.proxy.user_name = 'USERNAME'
|
60
60
|
config.proxy.password = 'PASSWORD'
|
61
61
|
|
62
|
+
You can to load plugins in this way:
|
63
|
+
|
64
|
+
Termtter::Client.init do |t|
|
65
|
+
t.plug 'stdout'
|
66
|
+
t.plug 'standard_commands'
|
67
|
+
t.plug 'auto_reload'
|
68
|
+
end
|
69
|
+
|
62
70
|
To update the config, just restart your termtter proccess.
|
63
71
|
|
64
72
|
== FORUM:
|
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.version = '#{Termtter::VERSION}'
|
17
17
|
s.summary = "Terminal based Twitter client"
|
18
18
|
s.description = "Termtter is a terminal based Twitter client"
|
19
|
-
s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
|
19
|
+
s.files = %w( #{Dir['lib/**/*.rb', 'lib/**/*.erb'].join(' ')}
|
20
20
|
#{Dir['spec/**/*.rb'].join(' ')}
|
21
21
|
#{Dir['test/**/*.rb', 'test/**/*.json'].join(' ')}
|
22
22
|
README.rdoc
|
data/lib/plugins/history.rb
CHANGED
data/lib/plugins/ignore.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
|
4
3
|
config.filters.ignore.set_default(:words, [])
|
5
4
|
|
6
5
|
module Termtter::Client
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
register_hook(
|
7
|
+
:name => :ignore,
|
8
|
+
:point => :filter_for_output,
|
9
|
+
:exec => lambda { |statuses, event|
|
10
|
+
ignore_words = config.filters.ignore.words
|
11
|
+
statuses.delete_if do |s|
|
12
|
+
ignore_words.any? do |word|
|
13
|
+
word = /#{Regexp.quote(word)}/ if word.kind_of? String
|
14
|
+
word =~ s.text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
}
|
18
|
+
)
|
13
19
|
end
|
14
20
|
|
15
21
|
# filter/ignore.rb
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'net/irc'
|
4
|
+
|
5
|
+
# TODO: post text of stdout too
|
6
|
+
|
7
|
+
config.plugins.irc_gw.set_default(:port, 16669)
|
8
|
+
config.plugins.irc_gw.set_default(:last_statuses_count, 100)
|
9
|
+
|
10
|
+
class TermtterIrcGateway < Net::IRC::Server::Session
|
11
|
+
@@listners = []
|
12
|
+
@@last_statuses = []
|
13
|
+
|
14
|
+
Termtter::Client.register_hook(
|
15
|
+
:name => :irc_gw,
|
16
|
+
:point => :output,
|
17
|
+
:exec => lambda { |statuses, event|
|
18
|
+
if event == :update_friends_timeline
|
19
|
+
@@last_statuses =
|
20
|
+
(@@last_statuses + statuses.dup).reverse![0..config.plugins.irc_gw.last_statuses_count].reverse!
|
21
|
+
end
|
22
|
+
|
23
|
+
@@listners.each do |listner|
|
24
|
+
listner.call(statuses.dup, event)
|
25
|
+
end
|
26
|
+
}
|
27
|
+
)
|
28
|
+
|
29
|
+
def server_name; 'termtter' end
|
30
|
+
def server_version; '0.0.0' end
|
31
|
+
def main_channel; '#termtter' end
|
32
|
+
|
33
|
+
def initialize(*args)
|
34
|
+
super
|
35
|
+
@@listners << self
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(statuses, event)
|
39
|
+
msg_type =
|
40
|
+
case event
|
41
|
+
when :update_friends_timeline
|
42
|
+
PRIVMSG
|
43
|
+
else
|
44
|
+
NOTICE
|
45
|
+
end
|
46
|
+
|
47
|
+
statuses.each do |s|
|
48
|
+
post s.user.screen_name, msg_type, main_channel, [s.text, s.id].join(' ')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def on_message(m)
|
53
|
+
termtter_command = m.command.downcase + ' ' + m.params.join(' ')
|
54
|
+
unless Termtter::Client.find_commands(termtter_command).empty?
|
55
|
+
post '#termtter', NOTICE, main_channel, '> ' + termtter_command
|
56
|
+
Termtter::Client.call_commands(termtter_command)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def on_user(m)
|
61
|
+
super
|
62
|
+
post @prefix, JOIN, main_channel
|
63
|
+
post server_name, MODE, main_channel, "+o", @prefix.nick
|
64
|
+
self.call(@@last_statuses || [], :update_friends_timeline)
|
65
|
+
end
|
66
|
+
|
67
|
+
def on_privmsg(m)
|
68
|
+
target, message = *m.params
|
69
|
+
Termtter::Client.call_commands('update ' + message)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
unless defined? IRC_SERVER
|
74
|
+
IRC_SERVER = Net::IRC::Server.new(
|
75
|
+
'localhost',
|
76
|
+
config.plugins.irc_gw.port,
|
77
|
+
TermtterIrcGateway,
|
78
|
+
:logger => Termtter::Client.logger
|
79
|
+
)
|
80
|
+
Thread.start do
|
81
|
+
IRC_SERVER.start
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
register_command(
|
4
|
+
:name => :list, :aliases => [:l],
|
5
|
+
:exec_proc => lambda {|arg|
|
6
|
+
_, options, user = */((?:\-[a-z][= ]\S+\s*)+)?(\w+)?/.match(arg)
|
7
|
+
params = {}
|
8
|
+
options.scan(/(\-[a-z])[= ](\S+)/).each do |k,v|
|
9
|
+
v = v.sub(/^['"]/,'').sub(/['"]$/,'')
|
10
|
+
case k
|
11
|
+
when '-n' #count
|
12
|
+
params['count'] = v.to_i if v.to_i > 0
|
13
|
+
when '-p' #page
|
14
|
+
params['page'] = v.to_i if v.to_i > 0
|
15
|
+
end
|
16
|
+
end if options
|
17
|
+
|
18
|
+
unless user
|
19
|
+
event = :list_friends_timeline
|
20
|
+
statuses = Termtter::API.twitter.friends_timeline(params)
|
21
|
+
else
|
22
|
+
event = :list_user_timeline
|
23
|
+
statuses = Termtter::API.twitter.user_timeline(user, params)
|
24
|
+
end
|
25
|
+
output(statuses, event)
|
26
|
+
},
|
27
|
+
:completion_proc => lambda {|cmd, arg|
|
28
|
+
find_user_candidates arg, "#{cmd} %s"
|
29
|
+
},
|
30
|
+
:help => ["list,l [USERNAME]", "List the posts"]
|
31
|
+
)
|
32
|
+
end
|
data/lib/plugins/mark.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
config.plugins.mark.set_default(
|
4
|
+
:text, '<on_green>' + (' ' * 30) + '#mark' + (' ' * 30) + '</on_green>')
|
5
|
+
|
6
|
+
Termtter::Client.register_command(
|
7
|
+
:name => :mark, :alias => :m,
|
8
|
+
:exec => lambda {|arg|
|
9
|
+
puts TermColor.parse(config.plugins.mark.text)
|
10
|
+
}
|
11
|
+
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
class << self
|
5
|
+
def wassr_update(text)
|
6
|
+
Net::HTTP.version_1_2
|
7
|
+
req = Net::HTTP::Post.new("/statuses/update.json?")
|
8
|
+
req.basic_auth config.plugins.wassr.username, config.plugins.wassr.password
|
9
|
+
Net::HTTP.start('api.wassr.jp', 80) do |http|
|
10
|
+
res = http.request(req, "status=#{URI.escape(text)}&source=Termtter")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Termtter::Client.register_hook(
|
17
|
+
:name => :multi_post,
|
18
|
+
:points => [:modify_arg_for_update, :modify_arg_for_reply],
|
19
|
+
:exec_proc => lambda {|cmd, arg|
|
20
|
+
begin
|
21
|
+
wassr_arg = arg.gsub(/\d{10,}/, '')
|
22
|
+
Termtter::Client.wassr_update(wassr_arg.strip)
|
23
|
+
rescue
|
24
|
+
puts "RuntimeError: #{$!}"
|
25
|
+
end
|
26
|
+
|
27
|
+
return arg
|
28
|
+
}
|
29
|
+
)
|
30
|
+
|
31
|
+
# multi_post.rb
|
32
|
+
# One post, multi update.
|
data/lib/plugins/notify-send3.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'RMagick'
|
5
|
+
require 'uri'
|
5
6
|
|
6
7
|
# Copy from notify-send2.rb
|
7
8
|
config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
@@ -33,9 +34,13 @@ Termtter::Client.register_hook(
|
|
33
34
|
Thread.start do
|
34
35
|
statuses.each do |s|
|
35
36
|
text = CGI.escapeHTML(s.text)
|
36
|
-
text
|
37
|
-
|
38
|
-
|
37
|
+
text = %Q{"#{text}"} if text =~ /^-/
|
38
|
+
text.gsub!(URI.regexp,'<a href="\0">\0</a>')
|
39
|
+
begin
|
40
|
+
system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
|
41
|
+
sleep 0.05
|
42
|
+
rescue
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
}
|
@@ -10,14 +10,28 @@ config.plugins.standard.set_default(
|
|
10
10
|
module Termtter::Client
|
11
11
|
|
12
12
|
register_command(
|
13
|
-
:name => :
|
14
|
-
:
|
13
|
+
:name => :reload,
|
14
|
+
:exec => lambda {|arg|
|
15
|
+
args = @since_id ? [{:since_id => @since_id}] : []
|
16
|
+
statuses = Termtter::API.twitter.friends_timeline(*args)
|
17
|
+
unless statuses.empty?
|
18
|
+
print "\e[1K\e[0G" unless win?
|
19
|
+
@since_id = statuses[0].id
|
20
|
+
output(statuses, :update_friends_timeline)
|
21
|
+
Readline.refresh_line
|
22
|
+
end
|
23
|
+
}
|
24
|
+
)
|
25
|
+
|
26
|
+
register_command(
|
27
|
+
:name => :update, :alias => :u,
|
28
|
+
:exec => lambda {|arg|
|
15
29
|
unless arg.empty?
|
16
|
-
Termtter::API.twitter.update(arg)
|
17
|
-
puts "=> #{
|
30
|
+
result = Termtter::API.twitter.update(arg)
|
31
|
+
puts TermColor.parse("updated => #{result.text} <90>#{result.id}</90>")
|
18
32
|
end
|
19
33
|
},
|
20
|
-
:
|
34
|
+
:completion => lambda {|cmd, args|
|
21
35
|
if /(.*)@([^\s]*)$/ =~ args
|
22
36
|
find_user_candidates $2, "#{cmd} #{$1}@%s"
|
23
37
|
end
|
@@ -25,6 +39,24 @@ module Termtter::Client
|
|
25
39
|
:help => ["update,u TEXT", "Post a new message"]
|
26
40
|
)
|
27
41
|
|
42
|
+
register_command(
|
43
|
+
:name => :delete, :aliases =>[:del],
|
44
|
+
:exec_proc => lambda {|arg|
|
45
|
+
id =
|
46
|
+
case arg
|
47
|
+
when ''
|
48
|
+
Termtter::API.twitter.user_timeline(config.user_name)[0].id
|
49
|
+
when /^\d+$/
|
50
|
+
arg.to_i
|
51
|
+
end
|
52
|
+
if id
|
53
|
+
result = Termtter::API.twitter.remove_status(id)
|
54
|
+
puts TermColor.parse("deleted => #{result.text} <90>#{result.id}</90>")
|
55
|
+
end
|
56
|
+
},
|
57
|
+
:help => ['delete,del [STATUS ID]', 'Delete a status']
|
58
|
+
)
|
59
|
+
|
28
60
|
direct_message_struct = Struct.new(:id, :text, :user, :created_at)
|
29
61
|
direct_message_struct.class_eval do
|
30
62
|
def method_missing(*args, &block)
|
@@ -142,9 +174,13 @@ module Termtter::Client
|
|
142
174
|
register_command(
|
143
175
|
:name => :replies, :aliases => [:r],
|
144
176
|
:exec_proc => lambda {|arg|
|
145
|
-
|
177
|
+
res = Termtter::API.twitter.replies
|
178
|
+
unless arg.empty?
|
179
|
+
res = res.map {|e| e.user.screen_name == arg ? e : nil }.compact
|
180
|
+
end
|
181
|
+
output(res, :replies)
|
146
182
|
},
|
147
|
-
:help => ["replies,r", "List the
|
183
|
+
:help => ["replies,r", "List the replies"]
|
148
184
|
)
|
149
185
|
|
150
186
|
register_command(
|
@@ -226,7 +262,11 @@ module Termtter::Client
|
|
226
262
|
word = $1
|
227
263
|
raise "Not implemented yet."
|
228
264
|
else
|
229
|
-
|
265
|
+
if public_storage[:typable_id] && typable_id?(arg)
|
266
|
+
id = typable_id_convert(arg)
|
267
|
+
else
|
268
|
+
return
|
269
|
+
end
|
230
270
|
end
|
231
271
|
|
232
272
|
r = Termtter::API.twitter.favorite id
|
@@ -239,10 +279,14 @@ module Termtter::Client
|
|
239
279
|
when /(\d+)/
|
240
280
|
find_status_ids(arg).map{|id| "#{cmd} #{id}"}
|
241
281
|
else
|
242
|
-
|
282
|
+
if public_storage[:typable_id] && typable_id?(arg)
|
283
|
+
"#{cmd} #{typable_id_convert(arg)}"
|
284
|
+
else
|
285
|
+
%w(favorite).grep(/^#{Regexp.quote arg}/)
|
286
|
+
end
|
243
287
|
end
|
244
288
|
},
|
245
|
-
:help => ['favorite,fav (ID|@USER|/WORD)', '
|
289
|
+
:help => ['favorite,fav (ID|@USER|/WORD)', 'Mark a status as a favorite']
|
246
290
|
)
|
247
291
|
|
248
292
|
def self.show_settings(conf, level = 0)
|
@@ -353,14 +397,15 @@ module Termtter::Client
|
|
353
397
|
end
|
354
398
|
|
355
399
|
register_command(
|
356
|
-
:name => :
|
400
|
+
:name => :plug,
|
401
|
+
:alias => :plugin,
|
357
402
|
:exec_proc => lambda {|arg|
|
358
403
|
if arg.empty?
|
359
404
|
puts 'Should specify plugin name.'
|
360
405
|
return
|
361
406
|
end
|
362
407
|
begin
|
363
|
-
result =
|
408
|
+
result = plug arg
|
364
409
|
rescue LoadError
|
365
410
|
ensure
|
366
411
|
puts "=> #{result.inspect}"
|
@@ -374,7 +419,7 @@ module Termtter::Client
|
|
374
419
|
public_storage[:plugins].sort
|
375
420
|
end
|
376
421
|
},
|
377
|
-
:help => ['
|
422
|
+
:help => ['plug FILE', 'Load a plugin']
|
378
423
|
)
|
379
424
|
|
380
425
|
register_command(
|
@@ -408,9 +453,10 @@ module Termtter::Client
|
|
408
453
|
update_with_user_and_id(text, user.screen_name, id) if user
|
409
454
|
public_storage.delete :log4re
|
410
455
|
when /^\s*(\d+)\s+(.+)$/
|
411
|
-
|
412
|
-
|
413
|
-
|
456
|
+
s = Termtter::API.twitter.show($1) rescue nil
|
457
|
+
if s
|
458
|
+
update_with_user_and_id($2, s.user.screen_name, id)
|
459
|
+
end
|
414
460
|
when /^\s*@(\w+)/
|
415
461
|
in_reply_to_status_id = Termtter::API.twitter.user($1).status.id rescue nil
|
416
462
|
params = in_reply_to_status_id ? {:in_reply_to_status_id => in_reply_to_status_id} : {}
|
@@ -454,10 +500,9 @@ module Termtter::Client
|
|
454
500
|
)
|
455
501
|
|
456
502
|
def self.update_with_user_and_id(text, username, id)
|
457
|
-
text =
|
503
|
+
text = "@#{username} #{text}"
|
458
504
|
result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id})
|
459
|
-
puts "=> #{text}"
|
460
|
-
result
|
505
|
+
puts TermColor.parse("replied => #{result.text} <90>#{result.id}</90>")
|
461
506
|
end
|
462
507
|
|
463
508
|
=begin
|
data/lib/plugins/stdout.rb
CHANGED
@@ -4,65 +4,13 @@ require 'termcolor'
|
|
4
4
|
require 'erb'
|
5
5
|
require 'tempfile'
|
6
6
|
require 'curses'
|
7
|
-
require 'dl/import'
|
8
|
-
|
9
|
-
module Readline
|
10
|
-
begin
|
11
|
-
module LIBREADLINE
|
12
|
-
if DL.const_defined? :Importable
|
13
|
-
extend DL::Importable
|
14
|
-
else
|
15
|
-
extend DL::Importer
|
16
|
-
end
|
17
|
-
pathes = Array(ENV['TERMTTER_EXT_LIB'] || [
|
18
|
-
'/opt/local/lib/libreadline.dylib',
|
19
|
-
'/usr/lib/libreadline.so',
|
20
|
-
'/usr/local/lib/libreadline.so',
|
21
|
-
File.join(Gem.bindir, 'readline.dll')
|
22
|
-
])
|
23
|
-
dlload(pathes.find { |path| File.exist?(path)})
|
24
|
-
extern 'int rl_refresh_line(int, int)'
|
25
|
-
end
|
26
|
-
def self.refresh_line
|
27
|
-
LIBREADLINE.rl_refresh_line(0, 0)
|
28
|
-
end
|
29
|
-
rescue Exception
|
30
|
-
def self.refresh_line;end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
if win?
|
35
|
-
require 'iconv'
|
36
|
-
|
37
|
-
module Readline
|
38
|
-
$iconv_sj_to_u8 = Iconv.new('UTF-8', "CP#{$wGetACP.call()}")
|
39
|
-
alias :old_readline :readline
|
40
|
-
def readline(*a)
|
41
|
-
str = old_readline(*a)
|
42
|
-
out = ''
|
43
|
-
loop do
|
44
|
-
begin
|
45
|
-
out << $iconv_sj_to_u8.iconv(str)
|
46
|
-
break
|
47
|
-
rescue Iconv::Failure
|
48
|
-
out << "#{$!.success}?"
|
49
|
-
str = $!.failed[1..-1]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
return out
|
53
|
-
end
|
54
|
-
module_function :old_readline, :readline
|
55
|
-
end
|
56
|
-
end
|
57
7
|
|
58
|
-
config.plugins.stdout.set_default(
|
59
|
-
:colors,
|
60
|
-
[:none, :red, :green, :yellow, :blue, :magenta, :cyan])
|
8
|
+
config.plugins.stdout.set_default(:colors, (31..36).to_a + (91..96).to_a)
|
61
9
|
config.plugins.stdout.set_default(
|
62
10
|
:timeline_format,
|
63
|
-
'<90><%=time%></90> <<%=
|
64
|
-
|
65
|
-
|
11
|
+
'<90><%=time%></90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
|
12
|
+
'<90><%=reply_to ? reply_to + " " : ""%><%=s.id%> <%=source%></90>'
|
13
|
+
)
|
66
14
|
config.plugins.stdout.set_default(:enable_pager, true)
|
67
15
|
config.plugins.stdout.set_default(:pager, 'less -R -f +G')
|
68
16
|
config.plugins.stdout.set_default(:window_height, 50)
|
@@ -70,18 +18,18 @@ config.plugins.stdout.set_default(:window_height, 50)
|
|
70
18
|
class String
|
71
19
|
def truncate_column(col)
|
72
20
|
count = 0
|
73
|
-
|
21
|
+
str = String.new
|
74
22
|
ret = []
|
75
23
|
self.split(//u).each {|c|
|
76
|
-
count += (c.
|
24
|
+
count += (c.bytesize == 1 ? 1 : 2)
|
77
25
|
if count > col then
|
78
|
-
ret.push(
|
79
|
-
|
26
|
+
ret.push(str)
|
27
|
+
str = String.new
|
80
28
|
count = 0
|
81
29
|
end
|
82
|
-
|
30
|
+
str += c
|
83
31
|
}
|
84
|
-
ret.push(
|
32
|
+
ret.push(str) unless str.empty?
|
85
33
|
ret
|
86
34
|
end
|
87
35
|
end
|
@@ -90,67 +38,12 @@ module Termtter
|
|
90
38
|
class StdOut < Hook
|
91
39
|
def initialize
|
92
40
|
super(:name => :stdout, :points => [:output])
|
93
|
-
@input_thread = nil
|
94
|
-
Client.register_hook(
|
95
|
-
:name => :stdout_exit,
|
96
|
-
:points => [:exit],
|
97
|
-
:exec_proc => lambda { @input_thread.kill if @input_thread }
|
98
|
-
)
|
99
|
-
Client.register_hook(
|
100
|
-
:name => :stdout_readline_yield_thread,
|
101
|
-
:points => [:before_task_thread_run],
|
102
|
-
:exec_proc => lambda { start_input_thread() unless @input_thread }
|
103
|
-
)
|
104
41
|
end
|
105
42
|
|
106
43
|
def call(statuses, event)
|
107
44
|
print_statuses(statuses)
|
108
45
|
end
|
109
46
|
|
110
|
-
def trap_setting()
|
111
|
-
begin
|
112
|
-
stty_save = `stty -g`.chomp
|
113
|
-
trap("INT") do
|
114
|
-
begin
|
115
|
-
system "stty", stty_save
|
116
|
-
ensure
|
117
|
-
exit
|
118
|
-
end
|
119
|
-
end
|
120
|
-
rescue Errno::ENOENT
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def setup_readline
|
125
|
-
if Readline.respond_to?(:basic_word_break_characters=)
|
126
|
-
Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
|
127
|
-
end
|
128
|
-
Readline.completion_proc = Client.get_command_completion_proc()
|
129
|
-
vi_or_emacs = config.editing_mod
|
130
|
-
unless vi_or_emacs.empty?
|
131
|
-
Readline.__send__("#{vi_or_emacs}_editing_mode")
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def start_input_thread
|
136
|
-
setup_readline()
|
137
|
-
trap_setting()
|
138
|
-
@input_thread = Thread.new do
|
139
|
-
while buf = Readline.readline(ERB.new(config.prompt).result(API.twitter.__send__(:binding)), true)
|
140
|
-
Readline::HISTORY.pop if buf.empty?
|
141
|
-
begin
|
142
|
-
Client.call_commands(buf)
|
143
|
-
rescue CommandNotFound => e
|
144
|
-
warn "Unknown command \"#{e}\""
|
145
|
-
warn 'Enter "help" for instructions'
|
146
|
-
rescue => e
|
147
|
-
Client.handle_error e
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
@input_thread.join
|
152
|
-
end
|
153
|
-
|
154
47
|
def print_statuses(statuses, sort = true, time_format = nil)
|
155
48
|
return unless statuses and statuses.first
|
156
49
|
unless time_format
|
@@ -172,14 +65,14 @@ module Termtter
|
|
172
65
|
cols = Curses.cols;
|
173
66
|
Curses::close_screen
|
174
67
|
statuses.each do |s|
|
175
|
-
text = s.text
|
176
|
-
|
177
|
-
|
68
|
+
text = TermColor.escape(s.text)
|
69
|
+
color = config.plugins.stdout.colors[s.user.id.to_i % config.plugins.stdout.colors.size]
|
70
|
+
reply_to = s.in_reply_to_status_id ? "(reply to #{s.in_reply_to_status_id})" : nil
|
71
|
+
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
178
72
|
if s.in_reply_to_status_id
|
179
73
|
status += " (reply to #{s.in_reply_to_status_id})"
|
180
74
|
end
|
181
75
|
|
182
|
-
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
183
76
|
id = s.id
|
184
77
|
len = id.to_s.length + 2
|
185
78
|
if cols > 0 then
|
@@ -206,7 +99,6 @@ module Termtter
|
|
206
99
|
output_text << TermColor.parse("<90>-----Fetched on " + Time.now.strftime(time_format) + "</90>\n")
|
207
100
|
print output_text
|
208
101
|
end
|
209
|
-
Readline.refresh_line
|
210
102
|
end
|
211
103
|
end
|
212
104
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Termtter::API.module_eval %Q{
|
4
|
+
class << self
|
5
|
+
attr_reader :wassr
|
6
|
+
|
7
|
+
def setup_wassr(user_name, password)
|
8
|
+
@wassr = create_wassr(user_name, password)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_wassr(user_name, password)
|
12
|
+
Rubytter.new(
|
13
|
+
user_name,
|
14
|
+
password,
|
15
|
+
{
|
16
|
+
:app_name => config.app_name.empty? ? Termtter::APP_NAME : config.app_name,
|
17
|
+
:host => 'api.wassr.jp',
|
18
|
+
:header => {
|
19
|
+
'User-Agent' => 'Termtter http://github.com/jugyo/termtter',
|
20
|
+
'X-Wassr-Client' => 'Termtter',
|
21
|
+
'X-Wassr-Client-URL' => 'http://github.com/jugyo/termtter',
|
22
|
+
'X-Wassr-Client-Version' => Termtter::VERSION
|
23
|
+
},
|
24
|
+
:enable_ssl => config.enable_ssl,
|
25
|
+
:proxy_host => config.proxy.host,
|
26
|
+
:proxy_port => config.proxy.port,
|
27
|
+
:proxy_user_name => config.proxy.user_name,
|
28
|
+
:proxy_password => config.proxy.password
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
|
35
|
+
module Termtter::Client
|
36
|
+
register_command(
|
37
|
+
:name => :wassr, :aliases => [:wsr],
|
38
|
+
:exec_proc => lambda {|arg|
|
39
|
+
Termtter::API.setup_wassr(config.plugins.wassr.username, config.plugins.wassr.password)
|
40
|
+
statuses = Termtter::API.wassr.friends_timeline
|
41
|
+
add_member = [:created_at, :in_reply_to_status_id]
|
42
|
+
event = :wassr_friends_timeline
|
43
|
+
print_statuses(statuses, event)
|
44
|
+
},
|
45
|
+
:completion_proc => lambda {|cmd, arg|
|
46
|
+
find_user_candidates arg, "#{cmd} %s"
|
47
|
+
},
|
48
|
+
:help => ["wassr, wsr", "List the wassr timeline."]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def print_statuses(statuses, sort = true, time_format = nil)
|
53
|
+
return unless statuses and statuses.first
|
54
|
+
unless time_format
|
55
|
+
t0 = Time.now
|
56
|
+
t1 = Time.at(statuses.first[:epoch])
|
57
|
+
t2 = Time.at(statuses.last[:epoch])
|
58
|
+
time_format =
|
59
|
+
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
60
|
+
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
61
|
+
'%H:%M:%S'
|
62
|
+
else
|
63
|
+
'%y/%m/%d %H:%M'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
output_text = ''
|
68
|
+
|
69
|
+
user_login_ids = []
|
70
|
+
statuses.sort{|a, b| a.epoch <=> b.epoch}.each do |s|
|
71
|
+
text = s.text
|
72
|
+
user_login_ids << s.user_login_id unless user_login_ids.include?(s.user_login_id)
|
73
|
+
status_color = config.plugins.stdout.colors[user_login_ids.index(s.user_login_id) % config.plugins.stdout.colors.size]
|
74
|
+
status = "#{s.user.screen_name}: #{TermColor.escape(text)}"
|
75
|
+
|
76
|
+
time = "[wassr] [#{Time.at(s.epoch).strftime(time_format)}]"
|
77
|
+
id = s.id
|
78
|
+
source =
|
79
|
+
case s.source
|
80
|
+
when />(.*?)</ then $1
|
81
|
+
when 'web' then 'web'
|
82
|
+
end
|
83
|
+
|
84
|
+
erbed_text = ERB.new('<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>>').result(binding)
|
85
|
+
output_text << TermColor.parse(erbed_text) + "\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
if config.plugins.stdout.enable_pager && ENV['LINES'] && statuses.size > ENV['LINES'].to_i
|
89
|
+
file = Tempfile.new('termtter')
|
90
|
+
file.print output_text
|
91
|
+
file.close
|
92
|
+
system "#{config.plugins.stdout.pager} #{file.path}"
|
93
|
+
file.close(true)
|
94
|
+
else
|
95
|
+
print output_text
|
96
|
+
end
|
97
|
+
end
|
data/lib/termtter/client.rb
CHANGED
@@ -3,6 +3,12 @@ require 'fileutils'
|
|
3
3
|
require 'logger'
|
4
4
|
require 'termcolor'
|
5
5
|
|
6
|
+
def plugin(name, init = {})
|
7
|
+
Termtter::Client.load_plugin(name, init)
|
8
|
+
rescue Exception => e
|
9
|
+
Termtter::Client.handle_error(e)
|
10
|
+
end
|
11
|
+
|
6
12
|
module Termtter
|
7
13
|
|
8
14
|
class CommandNotFound < StandardError; end
|
@@ -10,13 +16,29 @@ module Termtter
|
|
10
16
|
|
11
17
|
module Client
|
12
18
|
|
19
|
+
@hooks = {}
|
20
|
+
@commands = {}
|
21
|
+
@filters = []
|
22
|
+
@since_id = nil
|
23
|
+
@input_thread = nil
|
24
|
+
@task_manager = Termtter::TaskManager.new
|
25
|
+
|
26
|
+
config.set_default(:logger, nil)
|
27
|
+
config.set_default(:update_interval, 300)
|
28
|
+
config.set_default(:prompt, '> ')
|
29
|
+
config.set_default(:devel, false)
|
30
|
+
|
31
|
+
Thread.abort_on_exception = true
|
32
|
+
|
13
33
|
class << self
|
14
34
|
|
15
35
|
def init
|
16
36
|
@hooks = {}
|
17
37
|
@commands = {}
|
18
38
|
@filters = []
|
39
|
+
@loaded_plugins = []
|
19
40
|
@since_id = nil
|
41
|
+
@plugin_loader = nil
|
20
42
|
@task_manager = Termtter::TaskManager.new
|
21
43
|
config.set_default(:logger, nil)
|
22
44
|
config.set_default(:update_interval, 300)
|
@@ -30,6 +52,7 @@ module Termtter
|
|
30
52
|
end
|
31
53
|
|
32
54
|
def add_filter(&b)
|
55
|
+
warn "add_filter method will be removed. Use Termtter::Client.register_hook(:name => ..., :point => :filter_for_output, :exec => ... ) instead."
|
33
56
|
@filters << b
|
34
57
|
end
|
35
58
|
|
@@ -59,6 +82,15 @@ module Termtter
|
|
59
82
|
end
|
60
83
|
end
|
61
84
|
|
85
|
+
def load_plugin(name, init={})
|
86
|
+
unless init.empty?
|
87
|
+
init.each do |key, value|
|
88
|
+
config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
@plugin_loader.call(name) if @plugin_loader
|
92
|
+
end
|
93
|
+
|
62
94
|
def register_command(arg)
|
63
95
|
command = case arg
|
64
96
|
when Command
|
@@ -71,6 +103,10 @@ module Termtter
|
|
71
103
|
@commands[command.name] = command
|
72
104
|
end
|
73
105
|
|
106
|
+
def clear_command
|
107
|
+
@commands.clear
|
108
|
+
end
|
109
|
+
|
74
110
|
def get_command(name)
|
75
111
|
@commands[name]
|
76
112
|
end
|
@@ -110,26 +146,28 @@ module Termtter
|
|
110
146
|
|
111
147
|
statuses = statuses.sort_by{|s|s.id}
|
112
148
|
call_hooks(:pre_filter, statuses, event)
|
113
|
-
|
149
|
+
|
150
|
+
filtered = statuses.map(&:dup)
|
151
|
+
@filters.each do |f| # TODO: code for compatibility. delete someday.
|
152
|
+
statuses = f.call(statuses, event)
|
153
|
+
end
|
154
|
+
apply_filters_for_hook(:filter_for_output, statuses, event)
|
155
|
+
|
114
156
|
call_hooks(:post_filter, filtered, event)
|
115
157
|
get_hooks(:output).each do |hook|
|
116
|
-
|
117
|
-
|
158
|
+
hook.call(
|
159
|
+
apply_filters_for_hook("filter_for_#{hook.name}", filtered, event),
|
160
|
+
event
|
161
|
+
)
|
118
162
|
end
|
163
|
+
call_hooks(:post_output, filtered, event)
|
119
164
|
end
|
120
165
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
filtered
|
127
|
-
end
|
128
|
-
|
129
|
-
def apply_filters_for_hook(statuses, hook_name)
|
130
|
-
# TODO
|
131
|
-
filtered = statuses.map(&:dup)
|
132
|
-
filtered
|
166
|
+
def apply_filters_for_hook(hook_name, statuses, event)
|
167
|
+
get_hooks(hook_name).each do |hook|
|
168
|
+
statuses = hook.call(statuses, event)
|
169
|
+
end
|
170
|
+
statuses
|
133
171
|
end
|
134
172
|
|
135
173
|
# return last hook return value
|
@@ -142,12 +180,13 @@ module Termtter
|
|
142
180
|
result
|
143
181
|
end
|
144
182
|
|
145
|
-
def call_commands(text
|
183
|
+
def call_commands(text)
|
146
184
|
return if text.empty?
|
147
185
|
|
148
|
-
|
149
|
-
|
150
|
-
|
186
|
+
commands = find_commands(text)
|
187
|
+
raise CommandNotFound, text if commands.empty?
|
188
|
+
|
189
|
+
commands.each do |command|
|
151
190
|
command_found = true
|
152
191
|
command_str, command_arg = Command.split_command_line(text)
|
153
192
|
|
@@ -168,8 +207,10 @@ module Termtter
|
|
168
207
|
end
|
169
208
|
end
|
170
209
|
end
|
210
|
+
end
|
171
211
|
|
172
|
-
|
212
|
+
def find_commands(text)
|
213
|
+
@commands.values.select { |command| command.match?(text) }
|
173
214
|
end
|
174
215
|
|
175
216
|
def pause
|
@@ -194,6 +235,8 @@ module Termtter
|
|
194
235
|
def load_default_plugins
|
195
236
|
plugin 'standard_plugins'
|
196
237
|
plugin 'stdout'
|
238
|
+
plugin 'readline'
|
239
|
+
plugin 'update_timeline'
|
197
240
|
end
|
198
241
|
|
199
242
|
def load_config
|
@@ -224,12 +267,6 @@ module Termtter
|
|
224
267
|
Termtter::CONF_FILE)
|
225
268
|
end
|
226
269
|
|
227
|
-
def post_config_load()
|
228
|
-
if config.devel
|
229
|
-
plugin 'devel'
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
270
|
def logger
|
234
271
|
@logger
|
235
272
|
end
|
@@ -261,12 +298,29 @@ module Termtter
|
|
261
298
|
logger
|
262
299
|
end
|
263
300
|
|
301
|
+
def init(&block)
|
302
|
+
@init_block = block
|
303
|
+
end
|
304
|
+
|
264
305
|
def run
|
265
|
-
|
306
|
+
@plugin_loader = lambda do |name|
|
307
|
+
@loaded_plugins.push(name)
|
308
|
+
end
|
309
|
+
|
266
310
|
load_config()
|
311
|
+
load_default_plugins()
|
267
312
|
Termtter::API.setup()
|
268
313
|
setup_logger()
|
269
|
-
|
314
|
+
|
315
|
+
plugin 'devel' if config.devel
|
316
|
+
|
317
|
+
@plugin_loader = lambda do |name|
|
318
|
+
@loaded_plugins.push(name)
|
319
|
+
load "plugins/#{name}.rb"
|
320
|
+
end
|
321
|
+
@loaded_plugins.each { |name| load "plugins/#{name}.rb" }
|
322
|
+
|
323
|
+
call_hooks(:initialize)
|
270
324
|
|
271
325
|
config.system.eval_scripts.each do |script|
|
272
326
|
begin
|
@@ -279,10 +333,8 @@ module Termtter
|
|
279
333
|
config.system.run_commands.each { |cmd| call_commands(cmd) }
|
280
334
|
|
281
335
|
unless config.system.cmd_mode
|
282
|
-
call_hooks(:initialize)
|
283
|
-
plugin('update_timeline')
|
284
336
|
@task_manager.run()
|
285
|
-
call_hooks(:
|
337
|
+
call_hooks(:post_task_thread_run)
|
286
338
|
end
|
287
339
|
end
|
288
340
|
|
@@ -301,5 +353,3 @@ module Termtter
|
|
301
353
|
end
|
302
354
|
end
|
303
355
|
end
|
304
|
-
|
305
|
-
Termtter::Client.init
|
@@ -1,36 +1,28 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'erb'
|
4
|
+
|
3
5
|
module Termtter
|
4
6
|
module ConfigSetup
|
5
7
|
module_function
|
6
8
|
def run
|
7
9
|
ui = create_highline
|
8
|
-
|
10
|
+
user_name = ui.ask('your twitter user name: ')
|
9
11
|
password = ui.ask('your twitter password: ') { |q| q.echo = false }
|
10
12
|
|
13
|
+
plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
|
14
|
+
f.match(%r|lib/plugins/(.*?).rb$|)[1]
|
15
|
+
}
|
16
|
+
standard_plugins = %w[stdout standard_commands auto_reload]
|
17
|
+
|
18
|
+
template = open(File.dirname(__FILE__) + '/config_template.erb').read
|
19
|
+
config = ERB.new(template, nil, '-').result(binding) # trim_mode => '-'
|
20
|
+
|
11
21
|
Dir.mkdir(Termtter::CONF_DIR) unless File.exists?(Termtter::CONF_DIR)
|
12
22
|
File.open(Termtter::CONF_FILE, 'w') {|io|
|
13
|
-
io
|
14
|
-
|
15
|
-
io.puts
|
16
|
-
io.puts "config.user_name = '#{username}'"
|
17
|
-
io.puts "config.password = '#{password}'"
|
18
|
-
io.puts "#config.update_interval = 120"
|
19
|
-
io.puts "#config.proxy.host = 'proxy host'"
|
20
|
-
io.puts "#config.proxy.port = '8080'"
|
21
|
-
io.puts "#config.proxy.user_name = 'proxy user'"
|
22
|
-
io.puts "#config.proxy.password = 'proxy password'"
|
23
|
-
io.puts
|
24
|
-
plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
|
25
|
-
f.match(%r|lib/plugins/(.*?).rb$|)[1]
|
26
|
-
}
|
27
|
-
plugins -= %w[stdout standard_plugins]
|
28
|
-
plugins.each do |p|
|
29
|
-
io.puts "#plugin '#{p}'"
|
30
|
-
end
|
31
|
-
io.puts
|
32
|
-
io.puts "# vim: set filetype=ruby"
|
23
|
+
io << config
|
33
24
|
}
|
25
|
+
|
34
26
|
puts "generated: ~/.termtter/config"
|
35
27
|
puts "enjoy!"
|
36
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
config.user_name = '<%= user_name %>'
|
4
|
+
config.password = '<%= password %>'
|
5
|
+
#config.update_interval = 120
|
6
|
+
#config.proxy.host = 'proxy host'
|
7
|
+
#config.proxy.port = '8080'
|
8
|
+
#config.proxy.user_name = 'proxy user'
|
9
|
+
#config.proxy.password = 'proxy password'
|
10
|
+
|
11
|
+
Termtter::Client.init do |t|
|
12
|
+
<%- standard_plugins.each do |plugin| -%>
|
13
|
+
t.plug '<%= plugin %>'
|
14
|
+
<%- end -%>
|
15
|
+
<%- (plugins - standard_plugins).each do |plugin| -%>
|
16
|
+
# t.plug '<%= plugin %>'
|
17
|
+
<%- end -%>
|
18
|
+
end
|
data/lib/termtter/optparse.rb
CHANGED
@@ -23,6 +23,11 @@ OptionParser.new { |opt|
|
|
23
23
|
config.system.run_commands << cmd
|
24
24
|
end
|
25
25
|
|
26
|
+
config.system.load_plugins = []
|
27
|
+
opt.on('-p', '--plugin plugin', 'Load plugin') do |plugin|
|
28
|
+
config.system.load_plugins << plugin
|
29
|
+
end
|
30
|
+
|
26
31
|
config.system.eval_scripts = []
|
27
32
|
opt.on('-e', '--eval-script script', 'Eval script') do |script|
|
28
33
|
config.system.eval_scripts << script
|
@@ -1,23 +1,12 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
def plugin(name, init = {})
|
4
|
-
unless init.empty?
|
5
|
-
init.each do |key, value|
|
6
|
-
config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
load "plugins/#{name}.rb"
|
10
|
-
rescue Exception => e
|
11
|
-
Termtter::Client.handle_error(e)
|
12
|
-
end
|
13
|
-
|
14
3
|
def filter(name, init = {})
|
15
4
|
warn "filter method will be removed. Use plugin instead."
|
16
5
|
plugin(name, init)
|
17
6
|
end
|
18
7
|
|
19
8
|
def win?
|
20
|
-
RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/
|
9
|
+
RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin|cygwin/
|
21
10
|
end
|
22
11
|
|
23
12
|
if win?
|
@@ -103,13 +92,9 @@ require 'highline'
|
|
103
92
|
def create_highline
|
104
93
|
HighLine.track_eof = false
|
105
94
|
if $stdin.respond_to?(:getbyte) # for ruby1.9
|
106
|
-
|
107
|
-
stdin_for_highline = SimpleDelegator.new($stdin)
|
108
|
-
def stdin_for_highline.getc
|
95
|
+
def $stdin.getc
|
109
96
|
getbyte
|
110
97
|
end
|
111
|
-
else
|
112
|
-
stdin_for_highline = $stdin
|
113
98
|
end
|
114
|
-
HighLine.new(
|
99
|
+
HighLine.new($stdin)
|
115
100
|
end
|
data/lib/termtter/version.rb
CHANGED
@@ -6,8 +6,11 @@ module Termtter
|
|
6
6
|
|
7
7
|
describe Client do
|
8
8
|
|
9
|
-
|
9
|
+
before do
|
10
10
|
Client.setup_logger
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should take command' do
|
11
14
|
command = Command.new(:name => :test)
|
12
15
|
Client.register_command(command)
|
13
16
|
Client.get_command(:test).should == command
|
@@ -30,7 +33,7 @@ module Termtter
|
|
30
33
|
['test foo bar ', 'foo bar'],
|
31
34
|
['test foo bar ', 'foo bar'],
|
32
35
|
].each do |input, args|
|
33
|
-
Client.call_commands(input
|
36
|
+
Client.call_commands(input)
|
34
37
|
command_arg.should == args
|
35
38
|
end
|
36
39
|
end
|
@@ -177,10 +180,8 @@ module Termtter
|
|
177
180
|
end
|
178
181
|
|
179
182
|
it 'run' do
|
180
|
-
Client.should_receive(:load_default_plugins)
|
181
183
|
Client.should_receive(:load_config)
|
182
184
|
Termtter::API.should_receive(:setup)
|
183
|
-
Client.should_receive(:post_config_load)
|
184
185
|
Client.should_receive(:start_input_thread)
|
185
186
|
Client.run
|
186
187
|
end
|
@@ -249,5 +250,38 @@ module Termtter
|
|
249
250
|
$stdout.string.should match(/foo USER/)
|
250
251
|
$stdout.string.should match(/foo list/)
|
251
252
|
end
|
253
|
+
|
254
|
+
describe 'add commands' do
|
255
|
+
before(:each) do
|
256
|
+
Client.clear_command
|
257
|
+
Client.register_command(:name => :foo1)
|
258
|
+
Client.register_command(:name => :foo2)
|
259
|
+
Client.register_command(:name => :bar)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'commands number is 3' do
|
263
|
+
Client.commands.size.should == 3
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should find a command' do
|
267
|
+
Client.find_commands('foo1').size.should == 1
|
268
|
+
Client.find_commands('foo1')[0].name.should == :foo1
|
269
|
+
Client.find_commands('bar').size.should == 1
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should find no command' do
|
273
|
+
Client.find_commands('foo').size.should == 0
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe 'clear commands' do
|
278
|
+
before(:each) do
|
279
|
+
Client.clear_command
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should no command' do
|
283
|
+
Client.commands.size.should == 0
|
284
|
+
end
|
285
|
+
end
|
252
286
|
end
|
253
287
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: draftcode-termtter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- draftcode
|
@@ -65,6 +65,7 @@ extra_rdoc_files:
|
|
65
65
|
files:
|
66
66
|
- lib/plugins/addspace.rb
|
67
67
|
- lib/plugins/april_fool.rb
|
68
|
+
- lib/plugins/auto_reload.rb
|
68
69
|
- lib/plugins/bomb.rb
|
69
70
|
- lib/plugins/clear.rb
|
70
71
|
- lib/plugins/command_plus.rb
|
@@ -91,12 +92,16 @@ files:
|
|
91
92
|
- lib/plugins/hatebu_and_update.rb
|
92
93
|
- lib/plugins/history.rb
|
93
94
|
- lib/plugins/ignore.rb
|
95
|
+
- lib/plugins/irc_gw.rb
|
94
96
|
- lib/plugins/keyword.rb
|
95
97
|
- lib/plugins/l2.rb
|
98
|
+
- lib/plugins/list_with_opts.rb
|
96
99
|
- lib/plugins/log.rb
|
100
|
+
- lib/plugins/mark.rb
|
97
101
|
- lib/plugins/me.rb
|
98
102
|
- lib/plugins/modify_arg_hook_sample.rb
|
99
103
|
- lib/plugins/msagent.rb
|
104
|
+
- lib/plugins/multi_post.rb
|
100
105
|
- lib/plugins/multi_reply.rb
|
101
106
|
- lib/plugins/notify-send.rb
|
102
107
|
- lib/plugins/notify-send2.rb
|
@@ -123,7 +128,7 @@ files:
|
|
123
128
|
- lib/plugins/shell.rb
|
124
129
|
- lib/plugins/sl.rb
|
125
130
|
- lib/plugins/spam.rb
|
126
|
-
- lib/plugins/
|
131
|
+
- lib/plugins/standard_commands.rb
|
127
132
|
- lib/plugins/stdout.rb
|
128
133
|
- lib/plugins/storage/DB.rb
|
129
134
|
- lib/plugins/storage/status.rb
|
@@ -136,8 +141,8 @@ files:
|
|
136
141
|
- lib/plugins/translation.rb
|
137
142
|
- lib/plugins/typable_id.rb
|
138
143
|
- lib/plugins/update_editor.rb
|
139
|
-
- lib/plugins/update_timeline.rb
|
140
144
|
- lib/plugins/uri-open.rb
|
145
|
+
- lib/plugins/wassr.rb
|
141
146
|
- lib/plugins/wassr_post.rb
|
142
147
|
- lib/plugins/yhara.rb
|
143
148
|
- lib/plugins/yhara_filter.rb
|
@@ -155,6 +160,7 @@ files:
|
|
155
160
|
- lib/termtter/task_manager.rb
|
156
161
|
- lib/termtter/version.rb
|
157
162
|
- lib/termtter.rb
|
163
|
+
- lib/termtter/config_template.erb
|
158
164
|
- spec/plugins/cool_spec.rb
|
159
165
|
- spec/plugins/english_spec.rb
|
160
166
|
- spec/plugins/fib_spec.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module Termtter::Client
|
3
|
-
register_command(
|
4
|
-
:name => :_update_timeline,
|
5
|
-
:exec_proc => lambda {|arg|
|
6
|
-
begin
|
7
|
-
args = @since_id ? [{:since_id => @since_id}] : []
|
8
|
-
statuses = Termtter::API.twitter.friends_timeline(*args)
|
9
|
-
unless statuses.empty?
|
10
|
-
print "\e[1K\e[0G" unless win?
|
11
|
-
@since_id = statuses[0].id
|
12
|
-
output(statuses, :update_friends_timeline)
|
13
|
-
Readline.refresh_line
|
14
|
-
end
|
15
|
-
rescue OpenURI::HTTPError => e
|
16
|
-
if e.message == '401 Unauthorized'
|
17
|
-
puts 'Could not login'
|
18
|
-
puts 'plese check your account settings'
|
19
|
-
exit!
|
20
|
-
end
|
21
|
-
rescue => e
|
22
|
-
handle_error(e)
|
23
|
-
end
|
24
|
-
}
|
25
|
-
)
|
26
|
-
|
27
|
-
add_task(:name => :update_timeline, :interval => config.update_interval, :after => config.update_interval) do
|
28
|
-
call_commands('_update_timeline')
|
29
|
-
end
|
30
|
-
|
31
|
-
call_commands('_update_timeline')
|
32
|
-
end
|