gnip 0.4.2
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.
- data/README +144 -0
- data/Rakefile +53 -0
- data/TODO +72 -0
- data/bin/gnip +651 -0
- data/doc/api.html +1201 -0
- data/gemspec.rb +47 -0
- data/gnip-0.4.2.gem +0 -0
- data/lib/gnip.rb +71 -0
- data/lib/gnip/activity.rb +663 -0
- data/lib/gnip/api.rb +191 -0
- data/lib/gnip/arguments.rb +21 -0
- data/lib/gnip/blankslate.rb +5 -0
- data/lib/gnip/config.rb +144 -0
- data/lib/gnip/filter.rb +304 -0
- data/lib/gnip/list.rb +126 -0
- data/lib/gnip/options.rb +96 -0
- data/lib/gnip/orderedhash.rb +199 -0
- data/lib/gnip/publisher.rb +309 -0
- data/lib/gnip/resource.rb +301 -0
- data/lib/gnip/template.rb +44 -0
- data/lib/gnip/util.rb +120 -0
- data/sample/data/activity.yml +21 -0
- data/test/auth.rb +60 -0
- data/test/config.yml +2 -0
- data/test/data/activity.xml +14 -0
- data/test/data/activity_only_required.xml +4 -0
- data/test/data/activity_with_payload.xml +22 -0
- data/test/data/activity_with_place.xml +18 -0
- data/test/data/activity_with_place_wo_bounds.xml +36 -0
- data/test/data/activity_with_unbounded_media_urls.xml +44 -0
- data/test/data/activity_without_bounds.xml +24 -0
- data/test/helper.rb +115 -0
- data/test/helper.rb.bak +28 -0
- data/test/integration/auth.rb +12 -0
- data/test/integration/publisher.rb +86 -0
- data/test/lib/shoulda.rb +9 -0
- data/test/lib/shoulda/action_controller.rb +28 -0
- data/test/lib/shoulda/action_controller/helpers.rb +47 -0
- data/test/lib/shoulda/action_controller/macros.rb +277 -0
- data/test/lib/shoulda/action_controller/matchers.rb +37 -0
- data/test/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
- data/test/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
- data/test/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
- data/test/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
- data/test/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +77 -0
- data/test/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
- data/test/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
- data/test/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
- data/test/lib/shoulda/action_mailer.rb +10 -0
- data/test/lib/shoulda/action_mailer/assertions.rb +38 -0
- data/test/lib/shoulda/action_view.rb +10 -0
- data/test/lib/shoulda/action_view/macros.rb +56 -0
- data/test/lib/shoulda/active_record.rb +16 -0
- data/test/lib/shoulda/active_record/assertions.rb +69 -0
- data/test/lib/shoulda/active_record/helpers.rb +40 -0
- data/test/lib/shoulda/active_record/macros.rb +586 -0
- data/test/lib/shoulda/active_record/matchers.rb +42 -0
- data/test/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
- data/test/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
- data/test/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
- data/test/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
- data/test/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
- data/test/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
- data/test/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
- data/test/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
- data/test/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
- data/test/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
- data/test/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
- data/test/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
- data/test/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
- data/test/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
- data/test/lib/shoulda/assertions.rb +59 -0
- data/test/lib/shoulda/autoload_macros.rb +46 -0
- data/test/lib/shoulda/context.rb +304 -0
- data/test/lib/shoulda/helpers.rb +8 -0
- data/test/lib/shoulda/macros.rb +73 -0
- data/test/lib/shoulda/private_helpers.rb +20 -0
- data/test/lib/shoulda/proc_extensions.rb +14 -0
- data/test/lib/shoulda/rails.rb +13 -0
- data/test/lib/shoulda/rspec.rb +9 -0
- data/test/lib/shoulda/tasks.rb +3 -0
- data/test/lib/shoulda/tasks/list_tests.rake +29 -0
- data/test/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
- data/test/lib/shoulda/test_unit.rb +19 -0
- data/test/lib/xmlsimple.rb +1021 -0
- data/test/loader.rb +25 -0
- data/test/unit/activity.rb +26 -0
- data/test/unit/util.rb +39 -0
- metadata +198 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
module Gnip
|
|
2
|
+
class Resource
|
|
3
|
+
def Resource.default
|
|
4
|
+
@default ||= new
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def Resource.headers headers = {}
|
|
8
|
+
result = default_headers.dup
|
|
9
|
+
|
|
10
|
+
headers.each do |key, value|
|
|
11
|
+
key = key.to_s.downcase.split(%r/[_-]/).map{|part| part.capitalize}.join('-')
|
|
12
|
+
result[key] = value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
result
|
|
16
|
+
|
|
17
|
+
=begin
|
|
18
|
+
default_headers.dup.merge(headers).inject({}) do |final, (key, value)|
|
|
19
|
+
final[key.to_s.gsub(/_/, '-').capitalize] = value.to_s
|
|
20
|
+
final
|
|
21
|
+
end
|
|
22
|
+
=end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def Resource.default_headers
|
|
26
|
+
@default_headers ||= {
|
|
27
|
+
'Content-Type' => 'application/xml',
|
|
28
|
+
'User-Agent' => 'gnip.rb',
|
|
29
|
+
'Content-Encoding' => 'gzip',
|
|
30
|
+
'Accept-Encoding' => 'gzip',
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def Resource.compress(data)
|
|
35
|
+
writer = Zlib::GzipWriter.new(StringIO.new(result=''))
|
|
36
|
+
writer.write(data)
|
|
37
|
+
writer.close
|
|
38
|
+
result
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def Resource.uncompress(data)
|
|
42
|
+
Zlib::GzipReader.new(StringIO.new(data)).read
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
attr_accessor :config
|
|
46
|
+
|
|
47
|
+
def initialize(*args)
|
|
48
|
+
args, options = Gnip.args_for(args)
|
|
49
|
+
@config = args.shift || options.getopt(:config, Gnip.default.config)
|
|
50
|
+
which = options.getopt(:implementation, :restclient)
|
|
51
|
+
@implementation = Implementation.for(self, which)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def method_missing(m, *a, &b)
|
|
55
|
+
if @implementation.respond_to?(m)
|
|
56
|
+
@implementation.send(m, *a, &b)
|
|
57
|
+
else
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def Resource.method_missing(m, *a, &b)
|
|
63
|
+
if Implementation.respond_to?(m)
|
|
64
|
+
Implementation.send(m, *a, &b)
|
|
65
|
+
else
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def uri_for(*args)
|
|
71
|
+
args, options = Gnip.args_for(args)
|
|
72
|
+
uri = config.uri.dup
|
|
73
|
+
uri.path = "/#{ args.shift }".squeeze('/')
|
|
74
|
+
options.each{|k,v| uri.send "#{ k }=", v}
|
|
75
|
+
uri
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def [](*args, &block)
|
|
79
|
+
@implementation.send('[]', *args, &block)
|
|
80
|
+
end
|
|
81
|
+
alias_method 'endpoint', '[]'
|
|
82
|
+
alias_method '/', '[]'
|
|
83
|
+
|
|
84
|
+
# TODO - requires username and password?
|
|
85
|
+
#
|
|
86
|
+
class Implementation
|
|
87
|
+
class RestClient < Implementation
|
|
88
|
+
attr_accessor :interface
|
|
89
|
+
attr_accessor :resource
|
|
90
|
+
|
|
91
|
+
def initialize interface, options = {}
|
|
92
|
+
Gnip.options_for(options)
|
|
93
|
+
@interface = interface
|
|
94
|
+
uri = options.getopt(:uri, config.uri)
|
|
95
|
+
username = options.getopt(:username, config.username)
|
|
96
|
+
password = options.getopt(:password, config.password)
|
|
97
|
+
headers = options.getopt(:headers, default_headers)
|
|
98
|
+
@resource = ::RestClient::Resource.new(uri, :user => username, :password => password, :headers => headers)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def default_headers
|
|
102
|
+
{
|
|
103
|
+
:content_type => 'application/xml',
|
|
104
|
+
:user_agent => 'gnip.rb',
|
|
105
|
+
:content_encoding => 'gzip',
|
|
106
|
+
:accept_encoding => 'gzip',
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def compress(data, headers = {})
|
|
111
|
+
key = (resource.headers.keys + headers.keys).detect{|key| key.to_s =~ /^\s*content.encoding\s*$/i}
|
|
112
|
+
value = resource.headers[key] || headers[key] if key
|
|
113
|
+
( value.to_s =~ /gzip/ ? Util.compress(data) : data ).to_s
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def decompress(data)
|
|
117
|
+
Util.decompress(data.to_s).to_s
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def config
|
|
121
|
+
interface.config
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def uri
|
|
125
|
+
URI.parse resource.url.to_s
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def username
|
|
129
|
+
resource.user
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def password
|
|
133
|
+
resource.password
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def [] path
|
|
137
|
+
subresource = resource[relative_path(path)]
|
|
138
|
+
subclient = dup
|
|
139
|
+
subclient.resource = subresource
|
|
140
|
+
subclient
|
|
141
|
+
end
|
|
142
|
+
alias_method 'endpoint', '[]'
|
|
143
|
+
alias_method '/', '[]'
|
|
144
|
+
|
|
145
|
+
def for options = {}
|
|
146
|
+
Gnip.options_for(options)
|
|
147
|
+
path = options.getopt(:path)
|
|
148
|
+
if path
|
|
149
|
+
uri = URI.parse(resource.uri)
|
|
150
|
+
uri.path = absolute_path(path)
|
|
151
|
+
self.class.new(interface, :uri => uri, :username => username, :password => password)
|
|
152
|
+
else
|
|
153
|
+
raise ArgumentError
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class Error < ::StandardError
|
|
158
|
+
attr :error
|
|
159
|
+
def initialize message = nil, error = nil
|
|
160
|
+
super(message.to_s)
|
|
161
|
+
@error = error
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def wrapping_errors
|
|
166
|
+
begin
|
|
167
|
+
yield
|
|
168
|
+
rescue Exception => error
|
|
169
|
+
message = []
|
|
170
|
+
message << error.message if error.respond_to?(:message) rescue nil
|
|
171
|
+
message << error.response.body if error.respond_to?(:response) rescue nil
|
|
172
|
+
message = message.join(' #=> ')
|
|
173
|
+
raise Error.new(message, error)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
%w[ get delete post put ].each do |verb|
|
|
178
|
+
define_method(verb) do |*args|
|
|
179
|
+
Gnip.argify!(args)
|
|
180
|
+
headers = args.options
|
|
181
|
+
data = args.shift
|
|
182
|
+
|
|
183
|
+
args = []
|
|
184
|
+
args.push(compress(data, headers)) if data
|
|
185
|
+
args.push(headers)
|
|
186
|
+
|
|
187
|
+
wrapping_errors do
|
|
188
|
+
log_request(verb, data, headers)
|
|
189
|
+
log_response(resource.send(verb, *args))
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def inspect
|
|
195
|
+
options = resource.headers.dup.update(:username => username, :password => password)
|
|
196
|
+
"#{ resource.url }(#{ options.inspect })"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def absolute_path(*paths)
|
|
201
|
+
paths.join('/').squeeze('/').sub(%r|^/+|, '/')
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def relative_path(*paths)
|
|
205
|
+
absolute_path(*paths).sub(%r|^/+|, '')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def log_request verb, data = nil, headers = {}
|
|
209
|
+
log {
|
|
210
|
+
if data
|
|
211
|
+
data = data.size > log_max_size ? "#{ data[0,log_max_size] }...(#{ data.size }bytes)" : data
|
|
212
|
+
end
|
|
213
|
+
"\n#{ self.inspect }.#{ verb }(#{ data.inspect }, #{ headers.inspect })"
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def log_response response
|
|
218
|
+
log {
|
|
219
|
+
data = response.to_s
|
|
220
|
+
data = data.size > log_max_size ? "#{ data[0,log_max_size] }...(#{ data.size }bytes)" : data
|
|
221
|
+
"#{ data }"
|
|
222
|
+
}
|
|
223
|
+
response
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def Implementation.log= value
|
|
227
|
+
@@log =
|
|
228
|
+
case value
|
|
229
|
+
when STDERR, 'stderr', :stderr
|
|
230
|
+
STDERR
|
|
231
|
+
when STDOUT, 'stdout', :stdout
|
|
232
|
+
STDOUT
|
|
233
|
+
else
|
|
234
|
+
if respond_to?(:write)
|
|
235
|
+
value
|
|
236
|
+
else
|
|
237
|
+
fd = open(value, 'w')
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
ensure
|
|
241
|
+
@@log.sync = true if @@log.respond_to?(:sync)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def Implementation.log
|
|
245
|
+
unless defined?(@@log)
|
|
246
|
+
if value = ENV['GNIP_HTTP_LOG']
|
|
247
|
+
Implementation.log = value
|
|
248
|
+
else
|
|
249
|
+
@@log = nil
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
@@log
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def log &block
|
|
256
|
+
if Implementation.log and block
|
|
257
|
+
log.puts block.call
|
|
258
|
+
log.flush
|
|
259
|
+
else
|
|
260
|
+
Implementation.log
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def Implementation.log_max_size
|
|
265
|
+
unless defined?(@@log_max_size)
|
|
266
|
+
if value = ENV['GNIP_HTTP_LOG_MAX_SIZE']
|
|
267
|
+
Implementation.log_max_size = value
|
|
268
|
+
else
|
|
269
|
+
@@log_max_size = 4096
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
@@log_max_size
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def Implementation.log_max_size= value
|
|
276
|
+
@@log_max_size = Integer value
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def log_max_size
|
|
280
|
+
Implementation.log_max_size
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def Implementation.list
|
|
284
|
+
@list ||= [
|
|
285
|
+
RestClient
|
|
286
|
+
]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def Implementation.for endpoint, which
|
|
290
|
+
implementation =
|
|
291
|
+
case which = which.to_s.downcase.strip.to_sym
|
|
292
|
+
when :restclient
|
|
293
|
+
RestClient
|
|
294
|
+
else
|
|
295
|
+
raise ArgumentError, "unknown implementation #{ which }"
|
|
296
|
+
end
|
|
297
|
+
implementation.new(endpoint)
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Gnip
|
|
2
|
+
class Template < ERB
|
|
3
|
+
def Template.for(*args, &block)
|
|
4
|
+
new(*args, &block)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def initialize(*args, &block)
|
|
8
|
+
args, options = Gnip.args_for(args)
|
|
9
|
+
@context = options.getopt(:context, options.getopt(:object))
|
|
10
|
+
string = args.shift || block.call
|
|
11
|
+
super(Gnip.util.unindent(string), safe_mode=nil, trim_mode='%')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def expand context = nil, &block
|
|
15
|
+
context ||= block.binding if block
|
|
16
|
+
context ||= @context
|
|
17
|
+
raise ArgumentError, 'no context' unless context
|
|
18
|
+
context = context.instance_eval('binding') unless context.respond_to?('binding')
|
|
19
|
+
block.call(self) if block
|
|
20
|
+
result(context)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Xml < Template
|
|
24
|
+
Declaration = '<?xml version="1.0" encoding="UTF-8"?>'
|
|
25
|
+
|
|
26
|
+
def initialize(string = '', options = {}, &block)
|
|
27
|
+
Gnip.optify!(options)
|
|
28
|
+
|
|
29
|
+
declaration = options.getopt(:declaration)
|
|
30
|
+
case declaration
|
|
31
|
+
when TrueClass, FalseClass, NilClass
|
|
32
|
+
declaration = Declaration if declaration
|
|
33
|
+
else
|
|
34
|
+
declaration = declaration.to_s
|
|
35
|
+
end
|
|
36
|
+
string = "#{ declaration }\n#{ Gnip.util.unindent(string) }" if declaration
|
|
37
|
+
|
|
38
|
+
super(string, options, &block)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def Template.xml() Xml end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/gnip/util.rb
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module Gnip
|
|
2
|
+
module Util
|
|
3
|
+
def homedir
|
|
4
|
+
homedir =
|
|
5
|
+
catch :home do
|
|
6
|
+
["HOME", "USERPROFILE"].each do |key|
|
|
7
|
+
throw(:home, ENV[key]) if ENV[key]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
if ENV["HOMEDRIVE"] and ENV["HOMEPATH"]
|
|
11
|
+
throw(:home, "#{ ENV['HOMEDRIVE'] }:#{ ENV['HOMEPATH'] }")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
File.expand_path("~") rescue(File::ALT_SEPARATOR ? "C:/" : "/")
|
|
15
|
+
end
|
|
16
|
+
File.expand_path homedir
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unindent! s
|
|
20
|
+
indent = nil
|
|
21
|
+
s.each do |line|
|
|
22
|
+
next if line =~ %r/^\s*$/
|
|
23
|
+
indent = line[%r/^\s*/] and break
|
|
24
|
+
end
|
|
25
|
+
s.gsub! %r/^#{ indent }/, "" if indent
|
|
26
|
+
s
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def unindent s
|
|
30
|
+
unindent! "#{ s }"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def indent! s, n = 2
|
|
34
|
+
n = Integer n
|
|
35
|
+
margin = ' ' * n
|
|
36
|
+
unindent! s
|
|
37
|
+
s.gsub! %r/^/, margin
|
|
38
|
+
s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def indent s, n = 2
|
|
42
|
+
indent!(s.to_s.dup, n)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def inline! s
|
|
46
|
+
s.gsub! %r/\n/, ' '
|
|
47
|
+
s.squeeze! ' '
|
|
48
|
+
s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def inline s
|
|
52
|
+
inline!(s.dup)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def random_string options = {}
|
|
56
|
+
Gnip.options_for(options)
|
|
57
|
+
|
|
58
|
+
Kernel.srand
|
|
59
|
+
|
|
60
|
+
default_size = 6
|
|
61
|
+
size = Integer(options.getopt(:size, default_size))
|
|
62
|
+
|
|
63
|
+
default_chars = ( ('a' .. 'z').to_a + ('A' .. 'Z').to_a + (0 .. 9).to_a )
|
|
64
|
+
%w( 0 O l ).each{|char| default_chars.delete(char)}
|
|
65
|
+
|
|
66
|
+
chars = options.getopt(:chars, default_chars)
|
|
67
|
+
size = options.getopt(:chars, default_size)
|
|
68
|
+
|
|
69
|
+
Array.new(size).map{ chars[rand(2**32)%chars.size, 1] }.join
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def snake_case(camel_cased_word)
|
|
73
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
|
74
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
75
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
|
76
|
+
tr("-", "_").
|
|
77
|
+
downcase
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def camel_case(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
|
81
|
+
if first_letter_in_uppercase
|
|
82
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
|
83
|
+
else
|
|
84
|
+
camel_case(lower_case_and_underscored_word).sub(%r/^(.)/){ $1.downcase }
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def normalize!(s)
|
|
89
|
+
s.to_s.gsub!(%r/\s/, ' ')
|
|
90
|
+
s
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def number_for(arg)
|
|
94
|
+
arg = arg.to_s
|
|
95
|
+
arg.gsub! %r/^[0\s]+/, ''
|
|
96
|
+
Integer(arg) rescue Float(arg)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def compress(data)
|
|
100
|
+
writer = Zlib::GzipWriter.new(StringIO.new(result=''))
|
|
101
|
+
writer.write(data.to_s)
|
|
102
|
+
writer.close
|
|
103
|
+
result
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def decompress(data)
|
|
107
|
+
Zlib::GzipReader.new(StringIO.new(data.to_s)).read
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def encode(data)
|
|
111
|
+
Base64.encode64(compress(data))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def decode(data)
|
|
115
|
+
decompress(Base64.decode64(data.to_s))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
extend self
|
|
119
|
+
end
|
|
120
|
+
end
|