termtter 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/lib/plugins/aa.rb +1 -1
  4. data/lib/plugins/appendtitle.rb +5 -12
  5. data/lib/plugins/defaults/auto_reload.rb +1 -0
  6. data/lib/plugins/defaults/cache.rb +18 -0
  7. data/lib/plugins/defaults/command_line.rb +1 -1
  8. data/lib/plugins/defaults/fib.rb +15 -6
  9. data/lib/plugins/defaults/retweet.rb +1 -1
  10. data/lib/plugins/defaults/standard_commands.rb +31 -25
  11. data/lib/plugins/defaults/stdout.rb +12 -4
  12. data/lib/plugins/defaults/system.rb +27 -0
  13. data/lib/plugins/dupu.rb +13 -0
  14. data/lib/plugins/erase.rb +4 -0
  15. data/lib/plugins/error_log.rb +17 -0
  16. data/lib/plugins/expand-tinyurl.rb +8 -1
  17. data/lib/plugins/growl.rb +10 -7
  18. data/lib/plugins/hatena_keyword_haiku.rb +88 -0
  19. data/lib/plugins/irc_gw.rb +12 -4
  20. data/lib/plugins/itunes.rb +29 -26
  21. data/lib/plugins/mecab.rb +23 -0
  22. data/lib/plugins/mudan_kinshi.rb +13 -0
  23. data/lib/plugins/ndkn.rb +7 -0
  24. data/lib/plugins/other_user.rb +47 -0
  25. data/lib/plugins/reply_sound.rb +75 -25
  26. data/lib/plugins/ruby-v.rb +10 -0
  27. data/lib/plugins/time_signal.rb +21 -0
  28. data/lib/plugins/tinyurl.rb +6 -4
  29. data/lib/plugins/train.rb +1 -1
  30. data/lib/plugins/translation.rb +2 -0
  31. data/lib/plugins/user_stream.rb +122 -0
  32. data/lib/plugins/whale.rb +28 -0
  33. data/lib/termtter/active_rubytter.rb +4 -0
  34. data/lib/termtter/api.rb +55 -30
  35. data/lib/termtter/client.rb +19 -4
  36. data/lib/termtter/config_setup.rb +10 -2
  37. data/lib/termtter/config_template.erb +4 -2
  38. data/lib/termtter/crypt.rb +13 -0
  39. data/lib/termtter/default_config.rb +5 -2
  40. data/lib/termtter/hookable.rb +4 -0
  41. data/lib/termtter/memory_cache.rb +67 -19
  42. data/lib/termtter/rubytter_proxy.rb +101 -26
  43. data/lib/termtter/system_extensions.rb +22 -18
  44. data/lib/termtter.rb +5 -1
  45. data/spec/termtter/crypt_spec.rb +16 -0
  46. data/spec/termtter/rubytter_proxy_spec.rb +14 -0
  47. metadata +85 -26
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  gem.add_dependency("json", ">= 1.1.3")
12
12
  gem.add_dependency("highline", ">= 1.5.0")
13
13
  gem.add_dependency("termcolor", ">= 1.0.0")
14
- gem.add_dependency("rubytter", ">= 0.11.0")
14
+ gem.add_dependency("rubytter", ">= 1.4.0")
15
15
  gem.add_dependency("notify", ">= 0.2.1")
16
16
  gem.authors = %w(jugyo ujihisa)
17
17
  gem.email = 'jugyo.org@gmail.com'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.0
1
+ 1.9.0
data/lib/plugins/aa.rb CHANGED
@@ -34,6 +34,7 @@ end
34
34
 
35
35
  Termtter::Client.register_command(
36
36
  :name => :aa,
37
+ :author => 'hitode909',
37
38
  :exec_proc => lambda {|arg|
38
39
  name = Termtter::Client.normalize_as_user_name(arg)
39
40
  command = name.length > 0 ? "u @#{name} #{AAMaker.make}" : "u #{AAMaker.make}"
@@ -41,4 +42,3 @@ Termtter::Client.register_command(
41
42
  },
42
43
  :help => ["aa [(Optinal) USER]", "Post a AA"]
43
44
  )
44
-
@@ -9,33 +9,26 @@ require 'digest/sha1'
9
9
  module Termtter::Client
10
10
  config.plugins.appendtitle.set_default(:timeout, 30)
11
11
  config.plugins.appendtitle.set_default(:cache_expire, 3600 * 24 * 7)
12
- config.plugins.appendtitle.set_default(:memcached_server, 'localhost:11211')
13
-
14
- def self.memcache_client
15
- @memcache_client ||= MemCache.new(config.plugins.appendtitle.memcached_server)
16
- end
17
12
 
18
13
  def self.fetch_title(uri)
19
14
  return unless uri
20
- key = %w{ termtter plugins appendtitle title}.push(Digest::SHA1.hexdigest(uri)).join('-')
21
- if v = memcache_client.get(key)
15
+ key = %w{ plugins appendtitle title}.push(Digest::SHA1.hexdigest(uri)).join('-')
16
+ if v = memory_cache.get(key)
22
17
  logger.debug "appendtitle: cache hit for #{uri}"
23
18
  return v
24
19
  end
25
20
 
26
- memcache_client.set(key, '', config.plugins.appendtitle.cache_expire) # to avoid duplicate fetch
21
+ memory_cache.set(key, '', config.plugins.appendtitle.cache_expire) # to avoid duplicate fetch
27
22
  begin
28
23
  logger.debug "appendtitle: fetching title for #{uri}"
29
24
  source = Nokogiri(open(uri).read)
30
25
  if source and source.at('title')
31
26
  title = source.at('title').text
32
- memcache_client.set(key, title, config.plugins.appendtitle.cache_expire)
27
+ memory_cache.set(key, title, config.plugins.appendtitle.cache_expire)
33
28
  return title
34
29
  end
35
30
  nil
36
- rescue Timeout::Error
37
- nil
38
- rescue
31
+ rescue Timeout::Error, StandardError
39
32
  nil
40
33
  end
41
34
  end
@@ -4,6 +4,7 @@ auto_reload_proc = lambda do
4
4
  Termtter::Client.execute('reload -r')
5
5
  rescue TimeoutError
6
6
  # do nothing
7
+ rescue
7
8
  rescue Exception => e
8
9
  Termtter::Client.handle_error(e)
9
10
  end
@@ -0,0 +1,18 @@
1
+ require 'pp'
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :"cache stats",
6
+ :help => 'Show Memcached stats.',
7
+ :exec_proc => lambda {|arg|
8
+ puts memory_cache.stats.pretty_inspect
9
+ })
10
+
11
+ register_command(
12
+ :name => :"cache flush",
13
+ :help => 'Flush all caches.',
14
+ :exec_proc => lambda {|arg|
15
+ memory_cache.flush_all
16
+ logger.info "cache flushed."
17
+ })
18
+ end
@@ -113,7 +113,7 @@ module Termtter
113
113
 
114
114
  def trap_setting()
115
115
  return if /mswin(?!ce)|mingw|bccwin/ =~ RUBY_PLATFORM
116
-
116
+
117
117
  begin
118
118
  stty_save = `stty -g`.chomp
119
119
  trap("INT") do
@@ -1,7 +1,16 @@
1
1
  def fib(n)i=0;j=1;n.times{j=i+i=j};i end
2
- Termtter::Client.register_command(:fib) do |arg|
3
- n = arg.to_i
4
- text = "fib(#{n}) = #{fib n}"
5
- Termtter::API.twitter.update(text)
6
- puts "=> " << text
7
- end
2
+ Termtter::Client.register_command(:name => :fib,
3
+ :aliases => [:f, :ho],
4
+ :exec => lambda do |arg|
5
+ case arg
6
+ when "ukumori"
7
+ puts 'Does it mean "Sora Harakami (@sora_h)"?'
8
+ when "ootsuite", "otsuite"
9
+ puts "NDA :D"
10
+ else
11
+ n = arg.to_i
12
+ text = "fib(#{n}) = #{fib n}"
13
+ Termtter::API.twitter.update(text)
14
+ puts "=> " << text
15
+ end
16
+ end)
@@ -11,7 +11,7 @@ config.plugins.retweet.set_default(
11
11
 
12
12
  module Termtter::Client
13
13
  def self.post_retweet(s, comment = nil)
14
- s.user.protected and
14
+ s[:user][:protected] and
15
15
  config.plugins.retweet.confirm_protected and
16
16
  !confirm("#{s.user.screen_name} is protected! Are you sure?", false) and
17
17
  return
@@ -32,25 +32,31 @@ module Termtter::Client
32
32
  register_command(
33
33
  :name => :update, :alias => :u,
34
34
  :exec => lambda {|arg|
35
- unless arg.empty?
36
- params =
37
- if config.easy_reply && /^\s*(@\w+)/ =~ arg
38
- user_name = normalize_as_user_name($1)
39
- in_reply_to_status_id =
40
- Termtter::API.twitter.user(user_name).status.id rescue nil
41
- in_reply_to_status_id ?
42
- {:in_reply_to_status_id => in_reply_to_status_id} : {}
43
- else
44
- {}
45
- end
46
-
47
- result = Termtter::API.twitter.update(arg, params)
48
-
49
- if result.text == arg
50
- puts "updated => #{result.text}"
35
+ return if arg.empty?
36
+ params =
37
+ if config.easy_reply && /^\s*(@\w+)/ =~ arg
38
+ user_name = normalize_as_user_name($1)
39
+ in_reply_to_status_id =
40
+ Termtter::API.twitter.user(user_name).status.id rescue nil
41
+ in_reply_to_status_id ?
42
+ {:in_reply_to_status_id => in_reply_to_status_id} : {}
51
43
  else
52
- puts TermColor.parse("<red>Failed to update :(</red>")
44
+ {}
53
45
  end
46
+
47
+ # "u $aa msg" is likely to be a mistake of
48
+ # "re $aa msg".
49
+ if /^\s*\d+\s/ =~ arg
50
+ puts "Does it mean `re[ply] #{arg}`?"
51
+ break
52
+ end
53
+
54
+ result = Termtter::API.twitter.update(arg, params)
55
+
56
+ if result.text == arg
57
+ puts "updated => #{result.text}"
58
+ else
59
+ puts TermColor.parse("<red>Failed to update :(</red>")
54
60
  end
55
61
  },
56
62
  :help => ["update,u TEXT", "Post a new message"]
@@ -127,7 +133,7 @@ module Termtter::Client
127
133
  end
128
134
 
129
135
  def self.get_friends_or_followers(type, user_name, max)
130
- raise "type should :friends or :followers" unless [:friends, :followers].include? type
136
+ raise "type should be :friends or :followers" unless [:friends, :followers].include? type
131
137
  users = []
132
138
  cursor = -1
133
139
  begin
@@ -158,7 +164,7 @@ module Termtter::Client
158
164
  )
159
165
 
160
166
  def self.friends_or_followers_command(type, arg)
161
- raise "type should :friends or :followers" unless [:friends, :followers].include? type
167
+ raise "type should be :friends or :followers" unless [:friends, :followers].include? type
162
168
  limit = 20
163
169
  if /\-([\d]+)/ =~ arg
164
170
  limit = $1.to_i
@@ -171,7 +177,7 @@ module Termtter::Client
171
177
  users.reverse.each{|user|
172
178
  padding = ' ' * (longest - user.screen_name.length)
173
179
  user_id = Termtter::Client.data_to_typable_id(user.id) rescue ''
174
- color = user.following ? 'BLACK' : 'RED'
180
+ color = user.following ? config.plugins.stdout.colors.first : config.plugins.stdout.colors.last
175
181
  mark = user.following ? '♥' : '✂'
176
182
  erbed_text = ERB.new(config.plugins.standard.one_line_profile_format).result(binding)
177
183
  puts TermColor.unescape(TermColor.parse(erbed_text))
@@ -261,7 +267,7 @@ module Termtter::Client
261
267
  args.split(' ').each do |arg|
262
268
  user_name = normalize_as_user_name(arg)
263
269
  user = Termtter::API::twitter.follow(user_name)
264
- puts "followed #{user.name}"
270
+ puts "followed #{user.screen_name}"
265
271
  end
266
272
  },
267
273
  :help => ['follow USER', 'Follow user']
@@ -273,7 +279,7 @@ module Termtter::Client
273
279
  args.split(' ').each do |arg|
274
280
  user_name = normalize_as_user_name(arg)
275
281
  user = Termtter::API::twitter.leave(user_name)
276
- puts "leaved #{user.name}"
282
+ puts "left #{user.screen_name}"
277
283
  end
278
284
  },
279
285
  :help => ['leave USER', 'Leave user']
@@ -285,7 +291,7 @@ module Termtter::Client
285
291
  args.split(' ').each do |arg|
286
292
  user_name = normalize_as_user_name(arg)
287
293
  user = Termtter::API::twitter.block(user_name)
288
- puts "blocked #{user.name}"
294
+ puts "blocked #{user.screen_name}"
289
295
  end
290
296
  },
291
297
  :help => ['block USER', 'Block user']
@@ -297,7 +303,7 @@ module Termtter::Client
297
303
  args.split(' ').each do |arg|
298
304
  user_name = normalize_as_user_name(arg)
299
305
  user = Termtter::API::twitter.unblock(user_name)
300
- puts "unblocked #{user.name}"
306
+ puts "unblocked #{user.screen_name}"
301
307
  end
302
308
  },
303
309
  :help => ['unblock USER', 'Unblock user']
@@ -442,7 +448,7 @@ module Termtter::Client
442
448
  :alias => :plugin,
443
449
  :exec_proc => lambda {|arg|
444
450
  if arg.empty?
445
- plugin_list
451
+ puts plugin_list.join(', ')
446
452
  return
447
453
  end
448
454
  begin
@@ -14,7 +14,7 @@ config.plugins.stdout.set_default(
14
14
  '<90>',
15
15
  '<%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%>',
16
16
  '<%=retweeted_status_id ? " (retweet_to [#{retweeted_status_id}]) " : ""%>',
17
- '<%=source%><%=s.user.protected ? "[P]" : ""%>',
17
+ '<%=source%><%=s[:user][:protected] ? "[P]" : ""%>',
18
18
  '</90>'
19
19
  ].join('')
20
20
  )
@@ -98,6 +98,10 @@ module Termtter
98
98
  print_statuses(statuses, event)
99
99
  end
100
100
 
101
+ def inspect
102
+ "#<Termtter::StdOut @name=#{@name}, @points=#{@points.inspect}, @exec_proc=#{@exec_proc.inspect}>"
103
+ end
104
+
101
105
  def print_statuses(statuses, event, sort = true, time_format = nil)
102
106
  return unless statuses and statuses.first
103
107
  time_format ||= Termtter::Client.time_format_for statuses
@@ -122,7 +126,7 @@ module Termtter
122
126
 
123
127
  def status_line(s, time_format, event, indent = 0)
124
128
  return '' unless s
125
- text = TermColor.escape(s.text)
129
+ text = escape(TermColor.escape(s.text))
126
130
  color = color_of_user(s.user)
127
131
  status_id = Termtter::Client.data_to_typable_id(s.id)
128
132
  reply_to_status_id =
@@ -148,13 +152,13 @@ module Termtter
148
152
 
149
153
  text = colorize_users(text)
150
154
  text = Client.get_hooks(:pre_coloring).inject(text) {|result, hook|
151
- Termtter::Client.logger.debug "stdout status_line: call hook :pre_coloring #{hook.inspect}"
155
+ #Termtter::Client.logger.debug "stdout status_line: call hook :pre_coloring #{hook.inspect}"
152
156
  hook.call(result, event)
153
157
  }
154
158
  indent_text = indent > 0 ? eval(config.plugins.stdout.indent_format) : ''
155
159
  erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
156
160
  erbed_text = Client.get_hooks(:pre_output).inject(erbed_text) {|result, hook|
157
- Termtter::Client.logger.debug "stdout status_line: call hook :pre_output #{hook.inspect}"
161
+ #Termtter::Client.logger.debug "stdout status_line: call hook :pre_output #{hook.inspect}"
158
162
  hook.call(result, event)
159
163
  }
160
164
  text = TermColor.unescape(TermColor.parse(erbed_text) + "\n")
@@ -203,6 +207,10 @@ module Termtter
203
207
  def color_of_screen_name_cache
204
208
  @color_of_screen_name_cache ||= {}
205
209
  end
210
+
211
+ def escape(data)
212
+ data.gsub(/[:cntrl:]/) {|c| c == "\n" ? c : c.dump[1...-1]}.untaint
213
+ end
206
214
  end
207
215
 
208
216
  Client.register_hook(StdOut.new)
@@ -0,0 +1,27 @@
1
+ module Termtter::Client
2
+ register_command('hook list') do
3
+ name_max_size = hooks.keys.map{|i|i.size}.max
4
+ points_max_size = hooks.values.map{|i|i.points.join(', ').size}.max
5
+ hooks.each do |name, hook|
6
+ points = "[#{hook.points.join(', ')}]"
7
+ puts "#{name.to_s.ljust(name_max_size)} " +
8
+ "<90>=&gt;</90>".termcolor + " #{points.ljust(points_max_size)} " +
9
+ "<90>=&gt;</90>".termcolor + " #{hook.exec_proc}"
10
+ end
11
+ end
12
+
13
+ register_command('hook remove') do |name|
14
+ puts remove_hook(name) ? "removed => #{name}" : '<red>hook not found!</red>'.termcolor
15
+ end
16
+
17
+ register_command('command list') do
18
+ name_max_size = commands.keys.map{|i|i.size}.max
19
+ commands.each do |name, command|
20
+ puts "#{name.to_s.ljust(name_max_size)} " + "<90>=&gt;</90>".termcolor + " #{command.exec_proc}"
21
+ end
22
+ end
23
+
24
+ register_command('command remove') do |name|
25
+ puts remove_command(name) ? "removed => #{name}" : '<red>command not found!</red>'.termcolor
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # Maintainer: Sora Harakami
2
+ # http://gist.github.com/453709
3
+
4
+ Termtter::Client.register_command(:name => :dupu, :exec => lambda do |body|
5
+ #Termtter::Client.execute("update #{arg.chars.inject([]){|r,v|r << v*(5+rand(3)}.join}")
6
+ body.chomp!
7
+ max = 140
8
+ len = body.split(//).length
9
+ mod = max % len
10
+ ext = (0...len).to_a.sort_by{ rand }.take(mod)
11
+ res = body.split(//).each_with_index.map{ |c, i| c * (max / len + (ext.include?(i) ? 1 : 0)) }.join('')
12
+ Termtter::Client.execute("update #{res}")
13
+ end)
@@ -0,0 +1,4 @@
1
+ Termtter::Client.register_command('erase') do |arg|
2
+ num = /(\d+)/ =~ arg ? $1.to_i : 1
3
+ print "\e[#{num + 1}F\e[0J"
4
+ end
@@ -0,0 +1,17 @@
1
+ config.plugins.error_log.set_default(:file, File.expand_path("~/.termtter/error.log.txt"))
2
+
3
+ Termtter::Client.register_hook(
4
+ :name => :error_log,
5
+ :point => :on_error,
6
+ :exec => lambda do |e|
7
+ open(config.plugins.error_log.file,"a") do |f|
8
+ f.puts "#{Time.now} ---------------------"
9
+ f.puts " #{e.class.to_s}: #{e.message}"
10
+ begin
11
+ e.backtrace.each do |s|
12
+ f.puts " #{s}"
13
+ end
14
+ rescue NoMethodError; end
15
+ end
16
+ end
17
+ )
@@ -12,6 +12,13 @@ URL_SHORTTERS = [
12
12
  {:host => "ow.ly", :pattern => %r'(http://ow\.ly(/[\w/]+))'},
13
13
  {:host => "u.nu", :pattern => %r'(http://u\.nu(/[\w/]+))'},
14
14
  {:host => "twurl.nl", :pattern => %r'(http://twurl\.nl(/\w+))'},
15
+ {:host => "icio.us", :pattern => %r'(http://icio\.us(/\w+))'},
16
+ {:host => "htn.to", :pattern => %r'(http://htn\.to(/\w+))'},
17
+ {:host => "cot.ag", :pattern => %r'(http://cot\.ag(/\w+))'},
18
+ {:host => "ht.ly", :pattern => %r'(http://ht\.ly(/\w+))'},
19
+ {:host => "p.tl", :pattern => %r'(http://p\.tl(/\w+))'},
20
+ {:host => "url4.eu", :pattern => %r'(http://url4\.eu(/\w+))'},
21
+ {:host => "t.co", :pattern => %r'(http://t\.co(/\w+))'},
15
22
  ]
16
23
 
17
24
  config.plugins.expand_tinyurl.set_default(:shortters, [])
@@ -39,7 +46,7 @@ def expand_url(host, path)
39
46
  res = Termtter::HTTPpool.start(host) do |h|
40
47
  h.get(path, { 'User-Agent' => 'Mozilla' })
41
48
  end
42
- return nil unless res.code == "301" or res.code == "302"
49
+ return nil unless res.code =~ /\A30/
43
50
  newurl = res['Location']
44
51
  newurl.respond_to?(:force_encoding) ? newurl.force_encoding(Encoding::UTF_8) : newurl
45
52
  rescue Exception => e
data/lib/plugins/growl.rb CHANGED
@@ -93,13 +93,16 @@ Termtter::Client.register_hook(
93
93
  # TODO: Add option for priority and sticky
94
94
  system 'growlnotify', s.user.screen_name, '-m', s.text.gsub("\n",''), '-n', 'termtter', '--image', get_icon_path(s)
95
95
  else
96
- growl.notify(
97
- "update_friends_timeline",
98
- s.user.screen_name,
99
- CGI.unescapeHTML(s.text),
100
- config.plugins.growl.priority,
101
- config.plugins.growl.sticky
102
- )
96
+ begin
97
+ growl.notify(
98
+ "update_friends_timeline",
99
+ s.user.screen_name,
100
+ CGI.unescapeHTML(s.text),
101
+ config.plugins.growl.priority,
102
+ config.plugins.growl.sticky
103
+ )
104
+ rescue Errno::ECONNREFUSED
105
+ end
103
106
  end
104
107
  sleep 0.1
105
108
  end
@@ -0,0 +1,88 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'nkf'
3
+ require 'open-uri'
4
+
5
+ module HatenaKeywordHaiku
6
+ class Word
7
+ def initialize(word, yomi)
8
+ raise 'word is nil' unless word and not word.empty?
9
+ @word = word
10
+ @yomi = yomi
11
+ end
12
+
13
+ def word
14
+ @word
15
+ end
16
+
17
+ def yomi
18
+ @yomi
19
+ end
20
+
21
+ def length
22
+ @length ||= self.yomi.gsub(/\n|ぁ|ぃ|ぅ|ぇ|ぉ|ァ|ィ|ゥ|ェ|ォ|ゃ|ゅ|ょ|ャ|ュ|ョ/, '').split(//).length
23
+ end
24
+ end
25
+
26
+ @@words = nil
27
+
28
+ def self.generate(*args)
29
+ args = [5,7,5] if args.empty?
30
+
31
+ args.map{ |len|
32
+ words[len.to_i].choice rescue raise "No word which length is #{len}"
33
+ }.map{ |w| w.word }.join(' ')
34
+ end
35
+
36
+ # http://d.hatena.ne.jp/hatenadiary/20060922/1158908401
37
+ def self.setup(csv_path = '/tmp/keywordlist_furigana.csv', csv_url = 'http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv')
38
+ return if @@words
39
+ @@words = { }
40
+ csv_path = File.expand_path(csv_path)
41
+ unless File.exists? csv_path
42
+ puts "haiku: downloading CSV"
43
+ open(csv_path, 'w'){ |f|
44
+ f.write(open(csv_url).read)
45
+ }
46
+ end
47
+
48
+
49
+ puts "haiku: parsing CSV"
50
+ open(csv_path).each_line{ |line|
51
+ yomi, word = *NKF.nkf('-w', line.chomp).split(/\t/)
52
+ next unless yomi and word
53
+ w = Word.new(word, yomi)
54
+ @@words[w.length] = [] unless @@words.has_key? w.length
55
+ @@words[w.length].push w
56
+ }
57
+ puts "haiku: setup done"
58
+ @@words
59
+ end
60
+
61
+ def self.words
62
+ setup unless @@words
63
+ @@words
64
+ end
65
+ end
66
+
67
+ Thread.new{
68
+ HatenaKeywordHaiku.setup('~/.termtter/keywordlist_furigana.csv')
69
+ }
70
+ Termtter::Client.register_command(
71
+ :name => :hatena_keyword_haiku,
72
+ :aliases => [:haiku],
73
+ :author => 'hitode909',
74
+ :exec_proc => lambda {|arg|
75
+ args = arg.split(/\s+/)
76
+
77
+ name = ''
78
+ if args.first and not args.first =~ /^\d+$/
79
+ name = Termtter::Client.normalize_as_user_name(args.shift)
80
+ command = "u @#{name} #{HatenaKeywordHaiku.generate(*args)}"
81
+ else
82
+ command = "u #{HatenaKeywordHaiku.generate(*args)}"
83
+ end
84
+
85
+ Termtter::Client.execute command
86
+ },
87
+ :help => ['haiku [(Optinal) USER] [(Optional) 5 7 5 7 7]', 'Post a Haiku']
88
+ )
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'net/irc'
4
4
  require 'set'
5
+ require 'cgi'
5
6
 
6
7
  config.plugins.irc_gw.set_default(:port, 16669)
7
8
  config.plugins.irc_gw.set_default(:last_statuses_count, 100)
@@ -34,7 +35,7 @@ class TermtterIrcGateway < Net::IRC::Server::Session
34
35
  @@last_statuses = []
35
36
 
36
37
  Termtter::Client.register_hook(
37
- :name => :irc_gw,
38
+ :name => :irc_gw_output,
38
39
  :point => :output,
39
40
  :exec => lambda { |statuses, event|
40
41
  if event == :update_friends_timeline
@@ -47,6 +48,15 @@ class TermtterIrcGateway < Net::IRC::Server::Session
47
48
  end
48
49
  }
49
50
  )
51
+ Termtter::Client.register_hook(
52
+ :name => :irc_gw_handle_error,
53
+ :point => :on_error,
54
+ :exec => lambda { |error|
55
+ @@listners.each{ |listener|
56
+ listener.log "[ERROR] #{error.class.to_s}: #{error.message}"
57
+ }
58
+ }
59
+ )
50
60
  if Termtter::Client.respond_to? :register_output
51
61
  Termtter::Client.register_output(:irc) do |message|
52
62
  @@listners.each do |listener|
@@ -99,7 +109,7 @@ class TermtterIrcGateway < Net::IRC::Server::Session
99
109
  statuses.each do |s|
100
110
  typable_id = Termtter::Client.data_to_typable_id(s.id)
101
111
  time = Time.parse(s.created_at).strftime(time_format) if time_format
102
- post s.user.screen_name, msg_type, main_channel, [time, s.text, typable_id].compact.join(' ')
112
+ post s.user.screen_name, msg_type, main_channel, [time, CGI.unescapeHTML(s.text), typable_id].compact.join(' ')
103
113
  end
104
114
  end
105
115
 
@@ -109,7 +119,6 @@ class TermtterIrcGateway < Net::IRC::Server::Session
109
119
  post '#termtter', NOTICE, main_channel, '> ' + termtter_command
110
120
  Termtter::Client.execute(termtter_command)
111
121
  rescue Exception => e
112
- post '#termtter', NOTICE, main_channel, "#{e.class.to_s}: #{e.message}"
113
122
  Termtter::Client.handle_error(e)
114
123
  end
115
124
 
@@ -144,7 +153,6 @@ class TermtterIrcGateway < Net::IRC::Server::Session
144
153
  Termtter::Client.execute('update ' + message)
145
154
  post @prefix, TOPIC, main_channel, message
146
155
  rescue Exception => e
147
- post '#termtter', NOTICE, main_channel, "#{e.class.to_s}: #{e.message}"
148
156
  Termtter::Client.handle_error(e)
149
157
  end
150
158
 
@@ -1,33 +1,36 @@
1
1
  # -*- coding: utf-8 -*-
2
- require 'appscript' or raise 'itunes plugin cannot run'
2
+ begin
3
+ require 'appscript'
4
+ rescue LoadError
5
+ raise "itunes plug: can't load appscript gem. please run 'gem install rb-appscript'"
6
+ end
3
7
 
4
8
  config.plugins.itunes.set_default(:prefix, 'Listening now:')
5
9
  config.plugins.itunes.set_default(:suffix, '#iTunes #listening')
6
- config.plugins.itunes.set_default(
7
- :format,
10
+ config.plugins.itunes.set_default(:format,
8
11
  '<%=prefix%> <%=track_name%> (<%=time%>) <%=artist%> <%=album%> <%=suffix%>')
9
12
 
10
- module Termtter::Client
11
- register_command :name => :listening_now, :aliases => [:ln],
12
- :help => ['listening_now,ln', "Post the information of listening now."],
13
- :exec_proc => lambda {|args|
14
- begin
15
- prefix = config.plugins.itunes.prefix
16
- track_name = Appscript.app('iTunes').current_track.name.get
17
- artist = Appscript.app('iTunes').current_track.artist.get
18
- genre = Appscript.app('iTunes').current_track.genre.get
19
- time = Appscript.app('iTunes').current_track.time.get
20
- album = Appscript.app('iTunes').current_track.album.get
21
- suffix = config.plugins.itunes.suffix
22
- erbed_text = ERB.new(config.plugins.itunes.format).result(binding)
23
- erbed_text.gsub!(/\s{2,}/, ' ')
24
- if args.length > 0
25
- erbed_text = args + ' ' + erbed_text
26
- end
27
- Termtter::API.twitter.update(erbed_text)
28
- puts "=> " << erbed_text
29
- rescue => e
30
- p e
13
+ Termtter::Client.register_command(
14
+ :name => :listening_now, :aliases => [:ln, :itunes, :music, :m],
15
+ :help => ['listening_now,ln,itunes,music', "Post the information of listening now."],
16
+ :exec => lambda {|args|
17
+ begin
18
+ prefix = config.plugins.itunes.prefix
19
+ track_name = Appscript.app('iTunes').current_track.name.get
20
+ artist = Appscript.app('iTunes').current_track.artist.get
21
+ genre = Appscript.app('iTunes').current_track.genre.get
22
+ time = Appscript.app('iTunes').current_track.time.get
23
+ album = Appscript.app('iTunes').current_track.album.get
24
+ suffix = config.plugins.itunes.suffix
25
+ erbed_text = ERB.new(config.plugins.itunes.format).result(binding)
26
+ erbed_text.gsub!(/\s{2,}/, ' ')
27
+ if args.length > 0
28
+ erbed_text = args + ' ' + erbed_text
31
29
  end
32
- }
33
- end
30
+ Termtter::API.twitter.update(erbed_text)
31
+ puts "=> " << erbed_text
32
+ rescue => e
33
+ p e
34
+ end
35
+ }
36
+ )
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ $KCODE = 'u' unless defined?(Encoding)
3
+ # mecab('これはテストです') #=>
4
+ # [["これ", "名詞", "代名詞", "一般", "*", "*", "*", "これ", "コレ", "コレ"],
5
+ # ["は", "助詞", "係助詞", "*", "*", "*", "*", "は", "ハ", "ワ"],
6
+ # ["テスト", "名詞", "サ変接続", "*", "*", "*", "*", "テスト", "テスト", "テスト"],
7
+ # ["です", "助動詞", "*", "*", "*", "特殊・デス", "基本形", "です", "デス", "デス"]]
8
+ def mecab(str)
9
+ IO.popen('mecab', 'r+') {|io|
10
+ io.puts str
11
+ io.close_write
12
+ io.read.split(/\n/).map {|i| i.split(/\t|,/) }[0..-2]
13
+ }
14
+ end
15
+
16
+ Termtter::Client.register_command(
17
+ :name => 'mecab',
18
+ :help => 'post a Japanese message with syntaxtic explanations. Requirements: mecab command',
19
+ :exec => lambda {|arg|
20
+ text = mecab(arg).map {|i| "#{i[0]}(#{i[1]}: #{i[2]})" }.join + ' #mecab'
21
+ update(text)
22
+ puts "=> #{test}"
23
+ })