termtter 1.5.0 → 1.6.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 (86) hide show
  1. data/Rakefile +2 -1
  2. data/bin/termtter +1 -0
  3. data/lib/plugins/another_prompt.rb +131 -0
  4. data/lib/plugins/async.rb +23 -0
  5. data/lib/plugins/confirm.rb +1 -1
  6. data/lib/plugins/db.rb +1 -1
  7. data/lib/plugins/defaults/auto_reload.rb +20 -19
  8. data/lib/plugins/defaults/command_line.rb +10 -5
  9. data/lib/plugins/defaults/hashtag.rb +35 -0
  10. data/lib/plugins/defaults/lists.rb +14 -0
  11. data/lib/plugins/defaults/retweet.rb +15 -15
  12. data/lib/plugins/defaults/standard_commands.rb +22 -28
  13. data/lib/plugins/defaults/standard_completion.rb +5 -5
  14. data/lib/plugins/defaults/switch.rb +34 -0
  15. data/lib/plugins/eject.rb +15 -0
  16. data/lib/plugins/expand-tinyurl.rb +1 -1
  17. data/lib/plugins/favotter.rb +77 -0
  18. data/lib/plugins/friends.rb +50 -0
  19. data/lib/plugins/g.rb +16 -0
  20. data/lib/plugins/gsub.rb +17 -0
  21. data/lib/plugins/haml.rb +55 -0
  22. data/lib/plugins/hatebu_and_update.rb +2 -2
  23. data/lib/plugins/history.rb +9 -0
  24. data/lib/plugins/irc_gw.rb +11 -4
  25. data/lib/plugins/linefeed.rb +31 -0
  26. data/lib/plugins/md5pass.rb +42 -0
  27. data/lib/plugins/outputz.rb +1 -1
  28. data/lib/plugins/primes.rb +1 -1
  29. data/lib/plugins/quote.rb +43 -0
  30. data/lib/plugins/reduce_text.rb +26 -0
  31. data/lib/plugins/reverse.rb +7 -6
  32. data/lib/plugins/source.rb +31 -0
  33. data/lib/plugins/storage/status.rb +2 -2
  34. data/lib/plugins/storage.rb +1 -1
  35. data/lib/plugins/stream.rb +192 -0
  36. data/lib/plugins/switch_user.rb +1 -22
  37. data/lib/plugins/truncate.rb +29 -0
  38. data/lib/plugins/uri-open.rb +23 -9
  39. data/lib/plugins/w3mimg.rb +76 -0
  40. data/lib/termtter/active_rubytter.rb +8 -0
  41. data/lib/termtter/api.rb +37 -13
  42. data/lib/termtter/client.rb +26 -47
  43. data/lib/termtter/command.rb +15 -9
  44. data/lib/termtter/config.rb +6 -2
  45. data/lib/termtter/hookable.rb +59 -0
  46. data/lib/termtter/optparse.rb +51 -39
  47. data/lib/termtter/rubytter_proxy.rb +32 -0
  48. data/lib/termtter/system_extensions/core_compatibles.rb +16 -0
  49. data/lib/termtter/system_extensions/termtter_compatibles.rb +19 -0
  50. data/lib/termtter/system_extensions/windows.rb +86 -0
  51. data/lib/termtter/system_extensions.rb +8 -121
  52. data/lib/termtter/task_manager.rb +4 -10
  53. data/lib/termtter/version.rb +1 -1
  54. data/lib/termtter.rb +5 -3
  55. data/spec/plugins/defaults/hashtag_spec.rb +41 -0
  56. data/spec/plugins/defaults/lists_spec.rb +34 -0
  57. data/spec/plugins/{english_spec.rb → english_spec_.rb} +0 -0
  58. data/spec/plugins/{filter_spec.rb → filter_spec_.rb} +0 -0
  59. data/spec/plugins/gsub_spec.rb +18 -0
  60. data/spec/plugins/haml_spec.rb +134 -0
  61. data/spec/plugins/md5pass_spec.rb +13 -0
  62. data/spec/plugins/{primes_spec.rb → primes_spec_.rb} +0 -0
  63. data/spec/plugins/{sl_spec.rb → sl_spec_.rb} +0 -0
  64. data/spec/plugins/standard_commands_spec.rb +1 -1
  65. data/spec/plugins/storage/{DB_spec.rb → DB_spec_.rb} +0 -0
  66. data/spec/plugins/storage/{status_spec.rb → status_spec_.rb} +0 -0
  67. data/spec/plugins/truncate_spec.rb +27 -0
  68. data/spec/plugins/whois_spec_.rb +20 -0
  69. data/spec/spec_helper.rb +25 -0
  70. data/spec/termtter/active_rubytter_spec.rb +17 -0
  71. data/spec/termtter/api_spec.rb +107 -0
  72. data/spec/termtter/client_spec.rb +262 -73
  73. data/spec/termtter/command_spec.rb +31 -5
  74. data/spec/termtter/config_setup_spec.rb +19 -0
  75. data/spec/termtter/config_spec.rb +57 -27
  76. data/spec/termtter/hook_spec.rb +12 -0
  77. data/spec/termtter/hookable_spec.rb +53 -0
  78. data/spec/termtter/optparse_spec.rb +64 -9
  79. data/spec/termtter/rubytter_proxy_spec.rb +42 -0
  80. data/spec/termtter/system_extensions/windows_spec.rb +9 -0
  81. data/spec/termtter/system_extensions_spec.rb +61 -0
  82. data/spec/termtter/task_manager_spec.rb +58 -0
  83. data/spec/termtter_spec.rb +11 -0
  84. metadata +45 -20
  85. data/lib/termtter/connection.rb +0 -41
  86. data/spec/plugins/whois_spec.rb +0 -26
data/Rakefile CHANGED
@@ -23,7 +23,6 @@ spec = Gem::Specification.new do |s|
23
23
  s.add_dependency("highline", ">= 1.5.0")
24
24
  s.add_dependency("termcolor", ">= 1.0.0")
25
25
  s.add_dependency("rubytter", ">= 0.9.2")
26
- s.add_dependency("oauth", ">= 0.3.6")
27
26
  s.authors = %w(jugyo ujihisa)
28
27
  s.email = 'jugyo.org@gmail.com'
29
28
  s.homepage = 'http://termtter.org/'
@@ -61,12 +60,14 @@ end
61
60
  desc 'run all specs'
62
61
  Spec::Rake::SpecTask.new do |t|
63
62
  t.spec_files = FileList['spec/**/*_spec.rb']
63
+ t.spec_files.sort! # FIXME: Spec depends order.
64
64
  t.spec_opts = ['-c']
65
65
  end
66
66
  desc "Run all examples with RCov"
67
67
 
68
68
  Spec::Rake::SpecTask.new('rcov') do |t|
69
69
  t.spec_files = FileList['spec/**/*_spec.rb']
70
+ t.spec_files.sort! # FIXME: Spec depends order.
70
71
  t.spec_opts = ['-c', '-fs']
71
72
  t.rcov = true
72
73
  t.rcov_opts = ['-x', 'spec', '--exclude', 'lib/plugins']
data/bin/termtter CHANGED
@@ -3,4 +3,5 @@
3
3
 
4
4
  require 'rubygems'
5
5
  require 'termtter'
6
+ Termtter::OptParser.parse!(ARGV)
6
7
  Termtter::Client.run
@@ -0,0 +1,131 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ config.plugins.another_prompt.
4
+ set_default(:shortcut_setting,
5
+ { ':' => '',
6
+ 'd' => 'direct',
7
+ 'D' => 'delete',
8
+ 'f' => 'fib',
9
+ 'F' => 'favorite',
10
+ 'l' => 'list',
11
+ 'o' => 'open',
12
+ 'p' => 'profile',
13
+ 'R' => 'reply',
14
+ 's' => 'search',
15
+ 't' => 'retweet',
16
+ 'u' => 'update',
17
+ 'c' => lambda do
18
+ system('clear')
19
+ end,
20
+ 'L' => lambda do
21
+ puts '-' *
22
+ `stty size`.chomp.
23
+ sub(/^\d+\s(\d+)$/, '\\1').to_i
24
+ end,
25
+ 'q' => lambda do
26
+ Termtter::Client.call_commands('quit')
27
+ end,
28
+ 'r' => lambda do
29
+ Termtter::Client.call_commands('replies')
30
+ end,
31
+ '?' => lambda do
32
+ Termtter::Client.call_commands('help')
33
+ end,
34
+ "\e" => lambda do
35
+ system('screen', '-X', 'eval', 'copy')
36
+ end
37
+ })
38
+
39
+ Termtter::Client.plug 'curry'
40
+
41
+ module Termtter::Client
42
+ add_task(:name => :auto_reload,
43
+ :interval => config.update_interval,
44
+ :after => config.update_interval) do
45
+ begin
46
+ call_commands('reload')
47
+ rescue Exception => e
48
+ handle_error(e)
49
+ end
50
+ end
51
+
52
+ register_hook(
53
+ :name => :auto_reload_init,
54
+ :point => :initialize,
55
+ :exec => lambda {
56
+ begin
57
+ call_commands('reload')
58
+ rescue Exception => e
59
+ handle_error(e)
60
+ end
61
+ }
62
+ )
63
+ end
64
+
65
+ module Termtter
66
+ class CommandLine
67
+ include Singleton
68
+
69
+ STTY_ORIGIN = `stty -g`.chomp
70
+
71
+ def start_input_thread
72
+ setup_readline()
73
+ trap_setting()
74
+ @input_thread = Thread.new do
75
+ loop do
76
+ begin
77
+ value = config.plugins.another_prompt.shortcut_setting[wait_keypress]
78
+ Client.pause
79
+ case value
80
+ when String
81
+ call_prompt(value)
82
+ when Proc
83
+ value.call
84
+ end
85
+ ensure
86
+ Client.resume
87
+ end
88
+ end
89
+ end
90
+ @input_thread.join
91
+ end
92
+
93
+ def call_prompt(command)
94
+ Client.call_commands("curry #{command}")
95
+ if buf = Readline.readline(ERB.new(prompt).result(Termtter::API.twitter.__send__(:binding)), true)
96
+ Readline::HISTORY.pop if buf.empty?
97
+ begin
98
+ call(buf)
99
+ rescue Exception => e
100
+ Client.handle_error(e)
101
+ end
102
+ else
103
+ puts
104
+ end
105
+ ensure
106
+ Client.call_commands('uncurry')
107
+ end
108
+
109
+ def wait_keypress
110
+ system('stty', '-echo', '-icanon')
111
+ c = STDIN.getc
112
+ return [c].pack('c')
113
+ ensure
114
+ system('stty', STTY_ORIGIN)
115
+ end
116
+
117
+ def trap_setting()
118
+ begin
119
+ trap("INT") do
120
+ begin
121
+ system "stty", STTY_ORIGIN
122
+ ensure
123
+ Client.call_commands('exit')
124
+ end
125
+ end
126
+ rescue ArgumentError
127
+ rescue Errno::ENOENT
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,23 @@
1
+ module Termtter::Client
2
+ register_command(
3
+ :async,
4
+ :alias => :a,
5
+ :help => ['async COMMAND', 'asynchronously execute the command'],
6
+ :completion => lambda {|cmd, arg|
7
+ commands.map{|name, command| command.complement(arg)}.
8
+ flatten.
9
+ compact.
10
+ map{|i| "#{cmd} #{i}"}
11
+ },
12
+ :exec => lambda {|arg|
13
+ @task_manager.invoke_later do
14
+ begin
15
+ call_commands(arg)
16
+ rescue Exception => e
17
+ handle_error(e)
18
+ end
19
+ Readline.refresh_line
20
+ end
21
+ }
22
+ )
23
+ end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- config.plugins.confirm.set_default(:commands, [:update, :reply, :direct])
3
+ config.plugins.confirm.set_default(:commands, [:update, :reply, :direct, :retweet])
4
4
  config.plugins.confirm.set_default(
5
5
  :conditions,
6
6
  [
data/lib/plugins/db.rb CHANGED
@@ -76,7 +76,7 @@ module Termtter
76
76
  end
77
77
 
78
78
  register_command(:db_clear) do |arg|
79
- if confirm('Are you shure?')
79
+ if confirm('Are you sure?')
80
80
  User.delete
81
81
  Status.delete
82
82
  end
@@ -1,22 +1,23 @@
1
1
  # -*- coding: utf-8 -*-
2
- module Termtter::Client
3
- add_task(:name => :auto_reload, :interval => config.update_interval, :after => config.update_interval) do
4
- begin
5
- call_commands('reload -r')
6
- rescue Exception => e
7
- handle_error(e)
8
- end
2
+ auto_reload_proc = lambda do
3
+ begin
4
+ Termtter::Client.call_commands('reload -r')
5
+ rescue TimeoutError
6
+ # do nothing
7
+ rescue Exception => e
8
+ Termtter::Client.handle_error(e)
9
9
  end
10
-
11
- register_hook(
12
- :name => :auto_reload_init,
13
- :point => :initialize,
14
- :exec => lambda {
15
- begin
16
- call_commands('reload -r')
17
- rescue Exception => e
18
- handle_error(e)
19
- end
20
- }
21
- )
22
10
  end
11
+
12
+ Termtter::Client.add_task(
13
+ :name => :auto_reload,
14
+ :interval => config.update_interval,
15
+ :after => config.update_interval,
16
+ &auto_reload_proc
17
+ )
18
+
19
+ Termtter::Client.register_hook(
20
+ :name => :auto_reload_init,
21
+ :point => :initialize,
22
+ :exec => auto_reload_proc
23
+ )
@@ -20,7 +20,7 @@ module Termtter
20
20
  end
21
21
 
22
22
  def stop
23
- @input_thread.kill
23
+ @input_thread.kill if @input_thread
24
24
  end
25
25
 
26
26
  def call(command_text)
@@ -32,6 +32,8 @@ module Termtter
32
32
  command_text = hook.call(command_text)
33
33
  }
34
34
  Client.call_commands(command_text)
35
+ rescue TimeoutError
36
+ puts TermColor.parse("<red>Time out :(</red>")
35
37
  end
36
38
 
37
39
  def prompt
@@ -67,11 +69,14 @@ module Termtter
67
69
  Readline.completion_case_fold = true
68
70
  Readline.completion_proc = lambda {|input|
69
71
  begin
70
- words = []
71
- words << Client.commands.map {|name, command| command.complement(input) }
72
- Client.get_hooks(:completion).each do |hook|
73
- words << hook.call(input) rescue nil
72
+ words = Client.commands.map {|name, command| command.complement(input) }.flatten.compact
73
+
74
+ if words.empty?
75
+ Client.get_hooks(:completion).each do |hook|
76
+ words << hook.call(input) rescue nil
77
+ end
74
78
  end
79
+
75
80
  words.flatten.compact
76
81
  rescue Exception => e
77
82
  Client.handle_error(e)
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'set'
3
+
4
+ module Termtter::Client
5
+ public_storage[:hashtags] ||= Set.new
6
+ public_storage[:orig_prompt] = config.prompt
7
+
8
+ register_hook(:add_hashtags, :point => :modify_arg_for_update) do |cmd, arg|
9
+ "#{arg} #{public_storage[:hashtags].to_a.join(' ')}"
10
+ end
11
+
12
+ register_command(:raw_update) do |args|
13
+ temp = public_storage[:hashtags]
14
+ public_storage[:hashtags].clear
15
+ call_commands "update #{args}"
16
+ public_storage[:hashtags] = temp
17
+ end
18
+
19
+ register_command('hashtag add') do |args|
20
+ args.split(/\s+/).each do |arg|
21
+ hashtag = /^#/ =~ arg ? arg : "##{arg}"
22
+ public_storage[:hashtags] << hashtag
23
+ config.prompt = "#{public_storage[:hashtags].to_a.join(', ')} #{public_storage[:orig_prompt]}"
24
+ end
25
+ end
26
+
27
+ register_command('hashtag clear') do |args|
28
+ public_storage[:hashtags].clear
29
+ config.prompt = public_storage[:orig_prompt]
30
+ end
31
+
32
+ register_command('hashtag list') do |args|
33
+ puts public_storage[:hashtags].to_a
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Termtter::Client
2
+ register_command(
3
+ :name => :lists,
4
+ :exec => lambda {|arg|
5
+ unless arg.empty?
6
+ user_name = normalize_as_user_name(arg)
7
+ else
8
+ user_name = config.user_name
9
+ end
10
+ # TODO: show more information of lists
11
+ puts Termtter::API.twitter.lists(user_name).lists.map{|i| i.slug}
12
+ }
13
+ )
14
+ end
@@ -1,10 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  config.plugins.retweet.set_default(:format, '<%= comment %>RT @<%=s.user.screen_name%>: <%=s.text%>')
4
+ config.plugins.retweet.set_default(:confirm_protected, true)
4
5
 
5
6
  module Termtter::Client
6
7
  def self.post_retweet(s, comment = nil)
7
- if s.user.protected &&
8
+ if s.user.protected && config.plugins.retweet.confirm_protected &&
8
9
  !confirm("#{s.user.screen_name} is protected! Are you sure?", false)
9
10
  return
10
11
  end
@@ -23,21 +24,20 @@ module Termtter::Client
23
24
  :help => ['retweet,rt (ID|@USER)', 'Post a retweet message'],
24
25
  :exec_proc => lambda {|arg|
25
26
  arg, comment = arg.split(/\s/, 2)
26
- txt = if public_storage[:typable_id] && s = typable_id_status(arg)
27
- post_retweet(s, comment)
28
- else
29
- case arg
30
- when /(\d+)/
31
- post_retweet(Termtter::API.twitter.show(arg), comment)
32
- when /@([A-Za-z0-9_]+)/
33
- user = $1
34
- statuses = Termtter::API.twitter.user_timeline(user)
35
- return if statuses.empty?
36
- post_retweet(statuses[0], comment)
37
- end
38
- end
39
27
 
40
- return txt
28
+ if public_storage[:typable_id] && s = typable_id_status(arg)
29
+ post_retweet(s, comment)
30
+ else
31
+ case arg
32
+ when /(\d+)/
33
+ post_retweet(Termtter::API.twitter.show(arg), comment)
34
+ when /@([A-Za-z0-9_]+)/
35
+ user = $1
36
+ statuses = Termtter::API.twitter.user_timeline(user)
37
+ return if statuses.empty?
38
+ post_retweet(statuses[0], comment)
39
+ end
40
+ end
41
41
  }
42
42
  )
43
43
  end
@@ -28,8 +28,8 @@ module Termtter::Client
28
28
  register_command(
29
29
  :name => :update, :alias => :u,
30
30
  :exec => lambda {|arg|
31
- unless arg.empty?
32
- params =
31
+ unless arg.rstrip.empty?
32
+ params =
33
33
  if config.easy_reply && /^\s*(@\w+)/ =~ arg
34
34
  user_name = normalize_as_user_name($1)
35
35
  in_reply_to_status_id = Termtter::API.twitter.user(user_name).status.id rescue nil
@@ -167,7 +167,8 @@ module Termtter::Client
167
167
  register_command(
168
168
  :name => :search, :aliases => [:s],
169
169
  :exec_proc => lambda {|arg|
170
- statuses = Termtter::API.twitter.search(arg)
170
+ search_option = config.search.option.empty? ? {} : config.search.option
171
+ statuses = Termtter::API.twitter.search(arg, search_option)
171
172
  public_storage[:search_keywords] << arg
172
173
  output(statuses, SearchEvent.new(arg))
173
174
  },
@@ -256,25 +257,25 @@ module Termtter::Client
256
257
  register_command(
257
258
  :name => :favorite, :aliases => [:fav],
258
259
  :exec_proc => lambda {|arg|
259
- id = 0
260
- case arg
261
- when /^\d+/
262
- id = arg.to_i
263
- when /^@([A-Za-z0-9_]+)/
264
- user_name = normalize_as_user_name($1)
265
- statuses = Termtter::API.twitter.user_timeline(user_name)
266
- return if statuses.empty?
267
- id = statuses[0].id
268
- when /^\/(.*)$/
269
- word = $1
270
- raise "Not implemented yet."
271
- else
272
- if public_storage[:typable_id] && typable_id?(arg)
273
- id = typable_id_convert(arg)
260
+ id =
261
+ case arg
262
+ when /^\d+/
263
+ arg.to_i
264
+ when /^@([A-Za-z0-9_]+)/
265
+ user_name = normalize_as_user_name($1)
266
+ statuses = Termtter::API.twitter.user_timeline(user_name)
267
+ return if statuses.empty?
268
+ statuses[0].id
269
+ when /^\/(.*)$/
270
+ word = $1
271
+ raise "Not implemented yet."
274
272
  else
275
- return
273
+ if public_storage[:typable_id] && typable_id?(arg)
274
+ typable_id_convert(arg)
275
+ else
276
+ return
277
+ end
276
278
  end
277
- end
278
279
 
279
280
  r = Termtter::API.twitter.favorite id
280
281
  puts "Favorited status ##{r.id} on user @#{r.user.screen_name} #{r.text}"
@@ -405,16 +406,9 @@ module Termtter::Client
405
406
 
406
407
  ## plugin_list :: IO ()
407
408
  def self.plugin_list
408
- plugin_list = (Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
409
+ (Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
409
410
  map {|f| File.basename(f).sub(/\.rb$/, '')}.
410
411
  sort
411
- list = plugin_list
412
- width = list.map {|i|i.size}.max + 2
413
- a = []
414
- list.sort.each_slice(4) {|i|
415
- a << i.map {|j| j + (" " * (width - j.size))}.join
416
- }
417
- puts TermColor.parse('<green>' + TermColor.escape(a.join("\n")) + '</green>')
418
412
  end
419
413
 
420
414
  register_command(
@@ -40,7 +40,7 @@ module Termtter::Client
40
40
  if part_of_user_name.nil? || part_of_user_name.empty?
41
41
  public_storage[:users].to_a
42
42
  else
43
- public_storage[:users].grep(/^#{Regexp.quote(part_of_user_name)}/i)
43
+ public_storage[:users].grep(Regexp.compile("^#{Regexp.quote(part_of_user_name)}", part_of_user_name.downcase == part_of_user_name ? Regexp::IGNORECASE : 0))
44
44
  end
45
45
 
46
46
  users.map {|u| "#{command_str} @%s" % u }
@@ -51,19 +51,19 @@ module Termtter::Client
51
51
  # completion for hashtags
52
52
  #
53
53
 
54
- public_storage[:hashtags] ||= Set.new
54
+ public_storage[:hashtags_for_completion] ||= Set.new
55
55
 
56
56
  register_hook(:collect_hashtags, :point => :pre_filter) do |statuses, event|
57
57
  statuses.each do |s|
58
- public_storage[:hashtags] += s.text.scan(/#([^\s]+)/).flatten
58
+ public_storage[:hashtags_for_completion] += s.text.scan(/#([^\s]+)/).flatten
59
59
  end
60
60
  end
61
61
 
62
- register_hook(:hashtagss_completion, :point => :completion) do |input|
62
+ register_hook(:hashtags_completion, :point => :completion) do |input|
63
63
  if /(.*)\s#([^\s]*)$/ =~ input
64
64
  command_str = $1
65
65
  part_of_hashtag = $2
66
- ht = public_storage[:hashtags]
66
+ ht = public_storage[:hashtags_for_completion]
67
67
  (ht.grep(/^#{Regexp.quote(part_of_hashtag)}/) | # prior
68
68
  ht.grep(/^#{Regexp.quote(part_of_hashtag)}/i) ).
69
69
  map { |i| "#{command_str} ##{i}" }
@@ -0,0 +1,34 @@
1
+ module Termtter::Client
2
+ passwords = {}
3
+
4
+ register_command(
5
+ :name => :switch,
6
+ :alias => :switch_user,
7
+ :exec_proc => lambda {|arg|
8
+ user_name = !arg.empty? ? normalize_as_user_name(arg) : nil
9
+ return if user_name == config.user_name
10
+
11
+ passwords[config.user_name] = config.password
12
+
13
+ if user_name
14
+ config.user_name = normalize_as_user_name(arg)
15
+ if passwords.key?(config.user_name)
16
+ config.password = passwords[config.user_name]
17
+ else
18
+ config.__clear__(:password)
19
+ end
20
+ else
21
+ config.__clear__(:user_name)
22
+ config.__clear__(:password)
23
+ end
24
+
25
+ Termtter::API.setup
26
+ call_commands('reload')
27
+ },
28
+ :help => ["switch USERNAME", "Switch twitter account."]
29
+ )
30
+
31
+ register_command(:restore_user) do |arg|
32
+ puts 'Sorry, command "restore_user" was obsoleted, and use command "switch" instead.'
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ if /linux/ =~ PLATFORM
4
+ module Termtter::Client
5
+ help = ['eject [-t]', 'eject or close']
6
+ register_command(:eject, :help => help) do |flag|
7
+ if flag.empty?
8
+ system 'eject'
9
+ else
10
+ system 'eject -t'
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -51,7 +51,7 @@ def expand_url(host, path)
51
51
  config.proxy.user_name,
52
52
  config.proxy.password)
53
53
  end
54
- res = http_class.new(host).head(path)
54
+ res = http_class.new(host).get(path, { 'User-Agent' => 'Mozilla' })
55
55
  return nil unless res.code == "301" or res.code == "302"
56
56
  res['Location'].force_encoding(Encoding::UTF_8)
57
57
  rescue
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'nokogiri'
5
+ require 'open-uri'
6
+
7
+ module Termtter::Client
8
+
9
+ public_storage[:favorited_ids] = {}
10
+
11
+ class << self
12
+ def output_favorites(target, threshold)
13
+ favorites = parse("http://favotter.matope.com/user.php?user=#{target}&threshold=#{threshold}")
14
+
15
+ public_storage[:favorited_ids].clear
16
+ alphabet = '$a'
17
+ max_amount_width = favorites.map {|f| now = f[2].to_s.size }.max
18
+ favorites.reverse.each do |id, text, amount, users|
19
+ public_storage[:favorited_ids][alphabet] = id
20
+ color = fav_color(amount)
21
+ fav = "fav#{amount == 1 ? '' : 's'}"
22
+ favorites_info = "(#{amount} #{fav})".rjust(max_amount_width + 7)
23
+ format = "<GREEN>#{favorites_info} #{alphabet}</GREEN> <YELLOW>%s</YELLOW>: <#{color}>%s</#{color}>"
24
+ values = [users.join(', '), CGI.escape(text)]
25
+ puts CGI.unescape(TermColor.parse(format % values ))
26
+ alphabet.succ!
27
+ end
28
+ end
29
+
30
+ private
31
+ def parse(url)
32
+ doc = Nokogiri(open(url).read)
33
+ doc.css('div.entry').map do |entry|
34
+ id = entry['id'].gsub(/\Astatus_/, '')
35
+ text = entry.css('span.status_text').first.content
36
+ amount = entry.css('div.info span.favotters').first.content
37
+ amount = amount.match(/(\d+)/)[1].to_i
38
+ users = entry.css('div.info span.favotters img').map {|u| u['title'] }
39
+ [id, text, amount, users]
40
+ end
41
+ end
42
+
43
+ def fav_color(amount)
44
+ case amount
45
+ when 1 then 'WHITE'
46
+ when 2 then 'GREEN'
47
+ when 3 then 'BLUE'
48
+ when 4 then 'BLUE'
49
+ else 'RED'
50
+ end
51
+ end
52
+ end
53
+
54
+ help = ['favotter [USERNAME] [THRESHOLD]', 'Show info from favotter']
55
+ register_command('favotter', :help => help) do |arg|
56
+ target = if arg.empty?
57
+ config.user_name
58
+ else
59
+ args = arg.split
60
+ threshold = args.size == 1 ? 1 : args[1]
61
+ args[0]
62
+ end
63
+ if /@(.*)/ =~ target
64
+ target = $1
65
+ end
66
+ output_favorites target, threshold
67
+ end
68
+
69
+ help = ['favotter_fav [FavoritedID]', 'Favorite favorited status']
70
+ register_command('favotter_fav', :alias => :ffav, :help => help) do |arg|
71
+ raise 'need favorited_id' if arg.empty?
72
+ if id = public_storage[:favorited_ids][arg]
73
+ call_commands("favorite #{id}")
74
+ end
75
+ end
76
+ end
77
+