termtter 1.2.0 → 1.3.0

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 (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