termtter 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/Rakefile +15 -15
  2. data/VERSION +1 -1
  3. data/lib/plugins/appendtitle.rb +39 -19
  4. data/lib/plugins/basic.rb +25 -0
  5. data/lib/plugins/capture.rb +22 -0
  6. data/lib/plugins/channel.rb +4 -5
  7. data/lib/plugins/copy.rb +32 -0
  8. data/lib/plugins/defaults/auto_reload.rb +4 -0
  9. data/lib/plugins/defaults/cache.rb +2 -2
  10. data/lib/plugins/defaults/command_line.rb +21 -0
  11. data/lib/plugins/defaults/keyword.rb +58 -8
  12. data/lib/plugins/defaults/list.rb +6 -4
  13. data/lib/plugins/defaults/retweet.rb +6 -1
  14. data/lib/plugins/defaults/standard_commands.rb +54 -27
  15. data/lib/plugins/defaults/stdout.rb +8 -4
  16. data/lib/plugins/defaults/switch.rb +21 -9
  17. data/lib/plugins/encoding.rb +46 -0
  18. data/lib/plugins/english.rb +2 -1
  19. data/lib/plugins/friends.rb +5 -8
  20. data/lib/plugins/geo.rb +21 -0
  21. data/lib/plugins/http_server.rb +10 -3
  22. data/lib/plugins/http_server/{index.html → skin/default/index.html} +0 -0
  23. data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/001.png +0 -0
  24. data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/002.png +0 -0
  25. data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/003.png +0 -0
  26. data/lib/plugins/http_server/skin/miku/cui/chara/miku/images/004.png +0 -0
  27. data/lib/plugins/http_server/skin/miku/cui/chara/miku/script.js +66 -0
  28. data/lib/plugins/http_server/skin/miku/cui/core.js +198 -0
  29. data/lib/plugins/http_server/skin/miku/cui/util.js +65 -0
  30. data/lib/plugins/http_server/skin/miku/index.html +142 -0
  31. data/lib/plugins/http_server/skin/miku/jquery-1.4.2.min.js +154 -0
  32. data/lib/plugins/http_server/skin/sample1/index.html +165 -0
  33. data/lib/plugins/im_kayac.rb +33 -0
  34. data/lib/plugins/irc_gw.rb +53 -17
  35. data/lib/plugins/mongo.rb +112 -0
  36. data/lib/plugins/reply_sound.rb +1 -1
  37. data/lib/plugins/say.rb +2 -1
  38. data/lib/plugins/searchline.rb +1 -1
  39. data/lib/plugins/short_logger.rb +15 -0
  40. data/lib/plugins/storage.rb +1 -1
  41. data/lib/plugins/storage/status.rb +1 -1
  42. data/lib/plugins/stream.rb +1 -3
  43. data/lib/plugins/suspend.rb +9 -0
  44. data/lib/plugins/time_signal.rb +1 -1
  45. data/lib/plugins/tinyurl.rb +17 -8
  46. data/lib/plugins/truncate.rb +13 -3
  47. data/lib/plugins/update_editor.rb +1 -1
  48. data/lib/plugins/url.rb +11 -0
  49. data/lib/plugins/user_stream.rb +76 -51
  50. data/lib/termtter.rb +1 -0
  51. data/lib/termtter/active_rubytter.rb +3 -6
  52. data/lib/termtter/api.rb +18 -8
  53. data/lib/termtter/client.rb +30 -18
  54. data/lib/termtter/command.rb +22 -13
  55. data/lib/termtter/config.rb +15 -4
  56. data/lib/termtter/config_setup.rb +17 -2
  57. data/lib/termtter/config_template.erb +1 -0
  58. data/lib/termtter/default_config.rb +3 -1
  59. data/lib/termtter/hookable.rb +3 -3
  60. data/lib/termtter/httppool.rb +10 -4
  61. data/lib/termtter/memory_cache.rb +1 -1
  62. data/lib/termtter/optparse.rb +0 -4
  63. data/lib/termtter/rubytter_proxy.rb +31 -11
  64. data/lib/termtter/system_extensions.rb +9 -1
  65. data/lib/termtter/system_extensions/core_compatibles.rb +9 -2
  66. data/lib/termtter/task_manager.rb +2 -0
  67. data/spec/plugins/capital_update_spec.rb +1 -1
  68. data/spec/plugins/cool_spec.rb +1 -1
  69. data/spec/plugins/curry_spec.rb +1 -1
  70. data/spec/plugins/db_spec.rb +1 -1
  71. data/spec/plugins/defaults/hashtag_spec.rb +1 -1
  72. data/spec/plugins/defaults/list_spec.rb +1 -1
  73. data/spec/plugins/defaults/plugin_spec.rb +1 -1
  74. data/spec/plugins/defaults/retweet_spec.rb +1 -1
  75. data/spec/plugins/draft_spec.rb +1 -1
  76. data/spec/plugins/english_spec_.rb +1 -1
  77. data/spec/plugins/expand-tinyurl_spec.rb +1 -1
  78. data/spec/plugins/fib_spec.rb +1 -1
  79. data/spec/plugins/filter_spec_.rb +1 -1
  80. data/spec/plugins/footer_spec.rb +1 -1
  81. data/spec/plugins/gsub_spec.rb +1 -1
  82. data/spec/plugins/haml_spec.rb +1 -1
  83. data/spec/plugins/hi_spec.rb +1 -1
  84. data/spec/plugins/md5pass_spec.rb +1 -1
  85. data/spec/plugins/pause_spec.rb +1 -1
  86. data/spec/plugins/primes_spec_.rb +1 -1
  87. data/spec/plugins/shell_spec.rb +1 -1
  88. data/spec/plugins/sl_spec_.rb +1 -1
  89. data/spec/plugins/spam_spec.rb +1 -1
  90. data/spec/plugins/standard_commands_spec.rb +1 -1
  91. data/spec/plugins/storage/sqlite3_spec.rb +2 -2
  92. data/spec/plugins/storage/status_spec_.rb +2 -2
  93. data/spec/plugins/tinyurl_spec.rb +1 -1
  94. data/spec/plugins/truncate_spec.rb +36 -1
  95. data/spec/plugins/whois_spec_.rb +1 -1
  96. data/spec/termtter/active_rubytter_spec.rb +1 -1
  97. data/spec/termtter/api_spec.rb +1 -1
  98. data/spec/termtter/client_spec.rb +1 -1
  99. data/spec/termtter/command_spec.rb +1 -1
  100. data/spec/termtter/config_setup_spec.rb +1 -1
  101. data/spec/termtter/config_spec.rb +9 -1
  102. data/spec/termtter/crypt_spec.rb +1 -1
  103. data/spec/termtter/event_spec.rb +1 -1
  104. data/spec/termtter/hook_spec.rb +1 -1
  105. data/spec/termtter/hookable_spec.rb +1 -1
  106. data/spec/termtter/memory_cache_spec.rb +1 -1
  107. data/spec/termtter/optparse_spec.rb +1 -1
  108. data/spec/termtter/rubytter_proxy_spec.rb +1 -1
  109. data/spec/termtter/system_extensions/windows_spec.rb +1 -1
  110. data/spec/termtter/system_extensions_spec.rb +1 -1
  111. data/spec/termtter/task_manager_spec.rb +1 -1
  112. data/spec/termtter/task_spec.rb +1 -1
  113. data/spec/termtter_spec.rb +1 -1
  114. data/termtter.gemspec +326 -0
  115. metadata +81 -149
  116. data/.gitignore +0 -5
data/Rakefile CHANGED
@@ -25,21 +25,21 @@ rescue LoadError
25
25
  puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
26
  end
27
27
 
28
- require 'spec/rake/spectask'
29
- Spec::Rake::SpecTask.new(:spec) do |spec|
30
- spec.libs << 'lib' << 'spec'
31
- spec.spec_files = FileList['spec/**/*_spec.rb']
32
- end
33
-
34
- Spec::Rake::SpecTask.new(:rcov) do |spec|
35
- spec.libs << 'lib' << 'spec'
36
- spec.pattern = 'spec/**/*_spec.rb'
37
- spec.rcov = true
38
- end
39
-
40
- task :spec => :check_dependencies
41
-
42
- task :default => :spec
28
+ # require 'spec/rake/spectask'
29
+ # Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ # spec.libs << 'lib' << 'spec'
31
+ # spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ # end
33
+ #
34
+ # Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ # spec.libs << 'lib' << 'spec'
36
+ # spec.pattern = 'spec/**/*_spec.rb'
37
+ # spec.rcov = true
38
+ # end
39
+ #
40
+ # task :spec => :check_dependencies
41
+ #
42
+ # task :default => :spec
43
43
 
44
44
  require 'rake/rdoctask'
45
45
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.0
1
+ 1.10.0
@@ -3,32 +3,50 @@ require 'uri'
3
3
  require 'open-uri'
4
4
  require 'nokogiri'
5
5
  require 'timeout'
6
- require 'memcache'
7
6
  require 'digest/sha1'
8
7
 
9
8
  module Termtter::Client
10
9
  config.plugins.appendtitle.set_default(:timeout, 30)
11
10
  config.plugins.appendtitle.set_default(:cache_expire, 3600 * 24 * 7)
12
11
 
13
- def self.fetch_title(uri)
12
+ def self.fetch_title_data(uri) # returns {:title, :uri} | {:uri} | nil
14
13
  return unless uri
15
- key = %w{ plugins appendtitle title}.push(Digest::SHA1.hexdigest(uri)).join('-')
14
+ key = %w{ plugins appendtitle title-data}.push(Digest::SHA1.hexdigest(uri)).join('-')
16
15
  if v = memory_cache.get(key)
17
16
  logger.debug "appendtitle: cache hit for #{uri}"
18
17
  return v
19
18
  end
20
19
 
21
- memory_cache.set(key, '', config.plugins.appendtitle.cache_expire) # to avoid duplicate fetch
20
+ memory_cache.set(key, {}, config.plugins.appendtitle.cache_expire) # to avoid duplicate fetch
21
+ logger.debug "appendtitle: fetching title for #{uri}"
22
+ data = {}
23
+ uri_fetch = uri
22
24
  begin
23
- logger.debug "appendtitle: fetching title for #{uri}"
24
- source = Nokogiri(open(uri).read)
25
- if source and source.at('title')
26
- title = source.at('title').text
27
- memory_cache.set(key, title, config.plugins.appendtitle.cache_expire)
28
- return title
25
+ io = URI.parse(uri_fetch).read
26
+ base_uri = io.base_uri.to_s
27
+ base_uri = uri_fetch if base_uri.length > 1000
28
+ data[:uri] = base_uri
29
+ charset = io.scan(/charset="?([^\s"]*)/i).flatten.inject(Hash.new{0}){|a, b| a[b]+=1; a}.to_a.sort_by{|a|a[1]}.reverse.first[0] # XXX: scan charset from source
30
+ begin # title
31
+ source = Nokogiri(io, base_uri, charset)
32
+ title = source.at('title').text rescue nil
33
+ title ||= source.at('h1').text rescue nil
34
+ title ||= source.at('h2').text rescue nil
35
+ title = title.gsub(/\n/, '').gsub(/\s+/, ' ') if title
36
+ data[:title] = title if title
37
+ rescue
29
38
  end
30
- nil
31
- rescue Timeout::Error, StandardError
39
+ memory_cache.set(key, data, config.plugins.appendtitle.cache_expire)
40
+ data
41
+ rescue RuntimeError => error
42
+ # example: redirection forbidden: http://bit.ly/gSarwN -> https://github.com/jugyo/termtter/commit/6e5fa4455a5117fb6c10bdf82bae52cfcf57a91f
43
+ if error.message =~ /^redirection forbidden/
44
+ logger.debug "appendtitle: #{error.message}"
45
+ uri_fetch = error.message.split(/\s+/).last
46
+ retry
47
+ end
48
+ rescue Timeout::Error, StandardError => error
49
+ logger.debug "appendtitle: error #{uri}, #{error.class.to_s}: #{error.message}"
32
50
  nil
33
51
  end
34
52
  end
@@ -40,20 +58,22 @@ module Termtter::Client
40
58
  threads = statuses.map do |status|
41
59
  Thread.new{
42
60
  begin
43
- status.text.gsub!(URI.regexp(['http', 'https'])) {|uri|
44
- title = fetch_title(uri)
45
- title = title.gsub(/\n/, '').gsub(/\s+/, ' ') if title
61
+ status.text.gsub!(URI.regexp(['http', 'https'])) {|uri_before|
62
+ data = fetch_title_data(uri_before) || {}
63
+ title = data[:title]
46
64
  body_for_compare = status.text.gsub(/\n/, '').gsub(/\s+/, ' ')
65
+ uri_after = data[:uri] || uri_before
47
66
  if title and not (
48
67
  body_for_compare.include? title or
49
68
  body_for_compare.include? title[0..(title.length/2)] or
50
69
  body_for_compare.include? title[(title.length/2)..-1]) # XXX: heuristic!!!
51
- "#{uri} (#{title})"
70
+ "#{uri_after} (#{title})"
52
71
  else
53
- uri
72
+ uri_after
54
73
  end
55
74
  }
56
- rescue
75
+ rescue => error
76
+ logger.debug "appendtitle: [ERROR] #{error.class.to_s}: #{error.message}"
57
77
  end
58
78
  }
59
79
  end
@@ -72,4 +92,4 @@ module Termtter::Client
72
92
  end
73
93
 
74
94
  # appendtitle.rb:
75
- # append title for uri.
95
+ # append title for uri and expand short uri.
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ config.access_token = ''
3
+ config.access_token_secret = ''
4
+
5
+ module OAuth
6
+ class AccessToken
7
+ def initialize(consumer, access_token, access_token_secret)
8
+ end
9
+ end
10
+ end
11
+ module Termtter
12
+ class RubytterProxy
13
+ def initialize(access_token, twitter_option)
14
+ user_name = config.plugins.basic.user_name
15
+ password = config.plugins.basic.password
16
+ @rubytter = Rubytter.new(user_name, password, twitter_option)
17
+ end
18
+ end
19
+ end
20
+
21
+ # basic.rb
22
+ # Use Basic Auth instead of OAuth
23
+ #
24
+ # config.plugins.basic.user_name = 'your_name'
25
+ # config.plugins.basic.password = 'the secret'
@@ -0,0 +1,22 @@
1
+ require 'stringio'
2
+ module Termtter::Client
3
+ register_command(
4
+ 'capture',
5
+ :alias => 'cap',
6
+ :help => ['capture FILENAME COMMAND', 'capture the output of command to file']
7
+ ) do |args|
8
+ org = $stdout
9
+ begin
10
+ filename, command = args.split(/\s+/, 2)
11
+ $stdout = io = StringIO.new
12
+ execute(command)
13
+ ensure
14
+ $stdout = org
15
+ end
16
+
17
+ File.open(filename, 'a') do |file|
18
+ file << io.string.gsub(/\e\[\d+m/, '')
19
+ end
20
+ puts "=> #{filename.inspect}"
21
+ end
22
+ end
@@ -67,7 +67,6 @@ Termtter::Client.register_command(
67
67
  args = @since_id ? [{:since_id => @since_id}] : []
68
68
  statuses = Termtter::API.call_by_channel(now_channel, *args)
69
69
  unless statuses.empty?
70
- print "\e[0G" + "\e[K" unless win?
71
70
  @since_id = statuses[0].id
72
71
  Termtter::Client.output(statuses, Termtter::Event.new(:update_friends_timeline, :type => :main))
73
72
  Readline.refresh_line if arg =~ /\-r/
@@ -94,7 +93,7 @@ Termtter::Client.register_hook(
94
93
  when :direct_message, :direct
95
94
  :direct
96
95
  when :search
97
- :"#{e[:search_keyword]}_search"
96
+ :"#{e[:query]}_search"
98
97
  when :reply, :replies
99
98
  :replies
100
99
  when :show
@@ -117,8 +116,9 @@ Termtter::Client.register_hook(
117
116
  config.plugins.channel.channel_to_hash_proc.call(otc.to_s.gsub(/^\//, "")) %
118
117
  config.plugins.stdout.colors.size]
119
118
  colorize_channel_cache[otc] = ccolor
120
- th = "#{config.plugin.channel.colorize ? "<#{ccolor}>":""}#{c.to_s.length > config.plugins.channel.output_length ?
121
- otc.to_s[0, config.plugins.channel.output_length] : otc.to_s.rjust(config.plugins.channel.output_length)}#{config.plugin.channe.colorize ? "</#{ccolor}>":""}<90>| </90>"
119
+ cgray = config.plugins.stdout.gray || config.plugins.stdout.colors.last
120
+ th = "#{config.plugins.channel.colorize ? "<#{ccolor}>":""}#{c.to_s.length > config.plugins.channel.output_length ?
121
+ otc.to_s[0, config.plugins.channel.output_length] : otc.to_s.rjust(config.plugins.channel.output_length)}#{config.plugins.channel.colorize ? "</#{ccolor}>":""}<#{cgray}>| </#{cgray}>"
122
122
  th + t
123
123
  }
124
124
  )
@@ -133,7 +133,6 @@ config.plugins.channel.auto_reload_channels.each do |c, i|
133
133
  args = since_ids[c] ? [{:since_id => since_ids[c]}] : []
134
134
  statuses = Termtter::API.call_by_channel(c, *args)
135
135
  unless statuses.empty?
136
- print "\e[0G" + "\e[K" unless win?
137
136
  since_ids[c] = statuses[0].id
138
137
  Termtter::Client.output(statuses, Termtter::Event.new(:"update_#{c}", :type => :channel, :channel => c))
139
138
  Readline.refresh_line
@@ -0,0 +1,32 @@
1
+ config.plugins.copy.set_default(:style, "@<%= t.user.screen_name %>: <%= t.text %> [ <%= url %> ]")
2
+
3
+ def copy_to_clipboard(str)
4
+ if /darwin/i =~ RUBY_PLATFORM
5
+ IO.popen("pbcopy", "w") do |io|
6
+ io.print str
7
+ end
8
+ else
9
+ puts "Sorry, this plugin is only in Mac OS X."
10
+ end
11
+ str
12
+ end
13
+
14
+ Termtter::Client.plug 'url'
15
+
16
+ Termtter::Client.register_command(:name => :copy,
17
+ :exec => lambda do |arg|
18
+ t = Termtter::API.twitter.show(arg)
19
+ url = url_by_tweet(t)
20
+ erbed_text = ERB.new(config.plugins.copy.style).result(binding)
21
+
22
+ puts "Copied=> #{copy_to_clipboard(erbed_text)}"
23
+ end)
24
+
25
+ Termtter::Client.register_command(:name => :copy_url,
26
+ :exec => lambda do |arg|
27
+ t = Termtter::API.twitter.show(arg)
28
+ url = url_by_tweet(t)
29
+
30
+ puts "Copied=> #{copy_to_clipboard(url)}"
31
+
32
+ end)
@@ -17,6 +17,10 @@ Termtter::Client.add_task(
17
17
  &auto_reload_proc
18
18
  )
19
19
 
20
+ config.set_assign_hook(:update_interval) do |v|
21
+ Termtter::Client.task_manager.get_task(:auto_reload).interval = v
22
+ end
23
+
20
24
  Termtter::Client.register_hook(
21
25
  :name => :auto_reload_init,
22
26
  :point => :initialize,
@@ -3,14 +3,14 @@ require 'pp'
3
3
  module Termtter::Client
4
4
  register_command(
5
5
  :name => :"cache stats",
6
- :help => 'Show Memcached stats.',
6
+ :help => ['cache stats', 'Show Memcached stats.'],
7
7
  :exec_proc => lambda {|arg|
8
8
  puts memory_cache.stats.pretty_inspect
9
9
  })
10
10
 
11
11
  register_command(
12
12
  :name => :"cache flush",
13
- :help => 'Flush all caches.',
13
+ :help => ['cache flush', 'Flush all caches.'],
14
14
  :exec_proc => lambda {|arg|
15
15
  memory_cache.flush_all
16
16
  logger.info "cache flushed."
@@ -64,6 +64,7 @@ module Termtter
64
64
  Client.handle_error(e)
65
65
  end
66
66
  end
67
+ Client.exit
67
68
  end
68
69
  @input_thread.join
69
70
  end
@@ -126,10 +127,30 @@ module Termtter
126
127
  trap("CONT") do
127
128
  Readline.refresh_line
128
129
  end
130
+ trap_sigwinch
129
131
  rescue ArgumentError
130
132
  rescue Errno::ENOENT
131
133
  end
132
134
  end
135
+
136
+ # for Ruby 1.9.2(or later)'s Readline
137
+ # TODO: support other platforms (like Mac OS X)
138
+ if Readline.respond_to?(:set_screen_size) && /linux/ =~ RUBY_PLATFORM
139
+ TIOCGWINSZ = 0x5413 # in Linux
140
+
141
+ def trap_sigwinch
142
+ trap('WINCH') do
143
+ dat = ''
144
+ STDOUT.ioctl(TIOCGWINSZ, dat)
145
+ rows, cols = dat.unpack('S!4')
146
+ Readline.set_screen_size(rows, cols)
147
+ ENV['LINES'] = rows.to_s
148
+ ENV['COLUMNS'] = cols.to_s
149
+ end
150
+ end
151
+ else
152
+ def trap_sigwinch; end
153
+ end
133
154
  end
134
155
 
135
156
  Client.register_hook(:initialize_command_line, :point => :init_command_line) do
@@ -14,11 +14,34 @@ config.plugins.keyword.set_default(
14
14
  ['on_yellow', 'white'],
15
15
  ]
16
16
  )
17
-
18
17
  config.plugins.keyword.set_default(:keywords, [])
18
+ config.plugins.keyword.set_default(:notify, true)
19
+ config.plugins.keyword.set_default(:filter, false)
20
+ config.plugins.keyword.set_default(:apply_user_name, false)
21
+
22
+ def select_matched(statuses)
23
+ regexp = Regexp.union(*public_storage[:keywords].map(&:to_s))
24
+ statuses.select do |status|
25
+ /#{regexp}/ =~ status.text ||
26
+ (config.plugins.keyword.apply_user_name == true && /#{regexp}/ =~ status[:user][:screen_name])
27
+ end
28
+ end
29
+
30
+ def load_keywords
31
+ public_storage[:keywords] += config.plugins.keyword.keywords
32
+ file = File.expand_path(config.plugins.keyword.file)
33
+ if File.exists?(file)
34
+ public_storage[:keywords] += File.read(file).split(/\n/)
35
+ end
36
+ end
19
37
 
20
38
  module Termtter::Client
21
- public_storage[:keywords] ||= Set.new(config.plugins.keyword.keywords)
39
+ public_storage[:keywords] ||= Set.new()
40
+
41
+ register_hook :initialize_for_keywords, :point => :initialize do
42
+ config.plugins.keyword.set_default(:file, File.join(Termtter::CONF_DIR, 'keywords'))
43
+ load_keywords
44
+ end
22
45
 
23
46
  register_hook :highlight_keywords, :point => :pre_coloring do |text, event|
24
47
  public_storage[:keywords].each_with_index do |keyword, index|
@@ -33,13 +56,18 @@ module Termtter::Client
33
56
  text
34
57
  end
35
58
 
59
+ register_hook :keyword_filter, :point => :filter_for_output do |statuses, event|
60
+ if config.plugins.keyword.filter == true && event == :update_friends_timeline
61
+ select_matched(statuses)
62
+ else
63
+ statuses
64
+ end
65
+ end
66
+
36
67
  register_hook :notify_for_keywords, :point => :output do |statuses, event|
37
- if event == :update_friends_timeline
38
- regexp = Regexp.union(*public_storage[:keywords].map(&:to_s))
39
- statuses.select { |status|
40
- /#{regexp}/ =~ status.text
41
- }.each do |status|
42
- notify(status.user.screen_name, status.text)
68
+ if config.plugins.keyword.notify == true && event == :update_friends_timeline
69
+ select_matched(statuses).each do |status|
70
+ notify(status.user.screen_name, status.text) unless status[:user][:screen_name] == config.user_name
43
71
  end
44
72
  end
45
73
  end
@@ -66,4 +94,26 @@ module Termtter::Client
66
94
  ) do |args|
67
95
  p public_storage[:keywords].to_a
68
96
  end
97
+
98
+ register_command(
99
+ 'keyword save',
100
+ :help => ['keyword save', 'Save keywords']
101
+ ) do |args|
102
+ File.open(config.plugins.keyword.file, 'w') {|f| f << public_storage[:keywords].to_a.join("\n") }
103
+ end
104
+
105
+ register_command(
106
+ 'keyword edit',
107
+ :help => ['keyword edit', 'Edit keywords']
108
+ ) do |args|
109
+ system ENV['EDITOR'], config.plugins.keyword.file
110
+ end
111
+
112
+
113
+ register_command(
114
+ 'keyword load',
115
+ :help => ['keyword load', 'load keywords']
116
+ ) do |args|
117
+ load_keywords
118
+ end
69
119
  end
@@ -23,6 +23,8 @@ module Termtter::Client
23
23
  options = {}
24
24
  end
25
25
 
26
+ options[:include_rts] = 1
27
+
26
28
  last_error = nil
27
29
  if arg.empty?
28
30
  event = :list_friends_timeline
@@ -93,7 +95,7 @@ module Termtter::Client
93
95
  users.each{ |screen_name|
94
96
  begin
95
97
  user = Termtter::API.twitter.cached_user(screen_name) || Termtter::API.twitter.user(screen_name)
96
- Termtter::API.twitter.add_member_to_list(slug, user.id)
98
+ Termtter::API.twitter.add_member_to_list(config.user_name, slug, user.id)
97
99
  puts "#{slug} + #{screen_name}"
98
100
  rescue => e
99
101
  handle_error(e)
@@ -111,7 +113,7 @@ module Termtter::Client
111
113
  users.each{ |screen_name|
112
114
  begin
113
115
  user = Termtter::API.twitter.cached_user(screen_name) || Termtter::API.twitter.user(screen_name)
114
- Termtter::API.twitter.remove_member_from_list(slug, user.id)
116
+ Termtter::API.twitter.remove_member_from_list(config.user_name, slug, user.id)
115
117
  puts "#{slug} - #{screen_name}"
116
118
  rescue => e
117
119
  handle_error(e)
@@ -132,7 +134,7 @@ module Termtter::Client
132
134
  opt.on('--private') {|v| param[:mode] = 'private' }
133
135
  opt.parse(options)
134
136
  }
135
- list = Termtter::API.twitter.create_list(slug, param)
137
+ list = Termtter::API.twitter.create_list(config.user_name, slug, param)
136
138
  public_storage[:lists] << list.full_name
137
139
  p [list.full_name, param]
138
140
  },
@@ -146,7 +148,7 @@ module Termtter::Client
146
148
  arg.split(' ').each{ |list_name|
147
149
  begin
148
150
  slug = list_name_to_slug(list_name)
149
- list = Termtter::API.twitter.delete_list(slug)
151
+ list = Termtter::API.twitter.delete_list(config.user_name, slug)
150
152
  public_storage[:lists].delete(list.full_name)
151
153
  puts "#{list.full_name} deleted"
152
154
  rescue => e