termtter 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/plugins/aa.rb +1 -1
- data/lib/plugins/appendtitle.rb +5 -12
- data/lib/plugins/defaults/auto_reload.rb +1 -0
- data/lib/plugins/defaults/cache.rb +18 -0
- data/lib/plugins/defaults/command_line.rb +1 -1
- data/lib/plugins/defaults/fib.rb +15 -6
- data/lib/plugins/defaults/retweet.rb +1 -1
- data/lib/plugins/defaults/standard_commands.rb +31 -25
- data/lib/plugins/defaults/stdout.rb +12 -4
- data/lib/plugins/defaults/system.rb +27 -0
- data/lib/plugins/dupu.rb +13 -0
- data/lib/plugins/erase.rb +4 -0
- data/lib/plugins/error_log.rb +17 -0
- data/lib/plugins/expand-tinyurl.rb +8 -1
- data/lib/plugins/growl.rb +10 -7
- data/lib/plugins/hatena_keyword_haiku.rb +88 -0
- data/lib/plugins/irc_gw.rb +12 -4
- data/lib/plugins/itunes.rb +29 -26
- data/lib/plugins/mecab.rb +23 -0
- data/lib/plugins/mudan_kinshi.rb +13 -0
- data/lib/plugins/ndkn.rb +7 -0
- data/lib/plugins/other_user.rb +47 -0
- data/lib/plugins/reply_sound.rb +75 -25
- data/lib/plugins/ruby-v.rb +10 -0
- data/lib/plugins/time_signal.rb +21 -0
- data/lib/plugins/tinyurl.rb +6 -4
- data/lib/plugins/train.rb +1 -1
- data/lib/plugins/translation.rb +2 -0
- data/lib/plugins/user_stream.rb +122 -0
- data/lib/plugins/whale.rb +28 -0
- data/lib/termtter/active_rubytter.rb +4 -0
- data/lib/termtter/api.rb +55 -30
- data/lib/termtter/client.rb +19 -4
- data/lib/termtter/config_setup.rb +10 -2
- data/lib/termtter/config_template.erb +4 -2
- data/lib/termtter/crypt.rb +13 -0
- data/lib/termtter/default_config.rb +5 -2
- data/lib/termtter/hookable.rb +4 -0
- data/lib/termtter/memory_cache.rb +67 -19
- data/lib/termtter/rubytter_proxy.rb +101 -26
- data/lib/termtter/system_extensions.rb +22 -18
- data/lib/termtter.rb +5 -1
- data/spec/termtter/crypt_spec.rb +16 -0
- data/spec/termtter/rubytter_proxy_spec.rb +14 -0
- metadata +85 -26
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", ">=
|
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.
|
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
|
-
|
data/lib/plugins/appendtitle.rb
CHANGED
@@ -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{
|
21
|
-
if v =
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
data/lib/plugins/defaults/fib.rb
CHANGED
@@ -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(:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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 ?
|
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.
|
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 "
|
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.
|
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.
|
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
|
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>=></90>".termcolor + " #{points.ljust(points_max_size)} " +
|
9
|
+
"<90>=></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>=></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
|
data/lib/plugins/dupu.rb
ADDED
@@ -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,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
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
+
)
|
data/lib/plugins/irc_gw.rb
CHANGED
@@ -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 => :
|
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
|
|
data/lib/plugins/itunes.rb
CHANGED
@@ -1,33 +1,36 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
+
})
|