tool_pouch 0.0.34

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.
@@ -0,0 +1,27 @@
1
+ module ToolPouch::Mathema
2
+ def self.tax_for_amount(amount, region, options={})
3
+ options.reverse_merge!(:time => Time.now)
4
+
5
+ case region
6
+ when 'quebec' then get_quebec_taxes(amount, options)
7
+ else []
8
+ end
9
+ end
10
+
11
+ def self.get_quebec_taxes(amount, options={})
12
+ options.reverse_merge!(:time => Time.now)
13
+
14
+ gst = { :id => 'gst', :nature => 'tax', :rate => 0.05 }
15
+ qst = { :id => 'qst', :nature => 'tax' }
16
+
17
+ qst[:rate] = case
18
+ when options[:time] < Time.parse('2012-01-01') then 0.085
19
+ else 0.095
20
+ end
21
+
22
+ gst[:amount] = (amount * gst[:rate]).round
23
+ qst[:amount] = ((amount + gst[:amount]) * qst[:rate]).round
24
+
25
+ return [gst, qst]
26
+ end
27
+ end
@@ -0,0 +1,279 @@
1
+ require 'addressable/uri'
2
+
3
+ module ToolPouch::Trail
4
+ def self.build_querystring(form_data)
5
+ query_string = ''
6
+ if form_data
7
+ params = []
8
+ if not form_data.empty?
9
+ form_data.each do |d|
10
+ if d[1].is_a?(Hash)
11
+ d[1].each do |key, value|
12
+ params << "#{d[0]}[#{key}]=#{CGI.escape(CGI.unescape(value.to_s))}"
13
+ end
14
+ else
15
+ params << "#{d[0]}=#{CGI.escape(CGI.unescape(d[1].to_s))}"
16
+ end
17
+ end
18
+ end
19
+ query_string = params.sort.join('&')
20
+ end
21
+ return query_string
22
+ end
23
+
24
+ def self.directories(path)
25
+ directory = ''
26
+ if path and path.class == String
27
+ last_slash_index = path.rindex('/')
28
+
29
+ if last_slash_index.to_i > 0
30
+ directory = path[0, last_slash_index]
31
+ end
32
+ end
33
+
34
+ return directory
35
+ end
36
+
37
+ def self.extension(path)
38
+ file_extension = ''
39
+ if path
40
+ file_extension_with_dot = File.extname(path)
41
+ if not file_extension_with_dot.empty?
42
+ file_extension = file_extension_with_dot[1, file_extension_with_dot.length]
43
+ end
44
+ end
45
+ return file_extension
46
+ end
47
+
48
+ def self.filename_without_extension(path, options={})
49
+ options.reverse_merge!(:full_path => true)
50
+
51
+ filename = options[:full_path] ? path : filename_without_path(path)
52
+
53
+ return (filename and filename.rindex('.')) ? filename[0, filename.rindex('.')] : filename
54
+ end
55
+
56
+ def self.filename_without_path(path)
57
+ filename_without_path = path
58
+ if path
59
+ #Handle properly path without filename
60
+ if trailing_slash?(path)
61
+ filename_without_path = ''
62
+ else
63
+ filename_without_path = File.basename(path)
64
+ end
65
+ end
66
+ return filename_without_path
67
+ end
68
+
69
+ def self.get_domain(url)
70
+ domain = nil
71
+ if url
72
+ # add protocol so it becomes a valid URI
73
+ url = ('http://' + url) unless url =~ /^https?:\/\//
74
+
75
+ # remove %'s, which we don't need and could cause an URL to become invalid
76
+ url.gsub!('%', '')
77
+
78
+ begin
79
+ # get the host part, and remove the www. if present
80
+ domain = Addressable::URI.parse(url).host.gsub(/^www\./i, '')
81
+ rescue
82
+ ""
83
+ end
84
+ end
85
+ return domain
86
+ end
87
+
88
+ def self.get_all_files_with_extension(path, extensions=[])
89
+ extensions = [extensions] unless extensions.is_a? Array
90
+ extensions.collect!{|x| ".#{x}"}
91
+
92
+ files = []
93
+ Find.find(path) { |f| files << f if File.file?(f) and extensions.include? File.extname(f) }
94
+
95
+ return files
96
+ end
97
+
98
+ def self.get_file(root, filenames)
99
+ files = get_files(root, filenames)
100
+
101
+ return files.empty? ? nil : files.first
102
+ end
103
+
104
+ def self.get_files(root, filenames, options={})
105
+ options.reverse_merge!(:perfect_match => true)
106
+
107
+ filenames = [filenames] unless filenames.is_a? Array
108
+ root = slice_trailing_slash(root)
109
+ files = []
110
+
111
+ Find.find(root) do |f|
112
+ if options[:perfect_match]
113
+ files << f.gsub(root + '/', '') if File.file?(f) and filenames.include?(filename_without_path(f))
114
+ else
115
+ found = false
116
+ filename_only = filename_without_path(f)
117
+ filenames.each{ |m| found = true if filename_only.match(/#{m}/) }
118
+ files << f.gsub(root + '/', '') if File.file?(f) and found
119
+ end
120
+ end
121
+
122
+ return files
123
+ end
124
+
125
+ def self.get_first_file_with_extension(path, extensions=[])
126
+ return get_all_files_with_extension(path, extensions).first
127
+ end
128
+
129
+ def self.get_first_match(path, value)
130
+ File.open(path) do |io|
131
+ io.each do |line|
132
+ line.chomp!
133
+ return line if line.include? value
134
+ end
135
+ end
136
+
137
+ return nil
138
+ end
139
+
140
+ def self.get_querystring(url)
141
+ raw = URI.split(url)[7]
142
+
143
+ qs = {}
144
+
145
+ if raw
146
+ raw.split('&').each do |full_param|
147
+ key, value = full_param.split('=')
148
+ qs[key] = value
149
+ end
150
+ end
151
+
152
+ return qs
153
+ end
154
+
155
+ def self.get_section(url, options={})
156
+ section = nil
157
+ if url
158
+ if options[:base_path]
159
+ section = url.gsub(options[:base_path] + '/', '').split('/')[0]
160
+ else
161
+ section = url.split('/')[-1, 1].to_s
162
+ end
163
+
164
+ # Remove format if it was specified
165
+ section = File.basename(section, '.*')
166
+ end
167
+
168
+ return section
169
+ end
170
+
171
+ def self.is_file_with_extension?(path)
172
+ file_with_extension = false
173
+ if path
174
+ extension = File.extname(path)
175
+ if extension and not extension.empty?
176
+ file_with_extension = true
177
+ end
178
+ end
179
+ return file_with_extension
180
+ end
181
+
182
+ def self.is_url?(path)
183
+ return (path.to_s.include?('http://') or path.to_s.include?('https://')) ? true : false
184
+ end
185
+
186
+ def self.last_directory(path)
187
+ path += 'dummystring' if trailing_slash?(path)
188
+
189
+ return path.split('/')[-2, 1]
190
+ end
191
+
192
+ def self.open_and_merge(directories, options={})
193
+ options.reverse_merge!(:extensions => '')
194
+
195
+ directories = [directories] if not directories.is_a? Array
196
+
197
+ case options[:extensions]
198
+ when 'yml' then content = HashTree.new
199
+ else content = []
200
+ end
201
+
202
+ directories.each do |directory|
203
+ Find.find(directory) do |p|
204
+ next unless File.file?(p)
205
+
206
+ case options[:extensions]
207
+ when 'yml' then content.merge(yml_content(p))
208
+ when 'xml' then content << File.open(p, "r").readlines.join
209
+ end
210
+ end
211
+ end
212
+
213
+ case options[:extensions]
214
+ when 'yml' then content.get
215
+ else return content.join("\n")
216
+ end
217
+ end
218
+
219
+ def self.order_querystring_alpha(url)
220
+ ordered_url = url
221
+ if url and not url.strip.empty?
222
+ qs = URI.split(url)[7]
223
+
224
+ if qs
225
+ ordered_url = url.split('?')[0] + '?'
226
+ parameters = qs.split('&')
227
+ escaped_parameters = []
228
+ # Escape each parameter to ensure coherence with build_query_string
229
+ for parameter in parameters
230
+ name_value = parameter.split('=')
231
+ if name_value.size == 2
232
+ escaped_value = CGI.escape(CGI.unescape(name_value[1]))
233
+ escaped_parameters << "#{name_value[0]}=#{escaped_value}"
234
+ else
235
+ escaped_parameters << "#{name_value[0]}"
236
+ end
237
+ end
238
+ ordered_url << escaped_parameters.sort.join('&')
239
+ return ordered_url
240
+ end
241
+ end
242
+ return url
243
+ end
244
+
245
+ def self.partial_exists?(partial_short_path)
246
+ short_path = partial_short_path.split('/')
247
+ short_path[short_path.length-1] = '_' + short_path.last
248
+ return File.exists?(RAILS_ROOT + '/app/views' + short_path.join('/') + '.html.erb')
249
+ end
250
+
251
+ def self.refresh_file_content(path, content)
252
+ FileUtils.mkdir_p directories(path)
253
+ FileUtils.rm(path) if File.exists?(path)
254
+ File.open(path, 'w') {|f| f.write(content) }
255
+ end
256
+
257
+ def self.slice_trailing_slash(path)
258
+ return (trailing_slash?(path)) ? path.chop : path
259
+ end
260
+
261
+ def self.strip_scheme(uri)
262
+ uri.sub(/^#{Addressable::URI.parse(URI.encode(uri)).scheme}:\/\//,"")
263
+ end
264
+
265
+ def self.trailing_slash?(path)
266
+ trailing_slash = false
267
+ if path and path.length > 0
268
+ if path.slice(-1,1) == '/'
269
+ trailing_slash = true
270
+ end
271
+ end
272
+
273
+ return trailing_slash
274
+ end
275
+
276
+ def self.yml_content(file)
277
+ return YAML.load_file(file)
278
+ end
279
+ end
@@ -0,0 +1,98 @@
1
+ require "addressable/uri"
2
+
3
+ #*************************************************************************************
4
+ # TOCOMMENT
5
+ #*************************************************************************************
6
+ module ToolPouch::Transistor
7
+ def self.get(raw_url, options={})
8
+ raw_url += '?' + ToolPouch::Trail.build_querystring(options.delete(:params)) if options[:params]
9
+
10
+ return send_request(:get, raw_url, options)
11
+ end
12
+
13
+ def self.get_head(url)
14
+ begin
15
+ uri = parse_uri(url)
16
+ res = Net::HTTP.start(uri.host, uri.port)
17
+ rescue
18
+ return false
19
+ end
20
+
21
+ return (res and res.head(url) ? res.head(url) : false)
22
+ end
23
+
24
+ def self.parse_uri(uri)
25
+ parsed_uri = Addressable::URI.parse(uri)
26
+ parsed_uri.port = 443 if parsed_uri.scheme == 'https'
27
+
28
+ return parsed_uri
29
+ end
30
+
31
+ def self.post(raw_url, options={})
32
+ send_request(:post, raw_url, options)
33
+ end
34
+
35
+ def self.send_request(method, raw_url, options={})
36
+ options.reverse_merge!(body: nil, content_type: nil, login: nil, params: {}, password: nil, timeout: nil)
37
+
38
+ url = parse_uri raw_url
39
+
40
+ request = "Net::HTTP::#{method.to_s.camelize}".constantize.new(url.request_uri)
41
+ request.basic_auth(options[:login], options[:password]) if options[:login]
42
+ request.body = options[:body] if options[:body]
43
+ request.content_type = options[:content_type] if options[:content_type]
44
+ request.set_form_data(options[:params]) if not options[:params].empty?
45
+
46
+ return start_net_http(url, request, timeout: options[:timeout])
47
+ end
48
+
49
+ def self.start_net_http(url, request, options={})
50
+ http = Net::HTTP.new(url.host, url.port)
51
+
52
+ if http
53
+ http.use_ssl = (url.scheme == 'https')
54
+ http.read_timeout = options[:timeout] if options[:timeout]
55
+
56
+ return http.start { |r| r.request(request) }
57
+ end
58
+
59
+ return nil
60
+ end
61
+
62
+ #*************************************************************************************
63
+ # Digest communication module
64
+ #*************************************************************************************
65
+ module Digest
66
+ def self.delete(url, password, form_data={})
67
+ form_data['_method'] = 'delete'
68
+
69
+ return post_request_digest(url, password, form_data)
70
+ end
71
+
72
+ def self.get(url, password)
73
+ url_digest = ToolPouch::Locksmith.build_digest_request(url, password)
74
+
75
+ if url_digest
76
+ uri = parse_uri url_digest
77
+
78
+ return Net::HTTP.get_response(uri) if uri
79
+ end
80
+
81
+ return nil
82
+ end
83
+
84
+ def self.post(url, password, form_data={})
85
+ url << ('?' + ToolPouch::Trail.build_querystring(form_data)) if not form_data.empty?
86
+
87
+ url_digest = ToolPouch::Locksmith.build_digest_request(url, password)
88
+
89
+ return Net::HTTP.post_form(parse_uri(url_digest), ToolPouch::Trail.get_querystring(url_digest))
90
+ end
91
+
92
+ def self.put(url, password, form_data={})
93
+ form_data['_method'] = 'put'
94
+
95
+ return post(url, password, form_data)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ module ToolPouch
2
+ VERSION = "0.0.34"
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'tool_pouch'
2
+
3
+ Time.zone = 'Eastern Time (US & Canada)'
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe ToolPouch::Krono do
4
+ describe '#is_iso8601?' do
5
+ it "recognizes valid date" do
6
+ ToolPouch::Krono.is_iso8601?('2000-01-01T00:00:00-05:00').should be_true
7
+ ToolPouch::Krono.is_iso8601?('1900-01-01T00:00:00-05:00').should be_true
8
+ ToolPouch::Krono.is_iso8601?('1800-01-01T00:00:00-05:00').should be_true
9
+ ToolPouch::Krono.is_iso8601?('1700-01-01T00:00:00-05:00').should be_true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,105 @@
1
+ require "spec_helper"
2
+ require 'addressable/uri'
3
+
4
+ describe ToolPouch::Locksmith do
5
+ let (:password) {'ThiZizAS3cr3T'}
6
+
7
+ describe 'digesting an URL' do
8
+ it "works without an URL authority" do
9
+ url = "/home"
10
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
11
+
12
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
13
+ end
14
+
15
+ it "works without an URL query" do
16
+ url = "http://example.org"
17
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
18
+
19
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
20
+ end
21
+
22
+ it "works regardless of the scheme use (http vs https)" do
23
+ url = "https://example.org"
24
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
25
+ digested_url.gsub! /https:\/\//, 'http://'
26
+
27
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
28
+ end
29
+
30
+ it "allows specifying a lifespan" do
31
+ url = "http://example.org"
32
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password, 30.seconds)
33
+
34
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
35
+ end
36
+
37
+ it "works with an URL query" do
38
+ url = "http://example.org?key=value"
39
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
40
+
41
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
42
+ end
43
+
44
+ it "orders the query parameters" do
45
+ url = "http://example.org?b=1&c=1&a=1"
46
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
47
+
48
+ digested_url.should match /http:\/\/example.org\?a=1&b=1&c=1/
49
+ end
50
+
51
+ it "works regardless of the orders of URL query parameters" do
52
+ url = "http://example.org?b=1&c=1&a=1"
53
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
54
+ digested_url_with_different_orders = digested_url.gsub /a=1&b=1&c=1/, 'c=1&a=1&b=1'
55
+
56
+ ToolPouch::Locksmith.check_digest_request(digested_url_with_different_orders, password).should be_true
57
+ end
58
+
59
+ it "works regardless of using percent encoded characters or real characters in the query" do
60
+ url = "http://example.org?key=%C3%97"
61
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
62
+ unescaped_digested_url = digested_url.gsub /%C3%97/, '×'
63
+ ToolPouch::Locksmith.check_digest_request(unescaped_digested_url, password).should be_true
64
+
65
+ url = "http://example.org?key=×"
66
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
67
+ escaped_digested_url = digested_url.gsub /×/, '%C3%97'
68
+ ToolPouch::Locksmith.check_digest_request(escaped_digested_url, password).should be_true
69
+ end
70
+
71
+ it "does not allow token hacking" do
72
+ url = "http://example.org?key=value"
73
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
74
+ hacked_url = digested_url.gsub /token=/, 'token=X'
75
+
76
+ ToolPouch::Locksmith.check_digest_request(hacked_url, password).should be_false
77
+ end
78
+
79
+ it "does not allow an expired URL" do
80
+ url = "http://example.org"
81
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password, 2.seconds)
82
+ sleep 3
83
+
84
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_false
85
+ end
86
+
87
+ it "works regardless of the port used" do
88
+ url = "https://example.org:443"
89
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
90
+ digested_url.gsub! /:443/, ''
91
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
92
+
93
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
94
+ digested_url.gsub! /:443/, ':80'
95
+ ToolPouch::Locksmith.check_digest_request(digested_url, password).should be_true
96
+ end
97
+
98
+ it "keeps the port in the generated URL" do
99
+ url = "https://example.org:443"
100
+ digested_url = ToolPouch::Locksmith.build_digest_request(url, password)
101
+ digested_url.should match /:443/
102
+ end
103
+ end
104
+
105
+ end