termtter 1.9.0 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +15 -15
- data/VERSION +1 -1
- data/lib/plugins/appendtitle.rb +39 -19
- data/lib/plugins/basic.rb +25 -0
- data/lib/plugins/capture.rb +22 -0
- data/lib/plugins/channel.rb +4 -5
- data/lib/plugins/copy.rb +32 -0
- data/lib/plugins/defaults/auto_reload.rb +4 -0
- data/lib/plugins/defaults/cache.rb +2 -2
- data/lib/plugins/defaults/command_line.rb +21 -0
- data/lib/plugins/defaults/keyword.rb +58 -8
- data/lib/plugins/defaults/list.rb +6 -4
- data/lib/plugins/defaults/retweet.rb +6 -1
- data/lib/plugins/defaults/standard_commands.rb +54 -27
- data/lib/plugins/defaults/stdout.rb +8 -4
- data/lib/plugins/defaults/switch.rb +21 -9
- data/lib/plugins/encoding.rb +46 -0
- data/lib/plugins/english.rb +2 -1
- data/lib/plugins/friends.rb +5 -8
- data/lib/plugins/geo.rb +21 -0
- data/lib/plugins/http_server.rb +10 -3
- data/lib/plugins/http_server/{index.html → skin/default/index.html} +0 -0
- data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/001.png +0 -0
- data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/002.png +0 -0
- data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/003.png +0 -0
- data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/004.png +0 -0
- data/lib/plugins/http_server/skin/miku/cui/chara/miku/script.js +66 -0
- data/lib/plugins/http_server/skin/miku/cui/core.js +198 -0
- data/lib/plugins/http_server/skin/miku/cui/util.js +65 -0
- data/lib/plugins/http_server/skin/miku/index.html +142 -0
- data/lib/plugins/http_server/skin/miku/jquery-1.4.2.min.js +154 -0
- data/lib/plugins/http_server/skin/sample1/index.html +165 -0
- data/lib/plugins/im_kayac.rb +33 -0
- data/lib/plugins/irc_gw.rb +53 -17
- data/lib/plugins/mongo.rb +112 -0
- data/lib/plugins/reply_sound.rb +1 -1
- data/lib/plugins/say.rb +2 -1
- data/lib/plugins/searchline.rb +1 -1
- data/lib/plugins/short_logger.rb +15 -0
- data/lib/plugins/storage.rb +1 -1
- data/lib/plugins/storage/status.rb +1 -1
- data/lib/plugins/stream.rb +1 -3
- data/lib/plugins/suspend.rb +9 -0
- data/lib/plugins/time_signal.rb +1 -1
- data/lib/plugins/tinyurl.rb +17 -8
- data/lib/plugins/truncate.rb +13 -3
- data/lib/plugins/update_editor.rb +1 -1
- data/lib/plugins/url.rb +11 -0
- data/lib/plugins/user_stream.rb +76 -51
- data/lib/termtter.rb +1 -0
- data/lib/termtter/active_rubytter.rb +3 -6
- data/lib/termtter/api.rb +18 -8
- data/lib/termtter/client.rb +30 -18
- data/lib/termtter/command.rb +22 -13
- data/lib/termtter/config.rb +15 -4
- data/lib/termtter/config_setup.rb +17 -2
- data/lib/termtter/config_template.erb +1 -0
- data/lib/termtter/default_config.rb +3 -1
- data/lib/termtter/hookable.rb +3 -3
- data/lib/termtter/httppool.rb +10 -4
- data/lib/termtter/memory_cache.rb +1 -1
- data/lib/termtter/optparse.rb +0 -4
- data/lib/termtter/rubytter_proxy.rb +31 -11
- data/lib/termtter/system_extensions.rb +9 -1
- data/lib/termtter/system_extensions/core_compatibles.rb +9 -2
- data/lib/termtter/task_manager.rb +2 -0
- data/spec/plugins/capital_update_spec.rb +1 -1
- data/spec/plugins/cool_spec.rb +1 -1
- data/spec/plugins/curry_spec.rb +1 -1
- data/spec/plugins/db_spec.rb +1 -1
- data/spec/plugins/defaults/hashtag_spec.rb +1 -1
- data/spec/plugins/defaults/list_spec.rb +1 -1
- data/spec/plugins/defaults/plugin_spec.rb +1 -1
- data/spec/plugins/defaults/retweet_spec.rb +1 -1
- data/spec/plugins/draft_spec.rb +1 -1
- data/spec/plugins/english_spec_.rb +1 -1
- data/spec/plugins/expand-tinyurl_spec.rb +1 -1
- data/spec/plugins/fib_spec.rb +1 -1
- data/spec/plugins/filter_spec_.rb +1 -1
- data/spec/plugins/footer_spec.rb +1 -1
- data/spec/plugins/gsub_spec.rb +1 -1
- data/spec/plugins/haml_spec.rb +1 -1
- data/spec/plugins/hi_spec.rb +1 -1
- data/spec/plugins/md5pass_spec.rb +1 -1
- data/spec/plugins/pause_spec.rb +1 -1
- data/spec/plugins/primes_spec_.rb +1 -1
- data/spec/plugins/shell_spec.rb +1 -1
- data/spec/plugins/sl_spec_.rb +1 -1
- data/spec/plugins/spam_spec.rb +1 -1
- data/spec/plugins/standard_commands_spec.rb +1 -1
- data/spec/plugins/storage/sqlite3_spec.rb +2 -2
- data/spec/plugins/storage/status_spec_.rb +2 -2
- data/spec/plugins/tinyurl_spec.rb +1 -1
- data/spec/plugins/truncate_spec.rb +36 -1
- data/spec/plugins/whois_spec_.rb +1 -1
- data/spec/termtter/active_rubytter_spec.rb +1 -1
- data/spec/termtter/api_spec.rb +1 -1
- data/spec/termtter/client_spec.rb +1 -1
- data/spec/termtter/command_spec.rb +1 -1
- data/spec/termtter/config_setup_spec.rb +1 -1
- data/spec/termtter/config_spec.rb +9 -1
- data/spec/termtter/crypt_spec.rb +1 -1
- data/spec/termtter/event_spec.rb +1 -1
- data/spec/termtter/hook_spec.rb +1 -1
- data/spec/termtter/hookable_spec.rb +1 -1
- data/spec/termtter/memory_cache_spec.rb +1 -1
- data/spec/termtter/optparse_spec.rb +1 -1
- data/spec/termtter/rubytter_proxy_spec.rb +1 -1
- data/spec/termtter/system_extensions/windows_spec.rb +1 -1
- data/spec/termtter/system_extensions_spec.rb +1 -1
- data/spec/termtter/task_manager_spec.rb +1 -1
- data/spec/termtter/task_spec.rb +1 -1
- data/spec/termtter_spec.rb +1 -1
- data/termtter.gemspec +326 -0
- metadata +81 -149
- data/.gitignore +0 -5
data/lib/plugins/truncate.rb
CHANGED
@@ -5,10 +5,20 @@ def multibyte_string(text)
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def truncate(text, length = 140, omission = "...")
|
8
|
-
o = multibyte_string(omission)
|
9
|
-
l = length - o.length
|
10
8
|
chars = multibyte_string(text)
|
11
|
-
chars.length > length
|
9
|
+
if chars.length > length
|
10
|
+
_, text_base, urls =
|
11
|
+
text.match(/\A(.*?)((?:\s+#{URI.regexp(%w(http https ftp))}\S*)*)\z/).to_a
|
12
|
+
chars_base = multibyte_string(text_base)
|
13
|
+
o = multibyte_string(omission + urls)
|
14
|
+
if o.length >= length
|
15
|
+
o = multibyte_string(omission)
|
16
|
+
chars_base = chars
|
17
|
+
end
|
18
|
+
(chars_base[0...(length - o.length)] + o).pack('U*')
|
19
|
+
else
|
20
|
+
text
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
Termtter::RubytterProxy.register_hook(
|
data/lib/plugins/url.rb
ADDED
data/lib/plugins/user_stream.rb
CHANGED
@@ -1,3 +1,53 @@
|
|
1
|
+
module Termtter
|
2
|
+
class UserStreamReceiver
|
3
|
+
|
4
|
+
def run(&block)
|
5
|
+
loop {
|
6
|
+
begin
|
7
|
+
self.process &block
|
8
|
+
rescue => error
|
9
|
+
Termtter::Client.handle_error error
|
10
|
+
sleep 10
|
11
|
+
end
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.repack_error(error, chunk)
|
16
|
+
new_error = error.class.new("#{error.message} (#{JSON.parse(chunk).inspect})")
|
17
|
+
error.instance_variables.each{ |v|
|
18
|
+
new_error.instance_variable_set(v, error.instance_variable_get(v))
|
19
|
+
}
|
20
|
+
new_error
|
21
|
+
rescue
|
22
|
+
error
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
ENDPOINT = URI.parse('https://userstream.twitter.com/2/user.json')
|
27
|
+
|
28
|
+
def process(&block)
|
29
|
+
Termtter::Client.logger.info("connecting to UserStream")
|
30
|
+
https = Net::HTTP.new(ENDPOINT.host, ENDPOINT.port)
|
31
|
+
https.use_ssl = true
|
32
|
+
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
33
|
+
|
34
|
+
https.start{ |https|
|
35
|
+
request = Net::HTTP::Get.new(ENDPOINT.request_uri)
|
36
|
+
request.oauth!(https, Termtter::API.twitter.access_token.consumer, Termtter::API.twitter.access_token)
|
37
|
+
https.request(request){ |response|
|
38
|
+
raise StandardError, response.code.to_i unless response.code.to_i == 200
|
39
|
+
raise StandardError, 'Response is not chuncked' unless response.chunked?
|
40
|
+
Termtter::Client.logger.info("connected to UserStream")
|
41
|
+
response.read_body{ |chunk|
|
42
|
+
Termtter::Client.logger.debug("received: #{chunk}")
|
43
|
+
yield chunk
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
1
51
|
module Termtter::Client
|
2
52
|
register_command(:"user_stream stop", :help => 'user_stream stop') do |arg|
|
3
53
|
logger.info 'stopping user stream'
|
@@ -5,11 +55,13 @@ module Termtter::Client
|
|
5
55
|
@user_stream_thread.exit
|
6
56
|
end
|
7
57
|
@user_stream_thread = nil
|
58
|
+
plug "defaults/auto_reload"
|
8
59
|
end
|
9
60
|
|
10
61
|
handle_chunk = lambda { |chunk|
|
11
62
|
data = Termtter::ActiveRubytter.new(JSON.parse(chunk)) rescue return
|
12
63
|
Termtter::Client.logger.debug "user_stream: received #{JSON.parse(chunk).inspect}"
|
64
|
+
Termtter::Client.clear_line
|
13
65
|
begin
|
14
66
|
if data[:event]
|
15
67
|
if /list_/ =~ data[:event]
|
@@ -34,79 +86,52 @@ module Termtter::Client
|
|
34
86
|
elsif data[:friends]
|
35
87
|
puts "You have #{data[:friends].length} friends."
|
36
88
|
elsif data[:delete]
|
37
|
-
status = Termtter::API.twitter.
|
38
|
-
puts "#{status.user.screen_name} deleted: #{status.text}"
|
89
|
+
# status = Termtter::API.twitter.cached_status(data.delete.status.id)
|
90
|
+
# puts "#{status.user.screen_name} deleted: #{status.text}"
|
91
|
+
elsif data[:direct_message]
|
92
|
+
dm = data[:direct_message]
|
93
|
+
sender = dm.sender
|
94
|
+
text = dm.text
|
95
|
+
puts "[DM] #{sender.screen_name}: #{text}"
|
39
96
|
else
|
40
|
-
output([data], Termtter::Event.new(:update_friends_timeline, :type => :main))
|
41
97
|
Termtter::API.twitter.store_status_cache(data)
|
98
|
+
output([data], :update_friends_timeline)
|
42
99
|
end
|
43
|
-
rescue Termtter::RubytterProxy::FrequentAccessError
|
44
|
-
# ignore
|
45
100
|
rescue Timeout::Error, StandardError => error
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
}
|
50
|
-
handle_error new_error
|
101
|
+
Termtter::Client.handle_error Termtter::UserStreamReceiver.repack_error(error, chunk)
|
102
|
+
ensure
|
103
|
+
Readline.refresh_line
|
51
104
|
end
|
52
105
|
}
|
53
106
|
|
54
107
|
register_command(:"user_stream", :help => 'user_stream') do |arg|
|
55
|
-
unless config.password.kind_of? String
|
56
|
-
raise "config.password is required."
|
57
|
-
end
|
58
|
-
|
59
|
-
uri = URI.parse('http://betastream.twitter.com/2b/user.json')
|
60
|
-
|
61
|
-
unless @user_stream_thread
|
62
|
-
logger.info 'checking API status'
|
63
|
-
1.times{ # to use break
|
64
|
-
Net::HTTP.start(uri.host, uri.port){ |http|
|
65
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
66
|
-
request.basic_auth(config.user_name, config.password)
|
67
|
-
http.request(request){ |response|
|
68
|
-
raise response.code.to_i unless response.code.to_i == 200
|
69
|
-
break
|
70
|
-
}
|
71
|
-
}
|
72
|
-
}
|
73
|
-
logger.info 'API seems working'
|
74
|
-
end
|
75
108
|
|
76
109
|
execute('user_stream stop') if @user_stream_thread
|
77
110
|
delete_task(:auto_reload)
|
78
111
|
|
79
112
|
@user_stream_thread = Thread.new {
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
Net::HTTP.start(uri.host, uri.port){ |http|
|
84
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
85
|
-
request.basic_auth(config.user_name, config.password)
|
86
|
-
http.request(request){ |response|
|
87
|
-
raise response.code.to_i unless response.code.to_i == 200
|
88
|
-
raise 'Response is not chuncked' unless response.chunked?
|
89
|
-
response.read_body{ |chunk|
|
90
|
-
handle_chunk.call(chunk)
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
94
|
-
rescue Timeout::Error, StandardError => e
|
95
|
-
handle_error e
|
96
|
-
logger.info 'sleeping'
|
97
|
-
sleep 10
|
98
|
-
end
|
99
|
-
end
|
113
|
+
Termtter::UserStreamReceiver.new.run{|chunk|
|
114
|
+
call_hooks(:user_stream_receive, chunk)
|
115
|
+
}
|
100
116
|
}
|
101
117
|
end
|
102
118
|
|
103
119
|
register_hook(
|
104
120
|
:name => :user_stream_init,
|
105
|
-
:author => '?', # FIXME
|
106
121
|
:point => :initialize,
|
107
122
|
:exec => lambda {
|
108
123
|
execute('user_stream')
|
109
124
|
})
|
125
|
+
|
126
|
+
register_hook(
|
127
|
+
:name => :user_stream_print,
|
128
|
+
:point => :user_stream_receive,
|
129
|
+
:exec => lambda {|chunk|
|
130
|
+
Thread.new {
|
131
|
+
handle_chunk.call(chunk)
|
132
|
+
}
|
133
|
+
})
|
134
|
+
|
110
135
|
end
|
111
136
|
|
112
137
|
# user_stream.rb
|
data/lib/termtter.rb
CHANGED
@@ -43,6 +43,7 @@ module Termtter
|
|
43
43
|
OptParser.parse!(ARGV)
|
44
44
|
CONF_DIR = File.expand_path('~/.termtter') unless defined? CONF_DIR
|
45
45
|
CONF_FILE = File.join(Termtter::CONF_DIR, 'config') unless defined? CONF_FILE
|
46
|
+
config.token_file = File.join(Termtter::CONF_DIR, config.token_file_name)
|
46
47
|
$:.unshift(CONF_DIR)
|
47
48
|
|
48
49
|
CONSUMER_KEY = 'eFFLaGJ3M0VMZExvNmtlNHJMVndsQQ=='
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
gem 'rubytter', '>= 0.6.5'
|
3
2
|
require 'rubytter'
|
3
|
+
raise Gem::LoadError, 'Could not find RubyGem rubytter (>= 0.6.5)' \
|
4
|
+
unless Rubytter::VERSION >= '0.6.5'
|
4
5
|
|
5
6
|
module Termtter
|
6
7
|
class ActiveRubytter
|
@@ -17,11 +18,7 @@ module Termtter
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def method_missing(name, *args)
|
20
|
-
|
21
|
-
return @data[name]
|
22
|
-
else
|
23
|
-
super
|
24
|
-
end
|
21
|
+
@data[name]
|
25
22
|
end
|
26
23
|
|
27
24
|
def attributes=(raw_hash)
|
data/lib/termtter/api.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
config.set_default(:host, 'api.twitter.com')
|
4
4
|
config.set_default(:oauth_consumer_site, 'http://api.twitter.com')
|
5
|
-
if ENV
|
5
|
+
if ENV['HTTP_PROXY'] || ENV['http_proxy']
|
6
6
|
require 'uri'
|
7
|
-
proxy = ENV['HTTP_PROXY']
|
7
|
+
proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
|
8
8
|
proxy = "http://" + proxy if proxy !~ /^http:\/\//
|
9
9
|
u = URI.parse(proxy)
|
10
10
|
config.proxy.set_default(:host, u.host)
|
@@ -50,12 +50,12 @@ module Termtter
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def authorize_by_oauth(show_information=false, save_to_token_file=true, put_to_config=true, verbose=true)
|
53
|
-
puts '1.
|
53
|
+
puts '1. Connecting to twitter...' if verbose
|
54
54
|
|
55
55
|
request_token = consumer.get_request_token
|
56
56
|
|
57
|
-
puts '2. URL
|
58
|
-
puts ' Opening web page
|
57
|
+
puts '2. Authorization URL: ' + request_token.authorize_url if verbose
|
58
|
+
puts ' Opening authorization web page...' if verbose
|
59
59
|
|
60
60
|
begin
|
61
61
|
open_browser(request_token.authorize_url)
|
@@ -67,7 +67,7 @@ module Termtter
|
|
67
67
|
ui = create_highline
|
68
68
|
pin = ui.ask('3. Enter PIN: ')
|
69
69
|
puts ""
|
70
|
-
puts "4.
|
70
|
+
puts "4. Fetching access_token..."
|
71
71
|
access_token = request_token.get_access_token(:oauth_verifier => pin)
|
72
72
|
|
73
73
|
if put_to_config
|
@@ -83,7 +83,7 @@ module Termtter
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
puts "
|
86
|
+
puts "Authorization successfully completed."
|
87
87
|
|
88
88
|
return {:token => access_token.token,
|
89
89
|
:secret => access_token.secret}
|
@@ -94,7 +94,7 @@ module Termtter
|
|
94
94
|
Termtter::Crypt.decrypt(CONSUMER_KEY),
|
95
95
|
Termtter::Crypt.decrypt(CONSUMER_SECRET),
|
96
96
|
:site => config.oauth_consumer_site,
|
97
|
-
:proxy =>
|
97
|
+
:proxy => proxy_string
|
98
98
|
)
|
99
99
|
end
|
100
100
|
|
@@ -115,6 +115,16 @@ module Termtter
|
|
115
115
|
:proxy_password => config.proxy.password
|
116
116
|
}
|
117
117
|
end
|
118
|
+
|
119
|
+
def proxy_string
|
120
|
+
return unless config.proxy.host
|
121
|
+
if config.proxy.user_name && config.proxy.password
|
122
|
+
"http://#{config.proxy.user_name}:#{config.proxy.password}@#{config.proxy.host}:#{config.proxy.port}"
|
123
|
+
else
|
124
|
+
"http://#{config.proxy.host}:#{config.proxy.port}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
118
128
|
end
|
119
129
|
end
|
120
130
|
end
|
data/lib/termtter/client.rb
CHANGED
@@ -19,7 +19,8 @@ module Termtter
|
|
19
19
|
class << self
|
20
20
|
attr_reader :commands, :logger, :task_manager
|
21
21
|
|
22
|
-
#
|
22
|
+
# call-seq:
|
23
|
+
# plug :: Name -> (Hash) -> IO () where NAME = String | Symbol | [NAME]
|
23
24
|
def plug(name, options = {})
|
24
25
|
if Array === name # Obviously `name.respond_to?(:each)` is better, but for 1.8.6 compatibility we cannot.
|
25
26
|
name.each {|i| plug(i, options) }
|
@@ -116,7 +117,7 @@ module Termtter
|
|
116
117
|
# :text => status,
|
117
118
|
# :original_data => original data,
|
118
119
|
# }
|
119
|
-
def output(statuses, event)
|
120
|
+
def output(statuses, event = :default)
|
120
121
|
return if statuses.nil? || statuses.empty?
|
121
122
|
event = Termtter::Event.new(event) unless event.kind_of? Termtter::Event
|
122
123
|
|
@@ -132,7 +133,7 @@ module Termtter
|
|
132
133
|
|
133
134
|
call_hooks(:post_filter, filtered, event)
|
134
135
|
get_hooks(:output).each do |hook|
|
135
|
-
Termtter::Client.logger.debug "output: call hook :output #{hook.inspect}"
|
136
|
+
Termtter::Client.logger.debug { "output: call hook :output #{hook.inspect}" }
|
136
137
|
hook.call(
|
137
138
|
apply_filters_for_hook(:"filter_for_#{hook.name}", filtered, event),
|
138
139
|
event)
|
@@ -232,6 +233,10 @@ module Termtter
|
|
232
233
|
ConfigSetup.run
|
233
234
|
end
|
234
235
|
load Termtter::CONF_FILE
|
236
|
+
unless config.dmsg_permission
|
237
|
+
require 'termtter/config_setup'
|
238
|
+
ConfigSetup.reauth
|
239
|
+
end
|
235
240
|
end
|
236
241
|
|
237
242
|
def legacy_config_support
|
@@ -261,6 +266,7 @@ module Termtter
|
|
261
266
|
def setup_logger
|
262
267
|
@logger = config.logger || default_logger
|
263
268
|
@logger.level = config.devel ? Logger::DEBUG : Logger::INFO
|
269
|
+
call_hooks(:post_setup_logger)
|
264
270
|
@logger
|
265
271
|
end
|
266
272
|
|
@@ -314,24 +320,20 @@ module Termtter
|
|
314
320
|
|
315
321
|
def run
|
316
322
|
parse_options
|
317
|
-
|
318
|
-
show_splash
|
323
|
+
show_splash unless config.system.cmd_mode
|
319
324
|
setup_task_manager
|
320
325
|
load_config
|
321
326
|
load_plugins
|
322
327
|
eval_init_block
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
eval script
|
329
|
-
rescue Exception => e
|
330
|
-
handle_error(e)
|
331
|
-
end
|
328
|
+
begin
|
329
|
+
Termtter::API.setup
|
330
|
+
rescue Rubytter::APIError => e
|
331
|
+
handle_error(e)
|
332
|
+
exit!
|
332
333
|
end
|
333
334
|
|
334
|
-
config.system.
|
335
|
+
config.system.eval_scripts.each {|script| rescue_error { eval script }}
|
336
|
+
config.system.run_commands.each {|cmd| rescue_error { execute(cmd) }}
|
335
337
|
|
336
338
|
unless config.system.cmd_mode
|
337
339
|
@task_manager.run()
|
@@ -344,13 +346,23 @@ module Termtter
|
|
344
346
|
end
|
345
347
|
|
346
348
|
def handle_error(e)
|
347
|
-
|
348
|
-
message = message[0..29] + " ..." if message.size >= 30 && !config.devel
|
349
|
-
logger.error("#{e.class.to_s}: #{message}")
|
349
|
+
logger.error("#{e.class.to_s}: #{e.message}")
|
350
350
|
logger.error(e.backtrace.join("\n")) if (e.backtrace and config.devel)
|
351
351
|
get_hooks(:on_error).each {|hook| hook.call(e) }
|
352
352
|
end
|
353
353
|
|
354
|
+
def rescue_error
|
355
|
+
begin
|
356
|
+
yield
|
357
|
+
rescue Exception => e
|
358
|
+
handle_error(e)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def clear_line
|
363
|
+
print "\e[0G" + "\e[K" unless win?
|
364
|
+
end
|
365
|
+
|
354
366
|
def confirm(message, default_yes = true, &block)
|
355
367
|
pause # TODO: TaskManager から呼ばれるならこれいらないなぁ
|
356
368
|
|
data/lib/termtter/command.rb
CHANGED
@@ -28,7 +28,8 @@ module Termtter
|
|
28
28
|
set cfg
|
29
29
|
end
|
30
30
|
|
31
|
-
#
|
31
|
+
# call-seq:
|
32
|
+
# set :: Hash -> ()
|
32
33
|
def set(cfg)
|
33
34
|
self.name = cfg[:name].to_sym
|
34
35
|
self.aliases = cfg[:aliases]
|
@@ -38,7 +39,8 @@ module Termtter
|
|
38
39
|
self.author = cfg[:author]
|
39
40
|
end
|
40
41
|
|
41
|
-
#
|
42
|
+
# call-seq:
|
43
|
+
# complement :: String -> [String]
|
42
44
|
def complement(input)
|
43
45
|
input = input.sub(/^\s*/, '')
|
44
46
|
if match?(input) && input =~ /^[^\s]+\s/
|
@@ -53,7 +55,8 @@ module Termtter
|
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
56
|
-
# call
|
58
|
+
# call-seq:
|
59
|
+
# call :: ???
|
57
60
|
def call(cmd = nil, arg = nil, original_text = nil)
|
58
61
|
from = Time.now
|
59
62
|
arg = case arg
|
@@ -64,27 +67,30 @@ module Termtter
|
|
64
67
|
else
|
65
68
|
raise ArgumentError, 'arg should be String or nil'
|
66
69
|
end
|
67
|
-
Termtter::Client.logger.debug "command: #{cmd} #{arg}"
|
70
|
+
Termtter::Client.logger.debug { "command: #{cmd} #{arg}" }
|
68
71
|
result = exec_proc.call(arg)
|
69
|
-
Termtter::Client.logger.debug "command: #{cmd} #{arg} #{'%.2fsec' % (Time.now - from)}"
|
72
|
+
Termtter::Client.logger.debug { "command: #{cmd} #{arg} #{'%.2fsec' % (Time.now - from)}" }
|
70
73
|
result
|
71
74
|
rescue => e
|
72
|
-
Termtter::Client.logger.debug "command: #{cmd} #{arg} #{e.message} #{'%.2fsec' % (Time.now - from)}"
|
75
|
+
Termtter::Client.logger.debug { "command: #{cmd} #{arg} #{e.message} #{'%.2fsec' % (Time.now - from)}" }
|
73
76
|
raise e
|
74
77
|
end
|
75
78
|
|
76
|
-
#
|
79
|
+
# call-seq:
|
80
|
+
# match? :: String -> Boolean
|
77
81
|
def match?(input)
|
78
82
|
!!pattern.match(input)
|
79
83
|
end
|
80
84
|
|
81
|
-
#
|
85
|
+
# call-seq:
|
86
|
+
# pattern :: Regexp
|
82
87
|
def pattern
|
83
88
|
commands_regex = commands.map {|name| name.to_s.split(' ').map {|i| Regexp.quote(i)}.join('\s+') }.join('|')
|
84
|
-
/^\s*((#{commands_regex})|(#{commands_regex})
|
89
|
+
/^\s*((#{commands_regex})|(#{commands_regex})(?:\s+|\b)(.*?))\s*$/
|
85
90
|
end
|
86
91
|
|
87
|
-
#
|
92
|
+
# call-seq:
|
93
|
+
# commands :: [Symbol]
|
88
94
|
def commands
|
89
95
|
[name] + aliases
|
90
96
|
end
|
@@ -93,12 +99,14 @@ module Termtter
|
|
93
99
|
@aliases = as.map { |a| a.to_sym }
|
94
100
|
end
|
95
101
|
|
96
|
-
#
|
102
|
+
# call-seq:
|
103
|
+
# alias= :: Symbol -> ()
|
97
104
|
def alias=(a)
|
98
105
|
self.aliases = [a]
|
99
106
|
end
|
100
107
|
|
101
|
-
#
|
108
|
+
# call-seq:
|
109
|
+
# author= :: String -> ()
|
102
110
|
def author=(a)
|
103
111
|
@author = a
|
104
112
|
end
|
@@ -107,7 +115,8 @@ module Termtter
|
|
107
115
|
name.to_s.split(/\s+/)
|
108
116
|
end
|
109
117
|
|
110
|
-
#
|
118
|
+
# call-seq:
|
119
|
+
# split_command_line :: String -> (String, String)
|
111
120
|
def split_command_line(line)
|
112
121
|
m = pattern.match(line)
|
113
122
|
if m
|