jugyo-termtter 1.1.0 → 1.1.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/README.rdoc +8 -0
- data/lib/plugins/auto_reload.rb +8 -0
- data/lib/plugins/hatebu_and_update.rb +2 -2
- data/lib/plugins/ignore.rb +13 -7
- data/lib/plugins/irc_gw.rb +89 -0
- data/lib/plugins/list_with_opts.rb +32 -0
- data/lib/plugins/multi_post.rb +32 -0
- data/lib/plugins/notify-send3.rb +8 -3
- data/lib/plugins/{standard_plugins.rb → standard_commands.rb} +48 -5
- data/lib/plugins/wassr.rb +97 -0
- data/lib/termtter/client.rb +72 -48
- data/lib/termtter/config_setup.rb +13 -21
- data/lib/termtter/optparse.rb +5 -0
- data/lib/termtter/system_extensions.rb +4 -7
- data/lib/termtter/version.rb +1 -1
- data/spec/plugins/standard_plugins_spec.rb +1 -1
- data/spec/termtter/client_spec.rb +38 -4
- metadata +7 -3
- data/lib/plugins/update_timeline.rb +0 -32
data/README.rdoc
CHANGED
@@ -59,6 +59,14 @@ If you would like to use proxy server, add configurations like this:
|
|
59
59
|
config.proxy.user_name = 'USERNAME'
|
60
60
|
config.proxy.password = 'PASSWORD'
|
61
61
|
|
62
|
+
You can to load plugins in this way:
|
63
|
+
|
64
|
+
Termtter::Client.init do |t|
|
65
|
+
t.plug 'stdout'
|
66
|
+
t.plug 'standard_commands'
|
67
|
+
t.plug 'auto_reload'
|
68
|
+
end
|
69
|
+
|
62
70
|
To update the config, just restart your termtter proccess.
|
63
71
|
|
64
72
|
== FORUM:
|
data/lib/plugins/ignore.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
|
4
3
|
config.filters.ignore.set_default(:words, [])
|
5
4
|
|
6
5
|
module Termtter::Client
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
register_hook(
|
7
|
+
:name => :ignore,
|
8
|
+
:point => :filter_for_output,
|
9
|
+
:exec => lambda { |statuses, event|
|
10
|
+
ignore_words = config.filters.ignore.words
|
11
|
+
statuses.delete_if do |s|
|
12
|
+
ignore_words.any? do |word|
|
13
|
+
word = /#{Regexp.quote(word)}/ if word.kind_of? String
|
14
|
+
word =~ s.text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
}
|
18
|
+
)
|
13
19
|
end
|
14
20
|
|
15
21
|
# filter/ignore.rb
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'net/irc'
|
4
|
+
|
5
|
+
# TODO: post text of stdout too
|
6
|
+
|
7
|
+
config.plugins.irc_gw.set_default(:port, 16669)
|
8
|
+
config.plugins.irc_gw.set_default(:last_statuses_count, 100)
|
9
|
+
|
10
|
+
class TermtterIrcGateway < Net::IRC::Server::Session
|
11
|
+
@@listners = []
|
12
|
+
@@last_statuses = []
|
13
|
+
|
14
|
+
Termtter::Client.register_hook(
|
15
|
+
:name => :irc_gw,
|
16
|
+
:point => :output,
|
17
|
+
:exec => lambda { |statuses, event|
|
18
|
+
if event == :update_friends_timeline
|
19
|
+
@@last_statuses =
|
20
|
+
(@@last_statuses + statuses.dup).reverse![0..config.plugins.irc_gw.last_statuses_count].reverse!
|
21
|
+
end
|
22
|
+
|
23
|
+
@@listners.each do |listner|
|
24
|
+
listner.call(statuses.dup, event)
|
25
|
+
end
|
26
|
+
}
|
27
|
+
)
|
28
|
+
|
29
|
+
def server_name; 'termtter' end
|
30
|
+
def server_version; '0.0.0' end
|
31
|
+
def main_channel; '#termtter' end
|
32
|
+
|
33
|
+
def initialize(*args)
|
34
|
+
super
|
35
|
+
@@listners << self
|
36
|
+
Thread.start do
|
37
|
+
sleep 1
|
38
|
+
self.call(@@last_statuses || [], :update_friends_timeline)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(statuses, event)
|
43
|
+
msg_type =
|
44
|
+
case event
|
45
|
+
when :update_friends_timeline
|
46
|
+
PRIVMSG
|
47
|
+
else
|
48
|
+
NOTICE
|
49
|
+
end
|
50
|
+
|
51
|
+
statuses.each do |s|
|
52
|
+
post s.user.screen_name, msg_type, main_channel, s.text
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def on_message(m)
|
57
|
+
begin
|
58
|
+
termtter_command = m.command.downcase + ' ' + m.params.join(' ')
|
59
|
+
unless Termtter::Client.find_commands(termtter_command).empty?
|
60
|
+
post '#termtter', NOTICE, main_channel, '> ' + termtter_command
|
61
|
+
Termtter::Client.call_commands(termtter_command)
|
62
|
+
end
|
63
|
+
rescue Termtter::CommandNotFound => e
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def on_user(m)
|
69
|
+
super
|
70
|
+
post @prefix, JOIN, main_channel
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_privmsg(m)
|
74
|
+
target, message = *m.params
|
75
|
+
Termtter::Client.call_commands('update ' + message)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless defined? IRC_SERVER
|
80
|
+
IRC_SERVER = Net::IRC::Server.new(
|
81
|
+
'localhost',
|
82
|
+
config.plugins.irc_gw.port,
|
83
|
+
TermtterIrcGateway,
|
84
|
+
:logger => Termtter::Client.logger
|
85
|
+
)
|
86
|
+
Thread.start do
|
87
|
+
IRC_SERVER.start
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
register_command(
|
4
|
+
:name => :list, :aliases => [:l],
|
5
|
+
:exec_proc => lambda {|arg|
|
6
|
+
_, options, user = */((?:\-[a-z][= ]\S+\s*)+)?(\w+)?/.match(arg)
|
7
|
+
params = {}
|
8
|
+
options.scan(/(\-[a-z])[= ](\S+)/).each do |k,v|
|
9
|
+
v = v.sub(/^['"]/,'').sub(/['"]$/,'')
|
10
|
+
case k
|
11
|
+
when '-n' #count
|
12
|
+
params['count'] = v.to_i if v.to_i > 0
|
13
|
+
when '-p' #page
|
14
|
+
params['page'] = v.to_i if v.to_i > 0
|
15
|
+
end
|
16
|
+
end if options
|
17
|
+
|
18
|
+
unless user
|
19
|
+
event = :list_friends_timeline
|
20
|
+
statuses = Termtter::API.twitter.friends_timeline(params)
|
21
|
+
else
|
22
|
+
event = :list_user_timeline
|
23
|
+
statuses = Termtter::API.twitter.user_timeline(user, params)
|
24
|
+
end
|
25
|
+
output(statuses, event)
|
26
|
+
},
|
27
|
+
:completion_proc => lambda {|cmd, arg|
|
28
|
+
find_user_candidates arg, "#{cmd} %s"
|
29
|
+
},
|
30
|
+
:help => ["list,l [USERNAME]", "List the posts"]
|
31
|
+
)
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
class << self
|
5
|
+
def wassr_update(text)
|
6
|
+
Net::HTTP.version_1_2
|
7
|
+
req = Net::HTTP::Post.new("/statuses/update.json?")
|
8
|
+
req.basic_auth config.plugins.wassr.username, config.plugins.wassr.password
|
9
|
+
Net::HTTP.start('api.wassr.jp', 80) do |http|
|
10
|
+
res = http.request(req, "status=#{URI.escape(text)}&source=Termtter")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Termtter::Client.register_hook(
|
17
|
+
:name => :multi_post,
|
18
|
+
:points => [:modify_arg_for_update, :modify_arg_for_reply],
|
19
|
+
:exec_proc => lambda {|cmd, arg|
|
20
|
+
begin
|
21
|
+
wassr_arg = arg.gsub(/\d{10,}/, '')
|
22
|
+
Termtter::Client.wassr_update(wassr_arg.strip)
|
23
|
+
rescue
|
24
|
+
puts "RuntimeError: #{$!}"
|
25
|
+
end
|
26
|
+
|
27
|
+
return arg
|
28
|
+
}
|
29
|
+
)
|
30
|
+
|
31
|
+
# multi_post.rb
|
32
|
+
# One post, multi update.
|
data/lib/plugins/notify-send3.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'RMagick'
|
5
|
+
require 'uri'
|
5
6
|
|
6
7
|
# Copy from notify-send2.rb
|
7
8
|
config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
@@ -33,9 +34,13 @@ Termtter::Client.register_hook(
|
|
33
34
|
Thread.start do
|
34
35
|
statuses.each do |s|
|
35
36
|
text = CGI.escapeHTML(s.text)
|
36
|
-
text
|
37
|
-
|
38
|
-
|
37
|
+
text = %Q{"#{text}"} if text =~ /^-/
|
38
|
+
text.gsub!(URI.regexp,'<a href="\0">\0</a>')
|
39
|
+
begin
|
40
|
+
system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
|
41
|
+
sleep 0.05
|
42
|
+
rescue
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
}
|
@@ -9,12 +9,36 @@ config.plugins.standard.set_default(
|
|
9
9
|
|
10
10
|
module Termtter::Client
|
11
11
|
|
12
|
+
register_command(
|
13
|
+
:name => :reload,
|
14
|
+
:exec_proc => lambda {|arg|
|
15
|
+
begin
|
16
|
+
args = @since_id ? [{:since_id => @since_id}] : []
|
17
|
+
statuses = Termtter::API.twitter.friends_timeline(*args)
|
18
|
+
unless statuses.empty?
|
19
|
+
print "\e[1K\e[0G" unless win?
|
20
|
+
@since_id = statuses[0].id
|
21
|
+
output(statuses, :update_friends_timeline)
|
22
|
+
Readline.refresh_line
|
23
|
+
end
|
24
|
+
rescue OpenURI::HTTPError => e
|
25
|
+
if e.message == '401 Unauthorized'
|
26
|
+
puts 'Could not login'
|
27
|
+
puts 'plese check your account settings'
|
28
|
+
exit!
|
29
|
+
end
|
30
|
+
rescue => e
|
31
|
+
handle_error(e)
|
32
|
+
end
|
33
|
+
}
|
34
|
+
)
|
35
|
+
|
12
36
|
register_command(
|
13
37
|
:name => :update, :aliases => [:u],
|
14
38
|
:exec_proc => lambda {|arg|
|
15
39
|
unless arg.empty?
|
16
|
-
Termtter::API.twitter.update(arg)
|
17
|
-
puts "=> #{
|
40
|
+
result = Termtter::API.twitter.update(arg)
|
41
|
+
puts "updated => ##{result.id} #{result.text}"
|
18
42
|
end
|
19
43
|
},
|
20
44
|
:completion_proc => lambda {|cmd, args|
|
@@ -25,6 +49,24 @@ module Termtter::Client
|
|
25
49
|
:help => ["update,u TEXT", "Post a new message"]
|
26
50
|
)
|
27
51
|
|
52
|
+
register_command(
|
53
|
+
:name => :delete, :aliases =>[:del],
|
54
|
+
:exec_proc => lambda {|arg|
|
55
|
+
id =
|
56
|
+
case arg
|
57
|
+
when ''
|
58
|
+
Termtter::API.twitter.user_timeline(config.user_name)[0].id
|
59
|
+
when /^\d+$/
|
60
|
+
arg.to_i
|
61
|
+
end
|
62
|
+
if id
|
63
|
+
result = Termtter::API.twitter.remove_status(id)
|
64
|
+
puts "deleted => ##{result.id} #{result.text}"
|
65
|
+
end
|
66
|
+
},
|
67
|
+
:help => ['delete,del [STATUS ID]', 'Delete a status']
|
68
|
+
)
|
69
|
+
|
28
70
|
direct_message_struct = Struct.new(:id, :text, :user, :created_at)
|
29
71
|
direct_message_struct.class_eval do
|
30
72
|
def method_missing(*args, &block)
|
@@ -242,7 +284,7 @@ module Termtter::Client
|
|
242
284
|
%w(favorite).grep(/^#{Regexp.quote arg}/)
|
243
285
|
end
|
244
286
|
},
|
245
|
-
:help => ['favorite,fav (ID|@USER|/WORD)', '
|
287
|
+
:help => ['favorite,fav (ID|@USER|/WORD)', 'Mark a status as a favorite']
|
246
288
|
)
|
247
289
|
|
248
290
|
def self.show_settings(conf, level = 0)
|
@@ -353,14 +395,15 @@ module Termtter::Client
|
|
353
395
|
end
|
354
396
|
|
355
397
|
register_command(
|
356
|
-
:name => :
|
398
|
+
:name => :plug,
|
399
|
+
:alias => :plugin,
|
357
400
|
:exec_proc => lambda {|arg|
|
358
401
|
if arg.empty?
|
359
402
|
puts 'Should specify plugin name.'
|
360
403
|
return
|
361
404
|
end
|
362
405
|
begin
|
363
|
-
result =
|
406
|
+
result = plug arg
|
364
407
|
rescue LoadError
|
365
408
|
ensure
|
366
409
|
puts "=> #{result.inspect}"
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Termtter::API.module_eval %Q{
|
4
|
+
class << self
|
5
|
+
attr_reader :wassr
|
6
|
+
|
7
|
+
def setup_wassr(user_name, password)
|
8
|
+
@wassr = create_wassr(user_name, password)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_wassr(user_name, password)
|
12
|
+
Rubytter.new(
|
13
|
+
user_name,
|
14
|
+
password,
|
15
|
+
{
|
16
|
+
:app_name => config.app_name.empty? ? Termtter::APP_NAME : config.app_name,
|
17
|
+
:host => 'api.wassr.jp',
|
18
|
+
:header => {
|
19
|
+
'User-Agent' => 'Termtter http://github.com/jugyo/termtter',
|
20
|
+
'X-Wassr-Client' => 'Termtter',
|
21
|
+
'X-Wassr-Client-URL' => 'http://github.com/jugyo/termtter',
|
22
|
+
'X-Wassr-Client-Version' => Termtter::VERSION
|
23
|
+
},
|
24
|
+
:enable_ssl => config.enable_ssl,
|
25
|
+
:proxy_host => config.proxy.host,
|
26
|
+
:proxy_port => config.proxy.port,
|
27
|
+
:proxy_user_name => config.proxy.user_name,
|
28
|
+
:proxy_password => config.proxy.password
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
|
35
|
+
module Termtter::Client
|
36
|
+
register_command(
|
37
|
+
:name => :wassr, :aliases => [:wsr],
|
38
|
+
:exec_proc => lambda {|arg|
|
39
|
+
Termtter::API.setup_wassr(config.plugins.wassr.username, config.plugins.wassr.password)
|
40
|
+
statuses = Termtter::API.wassr.friends_timeline
|
41
|
+
add_member = [:created_at, :in_reply_to_status_id]
|
42
|
+
event = :wassr_friends_timeline
|
43
|
+
print_statuses(statuses, event)
|
44
|
+
},
|
45
|
+
:completion_proc => lambda {|cmd, arg|
|
46
|
+
find_user_candidates arg, "#{cmd} %s"
|
47
|
+
},
|
48
|
+
:help => ["wassr, wsr", "List the wassr timeline."]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def print_statuses(statuses, sort = true, time_format = nil)
|
53
|
+
return unless statuses and statuses.first
|
54
|
+
unless time_format
|
55
|
+
t0 = Time.now
|
56
|
+
t1 = Time.at(statuses.first[:epoch])
|
57
|
+
t2 = Time.at(statuses.last[:epoch])
|
58
|
+
time_format =
|
59
|
+
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
60
|
+
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
61
|
+
'%H:%M:%S'
|
62
|
+
else
|
63
|
+
'%y/%m/%d %H:%M'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
output_text = ''
|
68
|
+
|
69
|
+
user_login_ids = []
|
70
|
+
statuses.sort{|a, b| a.epoch <=> b.epoch}.each do |s|
|
71
|
+
text = s.text
|
72
|
+
user_login_ids << s.user_login_id unless user_login_ids.include?(s.user_login_id)
|
73
|
+
status_color = config.plugins.stdout.colors[user_login_ids.index(s.user_login_id) % config.plugins.stdout.colors.size]
|
74
|
+
status = "#{s.user.screen_name}: #{TermColor.escape(text)}"
|
75
|
+
|
76
|
+
time = "[wassr] [#{Time.at(s.epoch).strftime(time_format)}]"
|
77
|
+
id = s.id
|
78
|
+
source =
|
79
|
+
case s.source
|
80
|
+
when />(.*?)</ then $1
|
81
|
+
when 'web' then 'web'
|
82
|
+
end
|
83
|
+
|
84
|
+
erbed_text = ERB.new('<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>>').result(binding)
|
85
|
+
output_text << TermColor.parse(erbed_text) + "\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
if config.plugins.stdout.enable_pager && ENV['LINES'] && statuses.size > ENV['LINES'].to_i
|
89
|
+
file = Tempfile.new('termtter')
|
90
|
+
file.print output_text
|
91
|
+
file.close
|
92
|
+
system "#{config.plugins.stdout.pager} #{file.path}"
|
93
|
+
file.close(true)
|
94
|
+
else
|
95
|
+
print output_text
|
96
|
+
end
|
97
|
+
end
|
data/lib/termtter/client.rb
CHANGED
@@ -10,20 +10,33 @@ module Termtter
|
|
10
10
|
|
11
11
|
module Client
|
12
12
|
|
13
|
+
@hooks = {}
|
14
|
+
@commands = {}
|
15
|
+
@filters = []
|
16
|
+
@since_id = nil
|
17
|
+
@input_thread = nil
|
18
|
+
@task_manager = Termtter::TaskManager.new
|
19
|
+
|
20
|
+
config.set_default(:logger, nil)
|
21
|
+
config.set_default(:update_interval, 300)
|
22
|
+
config.set_default(:prompt, '> ')
|
23
|
+
config.set_default(:devel, false)
|
24
|
+
|
25
|
+
Thread.abort_on_exception = true
|
26
|
+
|
13
27
|
class << self
|
14
28
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Thread.abort_on_exception = true
|
29
|
+
attr_reader :commands, :hooks
|
30
|
+
|
31
|
+
def plug(name, options = {})
|
32
|
+
unless options.empty?
|
33
|
+
options.each do |key, value|
|
34
|
+
config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
load "plugins/#{name}.rb"
|
38
|
+
rescue Exception => e
|
39
|
+
Termtter::Client.handle_error(e)
|
27
40
|
end
|
28
41
|
|
29
42
|
def public_storage
|
@@ -31,6 +44,7 @@ module Termtter
|
|
31
44
|
end
|
32
45
|
|
33
46
|
def add_filter(&b)
|
47
|
+
warn "add_filter method will be removed. Use Termtter::Client.register_hook(:name => ..., :point => :filter_for_output, :exec => ... ) instead."
|
34
48
|
@filters << b
|
35
49
|
end
|
36
50
|
|
@@ -72,6 +86,10 @@ module Termtter
|
|
72
86
|
@commands[command.name] = command
|
73
87
|
end
|
74
88
|
|
89
|
+
def clear_command
|
90
|
+
@commands.clear
|
91
|
+
end
|
92
|
+
|
75
93
|
def get_command(name)
|
76
94
|
@commands[name]
|
77
95
|
end
|
@@ -101,26 +119,27 @@ module Termtter
|
|
101
119
|
|
102
120
|
statuses = statuses.sort_by{|s|s.id}
|
103
121
|
call_hooks(:pre_filter, statuses, event)
|
104
|
-
|
122
|
+
|
123
|
+
filtered = statuses.map(&:dup)
|
124
|
+
@filters.each do |f| # TODO: code for compatibility. delete someday.
|
125
|
+
statuses = f.call(statuses, event)
|
126
|
+
end
|
127
|
+
apply_filters_for_hook(:filter_for_output, statuses, event)
|
128
|
+
|
105
129
|
call_hooks(:post_filter, filtered, event)
|
106
130
|
get_hooks(:output).each do |hook|
|
107
|
-
|
108
|
-
|
131
|
+
hook.call(
|
132
|
+
apply_filters_for_hook("filter_for_#{hook.name}", filtered, event),
|
133
|
+
event
|
134
|
+
)
|
109
135
|
end
|
110
136
|
end
|
111
137
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
filtered
|
118
|
-
end
|
119
|
-
|
120
|
-
def apply_filters_for_hook(statuses, hook_name)
|
121
|
-
# TODO
|
122
|
-
filtered = statuses.map(&:dup)
|
123
|
-
filtered
|
138
|
+
def apply_filters_for_hook(hook_name, statuses, event)
|
139
|
+
get_hooks(hook_name).each do |hook|
|
140
|
+
statuses = hook.call(statuses, event)
|
141
|
+
end
|
142
|
+
statuses
|
124
143
|
end
|
125
144
|
|
126
145
|
# return last hook return value
|
@@ -133,12 +152,13 @@ module Termtter
|
|
133
152
|
result
|
134
153
|
end
|
135
154
|
|
136
|
-
def call_commands(text
|
155
|
+
def call_commands(text)
|
137
156
|
return if text.empty?
|
138
157
|
|
139
|
-
|
140
|
-
|
141
|
-
|
158
|
+
commands = find_commands(text)
|
159
|
+
raise CommandNotFound, text if commands.empty?
|
160
|
+
|
161
|
+
commands.each do |command|
|
142
162
|
command_found = true
|
143
163
|
command_str, command_arg = Command.split_command_line(text)
|
144
164
|
|
@@ -159,8 +179,10 @@ module Termtter
|
|
159
179
|
end
|
160
180
|
end
|
161
181
|
end
|
182
|
+
end
|
162
183
|
|
163
|
-
|
184
|
+
def find_commands(text)
|
185
|
+
@commands.values.select { |command| command.match?(text) }
|
164
186
|
end
|
165
187
|
|
166
188
|
def pause
|
@@ -183,11 +205,6 @@ module Termtter
|
|
183
205
|
@input_thread.kill if @input_thread
|
184
206
|
end
|
185
207
|
|
186
|
-
def load_default_plugins
|
187
|
-
plugin 'standard_plugins'
|
188
|
-
plugin 'stdout'
|
189
|
-
end
|
190
|
-
|
191
208
|
def load_config
|
192
209
|
legacy_config_support() if File.exist? Termtter::CONF_DIR
|
193
210
|
unless File.exist?(Termtter::CONF_FILE)
|
@@ -216,12 +233,6 @@ module Termtter
|
|
216
233
|
Termtter::CONF_FILE)
|
217
234
|
end
|
218
235
|
|
219
|
-
def post_config_load()
|
220
|
-
if config.devel
|
221
|
-
plugin 'devel'
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
236
|
def setup_readline
|
226
237
|
if Readline.respond_to?(:basic_word_break_characters=)
|
227
238
|
Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
|
@@ -303,12 +314,28 @@ module Termtter
|
|
303
314
|
logger
|
304
315
|
end
|
305
316
|
|
317
|
+
def init(&block)
|
318
|
+
@init_block = block
|
319
|
+
end
|
320
|
+
|
306
321
|
def run
|
307
|
-
load_default_plugins()
|
308
322
|
load_config()
|
309
323
|
Termtter::API.setup()
|
310
324
|
setup_logger()
|
311
|
-
|
325
|
+
|
326
|
+
@init_block.call(self) if @init_block
|
327
|
+
|
328
|
+
unless @init_block # compatibility for old style config file
|
329
|
+
plug 'stdout'
|
330
|
+
plug 'standard_commands'
|
331
|
+
plug 'auto_reload'
|
332
|
+
end
|
333
|
+
|
334
|
+
plug 'devel' if config.devel
|
335
|
+
|
336
|
+
config.system.load_plugins.each do |plugin|
|
337
|
+
plug plugin
|
338
|
+
end
|
312
339
|
|
313
340
|
config.system.eval_scripts.each do |script|
|
314
341
|
begin
|
@@ -322,7 +349,6 @@ module Termtter
|
|
322
349
|
|
323
350
|
unless config.system.cmd_mode
|
324
351
|
call_hooks(:initialize)
|
325
|
-
plugin('update_timeline')
|
326
352
|
@task_manager.run()
|
327
353
|
start_input_thread()
|
328
354
|
end
|
@@ -343,5 +369,3 @@ module Termtter
|
|
343
369
|
end
|
344
370
|
end
|
345
371
|
end
|
346
|
-
|
347
|
-
Termtter::Client.init
|
@@ -1,36 +1,28 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'erb'
|
4
|
+
|
3
5
|
module Termtter
|
4
6
|
module ConfigSetup
|
5
7
|
module_function
|
6
8
|
def run
|
7
9
|
ui = create_highline
|
8
|
-
|
10
|
+
user_name = ui.ask('your twitter user name: ')
|
9
11
|
password = ui.ask('your twitter password: ') { |q| q.echo = false }
|
10
12
|
|
13
|
+
plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
|
14
|
+
f.match(%r|lib/plugins/(.*?).rb$|)[1]
|
15
|
+
}
|
16
|
+
standard_plugins = %w[stdout standard_commands auto_reload]
|
17
|
+
|
18
|
+
template = open(File.dirname(__FILE__) + '/config_template.erb').read
|
19
|
+
config = ERB.new(template, nil, '-').result(binding) # trim_mode => '-'
|
20
|
+
|
11
21
|
Dir.mkdir(Termtter::CONF_DIR) unless File.exists?(Termtter::CONF_DIR)
|
12
22
|
File.open(Termtter::CONF_FILE, 'w') {|io|
|
13
|
-
io
|
14
|
-
|
15
|
-
io.puts
|
16
|
-
io.puts "config.user_name = '#{username}'"
|
17
|
-
io.puts "config.password = '#{password}'"
|
18
|
-
io.puts "#config.update_interval = 120"
|
19
|
-
io.puts "#config.proxy.host = 'proxy host'"
|
20
|
-
io.puts "#config.proxy.port = '8080'"
|
21
|
-
io.puts "#config.proxy.user_name = 'proxy user'"
|
22
|
-
io.puts "#config.proxy.password = 'proxy password'"
|
23
|
-
io.puts
|
24
|
-
plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
|
25
|
-
f.match(%r|lib/plugins/(.*?).rb$|)[1]
|
26
|
-
}
|
27
|
-
plugins -= %w[stdout standard_plugins]
|
28
|
-
plugins.each do |p|
|
29
|
-
io.puts "#plugin '#{p}'"
|
30
|
-
end
|
31
|
-
io.puts
|
32
|
-
io.puts "# vim: set filetype=ruby"
|
23
|
+
io << config
|
33
24
|
}
|
25
|
+
|
34
26
|
puts "generated: ~/.termtter/config"
|
35
27
|
puts "enjoy!"
|
36
28
|
end
|
data/lib/termtter/optparse.rb
CHANGED
@@ -23,6 +23,11 @@ OptionParser.new { |opt|
|
|
23
23
|
config.system.run_commands << cmd
|
24
24
|
end
|
25
25
|
|
26
|
+
config.system.load_plugins = []
|
27
|
+
opt.on('-p', '--plugin plugin', 'Load plugin') do |plugin|
|
28
|
+
config.system.load_plugins << plugin
|
29
|
+
end
|
30
|
+
|
26
31
|
config.system.eval_scripts = []
|
27
32
|
opt.on('-e', '--eval-script script', 'Eval script') do |script|
|
28
33
|
config.system.eval_scripts << script
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
def plugin(name, init = {})
|
4
|
+
warn "plugin method will be removed. Use Termtter::Client.plug instead."
|
4
5
|
unless init.empty?
|
5
6
|
init.each do |key, value|
|
6
7
|
config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
|
@@ -43,7 +44,7 @@ module Readline
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def win?
|
46
|
-
RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/
|
47
|
+
RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin|cygwin/
|
47
48
|
end
|
48
49
|
|
49
50
|
if win?
|
@@ -149,13 +150,9 @@ require 'highline'
|
|
149
150
|
def create_highline
|
150
151
|
HighLine.track_eof = false
|
151
152
|
if $stdin.respond_to?(:getbyte) # for ruby1.9
|
152
|
-
|
153
|
-
stdin_for_highline = SimpleDelegator.new($stdin)
|
154
|
-
def stdin_for_highline.getc
|
153
|
+
def $stdin.getc
|
155
154
|
getbyte
|
156
155
|
end
|
157
|
-
else
|
158
|
-
stdin_for_highline = $stdin
|
159
156
|
end
|
160
|
-
HighLine.new(
|
157
|
+
HighLine.new($stdin)
|
161
158
|
end
|
data/lib/termtter/version.rb
CHANGED
@@ -6,8 +6,11 @@ module Termtter
|
|
6
6
|
|
7
7
|
describe Client do
|
8
8
|
|
9
|
-
|
9
|
+
before do
|
10
10
|
Client.setup_logger
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should take command' do
|
11
14
|
command = Command.new(:name => :test)
|
12
15
|
Client.register_command(command)
|
13
16
|
Client.get_command(:test).should == command
|
@@ -30,7 +33,7 @@ module Termtter
|
|
30
33
|
['test foo bar ', 'foo bar'],
|
31
34
|
['test foo bar ', 'foo bar'],
|
32
35
|
].each do |input, args|
|
33
|
-
Client.call_commands(input
|
36
|
+
Client.call_commands(input)
|
34
37
|
command_arg.should == args
|
35
38
|
end
|
36
39
|
end
|
@@ -177,10 +180,8 @@ module Termtter
|
|
177
180
|
end
|
178
181
|
|
179
182
|
it 'run' do
|
180
|
-
Client.should_receive(:load_default_plugins)
|
181
183
|
Client.should_receive(:load_config)
|
182
184
|
Termtter::API.should_receive(:setup)
|
183
|
-
Client.should_receive(:post_config_load)
|
184
185
|
Client.should_receive(:start_input_thread)
|
185
186
|
Client.run
|
186
187
|
end
|
@@ -249,5 +250,38 @@ module Termtter
|
|
249
250
|
$stdout.string.should match(/foo USER/)
|
250
251
|
$stdout.string.should match(/foo list/)
|
251
252
|
end
|
253
|
+
|
254
|
+
describe 'add commands' do
|
255
|
+
before(:each) do
|
256
|
+
Client.clear_command
|
257
|
+
Client.register_command(:name => :foo1)
|
258
|
+
Client.register_command(:name => :foo2)
|
259
|
+
Client.register_command(:name => :bar)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'commands number is 3' do
|
263
|
+
Client.commands.size.should == 3
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should find a command' do
|
267
|
+
Client.find_commands('foo1').size.should == 1
|
268
|
+
Client.find_commands('foo1')[0].name.should == :foo1
|
269
|
+
Client.find_commands('bar').size.should == 1
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should find no command' do
|
273
|
+
Client.find_commands('foo').size.should == 0
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe 'clear commands' do
|
278
|
+
before(:each) do
|
279
|
+
Client.clear_command
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should no command' do
|
283
|
+
Client.commands.size.should == 0
|
284
|
+
end
|
285
|
+
end
|
252
286
|
end
|
253
287
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jugyo-termtter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jugyo
|
@@ -66,6 +66,7 @@ extra_rdoc_files:
|
|
66
66
|
files:
|
67
67
|
- lib/plugins/addspace.rb
|
68
68
|
- lib/plugins/april_fool.rb
|
69
|
+
- lib/plugins/auto_reload.rb
|
69
70
|
- lib/plugins/bomb.rb
|
70
71
|
- lib/plugins/clear.rb
|
71
72
|
- lib/plugins/command_plus.rb
|
@@ -92,12 +93,15 @@ files:
|
|
92
93
|
- lib/plugins/hatebu_and_update.rb
|
93
94
|
- lib/plugins/history.rb
|
94
95
|
- lib/plugins/ignore.rb
|
96
|
+
- lib/plugins/irc_gw.rb
|
95
97
|
- lib/plugins/keyword.rb
|
96
98
|
- lib/plugins/l2.rb
|
99
|
+
- lib/plugins/list_with_opts.rb
|
97
100
|
- lib/plugins/log.rb
|
98
101
|
- lib/plugins/me.rb
|
99
102
|
- lib/plugins/modify_arg_hook_sample.rb
|
100
103
|
- lib/plugins/msagent.rb
|
104
|
+
- lib/plugins/multi_post.rb
|
101
105
|
- lib/plugins/multi_reply.rb
|
102
106
|
- lib/plugins/notify-send.rb
|
103
107
|
- lib/plugins/notify-send2.rb
|
@@ -124,7 +128,7 @@ files:
|
|
124
128
|
- lib/plugins/shell.rb
|
125
129
|
- lib/plugins/sl.rb
|
126
130
|
- lib/plugins/spam.rb
|
127
|
-
- lib/plugins/
|
131
|
+
- lib/plugins/standard_commands.rb
|
128
132
|
- lib/plugins/stdout.rb
|
129
133
|
- lib/plugins/storage/DB.rb
|
130
134
|
- lib/plugins/storage/status.rb
|
@@ -137,8 +141,8 @@ files:
|
|
137
141
|
- lib/plugins/translation.rb
|
138
142
|
- lib/plugins/typable_id.rb
|
139
143
|
- lib/plugins/update_editor.rb
|
140
|
-
- lib/plugins/update_timeline.rb
|
141
144
|
- lib/plugins/uri-open.rb
|
145
|
+
- lib/plugins/wassr.rb
|
142
146
|
- lib/plugins/wassr_post.rb
|
143
147
|
- lib/plugins/yhara.rb
|
144
148
|
- lib/plugins/yhara_filter.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module Termtter::Client
|
3
|
-
register_command(
|
4
|
-
:name => :_update_timeline,
|
5
|
-
:exec_proc => lambda {|arg|
|
6
|
-
begin
|
7
|
-
args = @since_id ? [{:since_id => @since_id}] : []
|
8
|
-
statuses = Termtter::API.twitter.friends_timeline(*args)
|
9
|
-
unless statuses.empty?
|
10
|
-
print "\e[1K\e[0G" unless win?
|
11
|
-
@since_id = statuses[0].id
|
12
|
-
output(statuses, :update_friends_timeline)
|
13
|
-
Readline.refresh_line
|
14
|
-
end
|
15
|
-
rescue OpenURI::HTTPError => e
|
16
|
-
if e.message == '401 Unauthorized'
|
17
|
-
puts 'Could not login'
|
18
|
-
puts 'plese check your account settings'
|
19
|
-
exit!
|
20
|
-
end
|
21
|
-
rescue => e
|
22
|
-
handle_error(e)
|
23
|
-
end
|
24
|
-
}
|
25
|
-
)
|
26
|
-
|
27
|
-
add_task(:name => :update_timeline, :interval => config.update_interval, :after => config.update_interval) do
|
28
|
-
call_commands('_update_timeline')
|
29
|
-
end
|
30
|
-
|
31
|
-
call_commands('_update_timeline')
|
32
|
-
end
|