termtter 1.7.2 → 1.8.0
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/.gitignore +1 -1
- data/README.rdoc +1 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/termtter +1 -0
- data/bin/termtter_frame +134 -0
- data/lib/plugins/aa.rb +44 -0
- data/lib/plugins/another_prompt.rb +42 -41
- data/lib/plugins/appendtitle.rb +82 -0
- data/lib/plugins/ar.rb +11 -8
- data/lib/plugins/async.rb +3 -2
- data/lib/plugins/capital_update.rb +12 -0
- data/lib/plugins/channel.rb +149 -0
- data/lib/plugins/clock.rb +10 -0
- data/lib/plugins/defaults/command_line.rb +8 -0
- data/lib/plugins/defaults/confirm.rb +1 -1
- data/lib/plugins/defaults/hashtag.rb +1 -1
- data/lib/plugins/defaults/keyword.rb +11 -0
- data/lib/plugins/defaults/list.rb +32 -6
- data/lib/plugins/defaults/standard_commands.rb +135 -52
- data/lib/plugins/defaults/standard_completion.rb +14 -0
- data/lib/plugins/defaults/stdout.rb +59 -27
- data/lib/plugins/defaults/user.rb +32 -0
- data/lib/plugins/draft.rb +9 -12
- data/lib/plugins/easy_post.rb +5 -0
- data/lib/plugins/event_invoked_at.rb +23 -0
- data/lib/plugins/expand-tinyurl.rb +13 -20
- data/lib/plugins/favotter.rb +9 -9
- data/lib/plugins/footer.rb +9 -12
- data/lib/plugins/friends.rb +0 -26
- data/lib/plugins/grass.rb +2 -4
- data/lib/plugins/growl.rb +47 -0
- data/lib/plugins/gyazo.rb +16 -18
- data/lib/plugins/hi.rb +31 -10
- data/lib/plugins/http_server.rb +3 -2
- data/lib/plugins/irc_gw.rb +71 -17
- data/lib/plugins/line.rb +10 -0
- data/lib/plugins/linefeed.rb +6 -1
- data/lib/plugins/list_switch.rb +76 -0
- data/lib/plugins/nop.rb +9 -0
- data/lib/plugins/notify-send.rb +1 -1
- data/lib/plugins/notify-send2.rb +25 -16
- data/lib/plugins/notify-send3.rb +16 -13
- data/lib/plugins/nuance.rb +29 -0
- data/lib/plugins/open_url.rb +1 -5
- data/lib/plugins/random.rb +2 -6
- data/lib/plugins/reply_sound.rb +33 -0
- data/lib/plugins/say.rb +2 -2
- data/lib/plugins/storage/sqlite3.rb +1 -1
- data/lib/plugins/story.rb +44 -0
- data/lib/plugins/tinyurl.rb +50 -29
- data/lib/plugins/translate_tweet.rb +38 -0
- data/lib/plugins/web.rb +27 -0
- data/lib/termtter.rb +8 -4
- data/lib/termtter/client.rb +17 -21
- data/lib/termtter/command.rb +35 -13
- data/lib/termtter/config.rb +13 -0
- data/lib/termtter/config_template.erb +3 -2
- data/lib/termtter/default_config.rb +2 -2
- data/lib/termtter/event.rb +69 -0
- data/lib/termtter/hook.rb +6 -1
- data/lib/termtter/hookable.rb +9 -1
- data/lib/termtter/httppool.rb +17 -9
- data/lib/termtter/optparse.rb +11 -1
- data/lib/termtter/rubytter_proxy.rb +21 -5
- data/spec/plugins/capital_update_spec.rb +9 -0
- data/spec/plugins/fib_spec.rb +2 -4
- data/spec/plugins/hi_spec.rb +9 -0
- data/spec/plugins/tinyurl_spec.rb +78 -0
- data/spec/termtter/client_spec.rb +5 -12
- data/spec/termtter/command_spec.rb +22 -10
- data/spec/termtter/config_spec.rb +23 -0
- data/spec/termtter/event_spec.rb +129 -0
- data/spec/termtter/optparse_spec.rb +2 -2
- data/spec/termtter/rubytter_proxy_spec.rb +1 -1
- metadata +39 -8
- data/bin/kill_termtter +0 -22
- data/lib/plugins/defaults/users.rb +0 -63
- data/lib/plugins/pause.rb +0 -3
- data/test/friends_timeline.json +0 -5
- data/test/search.json +0 -8
@@ -0,0 +1,12 @@
|
|
1
|
+
module Termtter::Client
|
2
|
+
register_command(
|
3
|
+
:name => :capital_update,
|
4
|
+
:author => 'ujihisa',
|
5
|
+
:alias => :cu,
|
6
|
+
:help =>[
|
7
|
+
'capital_update, cu',
|
8
|
+
'Posts a tweet all in captalized text.'],
|
9
|
+
:exec_proc => lambda {|arg|
|
10
|
+
execute('update ' + arg.upcase)
|
11
|
+
})
|
12
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
config.plugins.channel.set_default(:auto_reload_channels, {})
|
2
|
+
config.plugins.channel.set_default(:short_names, {})
|
3
|
+
config.plugins.channel.set_default(:colorize, true)
|
4
|
+
config.plugins.channel.set_default(:output_length, 7)
|
5
|
+
config.plugins.channel.set_default(:default_channel, :main)
|
6
|
+
config.plugins.channel.set_default(:channel_to_hash_proc, lambda {|c| c.to_i(36) })
|
7
|
+
|
8
|
+
# Channel spec
|
9
|
+
# /^@(.+)/ -- user_timeline of $1
|
10
|
+
# /^(.+)_s(earch)?$/ -- search result of $1
|
11
|
+
# /^replies$/ -- replies
|
12
|
+
# /^main$/ -- home_timeline
|
13
|
+
# otherwise -- list
|
14
|
+
|
15
|
+
# Extention Core
|
16
|
+
module Termtter
|
17
|
+
module API
|
18
|
+
class << self
|
19
|
+
def call_by_channel(c, *opt)
|
20
|
+
case c.to_s
|
21
|
+
when "main"
|
22
|
+
Termtter::API.twitter.home_timeline(*opt)
|
23
|
+
when "replies"
|
24
|
+
Termtter::API.twitter.replies(*opt)
|
25
|
+
when /^(.+)_s(earch)?$/
|
26
|
+
Termtter::API.twitter.search($1, *opt)
|
27
|
+
else
|
28
|
+
user_name, slug = c.to_s.split('/')
|
29
|
+
if !user_name.nil? && slug.nil?
|
30
|
+
slug = user_name
|
31
|
+
user_name = config.user_name
|
32
|
+
elsif user_name.empty?
|
33
|
+
user_name = config.user_name
|
34
|
+
end
|
35
|
+
user_name = Termtter::Client.normalize_as_user_name(user_name)
|
36
|
+
Termtter::API.twitter.list_statuses(user_name, slug, *opt)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
now_channel = config.plugins.channel.default_channel
|
44
|
+
|
45
|
+
Termtter::Client.register_command(
|
46
|
+
:name => :channel,
|
47
|
+
:alias => :c,
|
48
|
+
:help => ['channel, c', 'Show current channel or change channel'],
|
49
|
+
:author => 'Sora Harakami',
|
50
|
+
:exec => lambda {|arg|
|
51
|
+
if arg.empty?
|
52
|
+
puts "Current channel is #{now_channel}"
|
53
|
+
else
|
54
|
+
old = now_channel
|
55
|
+
now_channel = arg.to_sym
|
56
|
+
puts "Channel is tuned. #{old} => #{now_channel}"
|
57
|
+
@since_id = nil
|
58
|
+
end
|
59
|
+
}
|
60
|
+
)
|
61
|
+
|
62
|
+
Termtter::Client.register_command(
|
63
|
+
:name => :reload,
|
64
|
+
:author => 'Sora Harakami',
|
65
|
+
:exec => lambda {|arg|
|
66
|
+
# NOTE: Please edit here as well if reload command in lib/plugins/default/standard_commands.rb was edited.
|
67
|
+
args = @since_id ? [{:since_id => @since_id}] : []
|
68
|
+
statuses = Termtter::API.call_by_channel(now_channel, *args)
|
69
|
+
unless statuses.empty?
|
70
|
+
print "\e[0G" + "\e[K" unless win?
|
71
|
+
@since_id = statuses[0].id
|
72
|
+
Termtter::Client.output(statuses, Termtter::Event.new(:update_friends_timeline, :type => :main))
|
73
|
+
Readline.refresh_line if arg =~ /\-r/
|
74
|
+
end
|
75
|
+
},
|
76
|
+
:help => ['reload', 'Reload time line']
|
77
|
+
)
|
78
|
+
|
79
|
+
colorize_channel_cache = {}
|
80
|
+
Termtter::Client.register_hook(
|
81
|
+
:name => :add_channel_line, :point => :pre_output,
|
82
|
+
:author => 'Sora Harakami',
|
83
|
+
:exec => lambda {|t, e|
|
84
|
+
# Additional to channel
|
85
|
+
c =
|
86
|
+
case e[:type]
|
87
|
+
when :list, :lists
|
88
|
+
:"#{e[:list_user] == config.user_name ?
|
89
|
+
"" : e[:list_user]}/#{e[:list_slug]}"
|
90
|
+
when :user
|
91
|
+
:"@#{e[:user_name]}"
|
92
|
+
when :home_timeline, :main, :friends_timeline
|
93
|
+
:main
|
94
|
+
when :direct_message, :direct
|
95
|
+
:direct
|
96
|
+
when :search
|
97
|
+
:"#{e[:search_keyword]}_search"
|
98
|
+
when :reply, :replies
|
99
|
+
:replies
|
100
|
+
when :show
|
101
|
+
:show
|
102
|
+
when :favorite, :favorites
|
103
|
+
:favorite
|
104
|
+
when :multiple
|
105
|
+
:multiple
|
106
|
+
when :channel
|
107
|
+
e[:channel]
|
108
|
+
else
|
109
|
+
:unknown
|
110
|
+
end
|
111
|
+
# Add channel text to output text
|
112
|
+
otc = config.plugins.channel.short_names.key?(c) ?
|
113
|
+
config.plugins.channel.short_names[c] : c
|
114
|
+
ccolor = colorize_channel_cache.key?(otc) ?
|
115
|
+
colorize_channel_cache[otc] :
|
116
|
+
config.plugins.stdout.colors[
|
117
|
+
config.plugins.channel.channel_to_hash_proc.call(otc.to_s.gsub(/^\//, "")) %
|
118
|
+
config.plugins.stdout.colors.size]
|
119
|
+
colorize_channel_cache[otc] = ccolor
|
120
|
+
th = "#{config.plugin.channel.colorize ? "<#{ccolor}>":""}#{c.to_s.length > config.plugins.channel.output_length ?
|
121
|
+
otc.to_s[0, config.plugins.channel.output_length] : otc.to_s.rjust(config.plugins.channel.output_length)}#{config.plugin.channe.colorize ? "</#{ccolor}>":""}<90>| </90>"
|
122
|
+
th + t
|
123
|
+
}
|
124
|
+
)
|
125
|
+
|
126
|
+
# Add auto reloads
|
127
|
+
config.plugins.channel.auto_reload_channels.each do |c, i|
|
128
|
+
since_ids = {}
|
129
|
+
Termtter::Client.add_task(:name => "auto_reload_#{c}".to_sym, :interval => i) do
|
130
|
+
begin
|
131
|
+
if c != now_channel
|
132
|
+
# NOTE: Please edit here as well if reload command in lib/plugins/default/standard_commands.rb was edited.
|
133
|
+
args = since_ids[c] ? [{:since_id => since_ids[c]}] : []
|
134
|
+
statuses = Termtter::API.call_by_channel(c, *args)
|
135
|
+
unless statuses.empty?
|
136
|
+
print "\e[0G" + "\e[K" unless win?
|
137
|
+
since_ids[c] = statuses[0].id
|
138
|
+
Termtter::Client.output(statuses, Termtter::Event.new(:"update_#{c}", :type => :channel, :channel => c))
|
139
|
+
Readline.refresh_line
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue TimeoutError
|
143
|
+
# do nothing
|
144
|
+
rescue Exception => e
|
145
|
+
Termtter::Client.handle_error(e)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
@@ -32,6 +32,12 @@ module Termtter
|
|
32
32
|
command_text = hook.call(command_text)
|
33
33
|
}
|
34
34
|
Client.execute(command_text)
|
35
|
+
rescue CommandNotFound => e
|
36
|
+
hooks = Client.get_hooks('command_not_found')
|
37
|
+
raise e if hooks.empty?
|
38
|
+
hooks.each {|hook|
|
39
|
+
hook.call(command_text)
|
40
|
+
}
|
35
41
|
rescue TimeoutError
|
36
42
|
puts TermColor.parse("<red>Time out :(</red>")
|
37
43
|
end
|
@@ -106,6 +112,8 @@ module Termtter
|
|
106
112
|
end
|
107
113
|
|
108
114
|
def trap_setting()
|
115
|
+
return if /mswin(?!ce)|mingw|bccwin/ =~ RUBY_PLATFORM
|
116
|
+
|
109
117
|
begin
|
110
118
|
stty_save = `stty -g`.chomp
|
111
119
|
trap("INT") do
|
@@ -33,6 +33,17 @@ module Termtter::Client
|
|
33
33
|
text
|
34
34
|
end
|
35
35
|
|
36
|
+
register_hook :notify_for_keywords, :point => :output do |statuses, event|
|
37
|
+
if event == :update_friends_timeline
|
38
|
+
regexp = Regexp.union(*public_storage[:keywords].map(&:to_s))
|
39
|
+
statuses.select { |status|
|
40
|
+
/#{regexp}/ =~ status.text
|
41
|
+
}.each do |status|
|
42
|
+
notify(status.user.screen_name, status.text)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
36
47
|
register_command(
|
37
48
|
'keyword add',
|
38
49
|
:help => ['keyword add KEYWORD', 'Add a highlight keyword']
|
@@ -15,7 +15,8 @@ module Termtter::Client
|
|
15
15
|
register_command(
|
16
16
|
:name => :list, :aliases => [:l],
|
17
17
|
:exec_proc => lambda {|arg|
|
18
|
-
|
18
|
+
a = {}
|
19
|
+
if /\-([\d]+)/ =~ arg
|
19
20
|
options = {:count => $1}
|
20
21
|
arg = arg.gsub(/\-([\d]+)/, '')
|
21
22
|
else
|
@@ -26,14 +27,18 @@ module Termtter::Client
|
|
26
27
|
if arg.empty?
|
27
28
|
event = :list_friends_timeline
|
28
29
|
statuses = Termtter::API.twitter.home_timeline(options)
|
30
|
+
a[:type] = :home_timeline
|
29
31
|
else
|
30
32
|
event = :list_user_timeline
|
31
33
|
statuses = []
|
32
34
|
Array(arg.split).each do |user|
|
33
35
|
if user =~ /\/\w+/
|
34
36
|
user_name, slug = *user.split('/')
|
37
|
+
a[:type] = :list
|
35
38
|
user_name = config.user_name if user_name.empty?
|
36
39
|
user_name = normalize_as_user_name(user_name)
|
40
|
+
a[:list_user] = user_name
|
41
|
+
a[:list_slug] = slug
|
37
42
|
options[:per_page] = options[:count]
|
38
43
|
options.delete(:count)
|
39
44
|
statuses += Termtter::API.twitter.list_statuses(user_name, slug, options)
|
@@ -47,6 +52,8 @@ module Termtter::Client
|
|
47
52
|
end
|
48
53
|
end
|
49
54
|
user_name = normalize_as_user_name(user.sub(/\/$/, ''))
|
55
|
+
a[:type] = :user
|
56
|
+
a[:user_name] = user_name
|
50
57
|
statuses += Termtter::API.twitter.user_timeline(user_name, options)
|
51
58
|
rescue Rubytter::APIError => e
|
52
59
|
last_error = e
|
@@ -54,7 +61,8 @@ module Termtter::Client
|
|
54
61
|
end
|
55
62
|
end
|
56
63
|
end
|
57
|
-
|
64
|
+
a[:type] = :multiple if arg.split.length > 1
|
65
|
+
output(statuses, Termtter::Event.new(event, a))
|
58
66
|
raise last_error if last_error
|
59
67
|
},
|
60
68
|
:help => ["list,l [USERNAME]/[SLUG] [-COUNT]", "List the posts"]
|
@@ -73,7 +81,7 @@ module Termtter::Client
|
|
73
81
|
public_storage[:lists] += lists.map(&:full_name)
|
74
82
|
puts lists.map{|i| i.full_name}.join("\n")
|
75
83
|
},
|
76
|
-
:help => ["
|
84
|
+
:help => ["list list [USERNAME]", "Show Lists"]
|
77
85
|
)
|
78
86
|
|
79
87
|
register_command(
|
@@ -92,7 +100,7 @@ module Termtter::Client
|
|
92
100
|
end
|
93
101
|
}
|
94
102
|
},
|
95
|
-
:help => ["list follow
|
103
|
+
:help => ["list follow|add LISTNAME USERNAME", "Follow users to the list"]
|
96
104
|
)
|
97
105
|
|
98
106
|
register_command(
|
@@ -110,7 +118,7 @@ module Termtter::Client
|
|
110
118
|
end
|
111
119
|
}
|
112
120
|
},
|
113
|
-
:help => ["list remove
|
121
|
+
:help => ["list remove LISTNAME USERNAME", "Remove user(s) from the list"]
|
114
122
|
)
|
115
123
|
|
116
124
|
register_command(
|
@@ -146,7 +154,25 @@ module Termtter::Client
|
|
146
154
|
end
|
147
155
|
}
|
148
156
|
},
|
149
|
-
:help => ["list delete
|
157
|
+
:help => ["list delete LISTNAME", "Delete list"]
|
158
|
+
)
|
159
|
+
|
160
|
+
register_command(
|
161
|
+
:name => %s{list show},
|
162
|
+
:exec => lambda { |arg|
|
163
|
+
raise ArgumentError unless /([^\s]*\/[^\s]+)/ =~ arg
|
164
|
+
user_name, slug = *arg.split('/')
|
165
|
+
user_name = config.user_name if user_name.empty?
|
166
|
+
user_name = normalize_as_user_name(user_name)
|
167
|
+
list = Termtter::API.twitter.list(user_name, slug)
|
168
|
+
attrs = %w[ full_name slug description mode id member_count subscriber_count]
|
169
|
+
label_width = attrs.map(&:size).max
|
170
|
+
attrs.each do |attr|
|
171
|
+
value = list.__send__(attr.to_sym)
|
172
|
+
puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
|
173
|
+
end
|
174
|
+
},
|
175
|
+
:help => ["list show LISTNAME", "Show the detail of list"]
|
150
176
|
)
|
151
177
|
|
152
178
|
def self.list_name_to_slug(list_name)
|
@@ -8,18 +8,21 @@ config.plugins.standard.set_default(
|
|
8
8
|
'<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=Time.parse(limit.reset_time).getlocal%> (<%=remaining_time%> remaining)')
|
9
9
|
|
10
10
|
config.set_default(:easy_reply, false)
|
11
|
+
config.plugins.standard.set_default(
|
12
|
+
:one_line_profile_format,
|
13
|
+
'<90>[<%=user_id%>]</90> <%= mark %> <<%=color%>><%= user.screen_name %>: <%= padding %><%= (user.description || "").gsub(/\r?\n/, "") %></<%=color%>>')
|
11
14
|
|
12
15
|
module Termtter::Client
|
13
|
-
|
14
16
|
register_command(
|
15
17
|
:name => :reload,
|
16
18
|
:exec => lambda {|arg|
|
19
|
+
# NOTE: If edit this command, please check and edit lib/plugins/channel.rb too, please.
|
17
20
|
args = @since_id ? [{:since_id => @since_id}] : []
|
18
21
|
statuses = Termtter::API.twitter.home_timeline(*args)
|
19
22
|
unless statuses.empty?
|
20
23
|
print "\e[0G" + "\e[K" unless win?
|
21
24
|
@since_id = statuses[0].id
|
22
|
-
output(statuses, :update_friends_timeline)
|
25
|
+
output(statuses, Termtter::Event.new(:update_friends_timeline, :type => :main))
|
23
26
|
Readline.refresh_line if arg =~ /\-r/
|
24
27
|
end
|
25
28
|
},
|
@@ -33,8 +36,10 @@ module Termtter::Client
|
|
33
36
|
params =
|
34
37
|
if config.easy_reply && /^\s*(@\w+)/ =~ arg
|
35
38
|
user_name = normalize_as_user_name($1)
|
36
|
-
in_reply_to_status_id =
|
37
|
-
|
39
|
+
in_reply_to_status_id =
|
40
|
+
Termtter::API.twitter.user(user_name).status.id rescue nil
|
41
|
+
in_reply_to_status_id ?
|
42
|
+
{:in_reply_to_status_id => in_reply_to_status_id} : {}
|
38
43
|
else
|
39
44
|
{}
|
40
45
|
end
|
@@ -77,7 +82,9 @@ module Termtter::Client
|
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
80
|
-
register_command(
|
85
|
+
register_command(
|
86
|
+
:direct, :alias => :d,
|
87
|
+
:help => ["direct,d USERNAME TEXT", "Send direct message"]) do |arg|
|
81
88
|
if /^([^\s]+)\s+?(.*)\s*$/ =~ arg
|
82
89
|
user, text = normalize_as_user_name($1), $2
|
83
90
|
Termtter::API.twitter.direct_message(user, text)
|
@@ -85,45 +92,93 @@ module Termtter::Client
|
|
85
92
|
end
|
86
93
|
end
|
87
94
|
|
88
|
-
register_command(
|
95
|
+
register_command(
|
96
|
+
'direct list', :help => ["direct list", 'List direct messages']) do |arg|
|
89
97
|
output(
|
90
98
|
Termtter::API.twitter.direct_messages.map { |d|
|
91
99
|
DirectMessage.new(d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
|
92
100
|
},
|
93
|
-
|
101
|
+
Termtter::Event.new(
|
102
|
+
:direct_messages,
|
103
|
+
:type => :direct_message)
|
94
104
|
)
|
95
105
|
end
|
96
106
|
|
97
|
-
register_command(
|
107
|
+
register_command(
|
108
|
+
'direct sent_list',
|
109
|
+
:help => ["direct sent_list", 'List sent direct messages']) do |arg|
|
98
110
|
output(
|
99
111
|
Termtter::API.twitter.sent_direct_messages.map { |d|
|
100
|
-
|
112
|
+
DirectMessage.new(
|
113
|
+
d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
|
101
114
|
},
|
102
|
-
|
115
|
+
Termtter::Event.new(
|
116
|
+
:direct_messages,
|
117
|
+
:type => :direct_message)
|
103
118
|
)
|
104
119
|
end
|
105
120
|
|
121
|
+
def self.get_friends(user_name, max)
|
122
|
+
self.get_friends_or_followers(:followers, user_name, max)
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.get_followers(user_name, max)
|
126
|
+
self.get_friends_or_followers(:followers, user_name, max)
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.get_friends_or_followers(type, user_name, max)
|
130
|
+
raise "type should :friends or :followers" unless [:friends, :followers].include? type
|
131
|
+
users = []
|
132
|
+
cursor = -1
|
133
|
+
begin
|
134
|
+
tmp = Termtter::API::twitter.__send__(type, user_name, :cursor => cursor)
|
135
|
+
cursor = tmp[:next_cursor]
|
136
|
+
users += tmp[:users]
|
137
|
+
puts "#{users.length}/#{max}" if max > 100
|
138
|
+
rescue
|
139
|
+
break
|
140
|
+
end until (cursor.zero? or users.length > max)
|
141
|
+
users.take(max)
|
142
|
+
end
|
143
|
+
|
106
144
|
register_command(
|
107
|
-
:name => :
|
145
|
+
:name => :friends, :aliases => [:following],
|
108
146
|
:exec_proc => lambda {|arg|
|
109
|
-
|
110
|
-
|
147
|
+
friends_or_followers_command(:friends, arg)
|
148
|
+
},
|
149
|
+
:help => ["friends [USERNAME] [-COUNT]", "Show user's friends."]
|
150
|
+
)
|
111
151
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
cursor = tmp[:next_cursor]
|
117
|
-
followers += tmp[:users]
|
118
|
-
end until cursor.zero?
|
119
|
-
Termtter::Client.public_storage[:followers] = followers
|
120
|
-
public_storage[:users] += followers.map(&:screen_name)
|
121
|
-
puts followers.map(&:screen_name).join(' ')
|
152
|
+
register_command(
|
153
|
+
:name => :followers,
|
154
|
+
:exec_proc => lambda {|arg|
|
155
|
+
friends_or_followers_command(:followers, arg)
|
122
156
|
},
|
123
|
-
:help => ["followers", "Show followers"]
|
157
|
+
:help => ["followers [USERNAME]", "Show user's followers."]
|
124
158
|
)
|
125
159
|
|
126
|
-
|
160
|
+
def self.friends_or_followers_command(type, arg)
|
161
|
+
raise "type should :friends or :followers" unless [:friends, :followers].include? type
|
162
|
+
limit = 20
|
163
|
+
if /\-([\d]+)/ =~ arg
|
164
|
+
limit = $1.to_i
|
165
|
+
arg = arg.gsub(/\-([\d]+)/, '')
|
166
|
+
end
|
167
|
+
arg.strip!
|
168
|
+
user_name = arg.empty? ? config.user_name : arg
|
169
|
+
users = get_friends_or_followers(type, user_name, limit)
|
170
|
+
longest = users.map{ |u| u.screen_name.length}.max
|
171
|
+
users.reverse.each{|user|
|
172
|
+
padding = ' ' * (longest - user.screen_name.length)
|
173
|
+
user_id = Termtter::Client.data_to_typable_id(user.id) rescue ''
|
174
|
+
color = user.following ? 'BLACK' : 'RED'
|
175
|
+
mark = user.following ? '♥' : '✂'
|
176
|
+
erbed_text = ERB.new(config.plugins.standard.one_line_profile_format).result(binding)
|
177
|
+
puts TermColor.unescape(TermColor.parse(erbed_text))
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
class SearchEvent < Termtter::Event; attr_reader :query; def initialize(query); @query = query end; end
|
127
182
|
public_storage[:search_keywords] = Set.new
|
128
183
|
register_command(
|
129
184
|
:name => :search, :aliases => [:s],
|
@@ -134,7 +189,7 @@ module Termtter::Client
|
|
134
189
|
output(statuses, SearchEvent.new(arg))
|
135
190
|
},
|
136
191
|
:completion_proc => lambda {|cmd, arg|
|
137
|
-
public_storage[:search_keywords].grep(/^#{Regexp.quote(arg)}/).map {
|
192
|
+
public_storage[:search_keywords].grep(/^#{Regexp.quote(arg)}/).map {|i| "#{cmd} #{i}" }
|
138
193
|
},
|
139
194
|
:help => ["search,s TEXT", "Search for Twitter"]
|
140
195
|
)
|
@@ -142,7 +197,7 @@ module Termtter::Client
|
|
142
197
|
case event
|
143
198
|
when SearchEvent
|
144
199
|
query = event.query.split(/\s/).map {|q|Regexp.quote(q)}.join("|")
|
145
|
-
text.gsub(
|
200
|
+
text.gsub(/#{query}/i, '<on_magenta><white>\0</white></on_magenta>')
|
146
201
|
else
|
147
202
|
text
|
148
203
|
end
|
@@ -151,7 +206,7 @@ module Termtter::Client
|
|
151
206
|
register_command(
|
152
207
|
:name => :replies, :aliases => [:r],
|
153
208
|
:exec_proc => lambda {|arg|
|
154
|
-
if
|
209
|
+
if /\-([\d]+)/ =~ arg
|
155
210
|
options = {:count => $1}
|
156
211
|
arg = arg.gsub(/\-([\d]+)/, '')
|
157
212
|
else
|
@@ -160,18 +215,18 @@ module Termtter::Client
|
|
160
215
|
|
161
216
|
res = Termtter::API.twitter.replies(options)
|
162
217
|
unless arg.empty?
|
163
|
-
res = res.
|
218
|
+
res = res.select {|e| e.user.screen_name == arg }
|
164
219
|
end
|
165
|
-
output(res, :replies)
|
220
|
+
output(res, Termtter::Event.new(:replies, :type => :reply))
|
166
221
|
},
|
167
|
-
:help => ["replies,r", "List the replies"]
|
222
|
+
:help => ["replies,r [username]", "List the replies (from the user)"]
|
168
223
|
)
|
169
224
|
|
170
225
|
register_command(
|
171
226
|
:name => :show,
|
172
227
|
:exec_proc => lambda {|arg|
|
173
228
|
id = arg.gsub(/.*:\s*/, '')
|
174
|
-
output([Termtter::API.twitter.show(id)], :show)
|
229
|
+
output([Termtter::API.twitter.show(id)], Termtter::Event.new(:show, :type => :show))
|
175
230
|
},
|
176
231
|
:completion_proc => lambda {|cmd, arg|
|
177
232
|
case arg
|
@@ -205,26 +260,52 @@ module Termtter::Client
|
|
205
260
|
:exec_proc => lambda {|args|
|
206
261
|
args.split(' ').each do |arg|
|
207
262
|
user_name = normalize_as_user_name(arg)
|
208
|
-
|
263
|
+
user = Termtter::API::twitter.follow(user_name)
|
264
|
+
puts "followed #{user.name}"
|
209
265
|
end
|
210
266
|
},
|
211
267
|
:help => ['follow USER', 'Follow user']
|
212
268
|
)
|
213
269
|
|
214
270
|
register_command(
|
215
|
-
:name => :leave, :aliases => [],
|
271
|
+
:name => :leave, :aliases => [:remove],
|
216
272
|
:exec_proc => lambda {|args|
|
217
273
|
args.split(' ').each do |arg|
|
218
274
|
user_name = normalize_as_user_name(arg)
|
219
|
-
|
275
|
+
user = Termtter::API::twitter.leave(user_name)
|
276
|
+
puts "leaved #{user.name}"
|
220
277
|
end
|
221
278
|
},
|
222
279
|
:help => ['leave USER', 'Leave user']
|
223
280
|
)
|
224
281
|
|
282
|
+
register_command(
|
283
|
+
:name => :block, :aliases => [],
|
284
|
+
:exec_proc => lambda {|args|
|
285
|
+
args.split(' ').each do |arg|
|
286
|
+
user_name = normalize_as_user_name(arg)
|
287
|
+
user = Termtter::API::twitter.block(user_name)
|
288
|
+
puts "blocked #{user.name}"
|
289
|
+
end
|
290
|
+
},
|
291
|
+
:help => ['block USER', 'Block user']
|
292
|
+
)
|
293
|
+
|
294
|
+
register_command(
|
295
|
+
:name => :unblock, :aliases => [],
|
296
|
+
:exec_proc => lambda {|args|
|
297
|
+
args.split(' ').each do |arg|
|
298
|
+
user_name = normalize_as_user_name(arg)
|
299
|
+
user = Termtter::API::twitter.unblock(user_name)
|
300
|
+
puts "unblocked #{user.name}"
|
301
|
+
end
|
302
|
+
},
|
303
|
+
:help => ['unblock USER', 'Unblock user']
|
304
|
+
)
|
305
|
+
|
225
306
|
help = ['favorite_list USERNAME', 'show user favorites']
|
226
307
|
register_command(:favorites, :alias => :favlist, :help => help) do |arg|
|
227
|
-
output Termtter::API.twitter.favorites(arg), :user_timeline
|
308
|
+
output Termtter::API.twitter.favorites(arg), :user_timeline, :type => :favorite
|
228
309
|
end
|
229
310
|
|
230
311
|
register_command(
|
@@ -372,15 +453,15 @@ module Termtter::Client
|
|
372
453
|
end
|
373
454
|
},
|
374
455
|
:completion_proc => lambda {|cmd, args|
|
375
|
-
plugin_list.grep(
|
456
|
+
plugin_list.grep(/#{Regexp.quote(args)}/).map {|i| "#{cmd} #{i}"}
|
376
457
|
},
|
377
458
|
:help => ['plug FILE', 'Load a plugin']
|
378
459
|
)
|
379
460
|
|
380
461
|
## plugin_list :: IO ()
|
381
462
|
def self.plugin_list
|
382
|
-
(Dir["#{File.dirname(__FILE__)}
|
383
|
-
map {|f| File.
|
463
|
+
(Dir["#{File.dirname(__FILE__)}/../**/*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/**/*.rb"]).
|
464
|
+
map {|f| File.expand_path(f).scan(/.*plugins\/(.*)\.rb/).flatten[0] }.
|
384
465
|
sort
|
385
466
|
end
|
386
467
|
|
@@ -455,21 +536,23 @@ module Termtter::Client
|
|
455
536
|
:help => ["redo,.", "Execute previous command"]
|
456
537
|
)
|
457
538
|
|
458
|
-
|
459
|
-
text
|
460
|
-
|
461
|
-
|
462
|
-
|
539
|
+
class << self
|
540
|
+
def update_with_user_and_id(text, username, id)
|
541
|
+
text = "@#{username} #{text}"
|
542
|
+
result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id })
|
543
|
+
puts "replied => #{result.text}"
|
544
|
+
end
|
463
545
|
|
464
|
-
|
465
|
-
|
466
|
-
|
546
|
+
def normalize_as_user_name(text)
|
547
|
+
text.strip.sub(/^@/, '')
|
548
|
+
end
|
467
549
|
|
468
|
-
|
469
|
-
|
470
|
-
|
550
|
+
def find_status_ids(text)
|
551
|
+
public_storage[:status_ids].select {|id| /#{Regexp.quote(text)}/ =~ id.to_s }
|
552
|
+
end
|
471
553
|
|
472
|
-
|
473
|
-
|
554
|
+
def find_users(text)
|
555
|
+
public_storage[:users].select {|user| /^#{Regexp.quote(text)}/ =~ user }
|
556
|
+
end
|
474
557
|
end
|
475
558
|
end
|