termtter 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/ChangeLog +115 -0
  2. data/README.rdoc +25 -10
  3. data/Rakefile +53 -34
  4. data/lib/plugins/cool.rb +2 -5
  5. data/lib/plugins/curry.rb +43 -0
  6. data/lib/plugins/db.rb +91 -0
  7. data/lib/plugins/{auto_reload.rb → defaults/auto_reload.rb} +0 -0
  8. data/lib/plugins/defaults/command_line.rb +111 -0
  9. data/lib/plugins/{exec.rb → defaults/exec.rb} +2 -7
  10. data/lib/plugins/{fib.rb → defaults/fib.rb} +1 -4
  11. data/lib/plugins/defaults/retweet.rb +34 -0
  12. data/lib/plugins/{standard_commands.rb → defaults/standard_commands.rb} +60 -136
  13. data/lib/plugins/defaults/standard_completion.rb +67 -0
  14. data/lib/plugins/{stdout.rb → defaults/stdout.rb} +30 -19
  15. data/lib/plugins/defaults.rb +14 -0
  16. data/lib/plugins/en2ja.rb +11 -5
  17. data/lib/plugins/english.rb +2 -2
  18. data/lib/plugins/expand-tinyurl.rb +27 -6
  19. data/lib/plugins/github-issues.rb +192 -0
  20. data/lib/plugins/group.rb +30 -4
  21. data/lib/plugins/growl.rb +10 -1
  22. data/lib/plugins/http_server/favicon.ico +0 -0
  23. data/lib/plugins/http_server/index.html +117 -0
  24. data/lib/plugins/http_server.rb +82 -0
  25. data/lib/plugins/irb.rb +6 -0
  26. data/lib/plugins/l2.rb +1 -1
  27. data/lib/plugins/list_with_opts.rb +0 -3
  28. data/lib/plugins/log.rb +6 -9
  29. data/lib/plugins/modify_arg_hook_sample.rb +3 -5
  30. data/lib/plugins/multi_reply.rb +0 -5
  31. data/lib/plugins/notify-send.rb +1 -1
  32. data/lib/plugins/notify-send2.rb +1 -1
  33. data/lib/plugins/notify-send3.rb +11 -3
  34. data/lib/plugins/open_url.rb +0 -8
  35. data/lib/plugins/otsune.rb +3 -9
  36. data/lib/plugins/outputz.rb +1 -1
  37. data/lib/plugins/pool.rb +30 -0
  38. data/lib/plugins/quicklook.rb +1 -1
  39. data/lib/plugins/saykanji.rb +81 -0
  40. data/lib/plugins/shell.rb +1 -6
  41. data/lib/plugins/sl.rb +8 -8
  42. data/lib/plugins/tinyurl.rb +26 -7
  43. data/lib/plugins/trends.rb +84 -0
  44. data/lib/plugins/twitpic.rb +46 -0
  45. data/lib/plugins/uri-open.rb +1 -1
  46. data/lib/plugins/wassr.rb +0 -3
  47. data/lib/plugins/whois.rb +45 -0
  48. data/lib/plugins/yhara.rb +2 -6
  49. data/lib/termtter/client.rb +73 -100
  50. data/lib/termtter/config.rb +4 -6
  51. data/lib/termtter/config_setup.rb +1 -1
  52. data/lib/termtter/hook.rb +2 -2
  53. data/lib/termtter/optparse.rb +14 -1
  54. data/lib/termtter/system_extensions.rb +3 -2
  55. data/lib/termtter/task_manager.rb +1 -5
  56. data/lib/termtter/version.rb +1 -1
  57. data/spec/plugins/cool_spec.rb +1 -1
  58. data/spec/plugins/curry_spec.rb +13 -0
  59. data/spec/plugins/db_spec.rb +62 -0
  60. data/spec/plugins/english_spec.rb +2 -2
  61. data/spec/plugins/fib_spec.rb +2 -2
  62. data/spec/plugins/filter_spec.rb +2 -2
  63. data/spec/plugins/pause_spec.rb +1 -1
  64. data/spec/plugins/primes_spec.rb +2 -2
  65. data/spec/plugins/shell_spec.rb +1 -1
  66. data/spec/plugins/sl_spec.rb +1 -1
  67. data/spec/plugins/{standard_plugins_spec.rb → standard_commands_spec.rb} +2 -2
  68. data/spec/plugins/whois_spec.rb +20 -0
  69. data/spec/termtter/client_spec.rb +114 -37
  70. data/spec/termtter/config_spec.rb +10 -0
  71. data/spec/termtter/optparse_spec.rb +16 -0
  72. data/spec/termtter_spec.rb +7 -8
  73. metadata +39 -19
  74. data/History.txt +0 -4
  75. data/lib/plugins/direct_messages.rb +0 -36
  76. data/lib/plugins/retweet.rb +0 -46
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'drb/drb'
4
+ require 'rinda/tuplespace'
5
+
6
+ config.plugins.pool.set_default(:port, '12354')
7
+
8
+ pool = Rinda::TupleSpace.new
9
+ DRb.start_service("druby://:#{config.plugins.pool.port}", pool)
10
+
11
+ Thread.new do
12
+ loop do
13
+ statement = pool.take([:statement, nil])
14
+ print 'pool: '
15
+ Termtter::Client.call_commands("update #{statement[1]}")
16
+ STDOUT.flush
17
+ end
18
+ end
19
+
20
+ # pool plugin allow remote update
21
+ # e.g)
22
+ #
23
+ # require 'drb/drb'
24
+ #
25
+ # DRb.start_service
26
+ # pool = DRbObject.new_with_uri('http://localhost:12354')
27
+ # pool.write(['statement', 'hey!'])
28
+ #
29
+ # run above code and you show 'pool: updated => hey
30
+ #
@@ -36,6 +36,6 @@ end
36
36
 
37
37
  # quicklook.rb
38
38
  # REQUIREMENTS:
39
- # plugin 'expand-tinyurl'
39
+ # t.plug 'expand-tinyurl'
40
40
  # TODO:
41
41
  # Close quicklook window automatically.
@@ -0,0 +1,81 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ## Need install "SayKana" & "MeCab (UTF-8)"
4
+ ## SayKana
5
+ ## http://www.a-quest.com/aquestalk/saykana/
6
+ ## MeCab
7
+ ## http://mecab.sourceforge.net/
8
+
9
+ require 'uri'
10
+
11
+ config.plugins.saykanji.set_default(:user_to_say, [])
12
+ config.plugins.saykanji.set_default(:keyword_to_say, [])
13
+ config.plugins.saykanji.set_default(:say_speed, 100)
14
+ config.plugins.saykanji.set_default(:kana_english_dict_path, "#{Termtter::CONF_DIR}/tmp/kana_english_dict.csv")
15
+
16
+ if config.plugins.saykanji.user_to_say.empty? &&
17
+ config.plugins.saykanji.keyword_to_say.empty?
18
+ config.plugins.saykanji.keyword_to_say = /./
19
+ end
20
+
21
+ def saykanji(text, say_speed)
22
+ text_without_uri = text.gsub(URI.regexp(['http', 'https']), 'URI').
23
+ gsub('~', '〜').gsub(/[-―]/, 'ー').gsub('&', 'アンド').
24
+ delete("\n\`\'\"<>[]()|:;#")
25
+ text_wakati = `echo #{text_without_uri}|mecab -O wakati`.split(' ')
26
+ text_wakati.map!{ |i|
27
+ if /[@a-zA-Z]/ =~ i && File.file?(config.plugins.saykanji.kana_english_dict_path)
28
+ kana_english = `grep -i "\\"#{i}\\"" #{config.plugins.saykanji.kana_english_dict_path}`
29
+ unless kana_english.empty?
30
+ /^"(.+?)"/.match(kana_english).to_a[1]
31
+ else
32
+ i
33
+ end
34
+ elsif i == 'は'
35
+ 'ワ'
36
+ elsif i == 'へ'
37
+ 'エ'
38
+ else
39
+ i
40
+ end
41
+ }
42
+ text_to_say = `echo #{text_wakati.join}|mecab -O yomi`
43
+ system "SayKana", "-s", "#{say_speed}", "#{text_to_say}"
44
+ end
45
+
46
+ def say(who, text)
47
+ text_to_say = text.gsub(URI.regexp(['http', 'https']), 'U.R.I.')
48
+ voices = %w(Alex Alex Bruce Fred Ralph Agnes Kathy Vicki)
49
+ voice = voices[who.hash % voices.size]
50
+ system 'say', '-v', voice, text_to_say
51
+ end
52
+
53
+ module Termtter::Client
54
+ say_threads = []
55
+ register_hook(:name => :saykanji,
56
+ :point => :output,
57
+ :exec_proc => lambda {|statuses, event|
58
+ return unless event == :update_friends_timeline
59
+ say_threads << Thread.start do
60
+ (say_threads - [Thread.current]).each { |t| t.join }
61
+ statuses.each do |s|
62
+ if /[ぁ-んァ-ヴ一-龠]/ =~ s.text
63
+ saykanji(s.text, config.plugins.saykanji.say_speed.to_i)
64
+ else
65
+ say(s.screen_name, s.text)
66
+ end
67
+ end
68
+ end
69
+ }
70
+ )
71
+
72
+ register_hook(:name => :saykanji_filter,
73
+ :point => :filter_for_saykanji,
74
+ :exec => lambda { |statuses, event|
75
+ statuses.select do |s|
76
+ config.plugins.saykanji.user_to_say.include?(s.user.screen_name) ||
77
+ Regexp.union(*config.plugins.saykanji.keyword_to_say) =~ s.text
78
+ end
79
+ }
80
+ )
81
+ end
data/lib/plugins/shell.rb CHANGED
@@ -4,11 +4,6 @@ module Termtter::Client
4
4
  register_command :name => :shell, :aliases => [:sh],
5
5
  :help => ['shell,sh', 'Start your shell'],
6
6
  :exec_proc => lambda {|args|
7
- begin
8
- pause
9
- system ENV['SHELL'] || ENV['COMSPEC']
10
- ensure
11
- resume
12
- end
7
+ system ENV['SHELL'] || ENV['COMSPEC']
13
8
  }
14
9
  end
data/lib/plugins/sl.rb CHANGED
@@ -23,10 +23,13 @@ module Termtter
23
23
  register_command(
24
24
  :name => :ls, :aliases => [],
25
25
  :exec_proc => lambda {|arg|
26
- call_commands("list #{arg.empty? ? public_storage[:current] : arg}")
27
- },
28
- :completion_proc => lambda {|cmd, args|
29
- find_user_candidates args, "#{cmd} %s"
26
+ if arg.empty? && /\A#/ =~ public_storage[:current]
27
+ call_commands("search #{public_storage[:current]}")
28
+ elsif /\A#/ =~ arg
29
+ call_commands("search #{arg}")
30
+ else
31
+ call_commands("list #{arg.empty? ? public_storage[:current] : arg}")
32
+ end
30
33
  },
31
34
  :help => ['ls', 'Show list in current directory']
32
35
  )
@@ -35,12 +38,9 @@ module Termtter
35
38
  :name => :cd, :aliases => [],
36
39
  :exec_proc => lambda {|arg|
37
40
  public_storage[:current] =
38
- (arg.nil? || /\~/ =~ arg) ? '' : arg
41
+ (arg.nil? || /\~/ =~ arg) ? '' : normalize_as_user_name(arg)
39
42
  config.prompt = "~/#{public_storage[:current]} #{public_storage[:orig_prompt]}"
40
43
  },
41
- :completion_proc => lambda {|cmd, args|
42
- find_user_candidates args, "#{cmd} %s"
43
- },
44
44
  :help => ['cd USER', 'Change current directory']
45
45
  )
46
46
  end
@@ -1,17 +1,36 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ SHORTURL_MAKERS = [
4
+ { :host => "tinyurl.com", :format => '/api-create.php?url=%s' },
5
+ { :host => "is.gd", :format => '/api.php?longurl=%s' },
6
+ ]
7
+ TINYURL_HOOK_COMMANDS = [:update, :reply]
8
+ URI_REGEXP = URI.regexp(%w(http https ftp))
9
+
3
10
  Termtter::Client.register_hook(
4
11
  :name => :tinyurl,
5
- :points => [:modify_arg_for_update],
12
+ :points => TINYURL_HOOK_COMMANDS.map {|cmd|
13
+ "modify_arg_for_#{cmd.to_s}".to_sym
14
+ },
6
15
  :exec_proc => lambda {|cmd, arg|
7
- arg = arg.gsub(URI.regexp) do |url|
8
- if url =~ %r!^https?:!
9
- Termtter::API.connection.start('tinyurl.com', 80) do |http|
10
- http.get('/api-create.php?url=' + URI.escape(url)).body
16
+ http_class = Net::HTTP
17
+ unless config.proxy.host.nil? or config.proxy.host.empty?
18
+ http_class = Net::HTTP::Proxy(config.proxy.host,
19
+ config.proxy.port,
20
+ config.proxy.user_name,
21
+ config.proxy.password)
22
+ end
23
+ arg.gsub(URI_REGEXP) do |url|
24
+ url_enc = URI.escape(url)
25
+ result = url
26
+ SHORTURL_MAKERS.each do |site|
27
+ res = http_class.new(site[:host]).get(site[:format] % url_enc)
28
+ if res.code == '200'
29
+ result = res.body
30
+ break
11
31
  end
12
- else
13
- url
14
32
  end
33
+ result
15
34
  end
16
35
  }
17
36
  )
@@ -0,0 +1,84 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'cgi'
6
+
7
+ Net::HTTP.version_1_2
8
+
9
+ module Termtter::Client
10
+ SEARCH_URI = 'search.twitter.com'
11
+ public_storage[:trends] = []
12
+
13
+ register_command :trend do |arg|
14
+ command, first, second = arg.split(/\s/)
15
+ query = []
16
+ if first
17
+ if /\A\d{4}-\d{2}-\d{2}\z/ =~ first
18
+ query << "date=#{first}"
19
+ query << "exclude=#{second}" if second
20
+ else
21
+ query << "exclude=#{first}"
22
+ end
23
+ end
24
+ case command
25
+ when 'list', nil
26
+ Net::HTTP.start(SEARCH_URI) do |http|
27
+ res = http.get('/trends.json')
28
+ show_trends JSON.parse(res.body)['trends']
29
+ end
30
+ when 'current'
31
+ Net::HTTP.start(SEARCH_URI) do |http|
32
+ query = "?#{query.join('&')}" unless query.size.zero?
33
+ res = http.get("/trends/current.json#{query}")
34
+ trends = JSON.parse(res.body)['trends']
35
+ date = trends.keys.first
36
+ puts "Trends: #{date}"
37
+ show_trends trends[date]
38
+ end
39
+ when 'daily'
40
+ Net::HTTP.start(SEARCH_URI) do |http|
41
+ query = "?#{query.join('&')}" unless query.size.zero?
42
+ res = http.get("/trends/daily.json#{query}")
43
+ trends = JSON.parse(res.body)['trends']
44
+ date = trends.keys.first
45
+ puts "Trends: #{date}"
46
+ show_trends trends[date]
47
+ end
48
+ when 'weekly'
49
+ Net::HTTP.start(SEARCH_URI) do |http|
50
+ query = "?#{query.join('&')}" unless query.size.zero?
51
+ res = http.get("/trends/weekly.json#{query}")
52
+ trends = JSON.parse(res.body)['trends']
53
+ date = trends.keys.first
54
+ puts "Trends: #{date}"
55
+ show_trends trends[date]
56
+ end
57
+ when 'show'
58
+ raise 'need number or word' if first.nil?
59
+ word = public_storage[:trends][first.to_i] || first
60
+ call_commands "search #{word}"
61
+ when /^\d$/
62
+ word = public_storage[:trends][command.to_i]
63
+ raise 'no such trend' unless word
64
+ call_commands "search #{word}"
65
+ when 'open'
66
+ raise 'nees number or word' if first.nil?
67
+ word = public_storage[:trends][first.to_i] || first
68
+ `open http://search.twitter.com/search?q=#{CGI.escape(word)}`
69
+ else
70
+ raise 'no such command'
71
+ end
72
+ end
73
+
74
+ private
75
+ def self.show_trends(trends)
76
+ public_storage[:trends].clear
77
+ max = trends.size.to_s.size
78
+ trends.each_with_index do |trend, idx|
79
+ public_storage[:trends] << trend['name']
80
+ puts "#{idx.to_s.rjust(max)}: #{trend['name']}"
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,46 @@
1
+ # = twitpic
2
+ #
3
+ # == usage
4
+ # > twitpic [MESSAGE] [IMAGE_FILE]
5
+ #
6
+ # == requirements
7
+ # * twitpic
8
+ # sudo gem install twitpic
9
+ #
10
+ # == TODO
11
+ # * スペースの混じったファイル名を扱えるようにする
12
+
13
+ gem "twitpic", ">=0.3.1"
14
+ require 'twitpic'
15
+
16
+ module Termtter::Client
17
+ register_command(
18
+ :name => :twitpic,
19
+ :help => ['twitpic [MESSAGE] [IMAGE_FILE]', 'Upload a image file to TwitPic'],
20
+ :exec => lambda do |arg|
21
+ path = arg.scan(/[^\s]+$/).flatten.first rescue nil
22
+
23
+ if path && File.exists?(path) && File.file?(path)
24
+ text = arg.gsub(/[^\s]+$/, '').strip
25
+ else
26
+ path = Termtter::CONF_DIR + '/tmp/twitpic_screencapture.png'
27
+ File.delete(path) if File.exists?(path)
28
+ puts 'Please capture screen!'
29
+ system('screencapture', '-i', '-f', path) || system('import', path) # TODO: こんなんで大丈夫かな
30
+ text = arg
31
+ end
32
+
33
+ if File.exists?(path)
34
+ puts 'Uploading...'
35
+ url = TwitPic.new(config.user_name, config.password).upload(path)[:mediaurl]
36
+ puts " => \"#{url}\""
37
+ post_message = "#{text} #{url}".strip
38
+ puts 'Post a message...'
39
+ Termtter::API.twitter.update(post_message)
40
+ puts " => \"#{post_message}\""
41
+ else
42
+ puts 'Aboat!'
43
+ end
44
+ end
45
+ )
46
+ end
@@ -63,7 +63,7 @@ module Termtter::Client
63
63
  )
64
64
  end
65
65
  # ~/.termtter/config
66
- # plugin 'uri-open'
66
+ # t.plug 'uri-open'
67
67
  #
68
68
  # see also: http://ujihisa.blogspot.com/2009/05/fixed-uri-open-of-termtter.html
69
69
  #
data/lib/plugins/wassr.rb CHANGED
@@ -42,9 +42,6 @@ module Termtter::Client
42
42
  event = :wassr_friends_timeline
43
43
  print_statuses(statuses, event)
44
44
  },
45
- :completion_proc => lambda {|cmd, arg|
46
- find_user_candidates arg, "#{cmd} %s"
47
- },
48
45
  :help => ["wassr, wsr", "List the wassr timeline."]
49
46
  )
50
47
  end
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # This plugin resolve inputed domain name or IP address, like this following:
4
+ #
5
+ # > whois www.google.com
6
+ # => 66.249.89.147
7
+ # > whois 65.74.177.129
8
+ # => github.com
9
+ #
10
+ # Just same dig command:p
11
+
12
+ require 'resolv'
13
+
14
+ module Termtter::Client
15
+ register_command(
16
+ :name => :whois,
17
+ :exec_proc => lambda {|name|
18
+ resolved = whois? name
19
+ Termtter::API.twitter.update(resolved)
20
+ puts '=> ' << resolved
21
+ }
22
+ )
23
+ end
24
+
25
+ def whois?(arg)
26
+ if addr? arg
27
+ begin
28
+ Resolv.getname(arg)
29
+ rescue => e
30
+ e.message
31
+ end
32
+ else
33
+ begin
34
+ Resolv.getaddress(arg)
35
+ rescue => e
36
+ e.message
37
+ end
38
+ end
39
+ end
40
+
41
+ def addr?(arg)
42
+ Resolv::AddressRegex =~ arg
43
+ end
44
+
45
+ # vim: textwidth=78
data/lib/plugins/yhara.rb CHANGED
@@ -128,15 +128,11 @@ module Termtter::Client
128
128
  register_command(
129
129
  :name => :yhara,
130
130
  :exec_proc => lambda{|arg|
131
- text = "#{'@' if arg[0..0] != '@'}#{arg} #{Yharian::text}"
131
+ name = normalize_as_user_name(arg)
132
+ text = "@#{name} #{Yharian::text}"
132
133
  Termtter::API.twitter.update(text)
133
134
  puts "=> #{text}"
134
135
  },
135
- :completion_proc => lambda {|cmd, args|
136
- if /(.*)@([^\s]*)$/ =~ args
137
- find_user_candidates $2, "#{cmd} #{$1}@%s"
138
- end
139
- },
140
136
  :help => ["yhara (USER)", 'Post a new Yharian sentence']
141
137
  )
142
138
  end