termtter 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -8
- data/Rakefile +13 -3
- data/lib/plugins/command_plus.rb +14 -14
- data/lib/plugins/confirm.rb +10 -4
- data/lib/plugins/countter.rb +18 -18
- data/lib/plugins/db.rb +1 -1
- data/lib/plugins/defaults/alias.rb +69 -0
- data/lib/plugins/defaults/auto_reload.rb +2 -2
- data/lib/plugins/defaults/command_line.rb +9 -0
- data/lib/plugins/defaults/fib.rb +5 -23
- data/lib/plugins/defaults/retweet.rb +17 -13
- data/lib/plugins/defaults/standard_commands.rb +40 -63
- data/lib/plugins/defaults/standard_completion.rb +14 -9
- data/lib/plugins/defaults/stdout.rb +32 -19
- data/lib/plugins/defaults.rb +1 -0
- data/lib/plugins/erb.rb +4 -8
- data/lib/plugins/expand-tinyurl.rb +4 -0
- data/lib/plugins/fibyou.rb +12 -0
- data/lib/plugins/group.rb +19 -20
- data/lib/plugins/hi.rb +15 -0
- data/lib/plugins/hugeurl.rb +1 -1
- data/lib/plugins/irc_gw.rb +53 -5
- data/lib/plugins/itunes.rb +33 -0
- data/lib/plugins/jakigan.rb +30 -0
- data/lib/plugins/list_with_opts.rb +1 -1
- data/lib/plugins/multi_output.rb +34 -0
- data/lib/plugins/multi_post.rb +30 -15
- data/lib/plugins/open.rb +44 -0
- data/lib/plugins/paranoid.rb +11 -0
- data/lib/plugins/quick_exit.rb +9 -0
- data/lib/plugins/replace.rb +54 -0
- data/lib/plugins/saykanji.rb +1 -1
- data/lib/plugins/searchline.rb +44 -0
- data/lib/plugins/tinyurl.rb +7 -1
- data/lib/plugins/train.rb +24 -0
- data/lib/termtter/active_rubytter.rb +39 -0
- data/lib/termtter/api.rb +24 -21
- data/lib/termtter/client.rb +17 -29
- data/lib/termtter/config_setup.rb +27 -2
- data/lib/termtter/config_template.erb +2 -2
- data/lib/termtter/version.rb +1 -1
- data/lib/termtter.rb +9 -4
- data/spec/plugins/db_spec.rb +1 -1
- data/spec/plugins/fib_spec.rb +1 -1
- data/spec/plugins/standard_commands_spec.rb +4 -0
- data/spec/plugins/whois_spec.rb +7 -7
- data/spec/termtter/active_rubytter_spec.rb +70 -0
- metadata +29 -5
@@ -10,12 +10,14 @@ config.plugins.stdout.set_default(
|
|
10
10
|
'<90><%=time%> [<%=status_id%>]</90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
|
11
11
|
'<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%><%=s.user.protected ? "[P]" : ""%></90>'
|
12
12
|
)
|
13
|
+
config.plugins.stdout.set_default(:time_format_today, '%H:%M:%S')
|
14
|
+
config.plugins.stdout.set_default(:time_format_not_today, '%y/%m/%d %H:%M')
|
13
15
|
config.plugins.stdout.set_default(:enable_pager, true)
|
14
16
|
config.plugins.stdout.set_default(:pager, 'less -R -f +G')
|
15
17
|
config.plugins.stdout.set_default(:window_height, 50)
|
16
18
|
config.plugins.stdout.set_default(:typable_ids, ('aa'..'zz').to_a)
|
17
19
|
config.plugins.stdout.set_default(:typable_id_prefix, '$')
|
18
|
-
config.plugins.stdout.set_default(:show_as_thread, false)
|
20
|
+
config.plugins.stdout.set_default(:show_as_thread, false) # db plugin is required
|
19
21
|
|
20
22
|
module Termtter
|
21
23
|
class TypableIdGenerator
|
@@ -27,30 +29,49 @@ module Termtter
|
|
27
29
|
end
|
28
30
|
@ids = ids
|
29
31
|
@table = {}
|
32
|
+
@rtable = {}
|
30
33
|
end
|
31
34
|
|
32
35
|
def next(data)
|
33
36
|
id = @ids.shift
|
34
37
|
@ids.push id
|
38
|
+
@rtable.delete(@table[id])
|
35
39
|
@table[id] = data
|
40
|
+
@rtable[data] = id
|
36
41
|
id
|
37
42
|
end
|
38
43
|
|
39
44
|
def get(id)
|
40
45
|
@table[id]
|
41
46
|
end
|
47
|
+
|
48
|
+
def get_id(data)
|
49
|
+
@rtable[data] || self.next(data)
|
50
|
+
end
|
42
51
|
end
|
43
52
|
|
44
53
|
module Client
|
45
54
|
@typable_id_generator = TypableIdGenerator.new(config.plugins.stdout.typable_ids)
|
46
55
|
|
47
56
|
def self.data_to_typable_id(data)
|
48
|
-
id = config.plugins.stdout.typable_id_prefix + @typable_id_generator.
|
57
|
+
id = config.plugins.stdout.typable_id_prefix + @typable_id_generator.get_id(data)
|
49
58
|
end
|
50
59
|
|
51
60
|
def self.typable_id_to_data(id)
|
52
61
|
@typable_id_generator.get(id)
|
53
62
|
end
|
63
|
+
|
64
|
+
def self.time_format_for(statuses)
|
65
|
+
t0 = Time.now
|
66
|
+
t1 = Time.parse(statuses.first[:created_at])
|
67
|
+
t2 = Time.parse(statuses.last[:created_at])
|
68
|
+
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
69
|
+
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
70
|
+
config.plugins.stdout.time_format_today
|
71
|
+
else
|
72
|
+
config.plugins.stdout.time_format_not_today
|
73
|
+
end
|
74
|
+
end
|
54
75
|
end
|
55
76
|
|
56
77
|
class StdOut < Hook
|
@@ -59,27 +80,16 @@ module Termtter
|
|
59
80
|
end
|
60
81
|
|
61
82
|
def call(statuses, event)
|
62
|
-
print_statuses(statuses)
|
83
|
+
print_statuses(statuses, event)
|
63
84
|
end
|
64
85
|
|
65
|
-
def print_statuses(statuses, sort = true, time_format = nil)
|
86
|
+
def print_statuses(statuses, event, sort = true, time_format = nil)
|
66
87
|
return unless statuses and statuses.first
|
67
|
-
|
68
|
-
t0 = Time.now
|
69
|
-
t1 = Time.parse(statuses.first[:created_at])
|
70
|
-
t2 = Time.parse(statuses.last[:created_at])
|
71
|
-
time_format =
|
72
|
-
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
73
|
-
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
74
|
-
'%H:%M:%S'
|
75
|
-
else
|
76
|
-
'%y/%m/%d %H:%M'
|
77
|
-
end
|
78
|
-
end
|
88
|
+
time_format ||= Termtter::Client.time_format_for statuses
|
79
89
|
|
80
90
|
output_text = ''
|
81
91
|
statuses.each do |s|
|
82
|
-
output_text << status_line(s, time_format)
|
92
|
+
output_text << status_line(s, time_format, event)
|
83
93
|
end
|
84
94
|
|
85
95
|
if config.plugins.stdout.enable_pager && ENV['LINES'] && statuses.size > ENV['LINES'].to_i
|
@@ -93,7 +103,7 @@ module Termtter
|
|
93
103
|
end
|
94
104
|
end
|
95
105
|
|
96
|
-
def status_line(s, time_format, indent = 0)
|
106
|
+
def status_line(s, time_format, event, indent = 0)
|
97
107
|
return '' unless s
|
98
108
|
text = TermColor.escape(s.text)
|
99
109
|
color = config.plugins.stdout.colors[s.user.id.to_i % config.plugins.stdout.colors.size]
|
@@ -114,10 +124,13 @@ module Termtter
|
|
114
124
|
|
115
125
|
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
116
126
|
indent_text = indent > 0 ? "#{' ' * (indent - 1)} ┗ " : ''
|
127
|
+
|
128
|
+
erbed_text = Client.get_hooks(:pre_coloring).inject(erbed_text){|result, hook| hook.call(result, event)}
|
129
|
+
|
117
130
|
text = TermColor.parse(indent_text + erbed_text) + "\n"
|
118
131
|
text = TermColor.unescape(text)
|
119
132
|
if config.plugins.stdout.show_as_thread && s.in_reply_to_status_id
|
120
|
-
text << status_line(Status[s.in_reply_to_status_id], time_format, indent + 1)
|
133
|
+
text << status_line(Status[s.in_reply_to_status_id], time_format, event, indent + 1)
|
121
134
|
end
|
122
135
|
text
|
123
136
|
end
|
data/lib/plugins/defaults.rb
CHANGED
data/lib/plugins/erb.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
|
3
2
|
require 'erb'
|
4
|
-
|
5
|
-
|
6
|
-
:name => :erb,
|
7
|
-
:point => :modify_arg_for_update,
|
8
|
-
:exec_proc => lambda {|cmd, arg|
|
3
|
+
module Termtter::Client
|
4
|
+
register_hook(:erb, :point => :modify_arg_for_update) do |cmd, arg|
|
9
5
|
ERB.new(arg).result(binding)
|
10
|
-
|
11
|
-
|
6
|
+
end
|
7
|
+
end
|
12
8
|
|
13
9
|
# erb.rb
|
14
10
|
# enable to <%= %> in the command update
|
@@ -5,6 +5,8 @@ URL_SHORTTERS = [
|
|
5
5
|
{ :host => "is.gd", :pattern => %r'(http://is\.gd(/[\w/]+))' },
|
6
6
|
{ :host => "bit.ly", :pattern => %r'(http://bit\.ly(/[\w/]+))' },
|
7
7
|
{ :host => "ff.im", :pattern => %r'(http://ff\.im(/[-\w/]+))'},
|
8
|
+
{ :host => "to.ly", :pattern => %r'(http://to\.ly(/[-\w/]+))'},
|
9
|
+
{ :host => "j.mp", :pattern => %r'(http://j\.mp(/[\w/]+))' },
|
8
10
|
]
|
9
11
|
|
10
12
|
config.plugins.expand_tinyurl.set_default(:shortters, [])
|
@@ -52,4 +54,6 @@ def expand_url(host, path)
|
|
52
54
|
res = http_class.new(host).head(path)
|
53
55
|
return nil unless res.code == "301" or res.code == "302"
|
54
56
|
res['Location'].force_encoding(Encoding::UTF_8)
|
57
|
+
rescue
|
58
|
+
nil
|
55
59
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# It depends on defaults/fib.rb
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command(:fibyou) do |arg|
|
5
|
+
/(\w+)\s(\d+)/ =~ arg
|
6
|
+
name = normalize_as_user_name($1)
|
7
|
+
n = $2.to_i
|
8
|
+
text = "@#{name} fib(#{n}) = #{fib n}"
|
9
|
+
Termtter::API.twitter.update(text)
|
10
|
+
puts "=> " << text
|
11
|
+
end
|
12
|
+
end
|
data/lib/plugins/group.rb
CHANGED
@@ -1,17 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
module Termtter
|
4
|
-
class Status
|
5
|
-
def is_member?(group = nil)
|
6
|
-
if group
|
7
|
-
config.plugins.group.groups[group].include? self.user.screen_name
|
8
|
-
else
|
9
|
-
config.plugins.group.groups.values.flatten.include? self.user.screen_name
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
3
|
module Termtter::Client
|
16
4
|
config.plugins.group.
|
17
5
|
set_default(:groups, {})
|
@@ -34,15 +22,25 @@ module Termtter::Client
|
|
34
22
|
:exec_proc => lambda {|arg|
|
35
23
|
unless arg.empty?
|
36
24
|
group_name = arg.to_sym
|
25
|
+
groups = config.plugins.group.groups
|
37
26
|
if group_name == :all
|
38
|
-
targets =
|
27
|
+
targets = groups.values.flatten.uniq
|
28
|
+
elsif groups.keys.include? group_name
|
29
|
+
targets = groups[group_name]
|
39
30
|
else
|
40
|
-
|
31
|
+
ignore_cased = groups.keys.map(&:to_s).grep(/^#{group_name}$/i).map(&:to_sym)
|
32
|
+
if ignore_cased.length == 1
|
33
|
+
targets = groups[ignore_cased.first]
|
34
|
+
elsif ignore_cased.length > 1
|
35
|
+
puts "which? #{ignore_cased.inspect.gsub(':','')}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
if targets
|
39
|
+
statuses = targets ? targets.map { |target|
|
40
|
+
public_storage[:tweet][target]
|
41
|
+
}.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
|
42
|
+
output(statuses, :search)
|
41
43
|
end
|
42
|
-
statuses = targets ? targets.map { |target|
|
43
|
-
public_storage[:tweet][target]
|
44
|
-
}.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
|
45
|
-
output(statuses, :search)
|
46
44
|
else
|
47
45
|
config.plugins.group.groups.each_pair do |key, value|
|
48
46
|
puts "#{key}: #{value.join(',')}"
|
@@ -69,10 +67,10 @@ module Termtter::Client
|
|
69
67
|
:exec_proc => lambda do |statuses, event|
|
70
68
|
return statuses unless event == :update_friends_timeline
|
71
69
|
return statuses unless config.plugins.group.default_filter
|
72
|
-
|
70
|
+
filter_group = config.plugins.group.default_filter
|
73
71
|
r = []
|
74
72
|
statuses.each do |s|
|
75
|
-
unless self.is_member?(s,
|
73
|
+
unless self.is_member?(s, filter_group)
|
76
74
|
r << s
|
77
75
|
end
|
78
76
|
end
|
@@ -86,5 +84,6 @@ end
|
|
86
84
|
# config.plugins.group.groups = {
|
87
85
|
# :rits => %w(hakobe isano hitode909)
|
88
86
|
# }
|
87
|
+
# config.plugins.group.default_filter = :rits
|
89
88
|
# NOTE: group.rb needs plugin/log
|
90
89
|
|
data/lib/plugins/hi.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
[:hi, :hola].each do |hi|
|
4
|
+
register_command(hi, :help => ["#{hi} [(Optinal) USER]", "Post a #{hi}"]) do |arg|
|
5
|
+
result =
|
6
|
+
if arg.empty?
|
7
|
+
Termtter::API.twitter.update(hi.to_s)
|
8
|
+
else
|
9
|
+
name = normalize_as_user_name(arg)
|
10
|
+
Termtter::API.twitter.update("#{hi} @#{name}")
|
11
|
+
end
|
12
|
+
puts "=> " << result.text
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/plugins/hugeurl.rb
CHANGED
@@ -26,7 +26,7 @@ Termtter::Client::register_hook(
|
|
26
26
|
config.plugins.hugeurl.skip_users.include?(s.user.screen_name) and next
|
27
27
|
s.text.gsub!(HUGEURL_TARGET_PATTERN) do |m|
|
28
28
|
res = http.get('/hugeurl?url=' + m)
|
29
|
-
res.code == '200' ? res.body : m
|
29
|
+
res.code == '200' && res.body !~ /^</ ? res.body : m
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
data/lib/plugins/irc_gw.rb
CHANGED
@@ -2,10 +2,24 @@
|
|
2
2
|
|
3
3
|
require 'net/irc'
|
4
4
|
|
5
|
-
# TODO: post text of stdout too
|
6
|
-
|
7
5
|
config.plugins.irc_gw.set_default(:port, 16669)
|
8
6
|
config.plugins.irc_gw.set_default(:last_statuses_count, 100)
|
7
|
+
config.plugins.irc_gw.set_default(:logger_level, Logger::ERROR)
|
8
|
+
|
9
|
+
module Termtter::Client
|
10
|
+
class << self
|
11
|
+
def friends
|
12
|
+
user_name = config.user_name
|
13
|
+
|
14
|
+
frinends = []
|
15
|
+
page = 0
|
16
|
+
begin
|
17
|
+
frinends += tmp = Termtter::API::twitter.friends(user_name, :page => page+=1)
|
18
|
+
end until tmp.empty?
|
19
|
+
frinends.map(&:screen_name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
9
23
|
|
10
24
|
class TermtterIrcGateway < Net::IRC::Server::Session
|
11
25
|
@@listners = []
|
@@ -25,6 +39,13 @@ class TermtterIrcGateway < Net::IRC::Server::Session
|
|
25
39
|
end
|
26
40
|
}
|
27
41
|
)
|
42
|
+
if Termtter::Client.respond_to? :register_output
|
43
|
+
Termtter::Client.register_output(:irc) do |message|
|
44
|
+
@@listners.each do |listener|
|
45
|
+
listener.log(message.gsub(/\e\[\d+m/, '')) # remove escape sequence
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
28
49
|
|
29
50
|
def server_name; 'termtter' end
|
30
51
|
def server_version; '0.0.0' end
|
@@ -41,11 +62,13 @@ class TermtterIrcGateway < Net::IRC::Server::Session
|
|
41
62
|
when :update_friends_timeline
|
42
63
|
PRIVMSG
|
43
64
|
else
|
65
|
+
time_format = Termtter::Client.time_format_for statuses
|
44
66
|
NOTICE
|
45
67
|
end
|
46
|
-
|
47
68
|
statuses.each do |s|
|
48
|
-
|
69
|
+
typable_id = Termtter::Client.data_to_typable_id(s.id)
|
70
|
+
time = Time.parse(s.created_at).strftime(time_format) if time_format
|
71
|
+
post s.user.screen_name, msg_type, main_channel, [time, s.text, typable_id].compact.join(' ')
|
49
72
|
end
|
50
73
|
end
|
51
74
|
|
@@ -61,21 +84,46 @@ class TermtterIrcGateway < Net::IRC::Server::Session
|
|
61
84
|
super
|
62
85
|
post @prefix, JOIN, main_channel
|
63
86
|
post server_name, MODE, main_channel, "+o", @prefix.nick
|
87
|
+
check_friends
|
64
88
|
self.call(@@last_statuses || [], :update_friends_timeline)
|
65
89
|
end
|
66
90
|
|
67
91
|
def on_privmsg(m)
|
68
92
|
target, message = *m.params
|
69
93
|
Termtter::Client.call_commands('update ' + message)
|
94
|
+
post @prefix, TOPIC, main_channel, message
|
95
|
+
end
|
96
|
+
|
97
|
+
def log(str)
|
98
|
+
str.each_line do |line|
|
99
|
+
post server_name, NOTICE, main_channel, line
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def check_friends
|
104
|
+
params = []
|
105
|
+
max_params_count = 3
|
106
|
+
Termtter::Client.friends.each do |name|
|
107
|
+
prefix = Prefix.new("#{name}!#{name}@localhost")
|
108
|
+
post prefix, JOIN, main_channel
|
109
|
+
params << prefix.nick
|
110
|
+
next if params.size < max_params_count
|
111
|
+
|
112
|
+
post server_name, MODE, main_channel, "+#{"v" * params.size}", *params
|
113
|
+
params = []
|
114
|
+
end
|
115
|
+
post server_name, MODE, main_channel, "+#{"v" * params.size}", *params unless params.empty?
|
70
116
|
end
|
71
117
|
end
|
72
118
|
|
73
119
|
unless defined? IRC_SERVER
|
120
|
+
logger = Logger.new($stdout)
|
121
|
+
logger.level = config.plugins.irc_gw.logger_level
|
74
122
|
IRC_SERVER = Net::IRC::Server.new(
|
75
123
|
'localhost',
|
76
124
|
config.plugins.irc_gw.port,
|
77
125
|
TermtterIrcGateway,
|
78
|
-
:logger =>
|
126
|
+
:logger => logger
|
79
127
|
)
|
80
128
|
Thread.start do
|
81
129
|
IRC_SERVER.start
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'appscript' or raise 'itunes plugin cannot run'
|
3
|
+
|
4
|
+
config.plugins.itunes.set_default(:prefix, 'Listening now:')
|
5
|
+
config.plugins.itunes.set_default(:suffix, '#iTunes #listening')
|
6
|
+
config.plugins.itunes.set_default(
|
7
|
+
:format,
|
8
|
+
'<%=prefix%> <%=track_name%> (<%=time%>) <%=artist%> <%=album%> <%=suffix%>')
|
9
|
+
|
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
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
if RUBY_VERSION >= '1.9'
|
4
|
+
# nop
|
5
|
+
elsif RUBY_VERSION >= '1.8.7'
|
6
|
+
class Array
|
7
|
+
alias sample choice
|
8
|
+
end
|
9
|
+
else
|
10
|
+
class Array
|
11
|
+
def sample
|
12
|
+
at(rand(size))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Termtter::Client
|
18
|
+
module Jakigan
|
19
|
+
TEMPLATES = [
|
20
|
+
# http://twitter.com/yugui/status/3086394151
|
21
|
+
'%s、か。ククク、その真の意図、邪気眼を持たぬ者には分かるまい。',
|
22
|
+
# http://twitter.com/Sixeight/statuses/3705973751
|
23
|
+
'僕の邪気眼は%sです。'
|
24
|
+
]
|
25
|
+
end
|
26
|
+
register_macro(:jkg, "update #{Jakigan::TEMPLATES.sample}",
|
27
|
+
:help => ['jkg {MESSAGE}', 'update "{MESSAGE}+something jkg."'],
|
28
|
+
:alias => :jk
|
29
|
+
)
|
30
|
+
end
|
@@ -3,7 +3,7 @@ module Termtter::Client
|
|
3
3
|
register_command(
|
4
4
|
:name => :list, :aliases => [:l],
|
5
5
|
:exec_proc => lambda {|arg|
|
6
|
-
_, options, user = */((?:\-[a-z][= ]\S+\s*)+)?(\w+)?/.match(arg)
|
6
|
+
_, options, user = */((?:\-[a-z][= ]\S+\s*)+)?(?:@?(\w+))?/.match(arg)
|
7
7
|
params = {}
|
8
8
|
options.scan(/(\-[a-z])[= ](\S+)/).each do |k,v|
|
9
9
|
v = v.sub(/^['"]/,'').sub(/['"]$/,'')
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
@outputs = { }
|
5
|
+
class << self
|
6
|
+
def register_output(as, &block)
|
7
|
+
@outputs[as] = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def delete_output(name)
|
11
|
+
@outputs.delete(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def puts message
|
15
|
+
@outputs.each_value do |block|
|
16
|
+
block.call(message)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Termtter::Client
|
23
|
+
register_command(
|
24
|
+
:name => :outputs,
|
25
|
+
:exec_proc => lambda {|arg|
|
26
|
+
puts @outputs.keys.inspect
|
27
|
+
},
|
28
|
+
:help => ['outputs', 'Show outputs']
|
29
|
+
)
|
30
|
+
|
31
|
+
register_output(:stdout) do |msg|
|
32
|
+
STDOUT.puts(msg)
|
33
|
+
end
|
34
|
+
end
|
data/lib/plugins/multi_post.rb
CHANGED
@@ -3,30 +3,45 @@
|
|
3
3
|
module Termtter::Client
|
4
4
|
class << self
|
5
5
|
def wassr_update(text)
|
6
|
+
if text.match(/^(\d+)\s+(.+)$/) and
|
7
|
+
(s = Termtter::API.twitter.show($1) rescue nil)
|
8
|
+
tmp_text = "@#{s.user.screen_name} #{$2}"
|
9
|
+
else
|
10
|
+
tmp_text = text
|
11
|
+
end
|
12
|
+
|
6
13
|
Net::HTTP.version_1_2
|
7
14
|
req = Net::HTTP::Post.new("/statuses/update.json?")
|
8
15
|
req.basic_auth config.plugins.wassr.username, config.plugins.wassr.password
|
9
16
|
Net::HTTP.start('api.wassr.jp', 80) do |http|
|
10
|
-
res = http.request(req, "status=#{URI.escape(
|
17
|
+
res = http.request(req, "status=#{URI.escape(tmp_text)}&source=Termtter")
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
14
|
-
end
|
15
21
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
register_hook(
|
23
|
+
:name => :multi_post,
|
24
|
+
:points => [:post_exec_update, :post_exec_reply, :post_exec_retweet],
|
25
|
+
:exec_proc => lambda {|cmd, arg, result|
|
26
|
+
prefix = config.plugins.stdout.typable_id_prefix
|
27
|
+
if result
|
28
|
+
wassr_arg = result
|
29
|
+
elsif arg.match(/(\$([a-z]{2}))/) and
|
30
|
+
s = Termtter::API.twitter.show(typable_id_to_data($2))
|
31
|
+
wassr_arg = arg.sub($1, "@" + s.user.screen_name)
|
32
|
+
else
|
33
|
+
wassr_arg = arg
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
Termtter::Client.wassr_update(wassr_arg.strip)
|
38
|
+
rescue
|
39
|
+
puts "RuntimeError: #{$!}"
|
40
|
+
end
|
41
|
+
}
|
42
|
+
)
|
43
|
+
end
|
26
44
|
|
27
|
-
return arg
|
28
|
-
}
|
29
|
-
)
|
30
45
|
|
31
46
|
# multi_post.rb
|
32
47
|
# One post, multi update.
|
data/lib/plugins/open.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter
|
4
|
+
module Client
|
5
|
+
plug 'uri-open'
|
6
|
+
register_command(
|
7
|
+
:name => :open, :aliases => [:o],
|
8
|
+
:exec_proc => proc {|arg|
|
9
|
+
sid, n = arg.split(/ +/)
|
10
|
+
if sid.nil?
|
11
|
+
call_commands "uri-open"
|
12
|
+
else
|
13
|
+
target = (n || 1).to_i
|
14
|
+
target_uri = nil
|
15
|
+
ids = find_status_ids(sid) || []
|
16
|
+
ids.each do |id|
|
17
|
+
text = Termtter::API.twitter.show(id).text
|
18
|
+
URI.extract(text, %w[http https]).each_with_index do |uri, i|
|
19
|
+
print "#{i + 1}) #{uri}"
|
20
|
+
if i + 1 == target
|
21
|
+
target_uri = uri
|
22
|
+
print " <-"
|
23
|
+
end
|
24
|
+
puts ""
|
25
|
+
end
|
26
|
+
end
|
27
|
+
if target_uri
|
28
|
+
open_uri target_uri
|
29
|
+
end
|
30
|
+
end
|
31
|
+
},
|
32
|
+
:help => ['open,o', 'Open n-th URI in the message']
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# usage
|
38
|
+
# > open $dq
|
39
|
+
# open 1st URI in $dq
|
40
|
+
# > open $dq 2
|
41
|
+
# open 2nd URI in $dq
|
42
|
+
#
|
43
|
+
# see also
|
44
|
+
# http://twitter.com/takiuchi
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Termtter::Client
|
3
|
+
register_command(
|
4
|
+
:paranoid,
|
5
|
+
:help => ['paranoid message', 'Something like `update`'],
|
6
|
+
:alias => :pd) do |arg|
|
7
|
+
str = arg.gsub(/\w+/, '@\0').gsub(/\#@/, '#')
|
8
|
+
result = Termtter::API.twitter.update(str)
|
9
|
+
puts "paranoid'ed=> " << result.text
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
def self.delete_and_replace(recent, pattern_reg, replace, global)
|
5
|
+
new_text =
|
6
|
+
if global
|
7
|
+
recent.text.gsub(pattern_reg, replace)
|
8
|
+
else
|
9
|
+
recent.text.sub(pattern_reg, replace)
|
10
|
+
end
|
11
|
+
|
12
|
+
param =
|
13
|
+
if recent.in_reply_to_status_id
|
14
|
+
{:in_reply_to_status_id => recent.in_reply_to_status_id}
|
15
|
+
else
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
|
19
|
+
if new_text == recent.text
|
20
|
+
puts "It was not replaced."
|
21
|
+
raise Termtter::CommandCanceled
|
22
|
+
end
|
23
|
+
|
24
|
+
if /^y?$/i !~ Readline.readline("\"replace #{new_text}\" [Y/n] ", false)
|
25
|
+
puts 'canceled.'
|
26
|
+
raise Termtter::CommandCanceled
|
27
|
+
else
|
28
|
+
result = Termtter::API.twitter.remove_status(recent.id)
|
29
|
+
puts "deleted => #{result.text}"
|
30
|
+
result = Termtter::API.twitter.update(new_text, param)
|
31
|
+
puts "updated => #{result.text}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
register_command(:name => :replace,
|
36
|
+
:aliases => [:typo],
|
37
|
+
:help => ['replace,typo /PATTERN/REPLACE/',
|
38
|
+
'Delete and replace most recent tweet.'],
|
39
|
+
:exec_proc => lambda {|arg|
|
40
|
+
recent =
|
41
|
+
Termtter::API.twitter.user_timeline(config.user_name)[0]
|
42
|
+
pattern, replace, mode =
|
43
|
+
/^s?\/(.*?(?:(?!\\).))\/(.*)\/$/.match(arg).to_a.values_at(1, 2, 3)
|
44
|
+
|
45
|
+
if pattern == ""
|
46
|
+
puts "PATTERN is empty."
|
47
|
+
raise Termtter::CommandCanceled
|
48
|
+
end
|
49
|
+
|
50
|
+
delete_and_replace(recent, Regexp.new(pattern, /i/.match(mode)),
|
51
|
+
replace, /g/ =~ mode)
|
52
|
+
}
|
53
|
+
)
|
54
|
+
end
|
data/lib/plugins/saykanji.rb
CHANGED