kmts 2.0.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 (72) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGELOG +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +29 -0
  5. data/LICENSE +202 -0
  6. data/README.md +64 -0
  7. data/README.rdoc +14 -0
  8. data/Rakefile +5 -0
  9. data/bin/km_send +35 -0
  10. data/doc/Accept.html +546 -0
  11. data/doc/Gemfile.html +110 -0
  12. data/doc/Hash.html +283 -0
  13. data/doc/Helper.html +318 -0
  14. data/doc/KMError.html +159 -0
  15. data/doc/KMTS.html +493 -0
  16. data/doc/KMTS/IdentError.html +159 -0
  17. data/doc/KMTS/InitError.html +159 -0
  18. data/doc/KMTS/SaaS.html +451 -0
  19. data/doc/Object.html +211 -0
  20. data/doc/README_rdoc.html +122 -0
  21. data/doc/Rakefile.html +111 -0
  22. data/doc/String.html +244 -0
  23. data/doc/bin/km_send.html +54 -0
  24. data/doc/created.rid +15 -0
  25. data/doc/images/brick.png +0 -0
  26. data/doc/images/brick_link.png +0 -0
  27. data/doc/images/bug.png +0 -0
  28. data/doc/images/bullet_black.png +0 -0
  29. data/doc/images/bullet_toggle_minus.png +0 -0
  30. data/doc/images/bullet_toggle_plus.png +0 -0
  31. data/doc/images/date.png +0 -0
  32. data/doc/images/find.png +0 -0
  33. data/doc/images/loadingAnimation.gif +0 -0
  34. data/doc/images/macFFBgHack.png +0 -0
  35. data/doc/images/package.png +0 -0
  36. data/doc/images/page_green.png +0 -0
  37. data/doc/images/page_white_text.png +0 -0
  38. data/doc/images/page_white_width.png +0 -0
  39. data/doc/images/plugin.png +0 -0
  40. data/doc/images/ruby.png +0 -0
  41. data/doc/images/tag_green.png +0 -0
  42. data/doc/images/wrench.png +0 -0
  43. data/doc/images/wrench_orange.png +0 -0
  44. data/doc/images/zoom.png +0 -0
  45. data/doc/index.html +142 -0
  46. data/doc/js/darkfish.js +116 -0
  47. data/doc/js/jquery.js +32 -0
  48. data/doc/js/quicksearch.js +114 -0
  49. data/doc/js/thickbox-compressed.js +10 -0
  50. data/doc/lib/km/saas_rb.html +54 -0
  51. data/doc/lib/km/version_rb.html +52 -0
  52. data/doc/lib/km_rb.html +60 -0
  53. data/doc/rdoc.css +730 -0
  54. data/doc/spec/accept_rb.html +62 -0
  55. data/doc/spec/km_old_rb.html +54 -0
  56. data/doc/spec/km_saas_spec_rb.html +56 -0
  57. data/doc/spec/km_send_spec_rb.html +54 -0
  58. data/doc/spec/km_spec_rb.html +54 -0
  59. data/doc/spec/setup_rb.html +60 -0
  60. data/doc/spec/watchr_rb.html +52 -0
  61. data/kmts.gemspec +26 -0
  62. data/lib/kmts.rb +245 -0
  63. data/lib/kmts/saas.rb +39 -0
  64. data/lib/kmts/version.rb +3 -0
  65. data/spec/accept.rb +91 -0
  66. data/spec/km_old.rb +105 -0
  67. data/spec/km_saas_spec.rb +107 -0
  68. data/spec/km_send_spec.rb +98 -0
  69. data/spec/km_spec.rb +175 -0
  70. data/spec/setup.rb +77 -0
  71. data/spec/watchr.rb +3 -0
  72. metadata +190 -0
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: accept.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 09:44:35 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>socket</li>
35
+
36
+ <li>rubygems</li>
37
+
38
+ <li>json</li>
39
+
40
+ <li>uri</li>
41
+
42
+ <li>cgi</li>
43
+
44
+ </ul>
45
+ </dd>
46
+
47
+
48
+
49
+ </dl>
50
+ </div>
51
+
52
+ <div id="documentation">
53
+
54
+ <div class="description">
55
+ <h2>Description</h2>
56
+
57
+ </div>
58
+
59
+ </div>
60
+ </body>
61
+ </html>
62
+
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: km_old.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 09:43:26 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>setup</li>
35
+
36
+ </ul>
37
+ </dd>
38
+
39
+
40
+
41
+ </dl>
42
+ </div>
43
+
44
+ <div id="documentation">
45
+
46
+ <div class="description">
47
+ <h2>Description</h2>
48
+
49
+ </div>
50
+
51
+ </div>
52
+ </body>
53
+ </html>
54
+
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: km_saas_spec.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 12:02:23 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>setup</li>
35
+
36
+ <li>km/saas</li>
37
+
38
+ </ul>
39
+ </dd>
40
+
41
+
42
+
43
+ </dl>
44
+ </div>
45
+
46
+ <div id="documentation">
47
+
48
+ <div class="description">
49
+ <h2>Description</h2>
50
+
51
+ </div>
52
+
53
+ </div>
54
+ </body>
55
+ </html>
56
+
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: km_send_spec.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 11:57:15 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>setup</li>
35
+
36
+ </ul>
37
+ </dd>
38
+
39
+
40
+
41
+ </dl>
42
+ </div>
43
+
44
+ <div id="documentation">
45
+
46
+ <div class="description">
47
+ <h2>Description</h2>
48
+
49
+ </div>
50
+
51
+ </div>
52
+ </body>
53
+ </html>
54
+
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: km_spec.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 11:12:57 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>setup</li>
35
+
36
+ </ul>
37
+ </dd>
38
+
39
+
40
+
41
+ </dl>
42
+ </div>
43
+
44
+ <div id="documentation">
45
+
46
+ <div class="description">
47
+ <h2>Description</h2>
48
+
49
+ </div>
50
+
51
+ </div>
52
+ </body>
53
+ </html>
54
+
@@ -0,0 +1,60 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: setup.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 09:59:12 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>ap</li>
35
+
36
+ <li>km</li>
37
+
38
+ <li>fileutils</li>
39
+
40
+ <li>accept</li>
41
+
42
+ </ul>
43
+ </dd>
44
+
45
+
46
+
47
+ </dl>
48
+ </div>
49
+
50
+ <div id="documentation">
51
+
52
+ <div class="description">
53
+ <h2>Description</h2>
54
+
55
+ </div>
56
+
57
+ </div>
58
+ </body>
59
+ </html>
60
+
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: watchr.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2011-02-04 16:43:58 -0800</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ </ul>
35
+ </dd>
36
+
37
+
38
+
39
+ </dl>
40
+ </div>
41
+
42
+ <div id="documentation">
43
+
44
+ <div class="description">
45
+ <h2>Description</h2>
46
+
47
+ </div>
48
+
49
+ </div>
50
+ </body>
51
+ </html>
52
+
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/kmts/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "kmts"
6
+ s.version = KMTS::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["KISSmetrics"]
9
+ s.email = ["support@kissmetrics.com"]
10
+ s.homepage = "https://github.com/kissmetrics/kmts"
11
+ s.summary = "KISSmetrics threadsafe ruby API gem"
12
+ s.description = "KISSmetrics threadsafe ruby API gem"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "kissmetrics"
16
+
17
+ s.add_development_dependency "bundler", ">= 1.0.0"
18
+ s.add_development_dependency "rspec", "~> 2.4.0"
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "json"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
25
+ s.require_path = 'lib'
26
+ end
@@ -0,0 +1,245 @@
1
+ require 'uri'
2
+ require 'socket'
3
+ require 'net/http'
4
+ require 'fileutils'
5
+ require 'kmts/saas'
6
+
7
+ class KMError < StandardError; end
8
+
9
+ class KMTS
10
+ @key = nil
11
+ @logs = {}
12
+ @host = 'trk.kissmetrics.com:80'
13
+ @log_dir = '/tmp'
14
+ @to_stderr = true
15
+ @use_cron = false
16
+ @dryrun = false
17
+
18
+ class << self
19
+ class IdentError < StandardError; end
20
+ class InitError < StandardError; end
21
+
22
+ def init(key, options={})
23
+ default = {
24
+ :host => @host,
25
+ :log_dir => @log_dir,
26
+ :to_stderr => @to_stderr,
27
+ :use_cron => @use_cron,
28
+ :dryrun => @dryrun,
29
+ :env => set_env,
30
+ }
31
+ options = default.merge(options)
32
+
33
+ begin
34
+ @key = key
35
+ @host = options[:host]
36
+ @log_dir = options[:log_dir]
37
+ @use_cron = options[:use_cron]
38
+ @to_stderr = options[:to_stderr]
39
+ @dryrun = options[:dryrun]
40
+ @env = options[:env]
41
+ log_dir_writable?
42
+ rescue Exception => e
43
+ log_error(e)
44
+ end
45
+ end
46
+
47
+ def set_env
48
+ @env = Rails.env if defined? Rails
49
+ @env ||= ENV['RACK_ENV']
50
+ @env ||= 'production'
51
+ end
52
+
53
+ def record(id, action, props={})
54
+ props = hash_keys_to_str(props)
55
+ begin
56
+ return unless is_initialized?
57
+ return set(id, action) if action.class == Hash
58
+
59
+ props.update('_n' => action)
60
+ generate_query('e', props, id)
61
+ rescue Exception => e
62
+ log_error(e)
63
+ end
64
+ end
65
+
66
+ def alias(name, alias_to)
67
+ begin
68
+ return unless is_initialized?
69
+ generate_query('a', { '_n' => alias_to, '_p' => name }, false)
70
+ rescue Exception => e
71
+ log_error(e)
72
+ end
73
+ end
74
+
75
+ def set(id, data)
76
+ begin
77
+ return unless is_initialized?
78
+ generate_query('s', data, id)
79
+ rescue Exception => e
80
+ log_error(e)
81
+ end
82
+ end
83
+
84
+ def send_logged_queries # :nodoc:
85
+ line = nil
86
+ begin
87
+ query_log = log_name(:query_old)
88
+ query_log = log_name(:query) unless File.exists?(query_log)
89
+ return unless File.exists?(query_log) # can't find logfile to send
90
+ FileUtils.move(query_log, log_name(:send))
91
+ File.open(log_name(:send)) do |fh|
92
+ while not fh.eof?
93
+ begin
94
+ line = fh.readline.chomp
95
+ send_query(line)
96
+ rescue Exception => e
97
+ log_query(line) if line
98
+ log_error(e)
99
+ end
100
+ end
101
+ end
102
+ FileUtils.rm(log_name(:send))
103
+ rescue Exception => e
104
+ log_error(e)
105
+ end
106
+ end
107
+
108
+ def log_dir
109
+ @log_dir
110
+ end
111
+ def host
112
+ @host
113
+ end
114
+
115
+ # :stopdoc:
116
+ protected
117
+ def hash_keys_to_str(hash)
118
+ Hash[*hash.map { |k,v| k.class == Symbol ? [k.to_s,v] : [k,v] }.flatten] # convert all keys to strings
119
+ end
120
+ def reset
121
+ @id = nil
122
+ @key = nil
123
+ @logs = {}
124
+ @host = 'trk.kissmetrics.com:80'
125
+ @log_dir = '/tmp'
126
+ @to_stderr = true
127
+ @use_cron = false
128
+ @env = nil
129
+ @force = false
130
+ end
131
+
132
+ def log_name(type)
133
+ return @logs[type] if @logs[type]
134
+ fname = ''
135
+ env = @env ? "_#{@env}" : ''
136
+ case type
137
+ when :error
138
+ fname = "kissmetrics#{env}_error.log"
139
+ when :query
140
+ fname = "kissmetrics#{env}_query.log"
141
+ when :query_old # backwards compatibility
142
+ fname = "kissmetrics_query.log"
143
+ when :sent
144
+ fname = "kissmetrics#{env}_sent.log"
145
+ when :send
146
+ fname = Time.now.to_i.to_s + "kissmetrics_#{env}_sending.log"
147
+ end
148
+ @logs[type] = File.join(@log_dir,fname)
149
+ end
150
+
151
+ def log_query(msg)
152
+ log(:query,msg)
153
+ end
154
+
155
+ def log_sent(msg)
156
+ log(:sent,msg)
157
+ end
158
+
159
+ def log_send(msg)
160
+ log(:send,msg)
161
+ end
162
+
163
+ def log_error(error)
164
+ if defined?(HoptoadNotifier)
165
+ HoptoadNotifier.notify_or_ignore(KMError.new(error))
166
+ end
167
+ msg = Time.now.strftime("<%c> ") + error.message
168
+ $stderr.puts msg if @to_stderr
169
+ log(:error, msg)
170
+ rescue Exception # rescue incase hoptoad has issues
171
+ end
172
+
173
+ def log(type,msg)
174
+ begin
175
+ File.open(log_name(type), 'a') do |fh|
176
+ fh.flock(File::LOCK_EX)
177
+ fh.puts(msg)
178
+ end
179
+ rescue Exception => e
180
+ raise KMError.new(e) if type.to_s == 'query'
181
+ # just discard at this point otherwise
182
+ end
183
+ end
184
+
185
+
186
+ def generate_query(type, data, id = nil)
187
+ data = hash_keys_to_str(data)
188
+ query_arr = []
189
+ query = ''
190
+ data.update('_p' => id) if id
191
+ data.update('_k' => @key)
192
+ data.update '_d' => 1 if data['_t']
193
+ data['_t'] ||= Time.now.to_i
194
+
195
+ unsafe = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}]", false, 'N')
196
+
197
+ data.inject(query) do |query,key_val|
198
+ query_arr << key_val.collect { |i| URI.escape(i.to_s, unsafe) }.join('=')
199
+ end
200
+ query = '/' + type + '?' + query_arr.join('&')
201
+ if @use_cron
202
+ log_query(query)
203
+ else
204
+ begin
205
+ send_query(query)
206
+ rescue Exception => e
207
+ log_query(query)
208
+ log_error(e)
209
+ end
210
+ end
211
+ end
212
+
213
+ def send_query(line)
214
+ if @dryrun
215
+ log_sent(line)
216
+ else
217
+ begin
218
+ host,port = @host.split(':')
219
+ proxy = URI.parse(ENV['http_proxy'] || ENV['HTTP_PROXY'] || '')
220
+ res = Net::HTTP::Proxy(proxy.host, proxy.port, proxy.user, proxy.password).start(host, port) do |http|
221
+ http.get(line)
222
+ end
223
+ rescue Exception => e
224
+ raise KMError.new("#{e} for host #{@host}")
225
+ end
226
+ log_sent(line)
227
+ end
228
+ end
229
+
230
+ def log_dir_writable?
231
+ if not FileTest.writable? @log_dir
232
+ $stderr.puts("Could't open #{log_name(:query)} for writing. Does #{@log_dir} exist? Permissions?") if @to_stderr
233
+ end
234
+ end
235
+
236
+ def is_initialized?
237
+ if @key == nil
238
+ log_error InitError.new("Need to initialize first (KMTS::init <your_key>)")
239
+ return false
240
+ end
241
+ return true
242
+ end
243
+ # :startdoc:
244
+ end
245
+ end