emasaka-termtter 1.0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) 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 +12 -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_and_update.rb +14 -0
  20. data/lib/plugins/expand-tinyurl.rb +33 -0
  21. data/lib/plugins/fib.rb +28 -0
  22. data/lib/plugins/fib_filter.rb +14 -0
  23. data/lib/plugins/filter.rb +69 -0
  24. data/lib/plugins/graduatter.rb +8 -0
  25. data/lib/plugins/grass.rb +27 -0
  26. data/lib/plugins/group.rb +64 -0
  27. data/lib/plugins/growl.rb +52 -0
  28. data/lib/plugins/growl2.rb +143 -0
  29. data/lib/plugins/hatebu.rb +59 -0
  30. data/lib/plugins/history.rb +93 -0
  31. data/lib/plugins/ignore.rb +19 -0
  32. data/lib/plugins/keyword.rb +18 -0
  33. data/lib/plugins/l2.rb +25 -0
  34. data/lib/plugins/log.rb +73 -0
  35. data/lib/plugins/me.rb +10 -0
  36. data/lib/plugins/modify_arg_hook_sample.rb +7 -0
  37. data/lib/plugins/msagent.rb +38 -0
  38. data/lib/plugins/multi_reply.rb +27 -0
  39. data/lib/plugins/notify-send.rb +22 -0
  40. data/lib/plugins/notify-send2.rb +52 -0
  41. data/lib/plugins/open_url.rb +59 -0
  42. data/lib/plugins/otsune.rb +21 -0
  43. data/lib/plugins/outputz.rb +33 -0
  44. data/lib/plugins/pause.rb +3 -0
  45. data/lib/plugins/post_exec_hook_sample.rb +9 -0
  46. data/lib/plugins/pre_exec_hook_sample.rb +9 -0
  47. data/lib/plugins/primes.rb +30 -0
  48. data/lib/plugins/quicklook.rb +41 -0
  49. data/lib/plugins/random.rb +23 -0
  50. data/lib/plugins/reblog.rb +40 -0
  51. data/lib/plugins/reload.rb +3 -0
  52. data/lib/plugins/reply.rb +8 -0
  53. data/lib/plugins/retweet.rb +46 -0
  54. data/lib/plugins/reverse.rb +13 -0
  55. data/lib/plugins/say.rb +26 -0
  56. data/lib/plugins/scrape.rb +41 -0
  57. data/lib/plugins/screen-notify.rb +20 -0
  58. data/lib/plugins/screen.rb +24 -0
  59. data/lib/plugins/shell.rb +14 -0
  60. data/lib/plugins/shorturl_on_update.rb +36 -0
  61. data/lib/plugins/sl.rb +48 -0
  62. data/lib/plugins/spam.rb +16 -0
  63. data/lib/plugins/standard_plugins.rb +519 -0
  64. data/lib/plugins/stdout.rb +83 -0
  65. data/lib/plugins/storage.rb +55 -0
  66. data/lib/plugins/storage/DB.rb +37 -0
  67. data/lib/plugins/storage/status.rb +83 -0
  68. data/lib/plugins/storage/status_mook.rb +30 -0
  69. data/lib/plugins/switch_user.rb +22 -0
  70. data/lib/plugins/system_status.rb +33 -0
  71. data/lib/plugins/timer.rb +18 -0
  72. data/lib/plugins/translation.rb +38 -0
  73. data/lib/plugins/typable_id.rb +94 -0
  74. data/lib/plugins/update_editor.rb +53 -0
  75. data/lib/plugins/update_filter.rb +30 -0
  76. data/lib/plugins/uri-open.rb +66 -0
  77. data/lib/plugins/wassr_post.rb +22 -0
  78. data/lib/plugins/yhara.rb +148 -0
  79. data/lib/plugins/yhara_filter.rb +8 -0
  80. data/lib/plugins/yonda.rb +21 -0
  81. data/lib/termtter.rb +38 -0
  82. data/lib/termtter/api.rb +57 -0
  83. data/lib/termtter/client.rb +370 -0
  84. data/lib/termtter/command.rb +80 -0
  85. data/lib/termtter/config.rb +68 -0
  86. data/lib/termtter/config_setup.rb +38 -0
  87. data/lib/termtter/connection.rb +41 -0
  88. data/lib/termtter/hook.rb +31 -0
  89. data/lib/termtter/optparse.rb +14 -0
  90. data/lib/termtter/system_extensions.rb +161 -0
  91. data/lib/termtter/task.rb +17 -0
  92. data/lib/termtter/task_manager.rb +116 -0
  93. data/lib/termtter/version.rb +4 -0
  94. data/spec/plugins/cool_spec.rb +10 -0
  95. data/spec/plugins/english_spec.rb +19 -0
  96. data/spec/plugins/fib_spec.rb +15 -0
  97. data/spec/plugins/filter_spec.rb +18 -0
  98. data/spec/plugins/pause_spec.rb +8 -0
  99. data/spec/plugins/primes_spec.rb +15 -0
  100. data/spec/plugins/shell_spec.rb +10 -0
  101. data/spec/plugins/sl_spec.rb +8 -0
  102. data/spec/plugins/spam_spec.rb +4 -0
  103. data/spec/plugins/standard_plugins_spec.rb +23 -0
  104. data/spec/plugins/storage/DB_spec.rb +12 -0
  105. data/spec/plugins/storage/status_spec.rb +24 -0
  106. data/spec/spec_helper.rb +7 -0
  107. data/spec/termtter/client_spec.rb +255 -0
  108. data/spec/termtter/command_spec.rb +107 -0
  109. data/spec/termtter/config_spec.rb +111 -0
  110. data/spec/termtter/hook_spec.rb +78 -0
  111. data/spec/termtter/task_manager_spec.rb +78 -0
  112. data/spec/termtter/task_spec.rb +22 -0
  113. data/spec/termtter_spec.rb +29 -0
  114. data/test/friends_timeline.json +5 -0
  115. data/test/search.json +8 -0
  116. metadata +210 -0
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ module Termtter
4
+ class Config
5
+ def initialize
6
+ @store = Hash.new(:undefined)
7
+ end
8
+
9
+ def inspect
10
+ @store.inspect
11
+ end
12
+
13
+ # set_default :: (Symbol | String) -> a -> IO ()
14
+ def set_default(name, value)
15
+ match_p, init, last = *name.to_s.match(/^(.+)\.([^\.]+)$/)
16
+ if match_p
17
+ tmp = eval(init)
18
+ if tmp.__refer__(last.to_sym).empty?
19
+ tmp.__assign__(last.to_sym, value)
20
+ end
21
+ else
22
+ __assign__(name.to_sym, value) if __refer__(name.to_sym).empty?
23
+ end
24
+ end
25
+
26
+ # empty? :: Boolean
27
+ def empty?
28
+ @store.empty?
29
+ end
30
+
31
+ def method_missing(name, *args)
32
+ case name.to_s
33
+ when /(.*)=$/
34
+ __assign__($1.to_sym, args.first)
35
+ else
36
+ __refer__(name.to_sym)
37
+ end
38
+ end
39
+
40
+ # __assign__ :: Symbol -> a -> IO ()
41
+ def __assign__(name, value)
42
+ @store[name] = value
43
+ end
44
+
45
+ # __refer__ :: Symbol -> IO a
46
+ def __refer__(name)
47
+ @store[name] == :undefined ? @store[name] = Termtter::Config.new : @store[name]
48
+ end
49
+
50
+ def __values__
51
+ @store.dup
52
+ end
53
+
54
+ __instance = self.new
55
+ (class << self; self end).
56
+ __send__(:define_method, :instance) { __instance }
57
+ end
58
+ end
59
+
60
+ def config
61
+ Termtter::Config.instance
62
+ end
63
+
64
+ def configatron
65
+ # remove this method until Termtter-1.2.0
66
+ warn "configatron method will be removed. Use config instead. (#{caller.first})"
67
+ Termtter::Config.instance
68
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ module ConfigSetup
5
+ module_function
6
+ def run
7
+ ui = create_highline
8
+ username = ui.ask('your twitter username: ')
9
+ password = ui.ask('your twitter password: ') { |q| q.echo = false }
10
+
11
+ Dir.mkdir(Termtter::CONF_DIR) unless File.exists?(Termtter::CONF_DIR)
12
+ File.open(Termtter::CONF_FILE, 'w') {|io|
13
+ io.puts '# -*- coding: utf-8 -*-'
14
+
15
+ io.puts
16
+ io.puts "config.user_name = '#{username}'"
17
+ io.puts "config.password = '#{password}'"
18
+ io.puts "#config.update_interval = 120"
19
+ io.puts "#config.proxy.host = 'proxy host'"
20
+ io.puts "#config.proxy.port = '8080'"
21
+ io.puts "#config.proxy.user_name = 'proxy user'"
22
+ io.puts "#config.proxy.password = 'proxy password'"
23
+ io.puts
24
+ plugins = Dir.glob(File.expand_path(File.dirname(__FILE__) + "/../plugins/*.rb")).map {|f|
25
+ f.match(%r|lib/plugins/(.*?).rb$|)[1]
26
+ }
27
+ plugins -= %w[stdout standard_plugins]
28
+ plugins.each do |p|
29
+ io.puts "#plugin '#{p}'"
30
+ end
31
+ io.puts
32
+ io.puts "# vim: set filetype=ruby"
33
+ }
34
+ puts "generated: ~/.termtter/config"
35
+ puts "enjoy!"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ class Connection
5
+ attr_reader :protocol, :port, :proxy_uri
6
+
7
+ def initialize
8
+ unless config.proxy.empty?
9
+ @proxy_host = config.proxy.host
10
+ @proxy_port = config.proxy.port
11
+ @proxy_user = config.proxy.user_name
12
+ @proxy_password = config.proxy.password
13
+ @proxy_uri = nil
14
+ @enable_ssl = config.enable_ssl
15
+ end
16
+ @protocol = "http"
17
+ @port = 80
18
+
19
+ if @proxy_host
20
+ @http_class = Net::HTTP::Proxy(@proxy_host, @proxy_port,
21
+ @proxy_user, @proxy_password)
22
+ @proxy_uri = "http://" + @proxy_host + ":" + @proxy_port + "/"
23
+ else
24
+ @http_class = Net::HTTP
25
+ end
26
+
27
+ if @enable_ssl
28
+ @protocol = "https"
29
+ @port = 443
30
+ end
31
+ end
32
+
33
+ def start(host, port, &block)
34
+ http = @http_class.new(host, port)
35
+ http.use_ssl = @enable_ssl
36
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
37
+ http.start(&block)
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ class Hook
5
+ attr_accessor :name, :points, :exec_proc
6
+
7
+ def initialize(args)
8
+ raise ArgumentError, ":name is not given." unless args.has_key?(:name)
9
+ @name = args[:name].to_sym
10
+ @points = args[:points] || [args[:point]].compact
11
+ @exec_proc = args[:exec_proc] || args[:exec] || lambda {}
12
+ end
13
+
14
+ def match?(point)
15
+ !points.select{|pt|
16
+ case pt
17
+ when String, Symbol
18
+ pt.to_s == point.to_s
19
+ when Regexp
20
+ (pt =~ point.to_s) ? true : false
21
+ else
22
+ false
23
+ end
24
+ }.empty?
25
+ end
26
+
27
+ def call(*args)
28
+ self.exec_proc.call(*args)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ OptionParser.new { |opt|
2
+ opt.on('-f', '--file config_file', 'Set path to configfile') do |val|
3
+ config.system.__assign__(:conf_file, val)
4
+ end
5
+ opt.on('-t', '--termtter-directory directory', 'Set termtter directory') do |val|
6
+ config.system.__assign__(:conf_dir, val)
7
+ end
8
+ opt.on('-d', '--devel', 'Start in developer mode') do |flg|
9
+ config.system.__assign__(:devel, true) if flg
10
+ end
11
+
12
+ Version = Termtter::VERSION
13
+ opt.parse!(ARGV)
14
+ }
@@ -0,0 +1,161 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ def plugin(name, init = {})
4
+ unless init.empty?
5
+ init.each do |key, value|
6
+ config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
7
+ end
8
+ end
9
+ load "plugins/#{name}.rb"
10
+ rescue Exception => e
11
+ Termtter::Client.handle_error(e)
12
+ end
13
+
14
+ def filter(name, init = {})
15
+ warn "filter method will be removed. Use plugin instead."
16
+ plugin(name, init)
17
+ end
18
+
19
+ require 'dl/import'
20
+ module Readline
21
+ begin
22
+ module LIBREADLINE
23
+ if DL.const_defined? :Importable
24
+ extend DL::Importable
25
+ else
26
+ extend DL::Importer
27
+ end
28
+ pathes = Array(ENV['TERMTTER_EXT_LIB'] || [
29
+ '/opt/local/lib/libreadline.dylib',
30
+ '/usr/lib/libreadline.so',
31
+ '/usr/local/lib/libreadline.so',
32
+ File.join(Gem.bindir, 'readline.dll')
33
+ ])
34
+ dlload(pathes.find { |path| File.exist?(path)})
35
+ extern 'int rl_refresh_line(int, int)'
36
+ end
37
+ def self.refresh_line
38
+ LIBREADLINE.rl_refresh_line(0, 0)
39
+ end
40
+ rescue Exception
41
+ def self.refresh_line;end
42
+ end
43
+ end
44
+
45
+ def win?
46
+ RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/
47
+ end
48
+
49
+ if win?
50
+ require 'iconv'
51
+ require 'Win32API'
52
+ $wGetACP = Win32API.new('kernel32','GetACP','','I')
53
+
54
+ module Readline
55
+ $iconv_sj_to_u8 = Iconv.new('UTF-8', "CP#{$wGetACP.call()}")
56
+ alias :old_readline :readline
57
+ def readline(*a)
58
+ str = old_readline(*a)
59
+ out = ''
60
+ loop do
61
+ begin
62
+ out << $iconv_sj_to_u8.iconv(str)
63
+ break
64
+ rescue Iconv::Failure
65
+ out << "#{$!.success}?"
66
+ str = $!.failed[1..-1]
67
+ end
68
+ end
69
+ return out
70
+ end
71
+ module_function :old_readline, :readline
72
+ end
73
+
74
+ $wSetConsoleTextAttribute = Win32API.new('kernel32','SetConsoleTextAttribute','II','I')
75
+ $wGetConsoleScreenBufferInfo = Win32API.new("kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'i')
76
+ $wGetStdHandle = Win32API.new('kernel32','GetStdHandle','I','I')
77
+ $wGetACP = Win32API.new('kernel32','GetACP','','I')
78
+
79
+ $hStdOut = $wGetStdHandle.call(0xFFFFFFF5)
80
+ lpBuffer = ' ' * 22
81
+ $wGetConsoleScreenBufferInfo.call($hStdOut, lpBuffer)
82
+ $oldColor = lpBuffer.unpack('SSSSSssssSS')[4]
83
+
84
+ $colorMap = {
85
+ 0 => 0x07|0x00|0x00|0x00, # black/white
86
+ 37 => 0x08|0x00|0x00|0x00, # white/intensity
87
+ 31 => 0x04|0x08|0x00|0x00, # red/red
88
+ 32 => 0x02|0x08|0x00|0x00, # green/green
89
+ 33 => 0x06|0x08|0x00|0x00, # yellow/yellow
90
+ 34 => 0x01|0x08|0x00|0x00, # blue/blue
91
+ 35 => 0x05|0x08|0x00|0x00, # magenta/purple
92
+ 36 => 0x03|0x08|0x00|0x00, # cyan/aqua
93
+ 39 => 0x07, # default
94
+ 40 => 0x00|0x00|0xf0|0x00, # background:white
95
+ 41 => 0x07|0x00|0x40|0x00, # background:red
96
+ 42 => 0x07|0x00|0x20|0x00, # background:green
97
+ 43 => 0x07|0x00|0x60|0x00, # background:yellow
98
+ 44 => 0x07|0x00|0x10|0x00, # background:blue
99
+ 45 => 0x07|0x00|0x50|0x80, # background:magenta
100
+ 46 => 0x07|0x00|0x30|0x80, # background:cyan
101
+ 47 => 0x07|0x00|0x70|0x80, # background:gray
102
+ 49 => 0x70, # default
103
+ 90 => 0x07|0x00|0x00|0x00, # erase/white
104
+ }
105
+ $iconv_u8_to_sj = Iconv.new("CP#{$wGetACP.call()}", 'UTF-8')
106
+ def print(str)
107
+ str.to_s.gsub("\xef\xbd\x9e", "\xe3\x80\x9c").split(/(\e\[\d*[a-zA-Z])/).each do |token|
108
+ case token
109
+ when /\e\[(\d+)m/
110
+ $wSetConsoleTextAttribute.call $hStdOut, $colorMap[$1.to_i].to_i
111
+ when /\e\[\d*[a-zA-Z]/
112
+ # do nothing
113
+ else
114
+ loop do
115
+ begin
116
+ STDOUT.print $iconv_u8_to_sj.iconv(token)
117
+ break
118
+ rescue Iconv::Failure
119
+ STDOUT.print "#{$!.success}?"
120
+ token = $!.failed[1..-1]
121
+ end
122
+ end
123
+ end
124
+ end
125
+ $wSetConsoleTextAttribute.call $hStdOut, $oldColor
126
+ $iconv_u8_to_sj.iconv(nil)
127
+ end
128
+ def puts(str)
129
+ print str
130
+ STDOUT.puts
131
+ end
132
+ end
133
+
134
+ unless Array.instance_methods.include?('take')
135
+ class Array
136
+ def take(n) self[0...n] end
137
+ end
138
+ end
139
+
140
+ unless Symbol.instance_methods.include?('to_proc')
141
+ class Symbol
142
+ def to_proc
143
+ Proc.new { |*args| args.shift.__send__(self, *args) }
144
+ end
145
+ end
146
+ end
147
+
148
+ require 'highline'
149
+ def create_highline
150
+ HighLine.track_eof = false
151
+ if $stdin.respond_to?(:getbyte) # for ruby1.9
152
+ require 'delegate'
153
+ stdin_for_highline = SimpleDelegator.new($stdin)
154
+ def stdin_for_highline.getc
155
+ getbyte
156
+ end
157
+ else
158
+ stdin_for_highline = $stdin
159
+ end
160
+ HighLine.new(stdin_for_highline)
161
+ end
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ class Task
5
+ attr_accessor :name, :exec_at, :exec_proc, :interval, :work
6
+ def initialize(args = {}, &block)
7
+ @name = args[:name]
8
+ @exec_at = Time.now + (args[:after] || 0)
9
+ @interval = args[:interval]
10
+ @exec_proc = block || lambda {}
11
+ @work = true
12
+ end
13
+ def execute
14
+ exec_proc.call(self) if work
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,116 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ class TaskManager
5
+
6
+ INTERVAL = 1
7
+
8
+ def initialize()
9
+ @tasks = {}
10
+ @work = true
11
+ @mutex = Mutex.new
12
+ @pause = false
13
+ end
14
+
15
+ def pause
16
+ @pause = true
17
+ end
18
+
19
+ def resume
20
+ @pause = false
21
+ end
22
+
23
+ def kill
24
+ @work = false
25
+ end
26
+
27
+ def run
28
+ Thread.new do
29
+ while @work
30
+ step unless @pause
31
+ sleep INTERVAL
32
+ end
33
+ end
34
+ end
35
+
36
+ def step
37
+ pull_due_tasks.each do |task|
38
+ invoke_and_wait do
39
+ task.execute
40
+ end
41
+ end
42
+ end
43
+
44
+ def invoke_later
45
+ Thread.new do
46
+ invoke_and_wait do
47
+ yield
48
+ end
49
+ end
50
+ end
51
+
52
+ def invoke_and_wait(&block)
53
+ synchronize do
54
+ begin
55
+ yield
56
+ rescue Exception => e
57
+ Termtter::Client.handle_error(e)
58
+ end
59
+ end
60
+ end
61
+
62
+ def add_task(args = {}, &block)
63
+ synchronize do
64
+ task = Task.new(args, &block)
65
+ @tasks[task.name || task.object_id] = task
66
+ end
67
+ end
68
+
69
+ def get_task(key)
70
+ synchronize do
71
+ @tasks[key]
72
+ end
73
+ end
74
+
75
+ def delete_task(key)
76
+ synchronize do
77
+ @tasks.delete(key)
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def synchronize
84
+ unless Thread.current == @thread_in_sync
85
+ @mutex.synchronize do
86
+ @thread_in_sync = Thread.current
87
+ yield
88
+ end
89
+ else
90
+ yield
91
+ end
92
+ end
93
+
94
+ def pull_due_tasks()
95
+ synchronize do
96
+ time_now = Time.now
97
+ due_tasks = []
98
+ @tasks.delete_if do |key, task|
99
+ if task.work && task.exec_at <= time_now
100
+ due_tasks << task
101
+ if task.interval
102
+ task.exec_at = time_now + task.interval
103
+ false
104
+ else
105
+ true
106
+ end
107
+ else
108
+ false
109
+ end
110
+ end
111
+ return due_tasks
112
+ end
113
+ end
114
+
115
+ end
116
+ end