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.
Files changed (93) hide show
  1. data/History.txt +4 -0
  2. data/README.rdoc +97 -0
  3. data/Rakefile +46 -0
  4. data/bin/kill_termtter +22 -0
  5. data/bin/termtter +7 -0
  6. data/lib/filter/en2ja.rb +11 -0
  7. data/lib/filter/english.rb +8 -0
  8. data/lib/filter/expand-tinyurl.rb +24 -0
  9. data/lib/filter/fib.rb +15 -0
  10. data/lib/filter/ignore.rb +19 -0
  11. data/lib/filter/reply.rb +8 -0
  12. data/lib/filter/reverse.rb +13 -0
  13. data/lib/filter/url_addspace.rb +16 -0
  14. data/lib/filter/yhara.rb +20 -0
  15. data/lib/plugin/april_fool.rb +15 -0
  16. data/lib/plugin/bomb.rb +29 -0
  17. data/lib/plugin/clear.rb +14 -0
  18. data/lib/plugin/confirm.rb +9 -0
  19. data/lib/plugin/cool.rb +10 -0
  20. data/lib/plugin/devel.rb +13 -0
  21. data/lib/plugin/english.rb +59 -0
  22. data/lib/plugin/erb.rb +17 -0
  23. data/lib/plugin/favorite.rb +75 -0
  24. data/lib/plugin/fib.rb +8 -0
  25. data/lib/plugin/filter.rb +69 -0
  26. data/lib/plugin/follow.rb +56 -0
  27. data/lib/plugin/graduatter.rb +9 -0
  28. data/lib/plugin/grass.rb +27 -0
  29. data/lib/plugin/group.rb +60 -0
  30. data/lib/plugin/growl.rb +62 -0
  31. data/lib/plugin/hatebu.rb +59 -0
  32. data/lib/plugin/history.rb +82 -0
  33. data/lib/plugin/keyword.rb +18 -0
  34. data/lib/plugin/log.rb +63 -0
  35. data/lib/plugin/modify_arg_hook_sample.rb +7 -0
  36. data/lib/plugin/msagent.rb +26 -0
  37. data/lib/plugin/multi_reply.rb +36 -0
  38. data/lib/plugin/notify-send.rb +17 -0
  39. data/lib/plugin/otsune.rb +21 -0
  40. data/lib/plugin/outputz.rb +35 -0
  41. data/lib/plugin/pause.rb +3 -0
  42. data/lib/plugin/plugin.rb +53 -0
  43. data/lib/plugin/post_exec_hook_sample.rb +9 -0
  44. data/lib/plugin/pre_exec_hook_sample.rb +9 -0
  45. data/lib/plugin/primes.rb +23 -0
  46. data/lib/plugin/quicklook.rb +38 -0
  47. data/lib/plugin/reblog.rb +40 -0
  48. data/lib/plugin/reload.rb +3 -0
  49. data/lib/plugin/say.rb +24 -0
  50. data/lib/plugin/scrape.rb +41 -0
  51. data/lib/plugin/screen.rb +24 -0
  52. data/lib/plugin/shell.rb +14 -0
  53. data/lib/plugin/sl.rb +48 -0
  54. data/lib/plugin/spam.rb +9 -0
  55. data/lib/plugin/standard_plugins.rb +269 -0
  56. data/lib/plugin/stdout.rb +62 -0
  57. data/lib/plugin/system_status.rb +33 -0
  58. data/lib/plugin/translation.rb +28 -0
  59. data/lib/plugin/update_editor.rb +53 -0
  60. data/lib/plugin/uri-open.rb +69 -0
  61. data/lib/plugin/wassr_post.rb +22 -0
  62. data/lib/plugin/yhara.rb +148 -0
  63. data/lib/plugin/yonda.rb +20 -0
  64. data/lib/termtter/api.rb +14 -0
  65. data/lib/termtter/client.rb +399 -0
  66. data/lib/termtter/command.rb +77 -0
  67. data/lib/termtter/connection.rb +39 -0
  68. data/lib/termtter/hook.rb +18 -0
  69. data/lib/termtter/status.rb +26 -0
  70. data/lib/termtter/task.rb +16 -0
  71. data/lib/termtter/task_manager.rb +116 -0
  72. data/lib/termtter/twitter.rb +173 -0
  73. data/lib/termtter/user.rb +13 -0
  74. data/lib/termtter/version.rb +3 -0
  75. data/lib/termtter.rb +157 -0
  76. data/spec/plugin/cool_spec.rb +10 -0
  77. data/spec/plugin/fib_spec.rb +16 -0
  78. data/spec/plugin/filter_spec.rb +18 -0
  79. data/spec/plugin/plugin_spec.rb +25 -0
  80. data/spec/plugin/shell_spec.rb +10 -0
  81. data/spec/plugin/spam_spec.rb +17 -0
  82. data/spec/plugin/standard_plugins_spec.rb +31 -0
  83. data/spec/spec_helper.rb +4 -0
  84. data/spec/termtter/client_spec.rb +175 -0
  85. data/spec/termtter/command_spec.rb +161 -0
  86. data/spec/termtter/task_manager_spec.rb +78 -0
  87. data/spec/termtter/task_spec.rb +22 -0
  88. data/spec/termtter/user_spec.rb +27 -0
  89. data/spec/termtter_spec.rb +43 -0
  90. data/test/friends_timeline.json +5 -0
  91. data/test/search.json +8 -0
  92. data/test/test_termtter.rb +86 -0
  93. 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
@@ -0,0 +1,3 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.register_macro :reload, "eval exec $0"
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
@@ -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
+
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Twitter.new(configatron.user_name, configatron.password).update_status('*super spam time*')
4
+ module Termtter::Client
5
+ clear_commands
6
+ add_command /.+/ do |m, t|
7
+ Thread.new { t.update_status(m[0]) }
8
+ end
9
+ end
@@ -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)