emasaka-termtter 1.0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/README.rdoc +100 -0
- data/Rakefile +55 -0
- data/bin/kill_termtter +22 -0
- data/bin/termtter +6 -0
- data/lib/plugins/addspace.rb +27 -0
- data/lib/plugins/april_fool.rb +15 -0
- data/lib/plugins/bomb.rb +39 -0
- data/lib/plugins/clear.rb +14 -0
- data/lib/plugins/command_plus.rb +47 -0
- data/lib/plugins/confirm.rb +12 -0
- data/lib/plugins/cool.rb +10 -0
- data/lib/plugins/countter.rb +23 -0
- data/lib/plugins/devel.rb +18 -0
- data/lib/plugins/direct_messages.rb +36 -0
- data/lib/plugins/en2ja.rb +11 -0
- data/lib/plugins/english.rb +25 -0
- data/lib/plugins/erb.rb +17 -0
- data/lib/plugins/exec_and_update.rb +14 -0
- data/lib/plugins/expand-tinyurl.rb +33 -0
- data/lib/plugins/fib.rb +28 -0
- data/lib/plugins/fib_filter.rb +14 -0
- data/lib/plugins/filter.rb +69 -0
- data/lib/plugins/graduatter.rb +8 -0
- data/lib/plugins/grass.rb +27 -0
- data/lib/plugins/group.rb +64 -0
- data/lib/plugins/growl.rb +52 -0
- data/lib/plugins/growl2.rb +143 -0
- data/lib/plugins/hatebu.rb +59 -0
- data/lib/plugins/history.rb +93 -0
- data/lib/plugins/ignore.rb +19 -0
- data/lib/plugins/keyword.rb +18 -0
- data/lib/plugins/l2.rb +25 -0
- data/lib/plugins/log.rb +73 -0
- data/lib/plugins/me.rb +10 -0
- data/lib/plugins/modify_arg_hook_sample.rb +7 -0
- data/lib/plugins/msagent.rb +38 -0
- data/lib/plugins/multi_reply.rb +27 -0
- data/lib/plugins/notify-send.rb +22 -0
- data/lib/plugins/notify-send2.rb +52 -0
- data/lib/plugins/open_url.rb +59 -0
- data/lib/plugins/otsune.rb +21 -0
- data/lib/plugins/outputz.rb +33 -0
- data/lib/plugins/pause.rb +3 -0
- data/lib/plugins/post_exec_hook_sample.rb +9 -0
- data/lib/plugins/pre_exec_hook_sample.rb +9 -0
- data/lib/plugins/primes.rb +30 -0
- data/lib/plugins/quicklook.rb +41 -0
- data/lib/plugins/random.rb +23 -0
- data/lib/plugins/reblog.rb +40 -0
- data/lib/plugins/reload.rb +3 -0
- data/lib/plugins/reply.rb +8 -0
- data/lib/plugins/retweet.rb +46 -0
- data/lib/plugins/reverse.rb +13 -0
- data/lib/plugins/say.rb +26 -0
- data/lib/plugins/scrape.rb +41 -0
- data/lib/plugins/screen-notify.rb +20 -0
- data/lib/plugins/screen.rb +24 -0
- data/lib/plugins/shell.rb +14 -0
- data/lib/plugins/shorturl_on_update.rb +36 -0
- data/lib/plugins/sl.rb +48 -0
- data/lib/plugins/spam.rb +16 -0
- data/lib/plugins/standard_plugins.rb +519 -0
- data/lib/plugins/stdout.rb +83 -0
- data/lib/plugins/storage.rb +55 -0
- data/lib/plugins/storage/DB.rb +37 -0
- data/lib/plugins/storage/status.rb +83 -0
- data/lib/plugins/storage/status_mook.rb +30 -0
- data/lib/plugins/switch_user.rb +22 -0
- data/lib/plugins/system_status.rb +33 -0
- data/lib/plugins/timer.rb +18 -0
- data/lib/plugins/translation.rb +38 -0
- data/lib/plugins/typable_id.rb +94 -0
- data/lib/plugins/update_editor.rb +53 -0
- data/lib/plugins/update_filter.rb +30 -0
- data/lib/plugins/uri-open.rb +66 -0
- data/lib/plugins/wassr_post.rb +22 -0
- data/lib/plugins/yhara.rb +148 -0
- data/lib/plugins/yhara_filter.rb +8 -0
- data/lib/plugins/yonda.rb +21 -0
- data/lib/termtter.rb +38 -0
- data/lib/termtter/api.rb +57 -0
- data/lib/termtter/client.rb +370 -0
- data/lib/termtter/command.rb +80 -0
- data/lib/termtter/config.rb +68 -0
- data/lib/termtter/config_setup.rb +38 -0
- data/lib/termtter/connection.rb +41 -0
- data/lib/termtter/hook.rb +31 -0
- data/lib/termtter/optparse.rb +14 -0
- data/lib/termtter/system_extensions.rb +161 -0
- data/lib/termtter/task.rb +17 -0
- data/lib/termtter/task_manager.rb +116 -0
- data/lib/termtter/version.rb +4 -0
- data/spec/plugins/cool_spec.rb +10 -0
- data/spec/plugins/english_spec.rb +19 -0
- data/spec/plugins/fib_spec.rb +15 -0
- data/spec/plugins/filter_spec.rb +18 -0
- data/spec/plugins/pause_spec.rb +8 -0
- data/spec/plugins/primes_spec.rb +15 -0
- data/spec/plugins/shell_spec.rb +10 -0
- data/spec/plugins/sl_spec.rb +8 -0
- data/spec/plugins/spam_spec.rb +4 -0
- data/spec/plugins/standard_plugins_spec.rb +23 -0
- data/spec/plugins/storage/DB_spec.rb +12 -0
- data/spec/plugins/storage/status_spec.rb +24 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/termtter/client_spec.rb +255 -0
- data/spec/termtter/command_spec.rb +107 -0
- data/spec/termtter/config_spec.rb +111 -0
- data/spec/termtter/hook_spec.rb +78 -0
- data/spec/termtter/task_manager_spec.rb +78 -0
- data/spec/termtter/task_spec.rb +22 -0
- data/spec/termtter_spec.rb +29 -0
- data/test/friends_timeline.json +5 -0
- data/test/search.json +8 -0
- metadata +210 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'atomutil'
|
5
|
+
|
6
|
+
module Termtter::Client
|
7
|
+
register_command(
|
8
|
+
:name => :hatebu, :aliases => [],
|
9
|
+
:exec_proc => lambda {|arg|
|
10
|
+
if arg =~ /^(\d+)(.*)$/
|
11
|
+
id = $1.strip
|
12
|
+
comment = $2.strip
|
13
|
+
statuses = public_storage[:log].select { |s| s.id == id }
|
14
|
+
unless statuses.empty?
|
15
|
+
status = statuses.first
|
16
|
+
else
|
17
|
+
status = t.show(id).first
|
18
|
+
end
|
19
|
+
auth = auth = Atompub::Auth::Wsse.new({
|
20
|
+
:username => config.plugins.hatebu.username,
|
21
|
+
:password => config.plugins.hatebu.password,
|
22
|
+
})
|
23
|
+
link = Atom::Link.new({
|
24
|
+
:href => "http://twitter.com/#{status.user.screen_name}/status/#{status.id}",
|
25
|
+
:rel => 'related',
|
26
|
+
:type => 'text/html',
|
27
|
+
})
|
28
|
+
entry = Atom::Entry.new({
|
29
|
+
:link => link,
|
30
|
+
:title => 'dummy',
|
31
|
+
:summary => comment,
|
32
|
+
})
|
33
|
+
req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
|
34
|
+
req['User-Agent'] = 'Mozilla/5.0'
|
35
|
+
req['Content-Type'] = 'application/atom+xml'
|
36
|
+
req['Slug'] = 'termtter'
|
37
|
+
req.body = entry.to_s
|
38
|
+
auth.authorize(req)
|
39
|
+
Net::HTTP.start('b.hatena.ne.jp', 80) do |http|
|
40
|
+
res = http.request(req)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
},
|
44
|
+
:completion_proc => lambda {|cmd, args|
|
45
|
+
if args =~ /^(\d*)$/
|
46
|
+
find_status_id_candidates $1, "#{cmd} %s"
|
47
|
+
end
|
48
|
+
},
|
49
|
+
:help => ['hatebu ID', 'Hatena bookmark a status']
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# hatebu.rb
|
54
|
+
# hatena bookmark it!
|
55
|
+
#
|
56
|
+
# config.plugins.hatebu.username = 'your-username-on-hatena'
|
57
|
+
# config.plugins.hatebu.password = 'your-password-on-hatena'
|
58
|
+
#
|
59
|
+
# hatebu 1114860346 [termtter][<82>±<82>ê<82>Í<82>·<82>²<82>¢]mattn++
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'zlib'
|
4
|
+
|
5
|
+
config.plugins.history.
|
6
|
+
set_default(:filename, Termtter::CONF_DIR + '/history')
|
7
|
+
config.plugins.history.
|
8
|
+
set_default(:keys, [:users, :status_ids])
|
9
|
+
config.plugins.history.
|
10
|
+
set_default(:max_of_history, 100)
|
11
|
+
config.plugins.history.
|
12
|
+
set_default(:enable_autosave, true)
|
13
|
+
config.plugins.history.
|
14
|
+
set_default(:autosave_interval, 3600)
|
15
|
+
|
16
|
+
module Termtter::Client
|
17
|
+
def self.load_history
|
18
|
+
filename = File.expand_path(config.plugins.history.filename)
|
19
|
+
keys = config.plugins.history.keys
|
20
|
+
|
21
|
+
if File.exist?(filename)
|
22
|
+
begin
|
23
|
+
history = Marshal.load Zlib::Inflate.inflate(File.read(filename))
|
24
|
+
end
|
25
|
+
if history
|
26
|
+
keys.each do |key|
|
27
|
+
public_storage[key] = history[key] if history[key]
|
28
|
+
end
|
29
|
+
Readline::HISTORY.push *history[:history] if history[:history]
|
30
|
+
puts "history loaded(#{File.size(filename)/1000}kb)"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.save_history
|
36
|
+
filename = File.expand_path(config.plugins.history.filename)
|
37
|
+
keys = config.plugins.history.keys
|
38
|
+
history = { }
|
39
|
+
keys.each do |key|
|
40
|
+
history[key] = public_storage[key]
|
41
|
+
end
|
42
|
+
max_of_history = config.plugins.history.max_of_history
|
43
|
+
history[:history] = Readline::HISTORY.to_a.reverse.uniq.reverse
|
44
|
+
if history[:history].size > max_of_history
|
45
|
+
history[:history] = history[:history][-max_of_history..-1]
|
46
|
+
end
|
47
|
+
|
48
|
+
File.open(filename, 'w') do |f|
|
49
|
+
f.write Zlib::Deflate.deflate(Marshal.dump(history))
|
50
|
+
end
|
51
|
+
puts "history saved(#{File.size(filename)/1000}kb)"
|
52
|
+
end
|
53
|
+
|
54
|
+
register_hook(
|
55
|
+
:name => :history_initialize,
|
56
|
+
:points => [:initialize],
|
57
|
+
:exec_proc => lambda { load_history; logger.debug('load_history') }
|
58
|
+
)
|
59
|
+
|
60
|
+
register_hook(
|
61
|
+
:name => :history_exit,
|
62
|
+
:points => [:exit],
|
63
|
+
:exec_proc => lambda { save_history; logger.debug('save_history') }
|
64
|
+
)
|
65
|
+
|
66
|
+
if config.plugins.history.enable_autosave
|
67
|
+
Termtter::Client.add_task(:interval => config.plugins.history.autosave_interval,
|
68
|
+
:after => config.plugins.history.autosave_interval) do
|
69
|
+
save_history
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
register_command(
|
74
|
+
:name => :save,
|
75
|
+
:exec_proc => lambda{|arg|
|
76
|
+
save_history
|
77
|
+
},
|
78
|
+
:help => ['save', 'Save hisory']
|
79
|
+
)
|
80
|
+
|
81
|
+
register_command(
|
82
|
+
:name => :load,
|
83
|
+
:exec_proc => lambda{|arg|
|
84
|
+
load_history
|
85
|
+
},
|
86
|
+
:help => ['load', 'Load hisory']
|
87
|
+
)
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# history.rb
|
93
|
+
# save log to file
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
config.filters.ignore.set_default(:words, [])
|
5
|
+
|
6
|
+
module Termtter::Client
|
7
|
+
add_filter do |statuses, _|
|
8
|
+
ignore_words = config.filters.ignore.words
|
9
|
+
statuses.delete_if do |s|
|
10
|
+
ignore_words.any? {|i| i =~ s.text }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# filter/ignore.rb
|
16
|
+
# ignore words
|
17
|
+
# setting
|
18
|
+
# config.filters.ignore.words = [ /ignore/, /words/ ]
|
19
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
config.set_default('plugins.keyword.keywords', [])
|
4
|
+
|
5
|
+
module Termtter
|
6
|
+
class Status
|
7
|
+
def has_keyword?
|
8
|
+
config.plugins.keyword.keywords.find { |k| k === self.text }
|
9
|
+
end
|
10
|
+
alias :has_keyword :has_keyword?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# keyword.rb
|
15
|
+
# provides a keyword watching method
|
16
|
+
# example config
|
17
|
+
# config.plugins.stdout.timeline_format = '<%= color(time, 90) %> <%= color(status, s.has_keyword ? 4 : status_color) %> <%= color(id, 90) %>'
|
18
|
+
# config.plugins.keyword.keywords = [ /motemen/ ]
|
data/lib/plugins/l2.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command(
|
5
|
+
:name => :list2,
|
6
|
+
:aliases => [:l2],
|
7
|
+
:exec_proc => lambda {|arg|
|
8
|
+
unless arg.empty?
|
9
|
+
targets = arg.split.uniq
|
10
|
+
statuses = targets ? targets.map { |target|
|
11
|
+
public_storage[:tweet][target]
|
12
|
+
}.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
|
13
|
+
output(statuses, :search)
|
14
|
+
end
|
15
|
+
},
|
16
|
+
:completion_proc => lambda {|cmd, arg|
|
17
|
+
#todo
|
18
|
+
},
|
19
|
+
:help => ['list2,l2 A B (C..)', "List statuses of A's and B's (and C's..)"]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
# l2.rb
|
24
|
+
# plugin 'l2'
|
25
|
+
# NOTE: l2.rb needs plugin/log
|
data/lib/plugins/log.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
public_storage[:log] = []
|
5
|
+
public_storage[:tweet] = { }
|
6
|
+
config.plugins.log.set_default('max_size', 1/0.0)
|
7
|
+
config.plugins.log.set_default('print_max_size', 30)
|
8
|
+
|
9
|
+
register_hook(
|
10
|
+
:name => :log,
|
11
|
+
:points => [:pre_filter],
|
12
|
+
:exec_proc => lambda {|statuses, event|
|
13
|
+
# log(sequential storage)
|
14
|
+
public_storage[:log] += statuses
|
15
|
+
max_size = config.plugins.log.max_size
|
16
|
+
if public_storage[:log].size > max_size
|
17
|
+
public_storage[:log] = public_storage[:log][-max_size..-1]
|
18
|
+
end
|
19
|
+
public_storage[:log] = public_storage[:log].uniq.sort_by{|s| s.created_at} if statuses.first
|
20
|
+
|
21
|
+
# tweet(storage for each user)
|
22
|
+
statuses.each do |s|
|
23
|
+
public_storage[:tweet][s.user.screen_name] = [] unless public_storage[:tweet][s.user.screen_name]
|
24
|
+
public_storage[:tweet][s.user.screen_name] << s
|
25
|
+
end
|
26
|
+
|
27
|
+
statuses.map{ |s| s.user.screen_name}.uniq.each do |name|
|
28
|
+
public_storage[:tweet][name]
|
29
|
+
if public_storage[:tweet][name].size > max_size
|
30
|
+
public_storage[:tweet][name] = public_storage[:tweet][name][-max_size..-1]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
)
|
35
|
+
|
36
|
+
register_command(
|
37
|
+
:name => :log,
|
38
|
+
:exec_proc => lambda{|arg|
|
39
|
+
if arg.empty?
|
40
|
+
# log
|
41
|
+
statuses = public_storage[:log]
|
42
|
+
print_max = config.plugins.log.print_max_size
|
43
|
+
print_max = 0 if statuses.size < print_max
|
44
|
+
output(statuses[-print_max..-1], :search)
|
45
|
+
else
|
46
|
+
# log (user) (max)
|
47
|
+
vars = arg.split(' ')
|
48
|
+
print_max = vars.last =~ /^\d+$/ ? vars.pop.to_i : config.plugins.log.print_max_size
|
49
|
+
id = vars
|
50
|
+
statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user.screen_name} : public_storage[:log]
|
51
|
+
print_max = 0 if statuses.size < print_max
|
52
|
+
output(statuses[-print_max..-1], :search)
|
53
|
+
end
|
54
|
+
},
|
55
|
+
:completion_proc => lambda {|cmd, arg|
|
56
|
+
find_user_candidates arg, "#{cmd} %s"
|
57
|
+
},
|
58
|
+
:help => [ 'log (USER(S)) (MAX)', 'Show local log of the user(s)']
|
59
|
+
)
|
60
|
+
|
61
|
+
register_command(
|
62
|
+
:name => :search_log, :aliases => [:sl],
|
63
|
+
:exec_proc => lambda{|arg|
|
64
|
+
unless arg.strip.empty?
|
65
|
+
pat = Regexp.new arg
|
66
|
+
statuses = public_storage[:log].select { |s| s.text =~ pat }
|
67
|
+
output(statuses, :search)
|
68
|
+
end
|
69
|
+
},
|
70
|
+
:help => [ 'search_log WORD', 'Search log for WORD' ]
|
71
|
+
)
|
72
|
+
|
73
|
+
end
|
data/lib/plugins/me.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
raise 'msagent.rb runs only in windows' if RUBY_PLATFORM.downcase !~ /mswin(?!ce)|mingw|bccwin/
|
4
|
+
require 'win32ole'
|
5
|
+
require 'kconv'
|
6
|
+
|
7
|
+
agent = WIN32OLE.new('Agent.Control.2')
|
8
|
+
agent.connected = true
|
9
|
+
agent.characters.load("Merlin", ENV['WINDIR'] + "\\msagent\\chars\\Merlin.acs")
|
10
|
+
achar = agent.characters.character("Merlin")
|
11
|
+
achar.languageID = 0x411
|
12
|
+
achar.show
|
13
|
+
|
14
|
+
Termtter::Client.register_hook(
|
15
|
+
:name => :msagent,
|
16
|
+
:points => [:output],
|
17
|
+
:exec_proc => lambda {|statuses, event|
|
18
|
+
if !statuses.empty? && event == :update_friends_timeline
|
19
|
+
Thread.start do
|
20
|
+
statuses.each do |s|
|
21
|
+
req = achar.speak("#{s.user.screen_name}: #{s.text}".tosjis)
|
22
|
+
sleep 1
|
23
|
+
WIN32OLE_EVENT.message_loop
|
24
|
+
achar.stop(req)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
}
|
29
|
+
)
|
30
|
+
|
31
|
+
Termtter::Client.register_hook(
|
32
|
+
:name => :msagent_exit,
|
33
|
+
:points => [:exit],
|
34
|
+
:exec_proc => lambda {
|
35
|
+
achar.hide
|
36
|
+
GC.start
|
37
|
+
}
|
38
|
+
)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command(
|
5
|
+
:name => :multi_reply, :aliases => [:mr],
|
6
|
+
:exec_proc => lambda {|arg|
|
7
|
+
text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
|
8
|
+
unless text.empty?
|
9
|
+
/(@(.+))*\s+(.+)/ =~ text
|
10
|
+
if $1
|
11
|
+
msg = $3
|
12
|
+
text = $1.split(/\s+/).map {|u| "#{u} #{msg}" }
|
13
|
+
end
|
14
|
+
Array(text).each do |post|
|
15
|
+
Termtter::API.twitter.update(post)
|
16
|
+
puts "=> #{post}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
},
|
20
|
+
:completion_proc => lambda {|cmd, args|
|
21
|
+
if /(.*)@([^\s]*)$/ =~ args
|
22
|
+
find_user_candidates $2, "#{cmd} #{$1}@%s"
|
23
|
+
end
|
24
|
+
},
|
25
|
+
:help => ["multi_reply,mp TEXT", "Reply to multi user"]
|
26
|
+
)
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Termtter::Client.register_hook(
|
4
|
+
:name => :notify_send,
|
5
|
+
:points => [:output],
|
6
|
+
:exec_proc => lambda {|statuses, event|
|
7
|
+
if event == :update_friends_timeline
|
8
|
+
max = 10
|
9
|
+
|
10
|
+
text = statuses.take(max).map {|s|
|
11
|
+
status_text = CGI.escapeHTML(s.text)
|
12
|
+
status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
|
13
|
+
"<b>#{s.user.screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
|
14
|
+
}.join("\n")
|
15
|
+
|
16
|
+
text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
|
17
|
+
|
18
|
+
system 'notify-send', 'Termtter', text, '-t', '60000'
|
19
|
+
end
|
20
|
+
}
|
21
|
+
)
|
22
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
6
|
+
|
7
|
+
FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
|
8
|
+
Dir.glob("#{config.plugins.notify_send.icon_cache_dir}/*") {|f| File.delete(f) unless File.size?(f) }
|
9
|
+
unless File.exist?("#{config.plugins.notify_send.icon_cache_dir}/default.png")
|
10
|
+
File.open("#{config.plugins.notify_send.icon_cache_dir}/default.png", "wb") do |f|
|
11
|
+
f << open("http://static.twitter.com/images/default_profile_normal.png").read
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_icon_path(s)
|
16
|
+
/https?:\/\/.+\/(\d+)\/.*?$/ =~ s.user.profile_image_url
|
17
|
+
cache_file = "%s/%s-%s%s" % [ config.plugins.notify_send.icon_cache_dir,
|
18
|
+
s.user.screen_name,
|
19
|
+
$+,
|
20
|
+
File.extname(s.user.profile_image_url) ]
|
21
|
+
unless File.exist?(cache_file)
|
22
|
+
Thread.new(s,cache_file) do |s,cache_file|
|
23
|
+
Dir.glob("#{config.plugins.notify_send.icon_cache_dir}/#{s.user.screen_name}-*") {|f| File.delete(f) }
|
24
|
+
begin
|
25
|
+
s.user.profile_image_url.sub!(/^https/,'http')
|
26
|
+
File.open(cache_file, 'wb') do |f|
|
27
|
+
f << open(URI.escape(s.user.profile_image_url)).read
|
28
|
+
end
|
29
|
+
rescue OpenURI::HTTPError
|
30
|
+
cache_file = "#{config.plugins.notify_send.icon_cache_dir}/default.png"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return cache_file
|
35
|
+
end
|
36
|
+
|
37
|
+
Termtter::Client.register_hook(
|
38
|
+
:name => :notify_send2,
|
39
|
+
:points => [:output],
|
40
|
+
:exec_proc => lambda {|statuses, event|
|
41
|
+
return unless event == :update_friends_timeline
|
42
|
+
Thread.start do
|
43
|
+
statuses.each do |s|
|
44
|
+
text = CGI.escapeHTML(s.text)
|
45
|
+
text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
|
46
|
+
system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
|
47
|
+
sleep 0.1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
}
|
51
|
+
)
|
52
|
+
|