termtter 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +24 -0
- data/lib/plugins/db.rb +7 -1
- data/lib/plugins/defaults/auto_reload.rb +12 -2
- data/lib/plugins/defaults/retweet.rb +5 -0
- data/lib/plugins/defaults/standard_commands.rb +35 -3
- data/lib/plugins/defaults/standard_completion.rb +3 -3
- data/lib/plugins/defaults/stdout.rb +2 -1
- data/lib/plugins/hugeurl.rb +38 -0
- data/lib/termtter/client.rb +20 -1
- data/lib/termtter/version.rb +1 -1
- data/spec/termtter/client_spec.rb +7 -0
- metadata +3 -2
data/ChangeLog
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
== 1.3.1 2009-08-10
|
|
2
|
+
|
|
3
|
+
Takaaki SONE:
|
|
4
|
+
Fixed help message for Exit
|
|
5
|
+
added protected column to users table.
|
|
6
|
+
|
|
7
|
+
Tomohiro Nishimura:
|
|
8
|
+
add new command around the alias
|
|
9
|
+
more powerful list command available!
|
|
10
|
+
add alias method to Client module
|
|
11
|
+
|
|
12
|
+
emasaka:
|
|
13
|
+
Added protected sign to default timeline_format.
|
|
14
|
+
Added hugeurl plugin: alternative of expand-tinyurl
|
|
15
|
+
|
|
16
|
+
jugyo:
|
|
17
|
+
Fixed for termtter shutdown when raise network error.
|
|
18
|
+
Added a method 'command_exists?'
|
|
19
|
+
Changed to apply TermColor.unescape for status.text
|
|
20
|
+
Changed retweet command to add confirmation for protected user.
|
|
21
|
+
|
|
22
|
+
ujihisa:
|
|
23
|
+
Ignore case for completion of user's screen name
|
|
24
|
+
|
|
1
25
|
== 1.3.0 2009-07-27
|
|
2
26
|
|
|
3
27
|
Koichiro Ohba (3):
|
data/lib/plugins/db.rb
CHANGED
|
@@ -21,6 +21,7 @@ unless DB.table_exists?(:users)
|
|
|
21
21
|
DB.create_table :users do
|
|
22
22
|
primary_key :id
|
|
23
23
|
String :screen_name
|
|
24
|
+
boolean :protected
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -56,7 +57,12 @@ module Termtter
|
|
|
56
57
|
if User.filter(:id => s.user.id).empty?
|
|
57
58
|
user = {}
|
|
58
59
|
User.columns.each do |col|
|
|
59
|
-
user[col] =
|
|
60
|
+
user[col] =
|
|
61
|
+
if event == :search && col == :protected
|
|
62
|
+
false
|
|
63
|
+
else
|
|
64
|
+
s.user[col]
|
|
65
|
+
end
|
|
60
66
|
end
|
|
61
67
|
User << user
|
|
62
68
|
end
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
module Termtter::Client
|
|
3
3
|
add_task(:name => :auto_reload, :interval => config.update_interval, :after => config.update_interval) do
|
|
4
|
-
|
|
4
|
+
begin
|
|
5
|
+
call_commands('reload')
|
|
6
|
+
rescue Exception => e
|
|
7
|
+
handle_error(e)
|
|
8
|
+
end
|
|
5
9
|
end
|
|
6
10
|
|
|
7
11
|
register_hook(
|
|
8
12
|
:name => :auto_reload_init,
|
|
9
13
|
:point => :initialize,
|
|
10
|
-
:exec => lambda {
|
|
14
|
+
:exec => lambda {
|
|
15
|
+
begin
|
|
16
|
+
call_commands('reload')
|
|
17
|
+
rescue Exception => e
|
|
18
|
+
handle_error(e)
|
|
19
|
+
end
|
|
20
|
+
}
|
|
11
21
|
)
|
|
12
22
|
end
|
|
@@ -4,6 +4,11 @@ config.plugins.retweet.set_default(:format, '<%= comment %>RT @<%=s.user.screen_
|
|
|
4
4
|
|
|
5
5
|
module Termtter::Client
|
|
6
6
|
def self.post_retweet(s, comment = nil)
|
|
7
|
+
if s.user.protected &&
|
|
8
|
+
!confirm("#{s.user.screen_name} is protected! Are you sure?", false)
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
comment += ' ' unless comment.nil?
|
|
8
13
|
text = ERB.new(config.plugins.retweet.format).result(binding)
|
|
9
14
|
Termtter::API.twitter.update(text)
|
|
@@ -143,8 +143,11 @@ module Termtter::Client
|
|
|
143
143
|
statuses = Termtter::API.twitter.friends_timeline
|
|
144
144
|
else
|
|
145
145
|
event = :list_user_timeline
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
statuses = []
|
|
147
|
+
Array(arg.split).each do |user|
|
|
148
|
+
user_name = normalize_as_user_name(user)
|
|
149
|
+
statuses += Termtter::API.twitter.user_timeline(user_name)
|
|
150
|
+
end
|
|
148
151
|
end
|
|
149
152
|
output(statuses, event)
|
|
150
153
|
},
|
|
@@ -327,7 +330,7 @@ module Termtter::Client
|
|
|
327
330
|
register_command(
|
|
328
331
|
:name => :exit, :aliases => [:quit],
|
|
329
332
|
:exec_proc => lambda {|arg| exit},
|
|
330
|
-
:help => ['exit,
|
|
333
|
+
:help => ['exit,quit', 'Exit']
|
|
331
334
|
)
|
|
332
335
|
|
|
333
336
|
register_command(
|
|
@@ -472,6 +475,35 @@ module Termtter::Client
|
|
|
472
475
|
:help => ["redo,.", "Execute previous command"]
|
|
473
476
|
)
|
|
474
477
|
|
|
478
|
+
register_command(:alias,
|
|
479
|
+
:help => ['alias NAME VALUE', 'Add alias for any operations']) do |text|
|
|
480
|
+
from, to = text.split(' ', 2)
|
|
481
|
+
next unless to
|
|
482
|
+
begin
|
|
483
|
+
add_alias from, to
|
|
484
|
+
rescue
|
|
485
|
+
STDOUT.print 'override? [y/n] '
|
|
486
|
+
STDOUT.flush
|
|
487
|
+
next unless /y/ =~ STDIN.gets.chomp
|
|
488
|
+
add_alias from, to, false
|
|
489
|
+
end
|
|
490
|
+
puts "#{from} => #{to}"
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
register_command(:remove_alias,
|
|
494
|
+
:help => ['remove_alias NAME', 'Remove alias completely']) do |target|
|
|
495
|
+
remove_alias target
|
|
496
|
+
STDOUT.puts 'done'
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
register_hook :aliases, :point => :pre_command do |text|
|
|
500
|
+
command, args = text.split(' ', 2)
|
|
501
|
+
if original = @aliases[command]
|
|
502
|
+
text = [original, args].compact.join(' ')
|
|
503
|
+
end
|
|
504
|
+
text
|
|
505
|
+
end
|
|
506
|
+
|
|
475
507
|
def self.update_with_user_and_id(text, username, id)
|
|
476
508
|
text = "@#{username} #{text}"
|
|
477
509
|
result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id})
|
|
@@ -27,7 +27,7 @@ module Termtter::Client
|
|
|
27
27
|
register_hook(:collect_user_names, :point => :pre_filter) do |statuses, event|
|
|
28
28
|
statuses.each do |s|
|
|
29
29
|
public_storage[:users].add(s.user.screen_name)
|
|
30
|
-
public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
|
|
30
|
+
public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/i).flatten
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -40,7 +40,7 @@ module Termtter::Client
|
|
|
40
40
|
if part_of_user_name.nil? || part_of_user_name.empty?
|
|
41
41
|
public_storage[:users].to_a
|
|
42
42
|
else
|
|
43
|
-
public_storage[:users].grep(/^#{Regexp.quote(part_of_user_name)}/)
|
|
43
|
+
public_storage[:users].grep(/^#{Regexp.quote(part_of_user_name)}/i)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
users.map {|u| "#{command_str}@%s" % u }
|
|
@@ -54,7 +54,7 @@ module Termtter::Client
|
|
|
54
54
|
public_storage[:hashtag] ||= Set.new
|
|
55
55
|
|
|
56
56
|
register_hook(:collect_hashtags, :point => /^post_exec_/) do |cmd, arg, result|
|
|
57
|
-
public_storage[:hashtag] += arg.scan(/\s+#([^\s]+)/).flatten if arg
|
|
57
|
+
public_storage[:hashtag] += arg.scan(/\s+#([^\s]+)/i).flatten if arg
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
register_hook(:hashtags_completion, :point => :completion) do |input|
|
|
@@ -8,7 +8,7 @@ config.plugins.stdout.set_default(:colors, (31..36).to_a + (91..96).to_a)
|
|
|
8
8
|
config.plugins.stdout.set_default(
|
|
9
9
|
:timeline_format,
|
|
10
10
|
'<90><%=time%> [<%=status_id%>]</90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
|
|
11
|
-
'<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%></90>'
|
|
11
|
+
'<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%><%=s.user.protected ? "[P]" : ""%></90>'
|
|
12
12
|
)
|
|
13
13
|
config.plugins.stdout.set_default(:enable_pager, true)
|
|
14
14
|
config.plugins.stdout.set_default(:pager, 'less -R -f +G')
|
|
@@ -115,6 +115,7 @@ module Termtter
|
|
|
115
115
|
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
|
116
116
|
indent_text = indent > 0 ? "#{' ' * (indent - 1)} ┗ " : ''
|
|
117
117
|
text = TermColor.parse(indent_text + erbed_text) + "\n"
|
|
118
|
+
text = TermColor.unescape(text)
|
|
118
119
|
if config.plugins.stdout.show_as_thread && s.in_reply_to_status_id
|
|
119
120
|
text << status_line(Status[s.in_reply_to_status_id], time_format, indent + 1)
|
|
120
121
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
HUGEURL_TARGET_PATTERN = %r{
|
|
4
|
+
http://tinyurl\.com/[\w/]+
|
|
5
|
+
| http://is\.gd/[\w/]+
|
|
6
|
+
| http://bit\.ly/[\w/]+
|
|
7
|
+
| http://ff\.im/[-\w/]+
|
|
8
|
+
| http://tr\.im/[\w/]+
|
|
9
|
+
}x
|
|
10
|
+
|
|
11
|
+
config.plugins.hugeurl.set_default(:skip_users, [])
|
|
12
|
+
|
|
13
|
+
Termtter::Client::register_hook(
|
|
14
|
+
:name => :hugeurl,
|
|
15
|
+
:point => :filter_for_output,
|
|
16
|
+
:exec_proc => lambda do |statuses, event|
|
|
17
|
+
http_class = Net::HTTP
|
|
18
|
+
unless config.proxy.host.nil? or config.proxy.host.empty?
|
|
19
|
+
http_class = Net::HTTP::Proxy(config.proxy.host,
|
|
20
|
+
config.proxy.port,
|
|
21
|
+
config.proxy.user_name,
|
|
22
|
+
config.proxy.password)
|
|
23
|
+
end
|
|
24
|
+
http_class.start('search.twitter.com') do |http|
|
|
25
|
+
statuses.each do |s|
|
|
26
|
+
config.plugins.hugeurl.skip_users.include?(s.user.screen_name) and next
|
|
27
|
+
s.text.gsub!(HUGEURL_TARGET_PATTERN) do |m|
|
|
28
|
+
res = http.get('/hugeurl?url=' + m)
|
|
29
|
+
res.code == '200' ? res.body : m
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
statuses
|
|
34
|
+
end
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# hugeurl.rb:
|
|
38
|
+
# expands bit.ly, tiniurl, etc. by search.twitter.com API
|
data/lib/termtter/client.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Termtter
|
|
|
13
13
|
@hooks = {}
|
|
14
14
|
@commands = {}
|
|
15
15
|
@filters = []
|
|
16
|
+
@aliases = {}
|
|
16
17
|
@since_id = nil
|
|
17
18
|
@task_manager = Termtter::TaskManager.new
|
|
18
19
|
|
|
@@ -41,6 +42,10 @@ module Termtter
|
|
|
41
42
|
Termtter::Client.handle_error(e)
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
def alias(name, value)
|
|
46
|
+
@aliases[name] = value
|
|
47
|
+
end
|
|
48
|
+
|
|
44
49
|
def public_storage
|
|
45
50
|
@public_storage ||= {}
|
|
46
51
|
end
|
|
@@ -125,6 +130,17 @@ module Termtter
|
|
|
125
130
|
register_command(command)
|
|
126
131
|
end
|
|
127
132
|
|
|
133
|
+
def add_alias(from, to, confirm = true)
|
|
134
|
+
if confirm
|
|
135
|
+
raise 'Already exist' if @aliases[from]
|
|
136
|
+
end
|
|
137
|
+
@aliases[from] = to
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def remove_alias(target)
|
|
141
|
+
@aliases.delete target
|
|
142
|
+
end
|
|
143
|
+
|
|
128
144
|
# statuses => [status, status, ...]
|
|
129
145
|
# status => {
|
|
130
146
|
# :id => status id,
|
|
@@ -176,7 +192,6 @@ module Termtter
|
|
|
176
192
|
|
|
177
193
|
def call_commands(text)
|
|
178
194
|
@task_manager.invoke_and_wait do
|
|
179
|
-
call_hooks("pre_command", text)
|
|
180
195
|
# FIXME: This block can become Maybe Monad
|
|
181
196
|
get_hooks("pre_command").each {|hook|
|
|
182
197
|
break if text == nil # interrupt if hook returns nil
|
|
@@ -208,6 +223,10 @@ module Termtter
|
|
|
208
223
|
end
|
|
209
224
|
end
|
|
210
225
|
|
|
226
|
+
def command_exists?(text)
|
|
227
|
+
@commands.values.any? {|command| command.match?(text) }
|
|
228
|
+
end
|
|
229
|
+
|
|
211
230
|
def find_commands(text)
|
|
212
231
|
@commands.values.select {|command| command.match?(text) }
|
|
213
232
|
end
|
data/lib/termtter/version.rb
CHANGED
|
@@ -368,6 +368,13 @@ module Termtter
|
|
|
368
368
|
Client.find_commands('bar').size.should == 1
|
|
369
369
|
end
|
|
370
370
|
|
|
371
|
+
it 'check command exists' do
|
|
372
|
+
Client.command_exists?('foo').should == false
|
|
373
|
+
Client.command_exists?('foo1').should == true
|
|
374
|
+
Client.command_exists?('bar').should == true
|
|
375
|
+
Client.command_exists?('foo1 bar').should == true
|
|
376
|
+
end
|
|
377
|
+
|
|
371
378
|
it 'finds no command' do
|
|
372
379
|
Client.find_commands('foo').size.should == 0
|
|
373
380
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: termtter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jugyo
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2009-
|
|
13
|
+
date: 2009-08-10 00:00:00 +09:00
|
|
14
14
|
default_executable:
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
@@ -106,6 +106,7 @@ files:
|
|
|
106
106
|
- lib/plugins/http_server/favicon.ico
|
|
107
107
|
- lib/plugins/http_server/index.html
|
|
108
108
|
- lib/plugins/http_server.rb
|
|
109
|
+
- lib/plugins/hugeurl.rb
|
|
109
110
|
- lib/plugins/ignore.rb
|
|
110
111
|
- lib/plugins/irb.rb
|
|
111
112
|
- lib/plugins/irc_gw.rb
|