termtter 0.8.3
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/History.txt +4 -0
- data/README.rdoc +97 -0
- data/Rakefile +46 -0
- data/bin/kill_termtter +22 -0
- data/bin/termtter +7 -0
- data/lib/filter/en2ja.rb +11 -0
- data/lib/filter/english.rb +8 -0
- data/lib/filter/expand-tinyurl.rb +24 -0
- data/lib/filter/fib.rb +15 -0
- data/lib/filter/ignore.rb +19 -0
- data/lib/filter/reply.rb +8 -0
- data/lib/filter/reverse.rb +13 -0
- data/lib/filter/url_addspace.rb +16 -0
- data/lib/filter/yhara.rb +20 -0
- data/lib/plugin/april_fool.rb +15 -0
- data/lib/plugin/bomb.rb +29 -0
- data/lib/plugin/clear.rb +14 -0
- data/lib/plugin/confirm.rb +9 -0
- data/lib/plugin/cool.rb +10 -0
- data/lib/plugin/devel.rb +13 -0
- data/lib/plugin/english.rb +59 -0
- data/lib/plugin/erb.rb +17 -0
- data/lib/plugin/favorite.rb +75 -0
- data/lib/plugin/fib.rb +8 -0
- data/lib/plugin/filter.rb +69 -0
- data/lib/plugin/follow.rb +56 -0
- data/lib/plugin/graduatter.rb +9 -0
- data/lib/plugin/grass.rb +27 -0
- data/lib/plugin/group.rb +60 -0
- data/lib/plugin/growl.rb +62 -0
- data/lib/plugin/hatebu.rb +59 -0
- data/lib/plugin/history.rb +82 -0
- data/lib/plugin/keyword.rb +18 -0
- data/lib/plugin/log.rb +63 -0
- data/lib/plugin/modify_arg_hook_sample.rb +7 -0
- data/lib/plugin/msagent.rb +26 -0
- data/lib/plugin/multi_reply.rb +36 -0
- data/lib/plugin/notify-send.rb +17 -0
- data/lib/plugin/otsune.rb +21 -0
- data/lib/plugin/outputz.rb +35 -0
- data/lib/plugin/pause.rb +3 -0
- data/lib/plugin/plugin.rb +53 -0
- data/lib/plugin/post_exec_hook_sample.rb +9 -0
- data/lib/plugin/pre_exec_hook_sample.rb +9 -0
- data/lib/plugin/primes.rb +23 -0
- data/lib/plugin/quicklook.rb +38 -0
- data/lib/plugin/reblog.rb +40 -0
- data/lib/plugin/reload.rb +3 -0
- data/lib/plugin/say.rb +24 -0
- data/lib/plugin/scrape.rb +41 -0
- data/lib/plugin/screen.rb +24 -0
- data/lib/plugin/shell.rb +14 -0
- data/lib/plugin/sl.rb +48 -0
- data/lib/plugin/spam.rb +9 -0
- data/lib/plugin/standard_plugins.rb +269 -0
- data/lib/plugin/stdout.rb +62 -0
- data/lib/plugin/system_status.rb +33 -0
- data/lib/plugin/translation.rb +28 -0
- data/lib/plugin/update_editor.rb +53 -0
- data/lib/plugin/uri-open.rb +69 -0
- data/lib/plugin/wassr_post.rb +22 -0
- data/lib/plugin/yhara.rb +148 -0
- data/lib/plugin/yonda.rb +20 -0
- data/lib/termtter/api.rb +14 -0
- data/lib/termtter/client.rb +399 -0
- data/lib/termtter/command.rb +77 -0
- data/lib/termtter/connection.rb +39 -0
- data/lib/termtter/hook.rb +18 -0
- data/lib/termtter/status.rb +26 -0
- data/lib/termtter/task.rb +16 -0
- data/lib/termtter/task_manager.rb +116 -0
- data/lib/termtter/twitter.rb +173 -0
- data/lib/termtter/user.rb +13 -0
- data/lib/termtter/version.rb +3 -0
- data/lib/termtter.rb +157 -0
- data/spec/plugin/cool_spec.rb +10 -0
- data/spec/plugin/fib_spec.rb +16 -0
- data/spec/plugin/filter_spec.rb +18 -0
- data/spec/plugin/plugin_spec.rb +25 -0
- data/spec/plugin/shell_spec.rb +10 -0
- data/spec/plugin/spam_spec.rb +17 -0
- data/spec/plugin/standard_plugins_spec.rb +31 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/termtter/client_spec.rb +175 -0
- data/spec/termtter/command_spec.rb +161 -0
- data/spec/termtter/task_manager_spec.rb +78 -0
- data/spec/termtter/task_spec.rb +22 -0
- data/spec/termtter/user_spec.rb +27 -0
- data/spec/termtter_spec.rb +43 -0
- data/test/friends_timeline.json +5 -0
- data/test/search.json +8 -0
- data/test/test_termtter.rb +86 -0
- metadata +177 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
def primes(n)
|
4
|
+
table = []
|
5
|
+
(2 .. n).each do |i|
|
6
|
+
table << i
|
7
|
+
end
|
8
|
+
|
9
|
+
prime = []
|
10
|
+
loop do
|
11
|
+
prime << table[0]
|
12
|
+
table = table.delete_if {|x| x % prime.max == 0 }
|
13
|
+
break if table.max < (prime.max ** 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
r = (table+prime).sort {|a, b| a<=>b }
|
17
|
+
r.join(', ')
|
18
|
+
end
|
19
|
+
|
20
|
+
module Termtter::Client
|
21
|
+
add_command /^primes\s(\d+)/ do|m,t|t.update_status x="primes(#{n=m[1].to_i}) = {#{primes n}}"
|
22
|
+
puts "=> #{x}" end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'pathname'
|
6
|
+
require 'tmpdir'
|
7
|
+
|
8
|
+
configatron.plugins.quicklook.set_default(:quicklook_tmpdir, "#{Dir.tmpdir}/termtter-quicklook-tmpdir")
|
9
|
+
tmpdir = Pathname.new(configatron.plugins.quicklook.quicklook_tmpdir)
|
10
|
+
tmpdir.mkdir unless tmpdir.exist?
|
11
|
+
|
12
|
+
def quicklook(url)
|
13
|
+
tmpdir = Pathname.new(configatron.plugins.quicklook.quicklook_tmpdir)
|
14
|
+
path = tmpdir + Pathname.new(url).basename
|
15
|
+
|
16
|
+
Thread.new do
|
17
|
+
open(path, 'w') do |f|
|
18
|
+
f.write(open(url).read)
|
19
|
+
end
|
20
|
+
system("qlmanage -p #{path} > /dev/null 2>&1")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Termtter::Client
|
25
|
+
add_command %r'^(?:quicklook|ql)\s+(\w+)$' do |m,t|
|
26
|
+
id = m[1]
|
27
|
+
status = t.show(id).first
|
28
|
+
|
29
|
+
if (status)
|
30
|
+
uris = URI.regexp.match(status.text).to_a
|
31
|
+
quicklook(uris.first) unless uris.empty?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# quicklook.rb
|
37
|
+
# TODO:
|
38
|
+
# Close quicklook window automatically.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'tumblr'
|
5
|
+
|
6
|
+
module Termtter::Client
|
7
|
+
register_command(
|
8
|
+
:name => :reblog, :aliases => [],
|
9
|
+
:exec_proc => lambda {|arg|
|
10
|
+
if arg =~ /^reblog\s+(\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
|
+
|
20
|
+
Tumblr::API.write(configatron.plugins.reblog.email, configatron.plugins.reblog.password) do
|
21
|
+
quote("#{status.text}", "<a href=\"http://twitter.com/#{status.user_screen_name}/status/#{status.id}\">Twitter / #{status.user_name}</a>")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
},
|
25
|
+
:completion_proc => lambda {|cmd, args|
|
26
|
+
if args =~ /^(\d*)$/
|
27
|
+
find_status_id_candidates $1, "#{cmd} %s"
|
28
|
+
end
|
29
|
+
},
|
30
|
+
:help => ['reblog ID', 'Tumblr Reblog a status']
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
# reblog.rb
|
35
|
+
# tumblr reblog it!
|
36
|
+
#
|
37
|
+
# configatron.plugins.reblog.email = 'your-email-on-tumblr'
|
38
|
+
# configatron.plugins.reblog.password = 'your-password-on-tumblr'
|
39
|
+
#
|
40
|
+
# reblog 1114860346
|
data/lib/plugin/say.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
raise 'say.rb runs only in OSX Leopard' if /darwin9/ !~ RUBY_PLATFORM
|
4
|
+
|
5
|
+
# say :: String -> String -> IO ()
|
6
|
+
def say(who, what)
|
7
|
+
voices = %w(Alex Alex Bruce Fred Ralph Agnes Kathy Vicki)
|
8
|
+
voice = voices[who.hash % voices.size]
|
9
|
+
system 'say', '-v', voice, what
|
10
|
+
end
|
11
|
+
|
12
|
+
module Termtter::Client
|
13
|
+
add_hook do |statuses, event, t|
|
14
|
+
if !statuses.empty? && event == :update_friends_timeline
|
15
|
+
statuses.reverse.each do |s|
|
16
|
+
text_without_uri = s.text.gsub(%r|https?://[^\s]+|, 'U.R.I.')
|
17
|
+
say s.user_screen_name, text_without_uri
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# KNOWN BUG:
|
24
|
+
# * exit or <C-c> doen't work quickly.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
|
5
|
+
def self.scrape_members(members)
|
6
|
+
statuses = []
|
7
|
+
members.each_with_index do |member, index|
|
8
|
+
puts "member #{index+1}/#{members.size} #{member}"
|
9
|
+
statuses += Termtter::API.twitter.get_user_timeline(member)
|
10
|
+
end
|
11
|
+
statuses
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.scrape_group(group)
|
15
|
+
members = configatron.plugins.group.groups[group] || []
|
16
|
+
scrape_members(members)
|
17
|
+
end
|
18
|
+
|
19
|
+
register_command(
|
20
|
+
:name => :scrape_group,
|
21
|
+
:exec_proc => lambda{ |args|
|
22
|
+
groups = args.split(' ').map{|g| g.to_sym}
|
23
|
+
if groups.include? :all
|
24
|
+
groups = configatron.plugins.group.groups.keys
|
25
|
+
puts "get all groups..."
|
26
|
+
end
|
27
|
+
members = []
|
28
|
+
groups.each do |group|
|
29
|
+
members += configatron.plugins.group.groups[group]
|
30
|
+
end
|
31
|
+
statuses = scrape_members(members.uniq.compact.sort)
|
32
|
+
call_hooks(statuses, :pre_filter)
|
33
|
+
},
|
34
|
+
:completion_proc => lambda {|cmd, args|
|
35
|
+
arg = args.split(' ').last
|
36
|
+
prefix = args.split(' ')[0..-2].join(' ')
|
37
|
+
find_group_candidates arg, "#{cmd} #{prefix} %s"
|
38
|
+
},
|
39
|
+
:help => ['scrape_group GROUPNAME(S)', 'Get the group timeline']
|
40
|
+
)
|
41
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter
|
4
|
+
module Plugin
|
5
|
+
module Screen
|
6
|
+
def self.set_title(title)
|
7
|
+
print "\033k#{title}\033\\"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add below to your ~/.termtter
|
14
|
+
#
|
15
|
+
# require 'plugin/yonda'
|
16
|
+
# require 'plugin/screen'
|
17
|
+
# module Termtter::Client
|
18
|
+
# add_hook do |statuses, event|
|
19
|
+
# case event
|
20
|
+
# when :update_friends_timeline, :plugin_yonda_yonda
|
21
|
+
# Termtter::Plugin::Screen::set_title("termtter(#{public_storage[:unread_count]})")
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
data/lib/plugin/shell.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command :name => :shell, :aliases => [:sh],
|
5
|
+
:help => ['shell,sh', 'Start your shell'],
|
6
|
+
:exec_proc => lambda {|args|
|
7
|
+
begin
|
8
|
+
pause
|
9
|
+
system ENV['SHELL'] || ENV['COMSPEC']
|
10
|
+
ensure
|
11
|
+
resume
|
12
|
+
end
|
13
|
+
}
|
14
|
+
end
|
data/lib/plugin/sl.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter
|
4
|
+
|
5
|
+
module Client
|
6
|
+
|
7
|
+
public_storage[:current] = ''
|
8
|
+
public_storage[:orig_prompt] = configatron.prompt
|
9
|
+
configatron.prompt = "~/ #{public_storage[:orig_prompt]}"
|
10
|
+
|
11
|
+
register_command(
|
12
|
+
:name => :sl, :aliases => [],
|
13
|
+
:exec_proc => lambda {|arg| system("sl") },
|
14
|
+
:help => ['sl', 'The train pass in front of your screen']
|
15
|
+
)
|
16
|
+
|
17
|
+
register_command(
|
18
|
+
:name => :pwd, :aliases => [],
|
19
|
+
:exec_proc => lambda {|arg| public_storage[:current] },
|
20
|
+
:help => ['pwd', 'Show current direcroty']
|
21
|
+
)
|
22
|
+
|
23
|
+
register_command(
|
24
|
+
:name => :ls, :aliases => [],
|
25
|
+
:exec_proc => lambda {|arg|
|
26
|
+
call_commands("list #{arg.empty? ? public_storage[:current] : arg}", API.twitter)
|
27
|
+
},
|
28
|
+
:completion_proc => lambda {|cmd, args|
|
29
|
+
find_user_candidates args, "#{cmd} %s"
|
30
|
+
},
|
31
|
+
:help => ['ls', 'Show list in current directory']
|
32
|
+
)
|
33
|
+
|
34
|
+
register_command(
|
35
|
+
:name => :cd, :aliases => [],
|
36
|
+
:exec_proc => lambda {|arg|
|
37
|
+
public_storage[:current] =
|
38
|
+
(arg.nil? || /\~/ =~ arg) ? '' : arg
|
39
|
+
configatron.prompt = "~/#{public_storage[:current]} #{public_storage[:orig_prompt]}"
|
40
|
+
},
|
41
|
+
:completion_proc => lambda {|cmd, args|
|
42
|
+
find_user_candidates args, "#{cmd} %s"
|
43
|
+
},
|
44
|
+
:help => ['cd USER', 'Change current directory']
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/plugin/spam.rb
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Termtter::Client
|
6
|
+
|
7
|
+
# standard commands
|
8
|
+
|
9
|
+
register_command(
|
10
|
+
:name => :update, :aliases => [:u],
|
11
|
+
:exec_proc => lambda {|arg|
|
12
|
+
text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
|
13
|
+
Termtter::API.twitter.update_status(text)
|
14
|
+
puts "=> #{text}"
|
15
|
+
},
|
16
|
+
:completion_proc => lambda {|cmd, args|
|
17
|
+
if /(.*)@([^\s]*)$/ =~ args
|
18
|
+
find_user_candidates $2, "#{cmd} #{$1}@%s"
|
19
|
+
end
|
20
|
+
}
|
21
|
+
)
|
22
|
+
|
23
|
+
register_command(
|
24
|
+
:name => :direct, :aliases => [:d],
|
25
|
+
:exec_proc => lambda {|arg|
|
26
|
+
if arg =~ /^([^\s]+)\s+(.*)\s*$/
|
27
|
+
user, text = $1, $2
|
28
|
+
Termtter::API.twitter.direct_message(user, text)
|
29
|
+
puts "=> to:#{user} message:#{text}"
|
30
|
+
end
|
31
|
+
},
|
32
|
+
:completion_proc => lambda {|cmd, args|
|
33
|
+
if args =~ /^([^\s]+)$/
|
34
|
+
find_user_candidates $1, "#{cmd} %s"
|
35
|
+
end
|
36
|
+
}
|
37
|
+
)
|
38
|
+
|
39
|
+
register_command(
|
40
|
+
:name => :profile, :aliases => [:p],
|
41
|
+
:exec_proc => lambda {|arg|
|
42
|
+
user = Termtter::API.twitter.get_user_profile(arg)
|
43
|
+
attrs = %w[ name screen_name url description profile_image_url location protected following
|
44
|
+
friends_count followers_count statuses_count favourites_count
|
45
|
+
id time_zone created_at utc_offset notifications
|
46
|
+
]
|
47
|
+
label_width = attrs.map{|i|i.size}.max
|
48
|
+
attrs.each do |attr|
|
49
|
+
value = user.__send__(attr.to_sym)
|
50
|
+
puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
|
51
|
+
end
|
52
|
+
},
|
53
|
+
:completion_proc => lambda {|cmd, arg|
|
54
|
+
find_user_candidates arg, "#{cmd} %s"
|
55
|
+
}
|
56
|
+
)
|
57
|
+
|
58
|
+
register_command(
|
59
|
+
:name => :followers,
|
60
|
+
:exec_proc => lambda {|arg|
|
61
|
+
followers = Termtter::API.twitter.followers
|
62
|
+
Termtter::Client.public_storage[:followers] = followers
|
63
|
+
p followers.map{|f|f.screen_name}
|
64
|
+
}
|
65
|
+
)
|
66
|
+
|
67
|
+
register_command(
|
68
|
+
:name => :list, :aliases => [:l],
|
69
|
+
:exec_proc => lambda {|arg|
|
70
|
+
unless arg.empty?
|
71
|
+
call_hooks(Termtter::API.twitter.get_user_timeline(arg), :list_user_timeline)
|
72
|
+
else
|
73
|
+
call_hooks(Termtter::API.twitter.get_friends_timeline(), :list_friends_timeline)
|
74
|
+
end
|
75
|
+
},
|
76
|
+
:completion_proc => lambda {|cmd, arg|
|
77
|
+
find_user_candidates arg, "#{cmd} %s"
|
78
|
+
}
|
79
|
+
)
|
80
|
+
|
81
|
+
register_command(
|
82
|
+
:name => :search, :aliases => [:s],
|
83
|
+
:exec_proc => lambda {|arg|
|
84
|
+
call_hooks(Termtter::API.twitter.search(arg), :search)
|
85
|
+
}
|
86
|
+
)
|
87
|
+
|
88
|
+
register_command(
|
89
|
+
:name => :replies, :aliases => [:r],
|
90
|
+
:exec_proc => lambda {|arg|
|
91
|
+
call_hooks(Termtter::API.twitter.replies(), :replies)
|
92
|
+
}
|
93
|
+
)
|
94
|
+
|
95
|
+
register_command(
|
96
|
+
:name => :show,
|
97
|
+
:exec_proc => lambda {|arg|
|
98
|
+
id = arg.gsub(/.*:/, '')
|
99
|
+
call_hooks(Termtter::API.twitter.show(id), :show)
|
100
|
+
}
|
101
|
+
)
|
102
|
+
|
103
|
+
register_command(
|
104
|
+
:name => :shows,
|
105
|
+
:exec_proc => lambda {|arg|
|
106
|
+
id = arg.gsub(/.*:/, '')
|
107
|
+
call_hooks(Termtter::API.twitter.show(id, true), :show)
|
108
|
+
}
|
109
|
+
)
|
110
|
+
|
111
|
+
# TODO: Change colors when remaining_hits is low.
|
112
|
+
# TODO: Simmulate remaining_hits.
|
113
|
+
register_command(
|
114
|
+
:name => :limit, :aliases => [:lm],
|
115
|
+
:exec_proc => lambda {|arg|
|
116
|
+
limit = Termtter::API.twitter.get_rate_limit_status
|
117
|
+
remaining_time = "%dmin %dsec" % (limit.reset_time - Time.now).divmod(60)
|
118
|
+
remaining_color =
|
119
|
+
case limit.remaining_hits / limit.hourly_limit.to_f
|
120
|
+
when 0.2..0.4 then :yellow
|
121
|
+
when 0..0.2 then :red
|
122
|
+
else :green
|
123
|
+
end
|
124
|
+
puts "=> #{color(limit.remaining_hits, remaining_color)}/#{limit.hourly_limit} until #{limit.reset_time} (#{remaining_time} remaining)"
|
125
|
+
},
|
126
|
+
:help => ["limit,lm", "Show the API limit status"]
|
127
|
+
)
|
128
|
+
|
129
|
+
register_command(
|
130
|
+
:name => :pause,
|
131
|
+
:exec_proc => lambda {|arg| pause},
|
132
|
+
:help => ["pause", "Pause updating"]
|
133
|
+
)
|
134
|
+
|
135
|
+
register_command(
|
136
|
+
:name => :resume,
|
137
|
+
:exec_proc => lambda {|arg| resume},
|
138
|
+
:help => ["resume", "Resume updating"]
|
139
|
+
)
|
140
|
+
|
141
|
+
register_command(
|
142
|
+
:name => :exit, :aliases => [:e],
|
143
|
+
:exec_proc => lambda {|arg| exit},
|
144
|
+
:help => ['exit,e', 'Exit']
|
145
|
+
)
|
146
|
+
|
147
|
+
register_hook(
|
148
|
+
:name => :default_error_handler,
|
149
|
+
:points => [:on_error],
|
150
|
+
:exec_proc => lambda {|e|
|
151
|
+
puts "Error: #{e}"
|
152
|
+
if configatron.devel == true
|
153
|
+
puts e.backtrace.join("\n")
|
154
|
+
end
|
155
|
+
}
|
156
|
+
)
|
157
|
+
|
158
|
+
register_command(
|
159
|
+
:name => :help, :aliases => [:h],
|
160
|
+
:exec_proc => lambda {|arg|
|
161
|
+
helps = [
|
162
|
+
["help,h", "Print this help message"],
|
163
|
+
["list,l", "List the posts in your friends timeline"],
|
164
|
+
["list,l USERNAME", "List the posts in the the given user's timeline"],
|
165
|
+
["update,u TEXT", "Post a new message"],
|
166
|
+
["direct,d @USERNAME TEXT", "Send direct message"],
|
167
|
+
["profile,p USERNAME", "Show user's profile"],
|
168
|
+
["replies,r", "List the most recent @replies for the authenticating user"],
|
169
|
+
["search,s TEXT", "Search for Twitter"],
|
170
|
+
["show ID", "Show a single status"]
|
171
|
+
]
|
172
|
+
helps += @@helps
|
173
|
+
helps += @@new_commands.map {|name, command| command.help}
|
174
|
+
helps.compact!
|
175
|
+
puts formatted_help(helps)
|
176
|
+
}
|
177
|
+
)
|
178
|
+
|
179
|
+
register_command(
|
180
|
+
:name => :execute,
|
181
|
+
:exec_proc => lambda{|arg|
|
182
|
+
if arg
|
183
|
+
`#{arg}`.each_line do |line|
|
184
|
+
unless line.strip.empty?
|
185
|
+
Termtter::API.twitter.update_status(line)
|
186
|
+
puts "=> #{line}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
},
|
191
|
+
:help => ['execute COMMAND', 'execute the command']
|
192
|
+
)
|
193
|
+
|
194
|
+
add_command /^!(!)?\s*(.*)$/ do |m, t|
|
195
|
+
warn '!COMMAND command will be removed. Use command execute instead.'
|
196
|
+
begin
|
197
|
+
result = `#{m[2]}` unless m[2].empty?
|
198
|
+
unless m[1].nil? || result.empty?
|
199
|
+
t.update_status(result.gsub("\n", " "))
|
200
|
+
end
|
201
|
+
puts "=> #{result}"
|
202
|
+
rescue => e
|
203
|
+
puts e
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.formatted_help(helps)
|
208
|
+
helps = helps.sort_by{|help| help[0]}
|
209
|
+
width = helps.map {|n, d| n.size }.max
|
210
|
+
space = 3
|
211
|
+
helps.map {|name, desc|
|
212
|
+
name.to_s.ljust(width + space) + desc.to_s
|
213
|
+
}.join("\n")
|
214
|
+
end
|
215
|
+
|
216
|
+
# completion for standard commands
|
217
|
+
|
218
|
+
require 'set'
|
219
|
+
public_storage[:users] ||= Set.new
|
220
|
+
public_storage[:status_ids] ||= Set.new
|
221
|
+
|
222
|
+
add_hook do |statuses, event, t|
|
223
|
+
statuses.each do |s|
|
224
|
+
public_storage[:users].add(s.user_screen_name)
|
225
|
+
public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
|
226
|
+
public_storage[:status_ids].add(s.id.to_s)
|
227
|
+
public_storage[:status_ids].add(s.in_reply_to_status_id.to_s) if s.in_reply_to_status_id
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def self.find_status_id_candidates(a, b, u = nil)
|
232
|
+
candidates = public_storage[:status_ids].to_a
|
233
|
+
if u && c = public_storage[:log].select {|s| s.user_screen_name == u }.map {|s| s.id.to_s }
|
234
|
+
candidates = c unless c.empty?
|
235
|
+
end
|
236
|
+
if a.empty?
|
237
|
+
candidates
|
238
|
+
else
|
239
|
+
candidates.grep(/#{Regexp.quote a}/)
|
240
|
+
end.
|
241
|
+
map {|u| b % u }
|
242
|
+
end
|
243
|
+
|
244
|
+
def self.find_user_candidates(a, b)
|
245
|
+
if a.nil? || a.empty?
|
246
|
+
public_storage[:users].to_a
|
247
|
+
else
|
248
|
+
public_storage[:users].grep(/^#{Regexp.quote a}/i)
|
249
|
+
end.
|
250
|
+
map {|u| b % u }
|
251
|
+
end
|
252
|
+
|
253
|
+
add_completion do |input|
|
254
|
+
standard_commands = %w[exit help list pause profile update direct resume replies search show limit]
|
255
|
+
case input
|
256
|
+
when /^show(s)?\s+(([\w\d]+):)?\s*(.*)/
|
257
|
+
if $2
|
258
|
+
find_status_id_candidates $4, "show#{$1} #{$2}%s", $3
|
259
|
+
else
|
260
|
+
result = find_user_candidates $4, "show#{$1} %s:"
|
261
|
+
result = find_status_id_candidates $4, "show#{$1} %s" if result.empty?
|
262
|
+
result
|
263
|
+
end
|
264
|
+
else
|
265
|
+
standard_commands.grep(/^#{Regexp.quote input}/)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'highline'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
configatron.plugins.stdout.set_default(
|
7
|
+
:colors,
|
8
|
+
[:none, :red, :green, :yellow, :blue, :magenta, :cyan])
|
9
|
+
configatron.plugins.stdout.set_default(
|
10
|
+
:timeline_format,
|
11
|
+
'<%= color(time, 90) %> <%= color(status, status_color) %> <%= color(id, 90) %>')
|
12
|
+
|
13
|
+
$highline = HighLine.new
|
14
|
+
|
15
|
+
def color(str, value)
|
16
|
+
return str if value == :none
|
17
|
+
case value
|
18
|
+
when String, Symbol
|
19
|
+
$highline.color(str, value)
|
20
|
+
else
|
21
|
+
"\e[#{value}m#{str}\e[0m"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Termtter::Client
|
26
|
+
|
27
|
+
def self.print_statuses(statuses, sort = true, time_format = '%H:%M:%S')
|
28
|
+
(sort ? statuses.sort_by{ |s| s.id} : statuses).each do |s|
|
29
|
+
text = s.text
|
30
|
+
status_color = configatron.plugins.stdout.colors[s.user_screen_name.hash % configatron.plugins.stdout.colors.size]
|
31
|
+
status = "#{s.user_screen_name}: #{text}"
|
32
|
+
if s.in_reply_to_status_id
|
33
|
+
status += " (reply to #{s.in_reply_to_status_id})"
|
34
|
+
end
|
35
|
+
|
36
|
+
time = "(#{s.created_at.strftime(time_format)})"
|
37
|
+
id = s.id
|
38
|
+
puts ERB.new(configatron.plugins.stdout.timeline_format).result(binding)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.print_statuses_with_date(statuses, sort = true)
|
43
|
+
print_statuses(statuses, sort, '%m-%d %H:%M')
|
44
|
+
end
|
45
|
+
|
46
|
+
add_hook do |statuses, event|
|
47
|
+
next if statuses.empty?
|
48
|
+
|
49
|
+
case event
|
50
|
+
when :update_friends_timeline, :list_friends_timeline
|
51
|
+
print_statuses(statuses)
|
52
|
+
when :search, :list_user_timeline, :show, :replies
|
53
|
+
print_statuses_with_date(statuses)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
# stdout.rb
|
59
|
+
# output statuses to stdout
|
60
|
+
# example config
|
61
|
+
# configatron.plugins.stdout.colors = [:none, :red, :green, :yellow, :blue, :magenta, :cyan]
|
62
|
+
# configatron.plugins.stdout.timeline_format = '<%= color(time, 90) %> <%= color(status, status_color) %> <%= color(id, 90) %>'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
configatron.plugins.system_status.set_default(:default_status_proc, lambda { Time.now.strftime("%x %X") })
|
6
|
+
configatron.plugins.system_status.set_default(:interval, 1)
|
7
|
+
configatron.plugins.system_status.set_default(:default_color, :on_blue)
|
8
|
+
configatron.plugins.system_status.set_default(:format, '<%= status %>')
|
9
|
+
|
10
|
+
def out_put_status(status, color)
|
11
|
+
formatted_status = ERB.new(configatron.plugins.system_status.format).result(binding)
|
12
|
+
colored_status = color(formatted_status, color)
|
13
|
+
print "\e[s\e[1000G\e[#{status.size - 1}D#{colored_status}\e[u"
|
14
|
+
$stdout.flush
|
15
|
+
end
|
16
|
+
|
17
|
+
module Termtter::Client
|
18
|
+
add_task(:name => :system_status, :interval => configatron.plugins.system_status.interval) do
|
19
|
+
status = (@@task_manager.get_task(:update_timeline).exec_at - Time.now).to_i.to_s
|
20
|
+
color = public_storage[:system_status_color] ||
|
21
|
+
configatron.plugins.system_status.default_color
|
22
|
+
out_put_status(status, color)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# system_status.rb
|
27
|
+
# show system status on left side.
|
28
|
+
# output public_storage[:system_status] or Time.now.strftime("%x %X") if nil
|
29
|
+
# example config
|
30
|
+
# configatron.plugins.system_status.default_status_proc = lambda { Time.now.strftime("%x %X") }
|
31
|
+
# configatron.plugins.system_status.interval = 1
|
32
|
+
# configatron.plugins.system_status.default_color = :on_blue
|
33
|
+
# configatron.plugins.system_status.format = '<%= status %>'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'net/http'
|
5
|
+
require 'kconv'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
def translate(text, langpair)
|
9
|
+
req = Net::HTTP::Post.new('/translate_t')
|
10
|
+
req.add_field('Content-Type', 'application/x-www-form-urlencoded')
|
11
|
+
req.add_field('User-Agent', 'Mozilla/5.0')
|
12
|
+
Net::HTTP.version_1_2 # Proxy に対応してない
|
13
|
+
Net::HTTP.start('translate.google.co.jp', 80) {|http|
|
14
|
+
response = http.request(req, "langpair=#{langpair}&text=#{URI.escape(text)}")
|
15
|
+
doc = Nokogiri::HTML.parse(response.body, nil, 'utf-8')
|
16
|
+
return doc.css('#result_box').text
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
Termtter::Client.add_command /^(en2ja|ja2en)\s+(.*)$/ do |m, t|
|
21
|
+
langpair = m[1].gsub('2', '|')
|
22
|
+
puts "translating..."
|
23
|
+
puts "=> #{translate(m[2], langpair)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# This plugin does not work yet.
|
27
|
+
# requirements
|
28
|
+
# nokogiri (sudo gem install nokogiri)
|