termtter 1.0.3 → 1.0.4
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/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")
|