jugyo-termtter 0.8.14 → 1.0.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.
Files changed (115) hide show
  1. data/README.rdoc +8 -8
  2. data/Rakefile +3 -5
  3. data/lib/{plugin → plugins}/april_fool.rb +0 -0
  4. data/lib/plugins/bomb.rb +42 -0
  5. data/lib/{plugin → plugins}/clear.rb +0 -0
  6. data/lib/{plugin → plugins}/confirm.rb +0 -0
  7. data/lib/{plugin → plugins}/cool.rb +0 -0
  8. data/lib/{plugin → plugins}/devel.rb +0 -0
  9. data/lib/{filter → plugins}/en2ja.rb +1 -1
  10. data/lib/plugins/english.rb +25 -0
  11. data/lib/{plugin → plugins}/erb.rb +0 -0
  12. data/lib/{filter → plugins}/expand-tinyurl.rb +6 -6
  13. data/lib/plugins/favorite.rb +63 -0
  14. data/lib/plugins/fib.rb +28 -0
  15. data/lib/{filter/fib.rb → plugins/fib_filter.rb} +1 -2
  16. data/lib/{plugin → plugins}/filter.rb +0 -0
  17. data/lib/{plugin → plugins}/graduatter.rb +1 -2
  18. data/lib/{plugin → plugins}/grass.rb +2 -2
  19. data/lib/{plugin → plugins}/group.rb +9 -9
  20. data/lib/{plugin → plugins}/growl.rb +11 -12
  21. data/lib/{plugin → plugins}/hatebu.rb +5 -5
  22. data/lib/{plugin → plugins}/history.rb +13 -13
  23. data/lib/plugins/ignore.rb +19 -0
  24. data/lib/plugins/keyword.rb +18 -0
  25. data/lib/{plugin → plugins}/log.rb +18 -12
  26. data/lib/{plugin → plugins}/me.rb +1 -2
  27. data/lib/{plugin → plugins}/modify_arg_hook_sample.rb +0 -0
  28. data/lib/{plugin → plugins}/msagent.rb +1 -1
  29. data/lib/plugins/multi_reply.rb +27 -0
  30. data/lib/{plugin → plugins}/notify-send.rb +1 -1
  31. data/lib/{plugin → plugins}/otsune.rb +0 -0
  32. data/lib/plugins/outputz.rb +33 -0
  33. data/lib/{plugin → plugins}/pause.rb +0 -0
  34. data/lib/{plugin → plugins}/plugin.rb +0 -0
  35. data/lib/{plugin → plugins}/post_exec_hook_sample.rb +0 -0
  36. data/lib/{plugin → plugins}/pre_exec_hook_sample.rb +0 -0
  37. data/lib/{plugin → plugins}/primes.rb +9 -2
  38. data/lib/plugins/quicklook.rb +41 -0
  39. data/lib/{plugin → plugins}/random.rb +0 -0
  40. data/lib/{plugin → plugins}/reblog.rb +3 -3
  41. data/lib/{plugin → plugins}/reload.rb +0 -0
  42. data/lib/{filter → plugins}/reply.rb +0 -0
  43. data/lib/{filter → plugins}/reverse.rb +1 -1
  44. data/lib/{plugin → plugins}/say.rb +1 -1
  45. data/lib/{plugin → plugins}/scrape.rb +4 -4
  46. data/lib/plugins/screen-notify.rb +13 -0
  47. data/lib/plugins/screen.rb +24 -0
  48. data/lib/{plugin → plugins}/shell.rb +0 -0
  49. data/lib/{plugin → plugins}/sl.rb +4 -4
  50. data/lib/plugins/spam.rb +13 -0
  51. data/lib/{plugin → plugins}/standard_plugins.rb +72 -18
  52. data/lib/plugins/stdout.rb +80 -0
  53. data/lib/plugins/storage/DB.rb +37 -0
  54. data/lib/plugins/storage/status.rb +48 -0
  55. data/lib/plugins/storage/status_mook.rb +30 -0
  56. data/lib/plugins/storage.rb +47 -0
  57. data/lib/plugins/system_status.rb +33 -0
  58. data/lib/{plugin → plugins}/translation.rb +15 -5
  59. data/lib/{plugin → plugins}/update_editor.rb +6 -6
  60. data/lib/plugins/uri-open.rb +64 -0
  61. data/lib/{filter → plugins}/url_addspace.rb +0 -0
  62. data/lib/{plugin → plugins}/wassr_post.rb +1 -1
  63. data/lib/{plugin → plugins}/yhara.rb +1 -1
  64. data/lib/plugins/yhara_filter.rb +8 -0
  65. data/lib/plugins/yonda.rb +21 -0
  66. data/lib/termtter/api.rb +28 -2
  67. data/lib/termtter/client.rb +90 -102
  68. data/lib/termtter/command.rb +32 -31
  69. data/lib/termtter/config.rb +64 -0
  70. data/lib/termtter/connection.rb +9 -7
  71. data/lib/termtter/hook.rb +11 -2
  72. data/lib/termtter/optparse.rb +14 -0
  73. data/lib/termtter/version.rb +1 -1
  74. data/lib/termtter.rb +19 -22
  75. data/spec/plugin/english_spec.rb +19 -0
  76. data/spec/plugin/favorite_spec.rb +10 -0
  77. data/spec/plugin/fib_spec.rb +1 -2
  78. data/spec/plugin/pause_spec.rb +8 -0
  79. data/spec/plugin/plugin_spec.rb +1 -1
  80. data/spec/plugin/primes_spec.rb +15 -0
  81. data/spec/plugin/sl_spec.rb +8 -0
  82. data/spec/plugin/spam_spec.rb +0 -13
  83. data/spec/plugin/standard_plugins_spec.rb +0 -7
  84. data/spec/plugin/storage/DB_spec.rb +12 -0
  85. data/spec/plugin/storage/status_spec.rb +24 -0
  86. data/spec/spec_helper.rb +3 -0
  87. data/spec/termtter/client_spec.rb +63 -1
  88. data/spec/termtter/command_spec.rb +6 -68
  89. data/spec/termtter/config_spec.rb +111 -0
  90. data/spec/termtter/hook_spec.rb +69 -0
  91. data/spec/termtter_spec.rb +22 -34
  92. metadata +81 -72
  93. data/lib/filter/english.rb +0 -8
  94. data/lib/filter/ignore.rb +0 -19
  95. data/lib/filter/yhara.rb +0 -20
  96. data/lib/plugin/bomb.rb +0 -29
  97. data/lib/plugin/english.rb +0 -59
  98. data/lib/plugin/favorite.rb +0 -75
  99. data/lib/plugin/fib.rb +0 -8
  100. data/lib/plugin/follow.rb +0 -60
  101. data/lib/plugin/keyword.rb +0 -18
  102. data/lib/plugin/multi_reply.rb +0 -36
  103. data/lib/plugin/outputz.rb +0 -35
  104. data/lib/plugin/quicklook.rb +0 -38
  105. data/lib/plugin/screen.rb +0 -24
  106. data/lib/plugin/spam.rb +0 -9
  107. data/lib/plugin/stdout.rb +0 -63
  108. data/lib/plugin/system_status.rb +0 -33
  109. data/lib/plugin/uri-open.rb +0 -69
  110. data/lib/plugin/yonda.rb +0 -20
  111. data/lib/termtter/status.rb +0 -26
  112. data/lib/termtter/twitter.rb +0 -188
  113. data/lib/termtter/user.rb +0 -13
  114. data/spec/termtter/user_spec.rb +0 -27
  115. data/test/test_termtter.rb +0 -86
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'pp'
4
+ require 'time'
5
+
6
+ require File.dirname(__FILE__) + '/storage/status'
7
+
8
+ module Termtter::Client
9
+ public_storage[:log] = []
10
+
11
+ add_hook do |statuses, event|
12
+ case event
13
+ when :pre_filter
14
+ statuses.each do |s|
15
+ Termtter::Storage::Status.insert(
16
+ :post_id => s.id,
17
+ :created_at => Time.parse(s.created_at).to_i,
18
+ :in_reply_to_status_id => s.in_reply_to_status_id,
19
+ :in_reply_to_user_id => s.in_reply_to_user_id,
20
+ :post_text => s.text,
21
+ :user_id => s.user.id,
22
+ :screen_name => s.user.screen_name)
23
+ end
24
+ end
25
+ end
26
+
27
+ register_command(
28
+ :name => :search_storage, :aliases => [:ss],
29
+ :exec_proc => lambda {|arg|
30
+ unless arg.strip.empty?
31
+ key = arg.strip
32
+ Termtter::Storage::Status.search({ :post_text => key})
33
+ =begin
34
+ statuses = public_storage[:storage].search({ :post_text => key})
35
+
36
+ statuses.each do |s|
37
+ p s
38
+ end
39
+ call_hooks(statuses, :search)
40
+ =end
41
+ end
42
+
43
+ },
44
+
45
+ :help => [ 'search_storage WORD', 'Search storage for WORD' ]
46
+ )
47
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'erb'
4
+
5
+ config.plugins.system_status.set_default(:default_status_proc, lambda { Time.now.strftime("%x %X") })
6
+ config.plugins.system_status.set_default(:interval, 1)
7
+ config.plugins.system_status.set_default(:default_color, :on_blue)
8
+ config.plugins.system_status.set_default(:format, '<%= status %>')
9
+
10
+ def out_put_status(status, color)
11
+ formatted_status = ERB.new(config.plugins.system_status.format).result(binding)
12
+ colored_status = color(formatted_status, color)
13
+ print "\e[s\e[1000G\e[#{status.size - 1}D#{colored_status}\e[u"
14
+ $stdout.flush
15
+ end
16
+
17
+ module Termtter::Client
18
+ add_task(:name => :system_status, :interval => config.plugins.system_status.interval) do
19
+ status = (@@task_manager.get_task(:update_timeline).exec_at - Time.now).to_i.to_s
20
+ color = public_storage[:system_status_color] ||
21
+ config.plugins.system_status.default_color
22
+ out_put_status(status, color)
23
+ end
24
+ end
25
+
26
+ # system_status.rb
27
+ # show system status on left side.
28
+ # output public_storage[:system_status] or Time.now.strftime("%x %X") if nil
29
+ # example config
30
+ # config.plugins.system_status.default_status_proc = lambda { Time.now.strftime("%x %X") }
31
+ # config.plugins.system_status.interval = 1
32
+ # config.plugins.system_status.default_color = :on_blue
33
+ # config.plugins.system_status.format = '<%= status %>'
@@ -17,11 +17,21 @@ def translate(text, langpair)
17
17
  }
18
18
  end
19
19
 
20
- Termtter::Client.add_command /^(en2ja|ja2en)\s+(.*)$/ do |m, t|
21
- langpair = m[1].gsub('2', '|')
22
- puts "translating..."
23
- puts "=> #{translate(m[2], langpair)}"
24
- end
20
+ Termtter::Client.register_command(
21
+ :name => :en2ja,
22
+ :exec_proc => lambda{|arg|
23
+ puts "translating..."
24
+ puts "=> #{translate(arg, 'en|ja')}"
25
+ }
26
+ )
27
+
28
+ Termtter::Client.register_command(
29
+ :name => :ja2en,
30
+ :exec_proc => lambda{|arg|
31
+ puts "translating..."
32
+ puts "=> #{translate(arg, 'ja|en')}"
33
+ }
34
+ )
25
35
 
26
36
  # This plugin does not work yet.
27
37
  # requirements
@@ -4,17 +4,17 @@ require 'tempfile'
4
4
 
5
5
  module Termtter::Client
6
6
  if ENV['EDITOR']
7
- configatron.plugins.update_editor.set_default('editor', ENV['EDITOR'])
7
+ config.plugins.update_editor.set_default('editor', ENV['EDITOR'])
8
8
  else
9
- configatron.plugins.update_editor.set_default('editor', 'vi')
9
+ config.plugins.update_editor.set_default('editor', 'vi')
10
10
  end
11
- configatron.plugins.update_editor.set_default('add_completion', false)
11
+ config.plugins.update_editor.set_default('add_completion', false)
12
12
 
13
13
 
14
14
  def self.input_editor
15
15
  file = Tempfile.new('termtter')
16
- editor = configatron.plugins.update_editor.editor
17
- if configatron.plugins.update_editor.add_completion
16
+ editor = config.plugins.update_editor.editor
17
+ if config.plugins.update_editor.add_completion
18
18
  file.puts "\n"*100 + "__END__\n" + public_storage[:users].to_a.join(' ')
19
19
  end
20
20
  file.close
@@ -34,7 +34,7 @@ module Termtter::Client
34
34
  text.split("\n").each do |post|
35
35
  break if post =~ /^__END__$/
36
36
  unless post.empty?
37
- Termtter::API.twitter.update_status(post)
37
+ Termtter::API.twitter.update(post)
38
38
  puts "=> #{post}"
39
39
  end
40
40
  end
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ public_storage[:uris] = []
5
+
6
+ add_hook do |statuses, event, t|
7
+ if event == :update_friends_timeline
8
+ statuses.each do |s|
9
+ public_storage[:uris] += s.text.scan(%r|https?://[^\s]+|)
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.open_uri(uri)
15
+ unless config.plugins.uri_open.browser.empty?
16
+ system config.plugins.uri_open.browser, uri
17
+ else
18
+ case RUBY_PLATFORM
19
+ when /linux/
20
+ system 'firefox', uri
21
+ when /mswin(?!ce)|mingw|bccwin/
22
+ system 'explorer', uri
23
+ else
24
+ system 'open', uri
25
+ end
26
+ end
27
+ end
28
+
29
+ register_command(
30
+ :name => :'uri-open', :aliases => [:uo],
31
+ :exec_proc => lambda{|arg|
32
+ case arg
33
+ when /^\s+$/
34
+ public_storage[:uris].each do |uri|
35
+ open_uri(uri)
36
+ end
37
+ public_storage[:uris].clear
38
+ when /^\s*list\s*$/
39
+ public_storage[:uris].each_with_index do |uri, index|
40
+ puts "#{index}: #{uri}"
41
+ end
42
+ when /^\s*delete\s+(\d+)\s*$/
43
+ puts 'delete'
44
+ public_storage[:uris].delete_at($1.to_i)
45
+ when /^\s*clear\s*$/
46
+ public_storage[:uris].clear
47
+ puts "clear uris"
48
+ when /^\s*(\d+)\s*$/
49
+ open_uri(public_storage[:uris][$1.to_i])
50
+ public_storage[:uris].delete_at($1.to_i)
51
+ end
52
+ },
53
+ :completion_proc => lambda{|cmd, arg|
54
+ %w(list delete clear).grep(/^#{Regexp.quote arg}/).map{|a| "#{cmd} #{a}"}
55
+ }
56
+ )
57
+ end
58
+ # ~/.termtter
59
+ # plugin 'uri-open'
60
+ #
61
+ # see also: http://ujihisa.nowa.jp/entry/c3dd00c4e0
62
+ #
63
+ # KNOWN BUG
64
+ # * In Debian, exit or C-c in the termtter kills your firefox.
File without changes
@@ -10,7 +10,7 @@ Termtter::Client.register_hook(
10
10
  begin
11
11
  Net::HTTP.version_1_2
12
12
  req = Net::HTTP::Post.new("/statuses/update.json?")
13
- req.basic_auth configatron.plugins.wassr_post.username, configatron.plugins.wassr_post.password
13
+ req.basic_auth config.plugins.wassr_post.username, config.plugins.wassr_post.password
14
14
  Net::HTTP.start('api.wassr.jp', 80) do |http|
15
15
  res = http.request(req, "status=#{URI.escape(arg.strip)}&source=Termtter")
16
16
  end
@@ -129,7 +129,7 @@ module Termtter::Client
129
129
  :name => :yhara,
130
130
  :exec_proc => lambda{|arg|
131
131
  text = "#{'@' if arg[0..0] != '@'}#{arg} #{Yharian::text}"
132
- Termtter::API.twitter.update_status(text)
132
+ Termtter::API.twitter.update(text)
133
133
  puts "=> #{text}"
134
134
  },
135
135
  :completion_proc => lambda {|cmd, args|
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.add_filter do |statuses, _|
4
+ statuses.select {|s| /^(?:\s|(y\s)|(?:hara\s))+\s*(?:y|(?:hara))(?:\?|!|\.)?\s*$/ =~ s.text }
5
+ end
6
+
7
+ # yhara_filter.rb
8
+ # select Yharian post only
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(:name => :yonda,
5
+ :aliases => [:y],
6
+ :exec_proc => lambda { |arg|
7
+ public_storage[:unread_count] = 0
8
+ print "\033[2J\033[H" # FIXME
9
+ true
10
+ },
11
+ :help => ['yonda,y', 'Mark as read']
12
+ )
13
+
14
+ register_hook(:name => :yonda,
15
+ :points => [:post_exec__update_timeline],
16
+ :exec_proc => lambda { |cmd, arg, result|
17
+ public_storage[:unread_count] ||= 0
18
+ public_storage[:unread_count] += result.size
19
+ }
20
+ )
21
+ end
data/lib/termtter/api.rb CHANGED
@@ -1,12 +1,38 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'rubytter'
3
+
4
+ config.set_default(:host, 'twitter.com')
5
+ config.proxy.set_default(:port, '8080')
6
+ config.proxy.set_default(:host, nil)
7
+ config.proxy.set_default(:port, nil)
8
+ config.proxy.set_default(:user_name, nil)
9
+ config.proxy.set_default(:password, nil)
10
+ config.set_default(:enable_ssl, false)
2
11
 
3
12
  module Termtter
4
13
  module API
5
14
  class << self
6
- attr_reader :connection, :twitter
15
+ attr_reader :connection, :twitter, :twitter_old
7
16
  def setup
8
17
  @connection = Connection.new
9
- @twitter = Termtter::Twitter.new(configatron.user_name, configatron.password, @connection)
18
+ @twitter = Rubytter.new(
19
+ config.user_name,
20
+ config.password,
21
+ {
22
+ :host => config.host,
23
+ :header => {
24
+ 'User-Agent' => 'Termtter http://github.com/jugyo/termtter',
25
+ 'X-Twitter-Client' => 'Termtter',
26
+ 'X-Twitter-Client-URL' => 'http://github.com/jugyo/termtter',
27
+ 'X-Twitter-Client-Version' => '0.1'
28
+ },
29
+ :enable_ssl => config.enable_ssl,
30
+ :proxy_host => config.proxy.host,
31
+ :proxy_port => config.proxy.port,
32
+ :proxy_user_name => config.proxy.user_name,
33
+ :proxy_password => config.proxy.password
34
+ }
35
+ )
10
36
  end
11
37
  end
12
38
  end
@@ -10,20 +10,16 @@ module Termtter
10
10
  def init
11
11
  @@hooks = []
12
12
  @@new_hooks = {}
13
- @@commands = {}
14
13
  @@new_commands = {}
15
14
  @@completions = []
16
15
  @@filters = []
17
16
  @@helps = []
18
17
  @@since_id = nil
19
- @@main_thread = nil
20
18
  @@input_thread = nil
21
19
  @@task_manager = Termtter::TaskManager.new
22
- configatron.set_default(:update_interval, 300)
23
- configatron.set_default(:prompt, '> ')
24
- configatron.set_default(:enable_ssl, false)
25
- configatron.proxy.set_default(:port, '8080')
26
- configatron.set_default(:devel, false)
20
+ config.set_default(:update_interval, 300)
21
+ config.set_default(:prompt, '> ')
22
+ config.set_default(:devel, false)
27
23
  Thread.abort_on_exception = true
28
24
  end
29
25
 
@@ -39,13 +35,6 @@ module Termtter
39
35
  EOF
40
36
  end
41
37
 
42
- # Deprecated
43
- # FIXME: delete when become unnecessary
44
- def add_command(regex, &block)
45
- warn "Termtter:Client.add_command method will be removed. Use Termtter::Client.register_command() instead. (#{caller.first})"
46
- @@commands[regex] = block
47
- end
48
-
49
38
  def register_hook(arg)
50
39
  hook = case arg
51
40
  when Hook
@@ -96,7 +85,7 @@ module Termtter
96
85
  @@helps << [name, desc]
97
86
  end
98
87
 
99
- %w[hooks commands completions helps filters].each do |n|
88
+ %w[hooks completions helps filters].each do |n|
100
89
  eval <<-EOF
101
90
  def clear_#{n}
102
91
  @@#{n}.clear
@@ -105,15 +94,27 @@ module Termtter
105
94
  end
106
95
 
107
96
  # memo: each filter must return Array of Status
108
- def apply_filters(statuses)
109
- filtered = statuses.map{|s| s.dup }
110
- @@filters.each do |f|
111
- filtered = f.call(filtered)
97
+ def apply_filters(result, event = nil)
98
+ case event
99
+ when :show
100
+ result
101
+ when :search
102
+ filtered = result.results.map(&:dup)
103
+ @@filters.each do |f|
104
+ filtered = f.call(filtered, event)
105
+ end
106
+ result.results = filtered
107
+ result
108
+ else
109
+ filtered = result.map(&:dup)
110
+ @@filters.each do |f|
111
+ filtered = f.call(filtered, event)
112
+ end
113
+ filtered
112
114
  end
113
- filtered
114
115
  rescue => e
115
116
  handle_error(e)
116
- statuses
117
+ result
117
118
  end
118
119
 
119
120
  def do_hooks(statuses, event)
@@ -133,7 +134,7 @@ module Termtter
133
134
  break if result == false # interrupt if hook return false
134
135
  result = hook.exec_proc.call(*args)
135
136
  }
136
- return result
137
+ result
137
138
  rescue => e
138
139
  if point.to_sym == :on_error
139
140
  raise
@@ -145,44 +146,40 @@ module Termtter
145
146
  # TODO: delete argument "tw" when unnecessary
146
147
  def call_hooks(statuses, event, tw = nil)
147
148
  do_hooks(statuses, :pre_filter)
148
- do_hooks(apply_filters(statuses), event)
149
+ filtered = apply_filters(statuses, event)
150
+ do_hooks(filtered, :post_filter)
151
+ do_hooks(filtered, event)
149
152
  end
150
153
 
151
154
  def call_commands(text, tw = nil)
152
155
  return if text.empty?
153
156
 
154
157
  command_found = false
155
- @@commands.each do |key, command|
156
- if key =~ text
157
- command_found = true
158
- @@task_manager.invoke_and_wait do
159
- command.call($~, Termtter::API.twitter)
160
- end
161
- end
162
- end
163
-
164
158
  @@new_commands.each do |key, command|
165
- command_info = command.match?(text)
166
- if command_info
159
+ command_str, command_arg = command.match?(text)
160
+ if command_str
167
161
  command_found = true
168
- input_command, arg = *command_info
169
162
 
170
- modified_arg = call_new_hooks("modify_arg_for_#{command.name.to_s}", input_command, arg) || arg || ''
163
+ modified_arg = call_new_hooks(
164
+ "modify_arg_for_#{command.name.to_s}",
165
+ command_str,
166
+ command_arg) || command_arg || ''
171
167
 
172
168
  @@task_manager.invoke_and_wait do
173
- pre_exec_hook_result = call_new_hooks("pre_exec_#{command.name.to_s}", input_command, modified_arg)
174
- next if pre_exec_hook_result == false
175
169
 
170
+ pre_exec_hook_result = call_new_hooks("pre_exec_#{command.name.to_s}", command_str, modified_arg)
171
+ next if pre_exec_hook_result == false
176
172
  # exec command
177
173
  result = command.execute(modified_arg)
178
174
  if result
179
- call_new_hooks("post_exec_#{command.name.to_s}", input_command, modified_arg, result)
175
+ call_new_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
180
176
  end
177
+
181
178
  end
182
179
  end
183
180
  end
184
181
 
185
- raise CommandNotFound unless command_found
182
+ raise CommandNotFound, text unless command_found
186
183
  end
187
184
 
188
185
  def pause
@@ -203,7 +200,6 @@ module Termtter
203
200
  call_hooks([], :exit)
204
201
  call_new_hooks(:exit)
205
202
  @@task_manager.kill
206
- @@main_thread.kill if @@main_thread
207
203
  @@input_thread.kill if @@input_thread
208
204
  end
209
205
 
@@ -213,20 +209,19 @@ module Termtter
213
209
  end
214
210
 
215
211
  def load_config
216
- conf_file = File.expand_path('~/.termtter')
217
- if File.exist? conf_file
218
- wrap_require do
219
- load conf_file
220
- end
212
+ legacy_config_support() if File.exist? Termtter::CONF_DIR
213
+ if File.exist? Termtter::CONF_FILE
214
+ load Termtter::CONF_FILE
221
215
  else
222
216
  ui = create_highline
223
217
  username = ui.ask('your twitter username: ')
224
218
  password = ui.ask('your twitter password: ') { |q| q.echo = false }
225
219
 
226
- File.open(File.expand_path('~/.termtter'), 'w') {|io|
220
+ Dir.mkdir(Termtter::CONF_DIR)
221
+ File.open(Termtter::CONF_FILE, 'w') {|io|
227
222
  io.puts '# -*- coding: utf-8 -*-'
228
223
 
229
- plugins = Dir.glob(File.dirname(__FILE__) + "/../lib/plugin/*.rb").map {|f|
224
+ plugins = Dir.glob(File.dirname(__FILE__) + "/../lib/plugins/*.rb").map {|f|
230
225
  f.match(%r|lib/plugin/(.*?).rb$|)[1]
231
226
  }
232
227
  plugins -= %w[stdout standard_plugins]
@@ -235,26 +230,43 @@ module Termtter
235
230
  end
236
231
 
237
232
  io.puts
238
- io.puts "configatron.user_name = '#{username}'"
239
- io.puts "configatron.password = '#{password}'"
240
- io.puts "#configatron.update_interval = 120"
241
- io.puts "#configatron.proxy.host = 'proxy host'"
242
- io.puts "#configatron.proxy.port = '8080'"
243
- io.puts "#configatron.proxy.user_name = 'proxy user'"
244
- io.puts "#configatron.proxy.password = 'proxy password'"
233
+ io.puts "config.user_name = '#{username}'"
234
+ io.puts "config.password = '#{password}'"
235
+ io.puts "#config.update_interval = 120"
236
+ io.puts "#config.proxy.host = 'proxy host'"
237
+ io.puts "#config.proxy.port = '8080'"
238
+ io.puts "#config.proxy.user_name = 'proxy user'"
239
+ io.puts "#config.proxy.password = 'proxy password'"
245
240
  io.puts
246
241
  io.puts "# vim: set filetype=ruby"
247
242
  }
248
- puts "generated: ~/.termtter"
243
+ puts "generated: ~/.termtter/config"
249
244
  puts "enjoy!"
250
- wrap_require do
251
- load conf_file
252
- end
245
+ load Termtter::CONF_FILE
253
246
  end
254
247
  end
255
248
 
249
+ def legacy_config_support
250
+ case File.ftype(File.expand_path('~/.termtter'))
251
+ when 'directory'
252
+ # nop
253
+ when 'file'
254
+ move_legacy_config_file
255
+ end
256
+ end
257
+
258
+ def move_legacy_config_file
259
+ FileUtils.mv(
260
+ Termtter::CONF_DIR,
261
+ File.expand_path('~/.termtter___'))
262
+ Dir.mkdir(Termtter::CONF_DIR)
263
+ FileUtils.mv(
264
+ File.expand_path('~/.termtter___'),
265
+ Termtter::CONF_FILE)
266
+ end
267
+
256
268
  def pre_config_load()
257
- if configatron.devel
269
+ if config.system.devel
258
270
  plugin 'devel'
259
271
  end
260
272
  end
@@ -277,7 +289,7 @@ module Termtter
277
289
  handle_error(e)
278
290
  end
279
291
  }
280
- vi_or_emacs = configatron.editing_mode
292
+ vi_or_emacs = config.editing_mode
281
293
  unless vi_or_emacs.empty?
282
294
  Readline.__send__("#{vi_or_emacs}_editing_mode")
283
295
  end
@@ -288,13 +300,13 @@ module Termtter
288
300
  :name => :_update_timeline,
289
301
  :exec_proc => lambda {|arg|
290
302
  begin
291
- statuses = Termtter::API.twitter.get_friends_timeline(@@since_id)
303
+ args = @@since_id ? [{:since_id => @@since_id}] : []
304
+ statuses = Termtter::API.twitter.friends_timeline(*args)
292
305
  unless statuses.empty?
293
306
  @@since_id = statuses[0].id
294
307
  end
295
- print "\e[1K\e[0G" if !statuses.empty? && !win?
296
308
  call_hooks(statuses, :update_friends_timeline)
297
- @@input_thread.kill if @@input_thread && !statuses.empty?
309
+ statuses
298
310
  rescue OpenURI::HTTPError => e
299
311
  if e.message == '401 Unauthorized'
300
312
  puts 'Could not login'
@@ -305,7 +317,7 @@ module Termtter
305
317
  }
306
318
  )
307
319
 
308
- add_task(:name => :update_timeline, :interval => configatron.update_interval) do
320
+ add_task(:name => :update_timeline, :interval => config.update_interval) do
309
321
  call_commands('_update_timeline')
310
322
  end
311
323
  end
@@ -327,13 +339,20 @@ module Termtter
327
339
  def start_input_thread
328
340
  setup_readline()
329
341
  trap_setting()
330
- @@main_thread = Thread.new do
331
- loop do
332
- @@input_thread = create_input_thread()
333
- @@input_thread.join
342
+ @@input_thread = Thread.new do
343
+ while buf = Readline.readline(ERB.new(config.prompt).result(API.twitter.__send__(:binding)), true)
344
+ Readline::HISTORY.pop if /^(u|update)\s+(.+)$/ =~ buf
345
+ begin
346
+ call_commands(buf)
347
+ rescue CommandNotFound => e
348
+ warn "Unknown command \"#{e}\""
349
+ warn 'Enter "help" for instructions'
350
+ rescue => e
351
+ handle_error e
352
+ end
334
353
  end
335
354
  end
336
- @@main_thread.join
355
+ @@input_thread.join
337
356
  end
338
357
 
339
358
  def run
@@ -354,21 +373,6 @@ module Termtter
354
373
  start_input_thread()
355
374
  end
356
375
 
357
- def create_input_thread()
358
- Thread.new do
359
- while buf = Readline.readline(ERB.new(configatron.prompt).result(API.twitter.__send__(:binding)), true)
360
- Readline::HISTORY.pop if /^(u|update)\s+(.+)$/ =~ buf
361
- begin
362
- call_commands(buf)
363
- rescue CommandNotFound => e
364
- puts "Unknown command \"#{buf}\""
365
- puts 'Enter "help" for instructions'
366
- end
367
- end
368
- exit # exit when press Control-D
369
- end
370
- end
371
-
372
376
  def create_highline
373
377
  HighLine.track_eof = false
374
378
  if $stdin.respond_to?(:getbyte) # for ruby1.9
@@ -380,7 +384,7 @@ module Termtter
380
384
  else
381
385
  stdin_for_highline = $stdin
382
386
  end
383
- return HighLine.new(stdin_for_highline)
387
+ HighLine.new(stdin_for_highline)
384
388
  end
385
389
 
386
390
  def handle_error(e)
@@ -389,22 +393,6 @@ module Termtter
389
393
  puts "Error: #{e}"
390
394
  puts e.backtrace.join("\n")
391
395
  end
392
-
393
- def wrap_require
394
- # FIXME: delete this method after the major version up
395
- alias original_require require
396
- def require(s)
397
- if %r|^termtter/(.*)| =~ s
398
- puts "[WARNING] use plugin '#{$1}' instead of require"
399
- puts " Such a legacy .termtter file will not be supported until version 1.0.0"
400
- s = "plugin/#{$1}"
401
- end
402
- original_require s
403
- end
404
- yield
405
- alias require original_require
406
- end
407
- private :wrap_require
408
396
  end
409
397
  end
410
398
  end