draftcode-termtter 1.0.8

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 (118) hide show
  1. data/History.txt +4 -0
  2. data/README.rdoc +100 -0
  3. data/Rakefile +55 -0
  4. data/bin/kill_termtter +22 -0
  5. data/bin/termtter +6 -0
  6. data/lib/plugins/addspace.rb +27 -0
  7. data/lib/plugins/april_fool.rb +15 -0
  8. data/lib/plugins/bomb.rb +39 -0
  9. data/lib/plugins/clear.rb +14 -0
  10. data/lib/plugins/command_plus.rb +47 -0
  11. data/lib/plugins/confirm.rb +33 -0
  12. data/lib/plugins/cool.rb +10 -0
  13. data/lib/plugins/countter.rb +23 -0
  14. data/lib/plugins/devel.rb +18 -0
  15. data/lib/plugins/direct_messages.rb +36 -0
  16. data/lib/plugins/en2ja.rb +11 -0
  17. data/lib/plugins/english.rb +25 -0
  18. data/lib/plugins/erb.rb +17 -0
  19. data/lib/plugins/exec.rb +17 -0
  20. data/lib/plugins/exec_and_update.rb +14 -0
  21. data/lib/plugins/expand-tinyurl.rb +34 -0
  22. data/lib/plugins/fib.rb +28 -0
  23. data/lib/plugins/fib_filter.rb +14 -0
  24. data/lib/plugins/filter.rb +69 -0
  25. data/lib/plugins/graduatter.rb +8 -0
  26. data/lib/plugins/grass.rb +27 -0
  27. data/lib/plugins/group.rb +64 -0
  28. data/lib/plugins/growl.rb +52 -0
  29. data/lib/plugins/growl2.rb +143 -0
  30. data/lib/plugins/hatebu.rb +59 -0
  31. data/lib/plugins/hatebu_and_update.rb +58 -0
  32. data/lib/plugins/history.rb +93 -0
  33. data/lib/plugins/ignore.rb +19 -0
  34. data/lib/plugins/keyword.rb +18 -0
  35. data/lib/plugins/l2.rb +25 -0
  36. data/lib/plugins/log.rb +73 -0
  37. data/lib/plugins/me.rb +10 -0
  38. data/lib/plugins/modify_arg_hook_sample.rb +7 -0
  39. data/lib/plugins/msagent.rb +38 -0
  40. data/lib/plugins/multi_reply.rb +27 -0
  41. data/lib/plugins/notify-send.rb +22 -0
  42. data/lib/plugins/notify-send2.rb +52 -0
  43. data/lib/plugins/notify-send3.rb +45 -0
  44. data/lib/plugins/open_url.rb +59 -0
  45. data/lib/plugins/otsune.rb +21 -0
  46. data/lib/plugins/outputz.rb +33 -0
  47. data/lib/plugins/pause.rb +3 -0
  48. data/lib/plugins/post_exec_hook_sample.rb +9 -0
  49. data/lib/plugins/pre_exec_hook_sample.rb +9 -0
  50. data/lib/plugins/primes.rb +30 -0
  51. data/lib/plugins/quicklook.rb +41 -0
  52. data/lib/plugins/random.rb +23 -0
  53. data/lib/plugins/reblog.rb +40 -0
  54. data/lib/plugins/reload.rb +3 -0
  55. data/lib/plugins/reply.rb +8 -0
  56. data/lib/plugins/retweet.rb +46 -0
  57. data/lib/plugins/reverse.rb +13 -0
  58. data/lib/plugins/say.rb +26 -0
  59. data/lib/plugins/scrape.rb +41 -0
  60. data/lib/plugins/screen-notify.rb +20 -0
  61. data/lib/plugins/screen.rb +24 -0
  62. data/lib/plugins/shell.rb +14 -0
  63. data/lib/plugins/sl.rb +48 -0
  64. data/lib/plugins/spam.rb +16 -0
  65. data/lib/plugins/standard_plugins.rb +525 -0
  66. data/lib/plugins/stdout.rb +220 -0
  67. data/lib/plugins/storage.rb +55 -0
  68. data/lib/plugins/storage/DB.rb +37 -0
  69. data/lib/plugins/storage/status.rb +83 -0
  70. data/lib/plugins/storage/status_mook.rb +30 -0
  71. data/lib/plugins/switch_user.rb +22 -0
  72. data/lib/plugins/system_status.rb +33 -0
  73. data/lib/plugins/timer.rb +18 -0
  74. data/lib/plugins/tinyurl.rb +20 -0
  75. data/lib/plugins/translation.rb +38 -0
  76. data/lib/plugins/typable_id.rb +94 -0
  77. data/lib/plugins/update_editor.rb +53 -0
  78. data/lib/plugins/uri-open.rb +66 -0
  79. data/lib/plugins/wassr_post.rb +22 -0
  80. data/lib/plugins/yhara.rb +148 -0
  81. data/lib/plugins/yhara_filter.rb +8 -0
  82. data/lib/plugins/yonda.rb +21 -0
  83. data/lib/termtter.rb +38 -0
  84. data/lib/termtter/api.rb +57 -0
  85. data/lib/termtter/client.rb +324 -0
  86. data/lib/termtter/command.rb +80 -0
  87. data/lib/termtter/config.rb +68 -0
  88. data/lib/termtter/config_setup.rb +38 -0
  89. data/lib/termtter/connection.rb +41 -0
  90. data/lib/termtter/hook.rb +31 -0
  91. data/lib/termtter/optparse.rb +14 -0
  92. data/lib/termtter/system_extensions.rb +115 -0
  93. data/lib/termtter/task.rb +17 -0
  94. data/lib/termtter/task_manager.rb +116 -0
  95. data/lib/termtter/version.rb +4 -0
  96. data/spec/plugins/cool_spec.rb +10 -0
  97. data/spec/plugins/english_spec.rb +19 -0
  98. data/spec/plugins/fib_spec.rb +15 -0
  99. data/spec/plugins/filter_spec.rb +18 -0
  100. data/spec/plugins/pause_spec.rb +8 -0
  101. data/spec/plugins/primes_spec.rb +15 -0
  102. data/spec/plugins/shell_spec.rb +10 -0
  103. data/spec/plugins/sl_spec.rb +8 -0
  104. data/spec/plugins/spam_spec.rb +4 -0
  105. data/spec/plugins/standard_plugins_spec.rb +23 -0
  106. data/spec/plugins/storage/DB_spec.rb +12 -0
  107. data/spec/plugins/storage/status_spec.rb +24 -0
  108. data/spec/spec_helper.rb +7 -0
  109. data/spec/termtter/client_spec.rb +255 -0
  110. data/spec/termtter/command_spec.rb +107 -0
  111. data/spec/termtter/config_spec.rb +111 -0
  112. data/spec/termtter/hook_spec.rb +78 -0
  113. data/spec/termtter/task_manager_spec.rb +78 -0
  114. data/spec/termtter/task_spec.rb +22 -0
  115. data/spec/termtter_spec.rb +29 -0
  116. data/test/friends_timeline.json +5 -0
  117. data/test/search.json +8 -0
  118. metadata +211 -0
@@ -0,0 +1,59 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'atomutil'
5
+
6
+ module Termtter::Client
7
+ register_command(
8
+ :name => :hatebu, :aliases => [],
9
+ :exec_proc => lambda {|arg|
10
+ if arg =~ /^(\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
+ auth = auth = Atompub::Auth::Wsse.new({
20
+ :username => config.plugins.hatebu.username,
21
+ :password => config.plugins.hatebu.password,
22
+ })
23
+ link = Atom::Link.new({
24
+ :href => "http://twitter.com/#{status.user.screen_name}/status/#{status.id}",
25
+ :rel => 'related',
26
+ :type => 'text/html',
27
+ })
28
+ entry = Atom::Entry.new({
29
+ :link => link,
30
+ :title => 'dummy',
31
+ :summary => comment,
32
+ })
33
+ req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
34
+ req['User-Agent'] = 'Mozilla/5.0'
35
+ req['Content-Type'] = 'application/atom+xml'
36
+ req['Slug'] = 'termtter'
37
+ req.body = entry.to_s
38
+ auth.authorize(req)
39
+ Net::HTTP.start('b.hatena.ne.jp', 80) do |http|
40
+ res = http.request(req)
41
+ end
42
+ end
43
+ },
44
+ :completion_proc => lambda {|cmd, args|
45
+ if args =~ /^(\d*)$/
46
+ find_status_ids($1){|id| "#{cmd} #{id}"}
47
+ end
48
+ },
49
+ :help => ['hatebu ID', 'Hatena bookmark a status']
50
+ )
51
+ end
52
+
53
+ # hatebu.rb
54
+ # hatena bookmark it!
55
+ #
56
+ # config.plugins.hatebu.username = 'your-username-on-hatena'
57
+ # config.plugins.hatebu.password = 'your-password-on-hatena'
58
+ #
59
+ # hatebu 1114860346 [termtter][<82>±<82>ê<82>Í<82>·<82>²<82>¢]mattn++
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'atomutil'
5
+ require 'nokogiri'
6
+
7
+ module Termtter::Client
8
+ register_command(
9
+ :name => :hatebu_and_update, :aliases => [:hau],
10
+ :exec_proc => lambda {|arg|
11
+ url, comment = arg.split(/\s/)
12
+ if url =~ URI.regexp
13
+ auth = auth = Atompub::Auth::Wsse.new({
14
+ :username => config.plugins.hatebu.username,
15
+ :password => config.plugins.hatebu.password,
16
+ })
17
+ link = Atom::Link.new({
18
+ :href => url,
19
+ :rel => 'related',
20
+ :type => 'text/html',
21
+ })
22
+ entry = Atom::Entry.new({
23
+ :link => link,
24
+ :title => 'dummy',
25
+ :summary => comment,
26
+ })
27
+ req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
28
+ req['User-Agent'] = 'Mozilla/5.0'
29
+ req['Content-Type'] = 'application/atom+xml'
30
+ req['Slug'] = 'termtter'
31
+ req.body = entry.to_s
32
+ auth.authorize(req)
33
+ title = nil
34
+ tinyurl = nil
35
+ Termtter::API.connection.start('b.hatena.ne.jp', 80) do |http|
36
+ res = http.request(req)
37
+ title = Nokogiri::XML(res.body).search('link[title]').first['title'] rescue nil
38
+ end
39
+ if title
40
+ Termtter::API.connection.start('tinyurl.com', 80) do |http|
41
+ tinyurl = http.get('/api-create.php?url=' + URI.escape(url)).body
42
+ end
43
+
44
+ Termtter::API.twitter.update("[はてぶ] #{title} #{tinyurl}")
45
+ end
46
+ end
47
+ },
48
+ :help => ['hatebu2 URL', 'Hatena bookmark a URL, and update']
49
+ )
50
+ end
51
+
52
+ # hatebu.rb
53
+ # hatena bookmark it, and post
54
+ #
55
+ # config.plugins.hatebu.username = 'your-username-on-hatena'
56
+ # config.plugins.hatebu.password = 'your-password-on-hatena'
57
+ #
58
+ # hatebu_and_update http://www.yahoo.co.jp/ [yahoo]
@@ -0,0 +1,93 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'zlib'
4
+
5
+ config.plugins.history.
6
+ set_default(:filename, Termtter::CONF_DIR + '/history')
7
+ config.plugins.history.
8
+ set_default(:keys, [:users, :status_ids])
9
+ config.plugins.history.
10
+ set_default(:max_of_history, 100)
11
+ config.plugins.history.
12
+ set_default(:enable_autosave, true)
13
+ config.plugins.history.
14
+ set_default(:autosave_interval, 3600)
15
+
16
+ module Termtter::Client
17
+ def self.load_history
18
+ filename = File.expand_path(config.plugins.history.filename)
19
+ keys = config.plugins.history.keys
20
+
21
+ if File.exist?(filename)
22
+ begin
23
+ history = Marshal.load Zlib::Inflate.inflate(File.read(filename))
24
+ end
25
+ if history
26
+ keys.each do |key|
27
+ public_storage[key] = history[key] if history[key]
28
+ end
29
+ Readline::HISTORY.push *history[:history] if history[:history]
30
+ puts "history loaded(#{File.size(filename)/1000}kb)"
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.save_history
36
+ filename = File.expand_path(config.plugins.history.filename)
37
+ keys = config.plugins.history.keys
38
+ history = { }
39
+ keys.each do |key|
40
+ history[key] = public_storage[key]
41
+ end
42
+ max_of_history = config.plugins.history.max_of_history
43
+ history[:history] = Readline::HISTORY.to_a.reverse.uniq.reverse
44
+ if history[:history].size > max_of_history
45
+ history[:history] = history[:history][-max_of_history..-1]
46
+ end
47
+
48
+ File.open(filename, 'w') do |f|
49
+ f.write Zlib::Deflate.deflate(Marshal.dump(history))
50
+ end
51
+ puts "history saved(#{File.size(filename)/1000}kb)"
52
+ end
53
+
54
+ register_hook(
55
+ :name => :history_initialize,
56
+ :points => [:initialize],
57
+ :exec_proc => lambda { load_history; logger.debug('load_history') }
58
+ )
59
+
60
+ register_hook(
61
+ :name => :history_exit,
62
+ :points => [:exit],
63
+ :exec_proc => lambda { save_history; logger.debug('save_history') }
64
+ )
65
+
66
+ if config.plugins.history.enable_autosave
67
+ Termtter::Client.add_task(:interval => config.plugins.history.autosave_interval,
68
+ :after => config.plugins.history.autosave_interval) do
69
+ save_history
70
+ end
71
+ end
72
+
73
+ register_command(
74
+ :name => :save,
75
+ :exec_proc => lambda{|arg|
76
+ save_history
77
+ },
78
+ :help => ['save', 'Save hisory']
79
+ )
80
+
81
+ register_command(
82
+ :name => :load,
83
+ :exec_proc => lambda{|arg|
84
+ load_history
85
+ },
86
+ :help => ['load', 'Load hisory']
87
+ )
88
+
89
+
90
+ end
91
+
92
+ # history.rb
93
+ # save log to file
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ config.filters.ignore.set_default(:words, [])
5
+
6
+ module Termtter::Client
7
+ add_filter do |statuses, _|
8
+ ignore_words = config.filters.ignore.words
9
+ statuses.delete_if do |s|
10
+ ignore_words.any? {|i| i =~ s.text }
11
+ end
12
+ end
13
+ end
14
+
15
+ # filter/ignore.rb
16
+ # ignore words
17
+ # setting
18
+ # config.filters.ignore.words = [ /ignore/, /words/ ]
19
+
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ config.set_default('plugins.keyword.keywords', [])
4
+
5
+ module Termtter
6
+ class Status
7
+ def has_keyword?
8
+ config.plugins.keyword.keywords.find { |k| k === self.text }
9
+ end
10
+ alias :has_keyword :has_keyword?
11
+ end
12
+ end
13
+
14
+ # keyword.rb
15
+ # provides a keyword watching method
16
+ # example config
17
+ # config.plugins.stdout.timeline_format = '<%= color(time, 90) %> <%= color(status, s.has_keyword ? 4 : status_color) %> <%= color(id, 90) %>'
18
+ # config.plugins.keyword.keywords = [ /motemen/ ]
data/lib/plugins/l2.rb ADDED
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :list2,
6
+ :aliases => [:l2],
7
+ :exec_proc => lambda {|arg|
8
+ unless arg.empty?
9
+ targets = arg.split.uniq
10
+ statuses = targets ? targets.map { |target|
11
+ public_storage[:tweet][target]
12
+ }.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
13
+ output(statuses, :search)
14
+ end
15
+ },
16
+ :completion_proc => lambda {|cmd, arg|
17
+ #todo
18
+ },
19
+ :help => ['list2,l2 A B (C..)', "List statuses of A's and B's (and C's..)"]
20
+ )
21
+ end
22
+
23
+ # l2.rb
24
+ # plugin 'l2'
25
+ # NOTE: l2.rb needs plugin/log
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ public_storage[:log] = []
5
+ public_storage[:tweet] = { }
6
+ config.plugins.log.set_default('max_size', 1/0.0)
7
+ config.plugins.log.set_default('print_max_size', 30)
8
+
9
+ register_hook(
10
+ :name => :log,
11
+ :points => [:pre_filter],
12
+ :exec_proc => lambda {|statuses, event|
13
+ # log(sequential storage)
14
+ public_storage[:log] += statuses
15
+ max_size = config.plugins.log.max_size
16
+ if public_storage[:log].size > max_size
17
+ public_storage[:log] = public_storage[:log][-max_size..-1]
18
+ end
19
+ public_storage[:log] = public_storage[:log].uniq.sort_by{|s| s.created_at} if statuses.first
20
+
21
+ # tweet(storage for each user)
22
+ statuses.each do |s|
23
+ public_storage[:tweet][s.user.screen_name] = [] unless public_storage[:tweet][s.user.screen_name]
24
+ public_storage[:tweet][s.user.screen_name] << s
25
+ end
26
+
27
+ statuses.map{ |s| s.user.screen_name}.uniq.each do |name|
28
+ public_storage[:tweet][name]
29
+ if public_storage[:tweet][name].size > max_size
30
+ public_storage[:tweet][name] = public_storage[:tweet][name][-max_size..-1]
31
+ end
32
+ end
33
+ }
34
+ )
35
+
36
+ register_command(
37
+ :name => :log,
38
+ :exec_proc => lambda{|arg|
39
+ if arg.empty?
40
+ # log
41
+ statuses = public_storage[:log]
42
+ print_max = config.plugins.log.print_max_size
43
+ print_max = 0 if statuses.size < print_max
44
+ output(statuses[-print_max..-1], :search)
45
+ else
46
+ # log (user) (max)
47
+ vars = arg.split(' ')
48
+ print_max = vars.last =~ /^\d+$/ ? vars.pop.to_i : config.plugins.log.print_max_size
49
+ id = vars
50
+ statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user.screen_name} : public_storage[:log]
51
+ print_max = 0 if statuses.size < print_max
52
+ output(statuses[-print_max..-1], :search)
53
+ end
54
+ },
55
+ :completion_proc => lambda {|cmd, arg|
56
+ find_user_candidates arg, "#{cmd} %s"
57
+ },
58
+ :help => [ 'log (USER(S)) (MAX)', 'Show local log of the user(s)']
59
+ )
60
+
61
+ register_command(
62
+ :name => :search_log, :aliases => [:sl],
63
+ :exec_proc => lambda{|arg|
64
+ unless arg.strip.empty?
65
+ pat = Regexp.new arg
66
+ statuses = public_storage[:log].select { |s| s.text =~ pat }
67
+ output(statuses, :search)
68
+ end
69
+ },
70
+ :help => [ 'search_log WORD', 'Search log for WORD' ]
71
+ )
72
+
73
+ end
data/lib/plugins/me.rb ADDED
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Termtter::Client
3
+ register_command(
4
+ :name => :me, :aliases => [],
5
+ :exec_proc => lambda {|arg|
6
+ call_commands('list ' + config.user_name)
7
+ },
8
+ :help => ['me', 'show my timeline']
9
+ )
10
+ end
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.register_hook(
4
+ :name => :modify_arg_hook_sample,
5
+ :points => [:modify_arg_for_update],
6
+ :exec_proc => lambda {|cmd, arg| arg + '\(^o^)/'}
7
+ )
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ raise 'msagent.rb runs only in windows' if RUBY_PLATFORM.downcase !~ /mswin(?!ce)|mingw|bccwin/
4
+ require 'win32ole'
5
+ require 'kconv'
6
+
7
+ agent = WIN32OLE.new('Agent.Control.2')
8
+ agent.connected = true
9
+ agent.characters.load("Merlin", ENV['WINDIR'] + "\\msagent\\chars\\Merlin.acs")
10
+ achar = agent.characters.character("Merlin")
11
+ achar.languageID = 0x411
12
+ achar.show
13
+
14
+ Termtter::Client.register_hook(
15
+ :name => :msagent,
16
+ :points => [:output],
17
+ :exec_proc => lambda {|statuses, event|
18
+ if !statuses.empty? && event == :update_friends_timeline
19
+ Thread.start do
20
+ statuses.each do |s|
21
+ req = achar.speak("#{s.user.screen_name}: #{s.text}".tosjis)
22
+ sleep 1
23
+ WIN32OLE_EVENT.message_loop
24
+ achar.stop(req)
25
+ end
26
+ end
27
+ end
28
+ }
29
+ )
30
+
31
+ Termtter::Client.register_hook(
32
+ :name => :msagent_exit,
33
+ :points => [:exit],
34
+ :exec_proc => lambda {
35
+ achar.hide
36
+ GC.start
37
+ }
38
+ )
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :multi_reply, :aliases => [:mr],
6
+ :exec_proc => lambda {|arg|
7
+ text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
8
+ unless text.empty?
9
+ /(@(.+))*\s+(.+)/ =~ text
10
+ if $1
11
+ msg = $3
12
+ text = $1.split(/\s+/).map {|u| "#{u} #{msg}" }
13
+ end
14
+ Array(text).each do |post|
15
+ Termtter::API.twitter.update(post)
16
+ puts "=> #{post}"
17
+ end
18
+ end
19
+ },
20
+ :completion_proc => lambda {|cmd, args|
21
+ if /(.*)@([^\s]*)$/ =~ args
22
+ find_user_candidates $2, "#{cmd} #{$1}@%s"
23
+ end
24
+ },
25
+ :help => ["multi_reply,mp TEXT", "Reply to multi user"]
26
+ )
27
+ end
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.register_hook(
4
+ :name => :notify_send,
5
+ :points => [:output],
6
+ :exec_proc => lambda {|statuses, event|
7
+ if event == :update_friends_timeline
8
+ max = 10
9
+
10
+ text = statuses.take(max).map {|s|
11
+ status_text = CGI.escapeHTML(s.text)
12
+ status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
13
+ "<b>#{s.user.screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
14
+ }.join("\n")
15
+
16
+ text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
17
+
18
+ system 'notify-send', 'Termtter', text, '-t', '60000'
19
+ end
20
+ }
21
+ )
22
+