termtter 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/plugins/bomb.rb +9 -12
- data/lib/plugins/expand-tinyurl.rb +12 -3
- data/lib/plugins/group.rb +10 -6
- data/lib/plugins/history.rb +21 -10
- data/lib/plugins/log.rb +10 -10
- data/lib/plugins/msagent.rb +23 -11
- data/lib/plugins/notify-send.rb +17 -12
- data/lib/plugins/say.rb +8 -6
- data/lib/plugins/scrape.rb +1 -1
- data/lib/plugins/screen-notify.rb +17 -10
- data/lib/plugins/standard_plugins.rb +29 -17
- data/lib/plugins/stdout.rb +35 -54
- data/lib/plugins/storage.rb +17 -23
- data/lib/plugins/storage/status.rb +23 -20
- data/lib/plugins/update_editor.rb +1 -1
- data/lib/plugins/uri-open.rb +7 -5
- data/lib/plugins/url_addspace.rb +2 -2
- data/lib/termtter/api.rb +2 -1
- data/lib/termtter/client.rb +88 -108
- data/lib/termtter/command.rb +1 -0
- data/lib/termtter/hook.rb +5 -0
- data/lib/termtter/system_extensions.rb +13 -3
- data/lib/termtter/version.rb +1 -1
- data/spec/{plugin → plugins}/cool_spec.rb +0 -0
- data/spec/{plugin → plugins}/english_spec.rb +0 -0
- data/spec/{plugin → plugins}/favorite_spec.rb +0 -0
- data/spec/{plugin → plugins}/fib_spec.rb +0 -0
- data/spec/{plugin → plugins}/filter_spec.rb +0 -0
- data/spec/{plugin → plugins}/pause_spec.rb +0 -0
- data/spec/{plugin → plugins}/plugin_spec.rb +0 -0
- data/spec/{plugin → plugins}/primes_spec.rb +0 -0
- data/spec/{plugin → plugins}/shell_spec.rb +0 -0
- data/spec/{plugin → plugins}/sl_spec.rb +0 -0
- data/spec/{plugin → plugins}/spam_spec.rb +0 -0
- data/spec/{plugin → plugins}/standard_plugins_spec.rb +0 -0
- data/spec/{plugin → plugins}/storage/DB_spec.rb +0 -0
- data/spec/{plugin → plugins}/storage/status_spec.rb +1 -1
- data/spec/termtter/client_spec.rb +1 -4
- metadata +17 -17
data/lib/plugins/stdout.rb
CHANGED
@@ -11,68 +11,49 @@ config.plugins.stdout.set_default(
|
|
11
11
|
'<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>> <90><%=id%></90>')
|
12
12
|
config.plugins.stdout.set_default(:search_highlihgt_format, '<on_magenta><white>\1</white></on_magenta>')
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
def
|
17
|
-
|
18
|
-
case value
|
19
|
-
when String, Symbol
|
20
|
-
$highline.color(str, value)
|
21
|
-
else
|
22
|
-
"\e[#{value}m#{str}\e[0m"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module Termtter::Client
|
27
|
-
|
28
|
-
def self.print_statuses(statuses, sort = true, time_format = '%H:%M:%S')
|
29
|
-
(sort ? statuses.sort_by{ |s| s.id} : statuses).each do |s|
|
30
|
-
text = s.text
|
31
|
-
status_color = config.plugins.stdout.colors[s.user.screen_name.hash % config.plugins.stdout.colors.size]
|
32
|
-
status = "#{s.user.screen_name}: #{text}"
|
33
|
-
if s.in_reply_to_status_id
|
34
|
-
status += " (repl. to #{s.in_reply_to_status_id})"
|
35
|
-
end
|
36
|
-
|
37
|
-
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
38
|
-
id = s.id
|
39
|
-
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
40
|
-
puts TermColor.parse(erbed_text)
|
14
|
+
module Termtter
|
15
|
+
class StdOut < Hook
|
16
|
+
def initialize
|
17
|
+
super(:name => :stdout, :points => [:output])
|
41
18
|
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.print_statuses_with_date(statuses, sort = true)
|
45
|
-
print_statuses(statuses, sort, '%m-%d %H:%M')
|
46
|
-
end
|
47
19
|
|
48
|
-
|
49
|
-
|
50
|
-
text = r.text.
|
51
|
-
gsub(/(\n|\r)/, '').
|
52
|
-
gsub(/(#{Regexp.escape(result.query)})/i, config.plugins.stdout.search_highlihgt_format)
|
53
|
-
status_color = config.plugins.stdout.colors[r.from_user_id.to_i.hash % config.plugins.stdout.colors.size]
|
54
|
-
status = "#{r.from_user}: #{text}"
|
55
|
-
time = "(#{Time.parse(r.created_at).strftime(time_format)})"
|
56
|
-
id = r.id
|
57
|
-
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
58
|
-
puts TermColor.parse(erbed_text)
|
20
|
+
def execute(statuses, event)
|
21
|
+
print_statuses(statuses)
|
59
22
|
end
|
60
|
-
end
|
61
23
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
24
|
+
def print_statuses(statuses, sort = true, time_format = nil)
|
25
|
+
return unless statuses
|
26
|
+
unless time_format
|
27
|
+
# 最初と最後の日付がちがうとき日付も出す
|
28
|
+
t1 = Time.parse(statuses.first[:created_at])
|
29
|
+
t2 = Time.parse(statuses.last[:created_at])
|
30
|
+
time_format =
|
31
|
+
if [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
32
|
+
'%H:%M:%S'
|
33
|
+
else
|
34
|
+
'%y/%m/%d %H:%M'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
statuses.each do |s|
|
39
|
+
text = s.text
|
40
|
+
status_color = config.plugins.stdout.colors[s.user.id.hash % config.plugins.stdout.colors.size]
|
41
|
+
status = "#{s.user.screen_name}: #{text}"
|
42
|
+
if s.in_reply_to_status_id
|
43
|
+
status += " (repl. to #{s.in_reply_to_status_id})"
|
44
|
+
end
|
45
|
+
|
46
|
+
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
47
|
+
id = s.id
|
48
|
+
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
49
|
+
puts TermColor.parse(erbed_text)
|
50
|
+
end
|
72
51
|
end
|
73
52
|
end
|
74
53
|
|
54
|
+
Client.register_hook(StdOut.new)
|
75
55
|
end
|
56
|
+
|
76
57
|
# stdout.rb
|
77
58
|
# output statuses to stdout
|
78
59
|
# example config
|
data/lib/plugins/storage.rb
CHANGED
@@ -8,40 +8,34 @@ require File.dirname(__FILE__) + '/storage/status'
|
|
8
8
|
module Termtter::Client
|
9
9
|
public_storage[:log] = []
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
register_hook(
|
12
|
+
:name => :storage,
|
13
|
+
:points => [:pre_filter],
|
14
|
+
:exec_proc => lambda {|statuses, event|
|
14
15
|
statuses.each do |s|
|
15
16
|
Termtter::Storage::Status.insert(
|
16
17
|
:post_id => s.id,
|
17
18
|
:created_at => Time.parse(s.created_at).to_i,
|
18
19
|
:in_reply_to_status_id => s.in_reply_to_status_id,
|
19
20
|
:in_reply_to_user_id => s.in_reply_to_user_id,
|
20
|
-
:
|
21
|
+
:post => s.text,
|
21
22
|
:user_id => s.user.id,
|
22
|
-
:screen_name => s.user.screen_name
|
23
|
+
:screen_name => s.user.screen_name
|
24
|
+
)
|
23
25
|
end
|
24
|
-
|
25
|
-
|
26
|
+
}
|
27
|
+
)
|
26
28
|
|
27
29
|
register_command(
|
28
|
-
:name => :search_storage,
|
30
|
+
:name => :search_storage,
|
31
|
+
:aliases => [:ss],
|
29
32
|
:exec_proc => lambda {|arg|
|
30
33
|
unless arg.strip.empty?
|
31
34
|
key = arg.strip
|
32
|
-
Termtter::Storage::Status.search({
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
call_hooks(statuses, :search)
|
40
|
-
=end
|
41
|
-
end
|
42
|
-
|
43
|
-
},
|
44
|
-
|
45
|
-
:help => [ 'search_storage WORD', 'Search storage for WORD' ]
|
46
|
-
)
|
35
|
+
statuses = Termtter::Storage::Status.search({:text => key})
|
36
|
+
output(statuses, :search)
|
37
|
+
end
|
38
|
+
},
|
39
|
+
:help => [ 'search_storage WORD', 'Search storage for WORD' ]
|
40
|
+
)
|
47
41
|
end
|
@@ -7,42 +7,45 @@ module Termtter::Storage
|
|
7
7
|
class Status
|
8
8
|
KEYS = %w[post_id created_at in_reply_to_status_id in_reply_to_user_id post_text user_id screen_name]
|
9
9
|
|
10
|
-
def size
|
10
|
+
def self.size
|
11
11
|
DB.instance.db.get_first_value("select count(*) from post").to_i
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.search(query)
|
15
15
|
raise "query must be Hash(#{query}, #{query.class})" unless query.kind_of? Hash
|
16
|
-
|
17
|
-
DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%' ",
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
result = []
|
17
|
+
DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%' ",
|
18
|
+
query[:text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id|
|
19
|
+
created_at = Time.at(created_at).to_s
|
20
|
+
result << {
|
21
|
+
:id => post_id,
|
22
|
+
:created_at => created_at,
|
23
|
+
:text => post_text,
|
24
|
+
:in_reply_to_status_id => in_reply_to_status_id,
|
25
|
+
:in_reply_to_user_id => nil,
|
26
|
+
:user => {
|
27
|
+
:id => user_id,
|
28
|
+
:screen_name => screen_name
|
29
|
+
}
|
30
|
+
}
|
21
31
|
end
|
32
|
+
Rubytter.json_to_struct(result)
|
22
33
|
end
|
23
34
|
|
24
35
|
def self.insert(data)
|
25
|
-
raise "data must be Hash(#{data}, #{data.class})" unless data.kind_of? Hash
|
26
|
-
# 条件しぼりたいけどやりかたがうまくわからない
|
27
|
-
# raise "unko" unless data.keys.all?{|c| KEYS.include? c}
|
28
|
-
begin
|
29
36
|
DB.instance.db.execute(
|
30
37
|
"insert into post values(?,?,?,?,?,?)",
|
31
38
|
data[:post_id],
|
32
39
|
data[:created_at],
|
33
40
|
data[:in_reply_to_status_id],
|
34
41
|
data[:in_reply_to_user_id],
|
35
|
-
data[:
|
42
|
+
data[:text],
|
36
43
|
data[:user_id])
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
rescue # FIXME: specify exceptions here
|
43
|
-
end
|
44
|
-
rescue # FIXME: specify exceptions here
|
45
|
-
end
|
44
|
+
DB.instance.db.execute(
|
45
|
+
"insert into user values(?,?)",
|
46
|
+
data[:user_id],
|
47
|
+
data[:screen_name])
|
48
|
+
rescue SQLite3::SQLException
|
46
49
|
end
|
47
50
|
end
|
48
51
|
end
|
@@ -8,7 +8,7 @@ module Termtter::Client
|
|
8
8
|
else
|
9
9
|
config.plugins.update_editor.set_default('editor', 'vi')
|
10
10
|
end
|
11
|
-
config.plugins.update_editor.set_default('add_completion',
|
11
|
+
config.plugins.update_editor.set_default('add_completion', true)
|
12
12
|
|
13
13
|
|
14
14
|
def self.input_editor
|
data/lib/plugins/uri-open.rb
CHANGED
@@ -3,13 +3,15 @@
|
|
3
3
|
module Termtter::Client
|
4
4
|
public_storage[:uris] = []
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
register_hook(
|
7
|
+
:name => :uri_open,
|
8
|
+
:points => [:post_filter],
|
9
|
+
:exec_proc => lambda {|statuses, event|
|
8
10
|
statuses.each do |s|
|
9
|
-
public_storage[:uris] += s.
|
11
|
+
public_storage[:uris] += s[:post_text].scan(%r|https?://[^\s]+|)
|
10
12
|
end
|
11
|
-
|
12
|
-
|
13
|
+
}
|
14
|
+
)
|
13
15
|
|
14
16
|
def self.open_uri(uri)
|
15
17
|
unless config.plugins.uri_open.browser.empty?
|
data/lib/plugins/url_addspace.rb
CHANGED
data/lib/termtter/api.rb
CHANGED
@@ -19,12 +19,13 @@ module Termtter
|
|
19
19
|
config.user_name,
|
20
20
|
config.password,
|
21
21
|
{
|
22
|
+
:app_name => Termtter::APP_NAME,
|
22
23
|
:host => config.host,
|
23
24
|
:header => {
|
24
25
|
'User-Agent' => 'Termtter http://github.com/jugyo/termtter',
|
25
26
|
'X-Twitter-Client' => 'Termtter',
|
26
27
|
'X-Twitter-Client-URL' => 'http://github.com/jugyo/termtter',
|
27
|
-
'X-Twitter-Client-Version' =>
|
28
|
+
'X-Twitter-Client-Version' => Termtter::VERSION
|
28
29
|
},
|
29
30
|
:enable_ssl => config.enable_ssl,
|
30
31
|
:proxy_host => config.proxy.host,
|
data/lib/termtter/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'fileutils'
|
3
|
+
require 'logger'
|
3
4
|
|
4
5
|
module Termtter
|
5
6
|
APP_NAME = 'termtter'
|
@@ -18,15 +19,14 @@ module Termtter
|
|
18
19
|
class << self
|
19
20
|
|
20
21
|
def init
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@@task_manager = Termtter::TaskManager.new
|
22
|
+
@hooks = {}
|
23
|
+
@commands = {}
|
24
|
+
@filters = []
|
25
|
+
@since_id = nil
|
26
|
+
@input_thread = nil
|
27
|
+
@task_manager = Termtter::TaskManager.new
|
28
|
+
config.log.set_default(:logger, nil)
|
29
|
+
config.log.set_default(:level, nil)
|
30
30
|
config.set_default(:update_interval, 300)
|
31
31
|
config.set_default(:prompt, '> ')
|
32
32
|
config.set_default(:devel, false)
|
@@ -34,15 +34,15 @@ module Termtter
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def public_storage
|
37
|
-
|
37
|
+
@public_storage ||= {}
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
def add_filter(&b)
|
41
|
+
filters << b
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear_filter
|
45
|
+
filters.clear
|
46
46
|
end
|
47
47
|
|
48
48
|
def register_hook(arg)
|
@@ -54,15 +54,15 @@ module Termtter
|
|
54
54
|
else
|
55
55
|
raise ArgumentError, 'must be given Termtter::Hook or Hash'
|
56
56
|
end
|
57
|
-
|
57
|
+
@hooks[hook.name] = hook
|
58
58
|
end
|
59
59
|
|
60
60
|
def get_hook(name)
|
61
|
-
|
61
|
+
@hooks[name]
|
62
62
|
end
|
63
63
|
|
64
64
|
def get_hooks(point)
|
65
|
-
|
65
|
+
@hooks.values.select do |hook|
|
66
66
|
hook.match?(point)
|
67
67
|
end
|
68
68
|
end
|
@@ -76,11 +76,11 @@ module Termtter
|
|
76
76
|
else
|
77
77
|
raise ArgumentError, 'must be given Termtter::Command or Hash'
|
78
78
|
end
|
79
|
-
|
79
|
+
@commands[command.name] = command
|
80
80
|
end
|
81
81
|
|
82
82
|
def get_command(name)
|
83
|
-
|
83
|
+
@commands[name]
|
84
84
|
end
|
85
85
|
|
86
86
|
def register_macro(name, macro, options = {})
|
@@ -91,58 +91,44 @@ module Termtter
|
|
91
91
|
register_command(command)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
94
|
+
# statuses => [status, status, ...]
|
95
|
+
# status => {
|
96
|
+
# :id => status id,
|
97
|
+
# :created_at => created time,
|
98
|
+
# :user_id => user id,
|
99
|
+
# :name => user name,
|
100
|
+
# :screen_name => user screen_name,
|
101
|
+
# :source => source,
|
102
|
+
# :reply_to => reply_to status id,
|
103
|
+
# :text => status,
|
104
|
+
# :original_data => original data,
|
105
|
+
# }
|
106
|
+
def output(statuses, event)
|
107
|
+
return if statuses.nil? || statuses.empty?
|
108
|
+
|
109
|
+
statuses = statuses.sort_by{|s|s.id}
|
110
|
+
call_hooks(:pre_filter, statuses, event)
|
111
|
+
filtered = apply_filters(statuses, event)
|
112
|
+
call_hooks(:post_filter, filtered, event)
|
113
|
+
call_hooks(:output, filtered, event)
|
104
114
|
end
|
105
115
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
when :show
|
110
|
-
result
|
111
|
-
when :search
|
112
|
-
filtered = result.results.map(&:dup)
|
113
|
-
@@filters.each do |f|
|
114
|
-
filtered = f.call(filtered, event)
|
115
|
-
end
|
116
|
-
result.results = filtered
|
117
|
-
result
|
118
|
-
else
|
119
|
-
filtered = result.map(&:dup)
|
120
|
-
@@filters.each do |f|
|
116
|
+
def apply_filters(statuses, event)
|
117
|
+
filtered = statuses.map(&:dup)
|
118
|
+
@filters.each do |f|
|
121
119
|
filtered = f.call(filtered, event)
|
122
120
|
end
|
123
121
|
filtered
|
124
|
-
|
125
|
-
|
126
|
-
handle_error(e)
|
127
|
-
result
|
128
|
-
end
|
129
|
-
|
130
|
-
def do_hooks(statuses, event)
|
131
|
-
@@hooks.each do |h|
|
132
|
-
begin
|
133
|
-
h.call(statuses.dup, event, Termtter::API.twitter)
|
134
|
-
rescue => e
|
135
|
-
handle_error(e)
|
136
|
-
end
|
137
|
-
end
|
122
|
+
rescue => e
|
123
|
+
handle_error(e)
|
138
124
|
end
|
139
125
|
|
140
126
|
# return last hook return value
|
141
|
-
def
|
127
|
+
def call_hooks(point, *args)
|
142
128
|
result = nil
|
143
129
|
get_hooks(point).each {|hook|
|
144
130
|
break if result == false # interrupt if hook return false
|
145
|
-
result = hook.
|
131
|
+
result = hook.execute(*args)
|
146
132
|
}
|
147
133
|
result
|
148
134
|
rescue => e
|
@@ -153,36 +139,29 @@ module Termtter
|
|
153
139
|
end
|
154
140
|
end
|
155
141
|
|
156
|
-
# TODO: delete argument "tw" when unnecessary
|
157
|
-
def call_hooks(statuses, event, tw = nil)
|
158
|
-
do_hooks(statuses, :pre_filter)
|
159
|
-
filtered = apply_filters(statuses, event)
|
160
|
-
do_hooks(filtered, :post_filter)
|
161
|
-
do_hooks(filtered, event)
|
162
|
-
end
|
163
|
-
|
164
142
|
def call_commands(text, tw = nil)
|
165
143
|
return if text.empty?
|
166
144
|
|
167
145
|
command_found = false
|
168
|
-
|
146
|
+
@commands.each do |key, command|
|
147
|
+
# match? メソッドがなんかきもちわるいので変える予定
|
169
148
|
command_str, command_arg = command.match?(text)
|
170
149
|
if command_str
|
171
150
|
command_found = true
|
172
151
|
|
173
|
-
modified_arg =
|
152
|
+
modified_arg = call_hooks(
|
174
153
|
"modify_arg_for_#{command.name.to_s}",
|
175
154
|
command_str,
|
176
155
|
command_arg) || command_arg || ''
|
177
156
|
|
178
|
-
|
157
|
+
@task_manager.invoke_and_wait do
|
179
158
|
|
180
|
-
pre_exec_hook_result =
|
159
|
+
pre_exec_hook_result = call_hooks("pre_exec_#{command.name.to_s}", command_str, modified_arg)
|
181
160
|
next if pre_exec_hook_result == false
|
182
161
|
# exec command
|
183
162
|
result = command.execute(modified_arg)
|
184
163
|
if result
|
185
|
-
|
164
|
+
call_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
|
186
165
|
end
|
187
166
|
|
188
167
|
end
|
@@ -193,24 +172,23 @@ module Termtter
|
|
193
172
|
end
|
194
173
|
|
195
174
|
def pause
|
196
|
-
|
175
|
+
@task_manager.pause
|
197
176
|
end
|
198
177
|
|
199
178
|
def resume
|
200
|
-
|
179
|
+
@task_manager.resume
|
201
180
|
end
|
202
181
|
|
203
182
|
def add_task(*arg, &block)
|
204
|
-
|
183
|
+
@task_manager.add_task(*arg, &block)
|
205
184
|
end
|
206
185
|
|
207
186
|
def exit
|
208
187
|
puts 'finalizing...'
|
209
188
|
|
210
|
-
call_hooks(
|
211
|
-
|
212
|
-
|
213
|
-
@@input_thread.kill if @@input_thread
|
189
|
+
call_hooks(:exit)
|
190
|
+
@task_manager.kill
|
191
|
+
@input_thread.kill if @input_thread
|
214
192
|
end
|
215
193
|
|
216
194
|
def load_default_plugins
|
@@ -246,7 +224,7 @@ module Termtter
|
|
246
224
|
Termtter::CONF_FILE)
|
247
225
|
end
|
248
226
|
|
249
|
-
def
|
227
|
+
def post_config_load()
|
250
228
|
if config.system.devel
|
251
229
|
plugin 'devel'
|
252
230
|
end
|
@@ -258,14 +236,7 @@ module Termtter
|
|
258
236
|
end
|
259
237
|
Readline.completion_proc = lambda {|input|
|
260
238
|
begin
|
261
|
-
|
262
|
-
completions = @@completions.map {|completion|
|
263
|
-
completion.call(input)
|
264
|
-
}
|
265
|
-
completions += @@new_commands.map {|name, command|
|
266
|
-
command.complement(input)
|
267
|
-
}
|
268
|
-
completions.flatten.compact
|
239
|
+
@commands.map {|name, command| command.complement(input) }.flatten.compact
|
269
240
|
rescue => e
|
270
241
|
handle_error(e)
|
271
242
|
end
|
@@ -276,19 +247,20 @@ module Termtter
|
|
276
247
|
end
|
277
248
|
end
|
278
249
|
|
250
|
+
# TODO: Make pluggable
|
279
251
|
def setup_update_timeline_task()
|
280
252
|
register_command(
|
281
253
|
:name => :_update_timeline,
|
282
254
|
:exec_proc => lambda {|arg|
|
283
255
|
begin
|
284
|
-
args =
|
256
|
+
args = @since_id ? [{:since_id => @since_id}] : []
|
285
257
|
statuses = Termtter::API.twitter.friends_timeline(*args)
|
286
258
|
unless statuses.empty?
|
287
|
-
|
259
|
+
print "\e[1K\e[0G" unless win?
|
260
|
+
@since_id = statuses[0].id
|
261
|
+
output(statuses, :update_friends_timeline)
|
262
|
+
Readline.refresh_line
|
288
263
|
end
|
289
|
-
call_hooks(statuses, :update_friends_timeline)
|
290
|
-
Readline.refresh_line
|
291
|
-
statuses
|
292
264
|
rescue OpenURI::HTTPError => e
|
293
265
|
if e.message == '401 Unauthorized'
|
294
266
|
puts 'Could not login'
|
@@ -299,9 +271,11 @@ module Termtter
|
|
299
271
|
}
|
300
272
|
)
|
301
273
|
|
302
|
-
add_task(:name => :update_timeline, :interval => config.update_interval) do
|
274
|
+
add_task(:name => :update_timeline, :interval => config.update_interval, :after => config.update_interval) do
|
303
275
|
call_commands('_update_timeline')
|
304
276
|
end
|
277
|
+
|
278
|
+
call_commands('_update_timeline')
|
305
279
|
end
|
306
280
|
|
307
281
|
def trap_setting()
|
@@ -321,9 +295,9 @@ module Termtter
|
|
321
295
|
def start_input_thread
|
322
296
|
setup_readline()
|
323
297
|
trap_setting()
|
324
|
-
|
298
|
+
@input_thread = Thread.new do
|
325
299
|
while buf = Readline.readline(ERB.new(config.prompt).result(API.twitter.__send__(:binding)), true)
|
326
|
-
Readline::HISTORY.pop if
|
300
|
+
Readline::HISTORY.pop if buf.empty?
|
327
301
|
begin
|
328
302
|
call_commands(buf)
|
329
303
|
rescue CommandNotFound => e
|
@@ -334,29 +308,35 @@ module Termtter
|
|
334
308
|
end
|
335
309
|
end
|
336
310
|
end
|
337
|
-
|
311
|
+
@input_thread.join
|
338
312
|
end
|
339
313
|
|
340
|
-
def
|
341
|
-
|
314
|
+
def logger
|
315
|
+
@logger
|
316
|
+
end
|
342
317
|
|
318
|
+
def setup_logger
|
319
|
+
@logger = config.log.logger || Logger.new(STDOUT)
|
320
|
+
@logger.level = config.log.level || Logger::WARN
|
321
|
+
end
|
322
|
+
|
323
|
+
def run
|
343
324
|
load_default_plugins()
|
344
325
|
load_config()
|
345
326
|
Termtter::API.setup()
|
346
|
-
|
327
|
+
setup_logger()
|
328
|
+
post_config_load()
|
347
329
|
|
348
|
-
call_hooks(
|
349
|
-
call_new_hooks(:initialize)
|
330
|
+
call_hooks(:initialize)
|
350
331
|
|
351
332
|
setup_update_timeline_task()
|
352
|
-
call_commands('_update_timeline')
|
353
333
|
|
354
|
-
|
334
|
+
@task_manager.run()
|
355
335
|
start_input_thread()
|
356
336
|
end
|
357
337
|
|
358
338
|
def handle_error(e)
|
359
|
-
|
339
|
+
call_hooks("on_error", e)
|
360
340
|
rescue => e
|
361
341
|
puts "Error: #{e}"
|
362
342
|
puts e.backtrace.join("\n")
|