jugyo-termtter 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/plugins/command_plus.rb +47 -0
- data/lib/plugins/confirm.rb +25 -4
- data/lib/plugins/countter.rb +23 -0
- data/lib/plugins/devel.rb +5 -0
- data/lib/plugins/direct_messages.rb +36 -0
- data/lib/plugins/erb.rb +1 -1
- data/lib/plugins/exec.rb +17 -0
- data/lib/plugins/exec_and_update.rb +14 -0
- data/lib/plugins/growl2.rb +143 -0
- data/lib/plugins/hatebu.rb +2 -2
- data/lib/plugins/hatebu_and_update.rb +58 -0
- data/lib/plugins/l2.rb +25 -0
- data/lib/plugins/notify-send2.rb +23 -10
- data/lib/plugins/notify-send3.rb +45 -0
- data/lib/plugins/open_url.rb +59 -0
- data/lib/plugins/reblog.rb +2 -2
- data/lib/plugins/retweet.rb +46 -0
- data/lib/plugins/standard_plugins.rb +290 -80
- data/lib/plugins/stdout.rb +7 -1
- data/lib/plugins/switch_user.rb +22 -0
- data/lib/plugins/tinyurl.rb +20 -0
- data/lib/plugins/typable_id.rb +94 -0
- data/lib/termtter/api.rb +35 -20
- data/lib/termtter/client.rb +33 -3
- data/lib/termtter/command.rb +3 -4
- data/lib/termtter/config.rb +4 -0
- data/lib/termtter/config_setup.rb +1 -16
- data/lib/termtter/system_extensions.rb +15 -0
- data/lib/termtter/task_manager.rb +1 -1
- data/lib/termtter/version.rb +1 -1
- data/spec/plugins/standard_plugins_spec.rb +0 -1
- data/spec/termtter/client_spec.rb +28 -21
- metadata +16 -6
- data/lib/plugins/favorite.rb +0 -63
- data/lib/plugins/plugin.rb +0 -53
- data/spec/plugins/favorite_spec.rb +0 -10
- data/spec/plugins/plugin_spec.rb +0 -25
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
class << self
|
4
|
+
def delete_command(arg)
|
5
|
+
if @commands.delete(arg.to_sym)
|
6
|
+
puts "#{arg} command is deleted."
|
7
|
+
else
|
8
|
+
raise "#{arg} command is not found."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def alias_command(arg)
|
13
|
+
original, new = arg.split(/\s+/)
|
14
|
+
if @commands[original.to_sym]
|
15
|
+
@commands[new.to_sym] = @commands[original.to_sym].clone
|
16
|
+
@commands[new.to_sym].name = new.to_sym
|
17
|
+
@commands[new.to_sym].aliases = []
|
18
|
+
@commands[new.to_sym].help = ''
|
19
|
+
puts "alias '#{original}' to '#{new}'."
|
20
|
+
else
|
21
|
+
raise "#{original} command is not found."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Termtter::Client
|
28
|
+
register_command(
|
29
|
+
:name => :delete_command,
|
30
|
+
:exec_proc => lambda {|arg|
|
31
|
+
Termtter::Client.delete_command(arg)
|
32
|
+
},
|
33
|
+
:completion_proc => lambda {|cmd, arg|
|
34
|
+
},
|
35
|
+
:help => ['delete_command command', 'delete command from command list (this command is experimental!)']
|
36
|
+
)
|
37
|
+
|
38
|
+
register_command(
|
39
|
+
:name => :alias_command,
|
40
|
+
:exec_proc => lambda {|arg|
|
41
|
+
Termtter::Client.alias_command(arg)
|
42
|
+
},
|
43
|
+
:completion_proc => lambda {|cmd, arg|
|
44
|
+
},
|
45
|
+
:help => ['alias_command A B', 'alias command A to B (this command is experimental!)']
|
46
|
+
)
|
47
|
+
end
|
data/lib/plugins/confirm.rb
CHANGED
@@ -1,12 +1,33 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
config.plugins.confirm.set_default(:commands, [:update, :reply, :direct])
|
4
|
+
config.plugins.confirm.set_default(
|
5
|
+
:conditions,
|
6
|
+
[
|
7
|
+
lambda { |cmd_name, arg|
|
8
|
+
if cmd_name == :direct && arg =~ /^(list|sent_list)$/
|
9
|
+
false
|
10
|
+
else
|
11
|
+
true
|
12
|
+
end
|
13
|
+
}
|
14
|
+
]
|
15
|
+
)
|
16
|
+
|
3
17
|
Termtter::Client.register_hook(
|
4
18
|
:name => :confirm,
|
5
|
-
:points => [
|
19
|
+
:points => [/^pre_exec_/],
|
6
20
|
:exec_proc => lambda {|cmd, arg|
|
7
|
-
if
|
8
|
-
|
9
|
-
|
21
|
+
if config.plugins.confirm.commands.include?(cmd.name) &&
|
22
|
+
config.plugins.confirm.conditions.any? { |cond| cond.call(cmd.name, arg) }
|
23
|
+
|
24
|
+
prompt = "\"#{cmd.name} #{arg}".strip + "\" [Y/n] "
|
25
|
+
|
26
|
+
if /^y?$/i !~ Readline.readline(prompt, false)
|
27
|
+
puts 'canceled.'
|
28
|
+
raise Termtter::CommandCanceled
|
29
|
+
end
|
30
|
+
|
10
31
|
end
|
11
32
|
}
|
12
33
|
)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Termtter::Client
|
2
|
+
register_command(
|
3
|
+
:name => :countter,
|
4
|
+
:exec_proc => lambda {|arg|
|
5
|
+
count = {}
|
6
|
+
public_storage[:log].each do |l|
|
7
|
+
source = l.source =~ /(?:<a href=\".+?\">)(.+)(?:<\/a>)/ ? $1 : l.source
|
8
|
+
count[source] = 0 unless count[source]
|
9
|
+
count[source] += 1
|
10
|
+
end
|
11
|
+
|
12
|
+
format = "%24s %6s"
|
13
|
+
puts format % %w(sources count)
|
14
|
+
puts format % ['-'*24, '-'*6]
|
15
|
+
count.to_a.sort{|a,b|b[1]<=>a[1]}.each do |k,v|
|
16
|
+
puts format % [k, v]
|
17
|
+
end
|
18
|
+
},
|
19
|
+
:completion_proc => lambda {|cmd, arg|
|
20
|
+
},
|
21
|
+
:help => ['countter', 'count sources']
|
22
|
+
)
|
23
|
+
end
|
data/lib/plugins/devel.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
register_command(
|
4
|
+
:name => :direct_messages,
|
5
|
+
:aliases => [:ds],
|
6
|
+
:exec_proc => lambda {|arg|
|
7
|
+
event = :list_user_timeline
|
8
|
+
ds = Termtter::API.twitter.direct_messages
|
9
|
+
DM = Struct.new :id, :text, :user, :created_at, :in_reply_to_status_id
|
10
|
+
statuses = ds.map do |d|
|
11
|
+
DM.new(d.id, d.text, d.sender, d.created_at)
|
12
|
+
end
|
13
|
+
output(statuses, event)
|
14
|
+
},
|
15
|
+
:completion_proc => lambda {|cmd, arg|
|
16
|
+
},
|
17
|
+
:help => ['direct_messages,ds', 'List direct messages for you']
|
18
|
+
)
|
19
|
+
|
20
|
+
register_command(
|
21
|
+
:name => :sent_direct_messages,
|
22
|
+
:aliases => [:sds],
|
23
|
+
:exec_proc => lambda {|arg|
|
24
|
+
event = :list_user_timeline
|
25
|
+
ds = Termtter::API.twitter.sent_direct_messages
|
26
|
+
DM = Struct.new :id, :text, :user, :created_at, :in_reply_to_status_id
|
27
|
+
statuses = ds.map do |d|
|
28
|
+
DM.new(d.id, "@#{d.recipient.screen_name} #{d.text}", d.sender, d.created_at)
|
29
|
+
end
|
30
|
+
output(statuses, event)
|
31
|
+
},
|
32
|
+
:completion_proc => lambda {|cmd, arg|
|
33
|
+
},
|
34
|
+
:help => ['sent_direct_messages, sds', 'List direct messages from you']
|
35
|
+
)
|
36
|
+
end
|
data/lib/plugins/erb.rb
CHANGED
data/lib/plugins/exec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command(
|
5
|
+
:name => :exec,
|
6
|
+
:exec_proc => lambda{|arg|
|
7
|
+
return unless arg
|
8
|
+
begin
|
9
|
+
pause
|
10
|
+
system *arg.split(/\s+/)
|
11
|
+
ensure
|
12
|
+
resume
|
13
|
+
end
|
14
|
+
},
|
15
|
+
:help => ['exec SHELL_COMMAND', 'execute a shell command']
|
16
|
+
)
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Termtter::Client.register_command(
|
4
|
+
:name => :exec_and_update,
|
5
|
+
:exec_proc => lambda{|arg|
|
6
|
+
return unless arg
|
7
|
+
`#{arg}`.each_line do |line|
|
8
|
+
next if line =~ /^\s*$/
|
9
|
+
Termtter::API.twitter.update(line)
|
10
|
+
puts "=> #{line}"
|
11
|
+
end
|
12
|
+
},
|
13
|
+
:help => ['exec_and_update COMMAND', 'execute the command']
|
14
|
+
)
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
require 'uri'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'cgi'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'meow'
|
10
|
+
growl = Meow.new('termtter', 'update_friends_timeline')
|
11
|
+
rescue LoadError
|
12
|
+
growl = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
config.plugins.growl.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
16
|
+
config.plugins.growl.set_default(:growl_user, [])
|
17
|
+
config.plugins.growl.set_default(:growl_keyword, [])
|
18
|
+
config.plugins.growl.set_default(:priority_veryhigh_user, [])
|
19
|
+
config.plugins.growl.set_default(:priority_high_user, [])
|
20
|
+
config.plugins.growl.set_default(:priority_normal_user, [])
|
21
|
+
config.plugins.growl.set_default(:priority_low_user, [])
|
22
|
+
config.plugins.growl.set_default(:priority_verylow_user, [])
|
23
|
+
config.plugins.growl.set_default(:priority_veryhigh_keyword, [])
|
24
|
+
config.plugins.growl.set_default(:priority_high_keyword, [])
|
25
|
+
config.plugins.growl.set_default(:priority_normal_keyword, [])
|
26
|
+
config.plugins.growl.set_default(:priority_low_keyword, [])
|
27
|
+
config.plugins.growl.set_default(:priority_verylow_keyword, [])
|
28
|
+
config.plugins.growl.set_default(:sticky_user, [])
|
29
|
+
config.plugins.growl.set_default(:sticky_keyword, [])
|
30
|
+
growl_keys = { 'user' => config.plugins.growl.growl_user,
|
31
|
+
'keyword' => Regexp.union(*config.plugins.growl.growl_keyword) }
|
32
|
+
priority_keys = { 'user' => [config.plugins.growl.priority_veryhigh_user,
|
33
|
+
config.plugins.growl.priority_high_user,
|
34
|
+
config.plugins.growl.priority_normal_user,
|
35
|
+
config.plugins.growl.priority_low_user,
|
36
|
+
config.plugins.growl.priority_verylow_user],
|
37
|
+
'keyword' => [Regexp.union(*config.plugins.growl.priority_veryhigh_keyword),
|
38
|
+
Regexp.union(*config.plugins.growl.priority_high_keyword),
|
39
|
+
Regexp.union(*config.plugins.growl.priority_normal_keyword),
|
40
|
+
Regexp.union(*config.plugins.growl.priority_low_keyword),
|
41
|
+
Regexp.union(*config.plugins.growl.priority_verylow_keyword) ] }
|
42
|
+
sticky_keys = { 'user' => config.plugins.growl.sticky_user,
|
43
|
+
'keyword' => Regexp.union(*config.plugins.growl.sticky_keyword) }
|
44
|
+
|
45
|
+
FileUtils.mkdir_p(config.plugins.growl.icon_cache_dir) unless File.exist?(config.plugins.growl.icon_cache_dir)
|
46
|
+
Dir.glob("#{config.plugins.growl.icon_cache_dir}/*") {|f| File.delete(f) unless File.size?(f) }
|
47
|
+
unless File.exist?("#{config.plugins.growl.icon_cache_dir}/default.png")
|
48
|
+
File.open("#{config.plugins.growl.icon_cache_dir}/default.png", "wb") do |f|
|
49
|
+
f << open("http://static.twitter.com/images/default_profile_normal.png").read
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_icon_path(s)
|
54
|
+
/https?:\/\/.+\/(\d+)\/.*?$/ =~ s.user.profile_image_url
|
55
|
+
cache_file = "%s/%s-%s%s" % [ config.plugins.growl.icon_cache_dir,
|
56
|
+
s.user.screen_name,
|
57
|
+
$+,
|
58
|
+
File.extname(s.user.profile_image_url) ]
|
59
|
+
unless File.exist?(cache_file)
|
60
|
+
Thread.new(s,cache_file) do |s,cache_file|
|
61
|
+
Dir.glob("#{config.plugins.growl.icon_cache_dir}/#{s.user.screen_name}-*") {|f| File.delete(f) }
|
62
|
+
begin
|
63
|
+
s.user.profile_image_url.sub!(/^https/,'http')
|
64
|
+
File.open(cache_file, 'wb') do |f|
|
65
|
+
f << open(URI.escape(s.user.profile_image_url)).read
|
66
|
+
end
|
67
|
+
rescue OpenURI::HTTPError
|
68
|
+
cache_file = "#{config.plugins.growl.icon_cache_dir}/default.png"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
return cache_file
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_priority(s,priority_keys)
|
76
|
+
priority = 2
|
77
|
+
5.times {|n|
|
78
|
+
return priority.to_s if priority_keys['user'][n].include?(s.user.screen_name) ||
|
79
|
+
priority_keys['keyword'][n] =~ s.text
|
80
|
+
priority -= 1
|
81
|
+
}
|
82
|
+
return '0'
|
83
|
+
end
|
84
|
+
|
85
|
+
def is_growl(s,growl_keys)
|
86
|
+
return true if (growl_keys['user'].empty? && growl_keys['keyword'] == /(?!)/) ||
|
87
|
+
(growl_keys['user'].include?(s.user.screen_name) || growl_keys['keyword'] =~ s.text)
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_sticky(s,sticky_keys)
|
92
|
+
return true if sticky_keys['user'].include?(s.user.screen_name) || sticky_keys['keyword'] =~ s.text
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
|
96
|
+
Termtter::Client.register_hook(
|
97
|
+
:name => :growl2,
|
98
|
+
:points => [:output],
|
99
|
+
:exec_proc => lambda {|statuses, event|
|
100
|
+
return unless event == :update_friends_timeline
|
101
|
+
Thread.start do
|
102
|
+
statuses.each do |s|
|
103
|
+
next unless is_growl(s,growl_keys)
|
104
|
+
growl_title = s.user.screen_name
|
105
|
+
growl_title += " (#{s.user.name})" unless s.user.screen_name == s.user.name
|
106
|
+
unless growl
|
107
|
+
arg = ['growlnotify', growl_title, '-m', s.text.gsub("\n",''), '-n', 'termtter', '-p', get_priority(s,priority_keys), '--image', get_icon_path(s)]
|
108
|
+
arg.push('-s') if is_sticky(s,sticky_keys)
|
109
|
+
system *arg
|
110
|
+
else
|
111
|
+
begin
|
112
|
+
icon = Meow.import_image(get_icon_path(s))
|
113
|
+
rescue
|
114
|
+
icon = Meow.import_image("#{config.plugins.growl.icon_cache_dir}/default.png")
|
115
|
+
end
|
116
|
+
growl.notify(growl_title, CGI.unescape(CGI.unescapeHTML(s.text)),
|
117
|
+
{:icon => icon,
|
118
|
+
:priority => get_priority(s,priority_keys),
|
119
|
+
:sticky => is_sticky(s,sticky_keys) }) do
|
120
|
+
s.text.gsub(URI.regexp) {|uri| system "open #{uri}"}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
sleep 0.1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
}
|
127
|
+
)
|
128
|
+
#Optional setting example.
|
129
|
+
# Growl ON setting.
|
130
|
+
# config.plugins.growl.growl_user = ['p2pquake', 'jihou']
|
131
|
+
# config.plugins.growl.growl_keyword = ['地震', /^@screen_name/]
|
132
|
+
# Priority setting.
|
133
|
+
# config.plugins.growl.priority_veryhigh_user = ['veryhigh_user']
|
134
|
+
# config.plugins.growl.priority_veryhigh_keyword = ['veryhigh_keyword', /^@screen_name']
|
135
|
+
# config.plugins.growl.priority_high_user = ['high_user']
|
136
|
+
# config.plugins.growl.priority_high_keyword = ['high_keyword']
|
137
|
+
# config.plugins.growl.priority_low_user = ['low_user']
|
138
|
+
# config.plugins.growl.priority_low_keyword = ['low_keyword']
|
139
|
+
# config.plugins.growl.priority_verylow_user = ['verylow_user']
|
140
|
+
# config.plugins.growl.priority_verylow_keyword = ['verylow_keyword']
|
141
|
+
# Sticky setting.
|
142
|
+
# config.plugins.growl.sticky_user = ['screen_name']
|
143
|
+
# config.plugins.growl.sticky_keyword = [/^@screen_name/, '#termtter']
|
data/lib/plugins/hatebu.rb
CHANGED
@@ -43,10 +43,10 @@ module Termtter::Client
|
|
43
43
|
},
|
44
44
|
:completion_proc => lambda {|cmd, args|
|
45
45
|
if args =~ /^(\d*)$/
|
46
|
-
|
46
|
+
find_status_ids($1){|id| "#{cmd} #{id}"}
|
47
47
|
end
|
48
48
|
},
|
49
|
-
|
49
|
+
:help => ['hatebu ID', 'Hatena bookmark a status']
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'atomutil'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
module Termtter::Client
|
8
|
+
register_command(
|
9
|
+
:name => :hatebu_and_update, :aliases => [:hau],
|
10
|
+
:exec_proc => lambda {|arg|
|
11
|
+
url, comment = arg.split(/\s/)
|
12
|
+
if url =~ URI.regexp
|
13
|
+
auth = auth = Atompub::Auth::Wsse.new({
|
14
|
+
:username => config.plugins.hatebu.username,
|
15
|
+
:password => config.plugins.hatebu.password,
|
16
|
+
})
|
17
|
+
link = Atom::Link.new({
|
18
|
+
:href => url,
|
19
|
+
:rel => 'related',
|
20
|
+
:type => 'text/html',
|
21
|
+
})
|
22
|
+
entry = Atom::Entry.new({
|
23
|
+
:link => link,
|
24
|
+
:title => 'dummy',
|
25
|
+
:summary => comment,
|
26
|
+
})
|
27
|
+
req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
|
28
|
+
req['User-Agent'] = 'Mozilla/5.0'
|
29
|
+
req['Content-Type'] = 'application/atom+xml'
|
30
|
+
req['Slug'] = 'termtter'
|
31
|
+
req.body = entry.to_s
|
32
|
+
auth.authorize(req)
|
33
|
+
title = nil
|
34
|
+
tinyurl = nil
|
35
|
+
Termtter::API.connection.start('b.hatena.ne.jp', 80) do |http|
|
36
|
+
res = http.request(req)
|
37
|
+
title = Nokogiri::XML(res.body).search('link[title]').first['title'] rescue nil
|
38
|
+
end
|
39
|
+
if title
|
40
|
+
Termtter::API.connection.start('tinyurl.com', 80) do |http|
|
41
|
+
tinyurl = http.get('/api-create.php?url=' + URI.escape(url)).body
|
42
|
+
end
|
43
|
+
|
44
|
+
Termtter::API.twitter.update("[はてぶ] #{title} #{tinyurl}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
},
|
48
|
+
:help => ['hatebu2 URL', 'Hatena bookmark a URL, and update']
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# hatebu.rb
|
53
|
+
# hatena bookmark it, and post
|
54
|
+
#
|
55
|
+
# config.plugins.hatebu.username = 'your-username-on-hatena'
|
56
|
+
# config.plugins.hatebu.password = 'your-password-on-hatena'
|
57
|
+
#
|
58
|
+
# hatebu_and_update http://www.yahoo.co.jp/ [yahoo]
|
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/notify-send2.rb
CHANGED
@@ -2,23 +2,36 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
|
-
# notify-send.rb からコピペ。共通化したいところ。
|
6
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
|
+
|
7
15
|
def get_icon_path(s)
|
8
|
-
|
9
|
-
cache_file = "%s/%s%s" % [ config.plugins.notify_send.icon_cache_dir,
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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) }
|
14
24
|
begin
|
15
|
-
|
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
|
16
29
|
rescue OpenURI::HTTPError
|
17
|
-
|
30
|
+
cache_file = "#{config.plugins.notify_send.icon_cache_dir}/default.png"
|
18
31
|
end
|
19
32
|
end
|
20
33
|
end
|
21
|
-
cache_file
|
34
|
+
return cache_file
|
22
35
|
end
|
23
36
|
|
24
37
|
Termtter::Client.register_hook(
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'RMagick'
|
5
|
+
|
6
|
+
# Copy from notify-send2.rb
|
7
|
+
config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
8
|
+
def get_icon_path(s)
|
9
|
+
FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
|
10
|
+
cache_file = "%s/%s%s" % [ config.plugins.notify_send.icon_cache_dir,
|
11
|
+
s.user.screen_name,
|
12
|
+
File.extname(s.user.profile_image_url) ]
|
13
|
+
if !File.exist?(cache_file) || (File.atime(cache_file) + 24*60*60) < Time.now
|
14
|
+
File.open(cache_file, "wb") do |f|
|
15
|
+
begin
|
16
|
+
image = open(URI.escape(s.user.profile_image_url)).read
|
17
|
+
rimage = Magick::Image.from_blob(image).first
|
18
|
+
rimage = rimage.resize_to_fill(48, 48)
|
19
|
+
f << rimage.to_blob
|
20
|
+
rescue OpenURI::HTTPError
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
cache_file
|
26
|
+
end
|
27
|
+
|
28
|
+
Termtter::Client.register_hook(
|
29
|
+
:name => :notify_send3,
|
30
|
+
:points => [:output],
|
31
|
+
:exec_proc => lambda {|statuses, event|
|
32
|
+
return unless event == :update_friends_timeline
|
33
|
+
Thread.start do
|
34
|
+
statuses.each do |s|
|
35
|
+
text = CGI.escapeHTML(s.text)
|
36
|
+
text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
|
37
|
+
system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
|
38
|
+
sleep 0.1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
}
|
42
|
+
)
|
43
|
+
|
44
|
+
# notify-send3.rb
|
45
|
+
# caching resized profile image.
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Termtter::Client
|
6
|
+
def self.open_uri(uri)
|
7
|
+
unless config.plugins.open_url.browser.empty?
|
8
|
+
system config.plugins.open_url.browser, uri
|
9
|
+
else
|
10
|
+
case RUBY_PLATFORM
|
11
|
+
when /linux/
|
12
|
+
system 'firefox', uri
|
13
|
+
when /mswin(?!ce)|mingw|bccwin/
|
14
|
+
system 'explorer', uri
|
15
|
+
else
|
16
|
+
system 'open', uri
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register_command(
|
22
|
+
:name => :open_url,
|
23
|
+
:help => ['open_url (TYPABLE|ID|@USER)', 'Open url'],
|
24
|
+
:exec_proc => lambda {|arg|
|
25
|
+
Thread.new(arg) do |arg|
|
26
|
+
if public_storage[:typable_id] && status = typable_id_status(arg)
|
27
|
+
status.text.gsub(URI.regexp) {|uri|
|
28
|
+
open_uri(uri)
|
29
|
+
}
|
30
|
+
else
|
31
|
+
case arg
|
32
|
+
when /^@([A-Za-z0-9_]+)/
|
33
|
+
user = $1
|
34
|
+
statuses = Termtter::API.twitter.user_timeline(user)
|
35
|
+
return if statuses.empty?
|
36
|
+
statuses[0].text.gsub(URI.regexp) {|uri| open_uri(uri) }
|
37
|
+
when /^\d+/
|
38
|
+
Termtter::API.twitter.show(arg).text.gsub(URI.regexp) {|uri| open_uri(uri) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
},
|
43
|
+
:completion_proc => lambda {|cmd, arg|
|
44
|
+
if public_storage[:typable_id] && typable_id?(arg)
|
45
|
+
"#{cmd} #{typable_id_convert(arg)}"
|
46
|
+
else
|
47
|
+
case arg
|
48
|
+
when /@(.*)/
|
49
|
+
find_user_candidates $1, "#{cmd} @%s"
|
50
|
+
when /(\d+)/
|
51
|
+
find_status_ids(arg).map{|id| "#{cmd} #{$1}"}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
}
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
#Optional Setting
|
59
|
+
# config.plugins.open_url.browser = firefox
|
data/lib/plugins/reblog.rb
CHANGED
@@ -16,7 +16,7 @@ module Termtter::Client
|
|
16
16
|
else
|
17
17
|
status = t.show(id).first
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
Tumblr::API.write(config.plugins.reblog.email, config.plugins.reblog.password) do
|
21
21
|
quote("#{status.text}", "<a href=\"http://twitter.com/#{status.user_screen_name}/status/#{status.id}\">Twitter / #{status.user_name}</a>")
|
22
22
|
end
|
@@ -24,7 +24,7 @@ module Termtter::Client
|
|
24
24
|
},
|
25
25
|
:completion_proc => lambda {|cmd, args|
|
26
26
|
if args =~ /^(\d*)$/
|
27
|
-
|
27
|
+
find_status_ids($1){|id| "#{cmd} #{id}"}
|
28
28
|
end
|
29
29
|
},
|
30
30
|
:help => ['reblog ID', 'Tumblr Reblog a status']
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
config.plugins.retweet.set_default(:format, 'RT @<%=s.user.screen_name%>: <%=s.text%>')
|
4
|
+
|
5
|
+
module Termtter::Client
|
6
|
+
def self.post_retweet(s)
|
7
|
+
text = ERB.new(config.plugins.retweet.format).result(binding)
|
8
|
+
Termtter::API.twitter.update(text)
|
9
|
+
puts "=> #{text}"
|
10
|
+
end
|
11
|
+
|
12
|
+
register_command(
|
13
|
+
:name => :retweet,
|
14
|
+
:aliases => [:rt],
|
15
|
+
:help => ['retweet,rt (TYPABLE|ID|@USER)', 'Post a retweet message'],
|
16
|
+
:exec_proc => lambda {|arg|
|
17
|
+
if public_storage[:typable_id] && s = typable_id_status(arg)
|
18
|
+
post_retweet(s)
|
19
|
+
else
|
20
|
+
case arg
|
21
|
+
when /(\d+)/
|
22
|
+
post_retweet(Termtter::API.twitter.show(arg))
|
23
|
+
#s = Twitter::API.twitter.show(arg)
|
24
|
+
#post_retweet(s)
|
25
|
+
when /@([A-Za-z0-9_]+)/
|
26
|
+
user = $1
|
27
|
+
statuses = Termtter::API.twitter.user_timeline(user)
|
28
|
+
return if statuses.empty?
|
29
|
+
post_retweet(statuses[0])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
},
|
33
|
+
:completion_proc => lambda {|cmd, arg|
|
34
|
+
if public_storage[:typable_id] && s = typable_id_status(arg)
|
35
|
+
"u #{ERB.new(config.plugins.retweet.format).result(binding)}"
|
36
|
+
else
|
37
|
+
case arg
|
38
|
+
when /@(.*)/
|
39
|
+
find_user_candidates $1, "#{cmd} @%s"
|
40
|
+
when /(\d+)/
|
41
|
+
find_status_ids(arg).map{|id| "#{cmd} #{$1}"}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
}
|
45
|
+
)
|
46
|
+
end
|