termtter 1.8.0 → 1.9.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/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/plugins/aa.rb +1 -1
- data/lib/plugins/appendtitle.rb +5 -12
- data/lib/plugins/defaults/auto_reload.rb +1 -0
- data/lib/plugins/defaults/cache.rb +18 -0
- data/lib/plugins/defaults/command_line.rb +1 -1
- data/lib/plugins/defaults/fib.rb +15 -6
- data/lib/plugins/defaults/retweet.rb +1 -1
- data/lib/plugins/defaults/standard_commands.rb +31 -25
- data/lib/plugins/defaults/stdout.rb +12 -4
- data/lib/plugins/defaults/system.rb +27 -0
- data/lib/plugins/dupu.rb +13 -0
- data/lib/plugins/erase.rb +4 -0
- data/lib/plugins/error_log.rb +17 -0
- data/lib/plugins/expand-tinyurl.rb +8 -1
- data/lib/plugins/growl.rb +10 -7
- data/lib/plugins/hatena_keyword_haiku.rb +88 -0
- data/lib/plugins/irc_gw.rb +12 -4
- data/lib/plugins/itunes.rb +29 -26
- data/lib/plugins/mecab.rb +23 -0
- data/lib/plugins/mudan_kinshi.rb +13 -0
- data/lib/plugins/ndkn.rb +7 -0
- data/lib/plugins/other_user.rb +47 -0
- data/lib/plugins/reply_sound.rb +75 -25
- data/lib/plugins/ruby-v.rb +10 -0
- data/lib/plugins/time_signal.rb +21 -0
- data/lib/plugins/tinyurl.rb +6 -4
- data/lib/plugins/train.rb +1 -1
- data/lib/plugins/translation.rb +2 -0
- data/lib/plugins/user_stream.rb +122 -0
- data/lib/plugins/whale.rb +28 -0
- data/lib/termtter/active_rubytter.rb +4 -0
- data/lib/termtter/api.rb +55 -30
- data/lib/termtter/client.rb +19 -4
- data/lib/termtter/config_setup.rb +10 -2
- data/lib/termtter/config_template.erb +4 -2
- data/lib/termtter/crypt.rb +13 -0
- data/lib/termtter/default_config.rb +5 -2
- data/lib/termtter/hookable.rb +4 -0
- data/lib/termtter/memory_cache.rb +67 -19
- data/lib/termtter/rubytter_proxy.rb +101 -26
- data/lib/termtter/system_extensions.rb +22 -18
- data/lib/termtter.rb +5 -1
- data/spec/termtter/crypt_spec.rb +16 -0
- data/spec/termtter/rubytter_proxy_spec.rb +14 -0
- metadata +85 -26
@@ -0,0 +1,13 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# http://twitter.com/ototorosama/status/14283311303
|
3
|
+
|
4
|
+
Termtter::Client.register_hook(
|
5
|
+
:name => :mudan_kinshi,
|
6
|
+
:author => 'Sora Harakami',
|
7
|
+
:point => :pre_coloring,
|
8
|
+
:exec => lambda {|r,e|
|
9
|
+
r.gsub(/無断(.+?)禁止/) {|s|
|
10
|
+
"か、勝手に#{$1}しないでよね!! ...バカ....."
|
11
|
+
}
|
12
|
+
}
|
13
|
+
)
|
data/lib/plugins/ndkn.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
config.plugins.other_user.set_default(:accounts,{})
|
4
|
+
config.plugins.other_user.set_default(:tokens_file,"~/.termtter/other_user_tokens")
|
5
|
+
config.plugins.other_user.set_default(:alias,{})
|
6
|
+
|
7
|
+
Termtter::Client.register_command(
|
8
|
+
:name => :other_user,
|
9
|
+
:alias => :o,
|
10
|
+
:help => ['other_user, o','Post by other user'],
|
11
|
+
:exec => lambda do |arg_raw|
|
12
|
+
tokens =
|
13
|
+
if File.exist?(File.expand_path(config.plugins.other_user.tokens_file))
|
14
|
+
Marshal.load(
|
15
|
+
Base64.decode64(File.read(File.expand_path(
|
16
|
+
config.plugins.other_user.tokens_file))))
|
17
|
+
else
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
|
21
|
+
body = arg_raw.split(/ /)
|
22
|
+
user_raw = body.shift
|
23
|
+
user = config.plugins.other_user.alias[user_raw] || user_raw
|
24
|
+
|
25
|
+
unless tokens[user]
|
26
|
+
puts "<on_red>ERROR</on_red> #{user} isn't authorized yet. Starting authorization...".termcolor
|
27
|
+
tokens[user] = Termtter::API.authorize_by_oauth(false,false,false)
|
28
|
+
open(File.expand_path(config.plugins.other_user.tokens_file), 'w') do |f|
|
29
|
+
f.print Base64.encode64(Marshal.dump(tokens))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
at = OAuth::AccessToken.new(
|
34
|
+
OAuth::Consumer.new(
|
35
|
+
Termtter::Crypt.decrypt(Termtter::CONSUMER_KEY),
|
36
|
+
Termtter::Crypt.decrypt(Termtter::CONSUMER_SECRET),
|
37
|
+
:site => "http://twitter.com/",
|
38
|
+
:proxy => ENV['http_proxy']),
|
39
|
+
tokens[user][:token],
|
40
|
+
tokens[user][:secret])
|
41
|
+
|
42
|
+
t = OAuthRubytter.new(at, Termtter::API.twitter_option)
|
43
|
+
t.update(body.join(' '))
|
44
|
+
|
45
|
+
puts "updated by #{user} => #{body.join(' ')}"
|
46
|
+
end
|
47
|
+
)
|
data/lib/plugins/reply_sound.rb
CHANGED
@@ -1,33 +1,83 @@
|
|
1
1
|
#-*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
|
3
|
+
config.plugins.reply_sound.set_default(:interval, 600)
|
4
4
|
|
5
|
-
|
6
|
-
config.plugins.reply_sound.set_default(:interval, 600)
|
7
|
-
config.plugins.reply_sound.set_default(
|
8
|
-
:sound_file, '/System/Library/Sounds/Hero.aiff')
|
5
|
+
nul_port = /mswin/i =~ RUBY_PLATFORM ? "NUL" : "/dev/null"
|
9
6
|
|
10
|
-
|
11
|
-
|
7
|
+
reply_sound_cache = nil
|
8
|
+
reply_sound_cache_ids = []
|
9
|
+
not_supported = false
|
10
|
+
cmd_ok = false
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
|
13
|
+
Termtter::Client.register_hook(
|
14
|
+
:name => :reply_sound_initialization,
|
15
|
+
:point => :initialize,
|
16
|
+
:exec => lambda do
|
17
|
+
case RUBY_PLATFORM
|
18
|
+
when /darwin/i
|
19
|
+
config.plugins.reply_sound.set_default(
|
20
|
+
:sound_file, '/System/Library/Sounds/Hero.aiff')
|
21
|
+
config.plugins.reply_sound.set_default(
|
22
|
+
:command, ['afplay', config.plugins.reply_sound.sound_file, {:out => nul_port, :err => nul_port}])
|
23
|
+
cmd_ok = true
|
24
|
+
when /linux/i
|
25
|
+
case `uname -v`.chomp
|
26
|
+
when /ubuntu/i
|
27
|
+
config.plugins.reply_sound.set_default(
|
28
|
+
:sound_file, '/usr/share/sounds/gnome/default/alerts/drip.ogg')
|
21
29
|
else
|
22
|
-
|
30
|
+
config.plugins.reply_sound.set_default(
|
31
|
+
:sound_file, '')
|
32
|
+
end
|
33
|
+
else
|
34
|
+
not_supported = true
|
35
|
+
puts TermColor.parse(
|
36
|
+
"<red>WARNING: Currently reply_sound plugin is not supported yet in your environment.</red>")
|
37
|
+
end
|
38
|
+
|
39
|
+
unless cmd_ok
|
40
|
+
begin
|
41
|
+
if /mplayer/i =~ `mplayer -v`.chomp
|
42
|
+
config.plugins.reply_sound.set_default(
|
43
|
+
:command, ['mplayer', config.plugins.reply_sound.sound_file, :out => nul_port, :err => nul_port])
|
44
|
+
cmd_ok = true
|
45
|
+
not_supported = false
|
46
|
+
end
|
47
|
+
rescue Errno::ENOENT
|
23
48
|
end
|
24
|
-
Termtter::Client.output(
|
25
|
-
new_replies, Termtter::Event.new(:new_replies,:type => :reply))
|
26
49
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
50
|
+
|
51
|
+
unless not_supported
|
52
|
+
Termtter::Client.add_task(
|
53
|
+
:name => :reply_sound_wait,
|
54
|
+
:interval => 10) do
|
55
|
+
Termtter::Client.add_task(
|
56
|
+
:name => :reply_sound,
|
57
|
+
:interval => config.plugins.reply_sound.interval) do
|
58
|
+
cmd = config.plugins.reply_sound.command.kind_of?(Array) ?
|
59
|
+
config.plugins.reply_sound.command : [config.plugins.reply_sound.command]
|
60
|
+
replies = Termtter::API.twitter.replies
|
61
|
+
new_replies = replies.delete_if {|x| reply_sound_cache_ids.index(x[:id]) }
|
62
|
+
if !reply_sound_cache.nil? && new_replies.size > 0
|
63
|
+
if respond_to? :spawn, true
|
64
|
+
if respond_to? :fork, true
|
65
|
+
fork { exec *cmd }
|
66
|
+
else
|
67
|
+
system *cmd
|
68
|
+
end
|
69
|
+
else
|
70
|
+
spawn *cmd
|
71
|
+
end
|
72
|
+
print "\e[0G" + "\e[K" unless win?
|
73
|
+
Termtter::Client.output(
|
74
|
+
new_replies, Termtter::Event.new(:new_replies,:type => :reply))
|
75
|
+
Readline.refresh_line
|
76
|
+
end
|
77
|
+
reply_sound_cache = replies
|
78
|
+
reply_sound_cache_ids += replies.map {|x| x[:id]}
|
79
|
+
end
|
80
|
+
Termtter::Client.delete_task(:reply_sound_wait)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Termtter::Client
|
2
|
+
register_command(
|
3
|
+
:name => 'ruby-v',
|
4
|
+
:author => 'ujihisa',
|
5
|
+
:help => ["ruby-v", "Post the Ruby version you are using"],
|
6
|
+
:exec_proc => lambda {|_|
|
7
|
+
result = Termtter::API.twitter.update("#{RUBY_DESCRIPTION} #termtterrubyversion")
|
8
|
+
puts "=> " << result.text
|
9
|
+
})
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
config.plugins.time_signal.set_default(:minutes, [0])
|
2
|
+
|
3
|
+
last_signal_time = nil
|
4
|
+
|
5
|
+
Termtter::Client.add_task(:name => :time_signal, :interval => 10) do
|
6
|
+
begin
|
7
|
+
now = Time.now
|
8
|
+
if config.plugins.time_signal.minutes.include?(now.min)
|
9
|
+
hour = now.strftime('%H:%M')
|
10
|
+
unless hour == last_signal_time
|
11
|
+
print "\e[0G\e[2K"
|
12
|
+
puts "<on_green> #{hour} </on_green>".termcolor
|
13
|
+
Termtter::Client.notify 'time signal', hour
|
14
|
+
Readline.refresh_line
|
15
|
+
last_signal_time = hour
|
16
|
+
end
|
17
|
+
end
|
18
|
+
rescue Exception => e
|
19
|
+
Termtter::Client.handle_error(e)
|
20
|
+
end
|
21
|
+
end
|
data/lib/plugins/tinyurl.rb
CHANGED
@@ -10,11 +10,14 @@ config.plugins.tinyurl.set_default(:ignore_regexp, %r{
|
|
10
10
|
\Ahttp://bit\.ly/ | \Ahttp://tinyurl\.com/ | \Ahttp://is\.gd/
|
11
11
|
| \Ahttp://ff\.im/ | \Ahttp://j\.mp/ | \Ahttp://goo\.gl/
|
12
12
|
| \Ahttp://tr\.im/ | \Ahttp://short\.to/ | \Ahttp://ow\.ly/
|
13
|
-
| \Ahttp://u\.nu/ | \Ahttp://twurl\.nl/
|
13
|
+
| \Ahttp://u\.nu/ | \Ahttp://twurl\.nl/ | \Ahttp://icio\.us/
|
14
|
+
| \Ahttp://htn\.to/ | \Ahttp://cot\.ag/ | \Ahttp://ht\.ly/ | \Ahttp://p\.tl/
|
15
|
+
| \Ahttp://url4\.eu/ | |Ahttp://t\.co/
|
14
16
|
}x )
|
15
17
|
config.plugins.tinyurl.set_default(:tinyurl_hook_commands, [:update, :reply, :retweet])
|
16
|
-
config.plugins.tinyurl.set_default(
|
17
|
-
|
18
|
+
config.plugins.tinyurl.set_default(
|
19
|
+
:uri_regexp,
|
20
|
+
/#{URI.regexp(%w(http https ftp))}\S*/ )
|
18
21
|
|
19
22
|
module Termtter::Client
|
20
23
|
register_hook(
|
@@ -53,7 +56,6 @@ module Termtter::Client
|
|
53
56
|
nil
|
54
57
|
end
|
55
58
|
end
|
56
|
-
|
57
59
|
end
|
58
60
|
|
59
61
|
# tinyuri.rb
|
data/lib/plugins/train.rb
CHANGED
data/lib/plugins/translation.rb
CHANGED
@@ -6,6 +6,8 @@ require 'kconv'
|
|
6
6
|
require 'uri'
|
7
7
|
|
8
8
|
def translate(text, langpair)
|
9
|
+
text = Termtter::API.twitter.show(text)[:text] if /^\d+$/ =~ text
|
10
|
+
|
9
11
|
req = Net::HTTP::Post.new('/translate_t')
|
10
12
|
req.add_field('Content-Type', 'application/x-www-form-urlencoded')
|
11
13
|
req.add_field('User-Agent', 'Mozilla/5.0')
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Termtter::Client
|
2
|
+
register_command(:"user_stream stop", :help => 'user_stream stop') do |arg|
|
3
|
+
logger.info 'stopping user stream'
|
4
|
+
if @user_stream_thread
|
5
|
+
@user_stream_thread.exit
|
6
|
+
end
|
7
|
+
@user_stream_thread = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
handle_chunk = lambda { |chunk|
|
11
|
+
data = Termtter::ActiveRubytter.new(JSON.parse(chunk)) rescue return
|
12
|
+
Termtter::Client.logger.debug "user_stream: received #{JSON.parse(chunk).inspect}"
|
13
|
+
begin
|
14
|
+
if data[:event]
|
15
|
+
if /list_/ =~ data[:event]
|
16
|
+
typable_id = Termtter::Client.data_to_typable_id(data.target.id)
|
17
|
+
puts "[%s] %s %s %s to %s]" %
|
18
|
+
[typable_id, data.source.screen_name, data.event, data.target.screen_name, data.target_object.uri]
|
19
|
+
return
|
20
|
+
end
|
21
|
+
if data[:target_object]
|
22
|
+
# target_object is status
|
23
|
+
source_user = data.source
|
24
|
+
status = data.target_object
|
25
|
+
typable_id = Termtter::Client.data_to_typable_id(status.id)
|
26
|
+
puts "[#{typable_id}] #{source_user.screen_name} #{data.event} #{status.user.screen_name}: #{status.text}"
|
27
|
+
else
|
28
|
+
# target is user
|
29
|
+
source_user = data.source
|
30
|
+
target_user = data.target
|
31
|
+
typable_id = Termtter::Client.data_to_typable_id(target_user.id)
|
32
|
+
puts "[#{typable_id}] #{source_user.screen_name} #{data.event} #{target_user.screen_name}"
|
33
|
+
end
|
34
|
+
elsif data[:friends]
|
35
|
+
puts "You have #{data[:friends].length} friends."
|
36
|
+
elsif data[:delete]
|
37
|
+
status = Termtter::API.twitter.safe.show(data.delete.status.id)
|
38
|
+
puts "#{status.user.screen_name} deleted: #{status.text}"
|
39
|
+
else
|
40
|
+
output([data], Termtter::Event.new(:update_friends_timeline, :type => :main))
|
41
|
+
Termtter::API.twitter.store_status_cache(data)
|
42
|
+
end
|
43
|
+
rescue Termtter::RubytterProxy::FrequentAccessError
|
44
|
+
# ignore
|
45
|
+
rescue Timeout::Error, StandardError => error
|
46
|
+
new_error = error.class.new("#{error.message} (#{JSON.parse(chunk).inspect})")
|
47
|
+
error.instance_variables.each{ |v|
|
48
|
+
new_error.instance_variable_set(v, error.instance_variable_get(v))
|
49
|
+
}
|
50
|
+
handle_error new_error
|
51
|
+
end
|
52
|
+
}
|
53
|
+
|
54
|
+
register_command(:"user_stream", :help => 'user_stream') do |arg|
|
55
|
+
unless config.password.kind_of? String
|
56
|
+
raise "config.password is required."
|
57
|
+
end
|
58
|
+
|
59
|
+
uri = URI.parse('http://betastream.twitter.com/2b/user.json')
|
60
|
+
|
61
|
+
unless @user_stream_thread
|
62
|
+
logger.info 'checking API status'
|
63
|
+
1.times{ # to use break
|
64
|
+
Net::HTTP.start(uri.host, uri.port){ |http|
|
65
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
66
|
+
request.basic_auth(config.user_name, config.password)
|
67
|
+
http.request(request){ |response|
|
68
|
+
raise response.code.to_i unless response.code.to_i == 200
|
69
|
+
break
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
logger.info 'API seems working'
|
74
|
+
end
|
75
|
+
|
76
|
+
execute('user_stream stop') if @user_stream_thread
|
77
|
+
delete_task(:auto_reload)
|
78
|
+
|
79
|
+
@user_stream_thread = Thread.new {
|
80
|
+
loop do
|
81
|
+
begin
|
82
|
+
logger.info 'connecting to user stream'
|
83
|
+
Net::HTTP.start(uri.host, uri.port){ |http|
|
84
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
85
|
+
request.basic_auth(config.user_name, config.password)
|
86
|
+
http.request(request){ |response|
|
87
|
+
raise response.code.to_i unless response.code.to_i == 200
|
88
|
+
raise 'Response is not chuncked' unless response.chunked?
|
89
|
+
response.read_body{ |chunk|
|
90
|
+
handle_chunk.call(chunk)
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
rescue Timeout::Error, StandardError => e
|
95
|
+
handle_error e
|
96
|
+
logger.info 'sleeping'
|
97
|
+
sleep 10
|
98
|
+
end
|
99
|
+
end
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
register_hook(
|
104
|
+
:name => :user_stream_init,
|
105
|
+
:author => '?', # FIXME
|
106
|
+
:point => :initialize,
|
107
|
+
:exec => lambda {
|
108
|
+
execute('user_stream')
|
109
|
+
})
|
110
|
+
end
|
111
|
+
|
112
|
+
# user_stream.rb
|
113
|
+
#
|
114
|
+
# to use,
|
115
|
+
# > plug user_stream
|
116
|
+
# > user_stream
|
117
|
+
#
|
118
|
+
# to stop,
|
119
|
+
# > user_stream stop
|
120
|
+
#
|
121
|
+
# Specification
|
122
|
+
# http://apiwiki.twitter.com/ChirpUserStreams
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter
|
3
|
+
class RubytterProxy
|
4
|
+
alias_method :error_html_message_orig, :error_html_message
|
5
|
+
|
6
|
+
def error_html_message_whale(e)
|
7
|
+
if %r'Twitter / Over capacity' =~ e.message
|
8
|
+
WHALE
|
9
|
+
else
|
10
|
+
error_html_message_orig(e)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :error_html_message, :error_html_message_whale
|
15
|
+
end
|
16
|
+
|
17
|
+
# first blank line is to skip prompt.
|
18
|
+
WHALE = <<'__WHALE__'
|
19
|
+
|
20
|
+
,......-..-—‐—--..r、_ ,r:, Twitter / Over capacity
|
21
|
+
ヾー-゚、 :::::::::::::::::::::::::_ ̄ニ、く
|
22
|
+
゙`ー-`ー'-ー'" ̄ `'
|
23
|
+
__WHALE__
|
24
|
+
end
|
25
|
+
|
26
|
+
# whale.rb:
|
27
|
+
# print whale when twitter is over capacity.
|
28
|
+
# ASCII-Art from http://bhdaamov.hp.infoseek.co.jp/zukan/fish.html#kuji
|
data/lib/termtter/api.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
config.set_default(:host, 'twitter.com')
|
3
|
+
config.set_default(:host, 'api.twitter.com')
|
4
|
+
config.set_default(:oauth_consumer_site, 'http://api.twitter.com')
|
4
5
|
if ENV.has_key?('HTTP_PROXY')
|
5
6
|
require 'uri'
|
6
7
|
proxy = ENV['HTTP_PROXY']
|
@@ -30,47 +31,71 @@ module Termtter
|
|
30
31
|
class << self
|
31
32
|
attr_reader :connection, :twitter
|
32
33
|
def setup
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
puts TermColor.parse("<red>Time out :(</red>")
|
43
|
-
exit!
|
34
|
+
# NOTE: for compatible
|
35
|
+
@connection = twitter.instance_variable_get(:@connection)
|
36
|
+
if config.access_token.empty? || config.access_token_secret.empty?
|
37
|
+
if config.token_file &&
|
38
|
+
File.exist?(File.expand_path(config.token_file))
|
39
|
+
config.access_token, config.access_token_secret = File.read(File.expand_path(config.token_file)) \
|
40
|
+
.split(/\r?\n/).map(&:chomp)
|
41
|
+
else
|
42
|
+
self.authorize_by_oauth(true)
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
|
-
|
46
|
+
access_token = OAuth::AccessToken.new(consumer, config.access_token, config.access_token_secret)
|
47
|
+
@twitter = RubytterProxy.new(access_token, twitter_option)
|
48
|
+
|
49
|
+
config.user_name = @twitter.verify_credentials[:screen_name]
|
48
50
|
end
|
51
|
+
|
52
|
+
def authorize_by_oauth(show_information=false, save_to_token_file=true, put_to_config=true, verbose=true)
|
53
|
+
puts '1. Contacting to twitter...' if verbose
|
54
|
+
|
55
|
+
request_token = consumer.get_request_token
|
56
|
+
|
57
|
+
puts '2. URL for authorize: ' + request_token.authorize_url if verbose
|
58
|
+
puts ' Opening web page to authorization...' if verbose
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
60
|
+
begin
|
61
|
+
open_browser(request_token.authorize_url)
|
62
|
+
rescue BrowserNotFound
|
63
|
+
puts "Browser not found. Please log in and/or grant access to get PIN via your browser at #{request_token.authorize_url}"
|
53
64
|
end
|
65
|
+
sleep 2
|
54
66
|
|
55
67
|
ui = create_highline
|
68
|
+
pin = ui.ask('3. Enter PIN: ')
|
69
|
+
puts ""
|
70
|
+
puts "4. Getting access_token..."
|
71
|
+
access_token = request_token.get_access_token(:oauth_verifier => pin)
|
56
72
|
|
57
|
-
if
|
58
|
-
config.
|
59
|
-
|
60
|
-
puts "Username: #{config.user_name}"
|
61
|
-
end
|
62
|
-
if config.password.empty?
|
63
|
-
config.password = ui.ask('Password: ') { |q| q.echo = false}
|
73
|
+
if put_to_config
|
74
|
+
config.access_token = access_token.token
|
75
|
+
config.access_token_secret = access_token.secret
|
64
76
|
end
|
65
77
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
78
|
+
if save_to_token_file
|
79
|
+
puts "5. Saving to token file... (" + config.token_file + ")"
|
80
|
+
open(File.expand_path(config.token_file),"w") do |f|
|
81
|
+
f.puts access_token.token
|
82
|
+
f.puts access_token.secret
|
83
|
+
end
|
72
84
|
end
|
73
|
-
|
85
|
+
|
86
|
+
puts "Authorize is successfully done."
|
87
|
+
|
88
|
+
return {:token => access_token.token,
|
89
|
+
:secret => access_token.secret}
|
90
|
+
end
|
91
|
+
|
92
|
+
def consumer
|
93
|
+
@consumer ||= OAuth::Consumer.new(
|
94
|
+
Termtter::Crypt.decrypt(CONSUMER_KEY),
|
95
|
+
Termtter::Crypt.decrypt(CONSUMER_SECRET),
|
96
|
+
:site => config.oauth_consumer_site,
|
97
|
+
:proxy => ENV['http_proxy']
|
98
|
+
)
|
74
99
|
end
|
75
100
|
|
76
101
|
def twitter_option
|
data/lib/termtter/client.rb
CHANGED
@@ -17,7 +17,7 @@ module Termtter
|
|
17
17
|
Thread.abort_on_exception = true
|
18
18
|
|
19
19
|
class << self
|
20
|
-
attr_reader :commands
|
20
|
+
attr_reader :commands, :logger, :task_manager
|
21
21
|
|
22
22
|
# plug :: Name -> (Hash) -> IO () where NAME = String | Symbol | [NAME]
|
23
23
|
def plug(name, options = {})
|
@@ -30,8 +30,9 @@ module Termtter
|
|
30
30
|
|
31
31
|
return if config.system.disable_plugins.include?(name.gsub('defaults/', ''))
|
32
32
|
|
33
|
+
name_sym = name.gsub(/-/, '_').to_sym
|
33
34
|
options.each do |key, value|
|
34
|
-
config.plugins.__refer__(
|
35
|
+
config.plugins.__refer__(name_sym).__assign__(key.to_sym, value)
|
35
36
|
end
|
36
37
|
load "plugins/#{name}.rb"
|
37
38
|
rescue Exception => e
|
@@ -42,6 +43,10 @@ module Termtter
|
|
42
43
|
@public_storage ||= {}
|
43
44
|
end
|
44
45
|
|
46
|
+
def memory_cache
|
47
|
+
@memory_cache ||= Termtter::MemoryCache.new
|
48
|
+
end
|
49
|
+
|
45
50
|
def add_filter(&b)
|
46
51
|
warn "add_filter method will be removed. Use Termtter::Client.register_hook(:name => ..., :point => :filter_for_output, :exec => ... ) instead."
|
47
52
|
@filters << b
|
@@ -68,6 +73,10 @@ module Termtter
|
|
68
73
|
@commands[command.name] = command
|
69
74
|
end
|
70
75
|
|
76
|
+
def remove_command(name)
|
77
|
+
commands.delete(name.to_sym)
|
78
|
+
end
|
79
|
+
|
71
80
|
def add_command(name)
|
72
81
|
if block_given?
|
73
82
|
command = Command.new(:name => name)
|
@@ -206,6 +215,10 @@ module Termtter
|
|
206
215
|
@task_manager.add_task(*arg, &block)
|
207
216
|
end
|
208
217
|
|
218
|
+
def delete_task(name)
|
219
|
+
@task_manager.delete_task(name)
|
220
|
+
end
|
221
|
+
|
209
222
|
def exit
|
210
223
|
puts 'finalizing...'
|
211
224
|
call_hooks(:exit)
|
@@ -303,8 +316,8 @@ module Termtter
|
|
303
316
|
parse_options
|
304
317
|
config.__freeze__(:user_name) unless config.user_name.empty?
|
305
318
|
show_splash
|
306
|
-
load_config
|
307
319
|
setup_task_manager
|
320
|
+
load_config
|
308
321
|
load_plugins
|
309
322
|
eval_init_block
|
310
323
|
config.__unfreeze__(:user_name)
|
@@ -331,7 +344,9 @@ module Termtter
|
|
331
344
|
end
|
332
345
|
|
333
346
|
def handle_error(e)
|
334
|
-
|
347
|
+
message = e.message
|
348
|
+
message = message[0..29] + " ..." if message.size >= 30 && !config.devel
|
349
|
+
logger.error("#{e.class.to_s}: #{message}")
|
335
350
|
logger.error(e.backtrace.join("\n")) if (e.backtrace and config.devel)
|
336
351
|
get_hooks(:on_error).each {|hook| hook.call(e) }
|
337
352
|
end
|
@@ -5,9 +5,8 @@ require 'erb'
|
|
5
5
|
module Termtter
|
6
6
|
module ConfigSetup
|
7
7
|
module_function
|
8
|
+
|
8
9
|
def run
|
9
|
-
ui = create_highline
|
10
|
-
user_name = ui.ask('your twitter user name: ')
|
11
10
|
|
12
11
|
plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
|
13
12
|
f.match(%r|lib/plugins/(.*?).rb$|)[1]
|
@@ -23,6 +22,15 @@ module Termtter
|
|
23
22
|
}
|
24
23
|
|
25
24
|
puts "generated: ~/.termtter/config"
|
25
|
+
|
26
|
+
token_and_secret = Termtter::API.authorize_by_oauth
|
27
|
+
token = token_and_secret[:token]
|
28
|
+
secret = token_and_secret[:secret]
|
29
|
+
|
30
|
+
puts "Setup is all over. enjoy!"
|
31
|
+
rescue OAuth::Unauthorized
|
32
|
+
puts 'failed to authentication!'
|
33
|
+
exit!
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
# vim: filetype=ruby
|
3
|
+
|
4
|
+
config.token_file = "~/.termtter/token"
|
2
5
|
|
3
|
-
config.user_name = '<%= user_name %>'
|
4
6
|
#config.update_interval = 120
|
5
7
|
#config.timeout = 60
|
6
8
|
#config.retry = 3
|
@@ -10,7 +12,7 @@ config.user_name = '<%= user_name %>'
|
|
10
12
|
#config.proxy.user_name = 'proxy user'
|
11
13
|
#config.proxy.password = 'proxy password'
|
12
14
|
|
13
|
-
config.plugins.keyword.keywords = ["
|
15
|
+
#config.plugins.keyword.keywords = ["termtter"]
|
14
16
|
config.confirm = true
|
15
17
|
#config.plugins.stdout.colors = (31..36).to_a + (91..96).to_a
|
16
18
|
|