gnip-gnip 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README +144 -0
  2. data/Rakefile +221 -0
  3. data/TODO +72 -0
  4. data/bin/gnip +651 -0
  5. data/doc/api.html +1201 -0
  6. data/gemspec.rb +25 -0
  7. data/gnip-ruby.gemspec +26 -0
  8. data/lib/gnip.rb +71 -0
  9. data/lib/gnip/activity.rb +665 -0
  10. data/lib/gnip/api.rb +191 -0
  11. data/lib/gnip/arguments.rb +21 -0
  12. data/lib/gnip/blankslate.rb +5 -0
  13. data/lib/gnip/config.rb +144 -0
  14. data/lib/gnip/filter.rb +311 -0
  15. data/lib/gnip/list.rb +126 -0
  16. data/lib/gnip/options.rb +96 -0
  17. data/lib/gnip/orderedhash.rb +199 -0
  18. data/lib/gnip/publisher.rb +316 -0
  19. data/lib/gnip/resource.rb +301 -0
  20. data/lib/gnip/template.rb +44 -0
  21. data/lib/gnip/util.rb +120 -0
  22. data/sample/data/activity.yml +21 -0
  23. data/test/auth.rb +60 -0
  24. data/test/config.yml +2 -0
  25. data/test/data/activity.xml +14 -0
  26. data/test/data/activity_only_required.xml +4 -0
  27. data/test/data/activity_with_payload.xml +22 -0
  28. data/test/data/activity_with_place.xml +18 -0
  29. data/test/data/activity_with_place_wo_bounds.xml +36 -0
  30. data/test/data/activity_with_unbounded_media_urls.xml +44 -0
  31. data/test/data/activity_without_bounds.xml +24 -0
  32. data/test/helper.rb +115 -0
  33. data/test/integration/auth.rb +12 -0
  34. data/test/integration/publisher.rb +86 -0
  35. data/test/lib/shoulda.rb +9 -0
  36. data/test/lib/shoulda/action_controller.rb +28 -0
  37. data/test/lib/shoulda/action_controller/helpers.rb +47 -0
  38. data/test/lib/shoulda/action_controller/macros.rb +277 -0
  39. data/test/lib/shoulda/action_controller/matchers.rb +37 -0
  40. data/test/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  41. data/test/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  42. data/test/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  43. data/test/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  44. data/test/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +77 -0
  45. data/test/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  46. data/test/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
  47. data/test/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  48. data/test/lib/shoulda/action_mailer.rb +10 -0
  49. data/test/lib/shoulda/action_mailer/assertions.rb +38 -0
  50. data/test/lib/shoulda/action_view.rb +10 -0
  51. data/test/lib/shoulda/action_view/macros.rb +56 -0
  52. data/test/lib/shoulda/active_record.rb +16 -0
  53. data/test/lib/shoulda/active_record/assertions.rb +69 -0
  54. data/test/lib/shoulda/active_record/helpers.rb +40 -0
  55. data/test/lib/shoulda/active_record/macros.rb +586 -0
  56. data/test/lib/shoulda/active_record/matchers.rb +42 -0
  57. data/test/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  58. data/test/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  59. data/test/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  60. data/test/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  61. data/test/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  62. data/test/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  63. data/test/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
  64. data/test/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
  65. data/test/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  66. data/test/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  67. data/test/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  68. data/test/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  69. data/test/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  70. data/test/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  71. data/test/lib/shoulda/assertions.rb +59 -0
  72. data/test/lib/shoulda/autoload_macros.rb +46 -0
  73. data/test/lib/shoulda/context.rb +304 -0
  74. data/test/lib/shoulda/helpers.rb +8 -0
  75. data/test/lib/shoulda/macros.rb +73 -0
  76. data/test/lib/shoulda/private_helpers.rb +20 -0
  77. data/test/lib/shoulda/proc_extensions.rb +14 -0
  78. data/test/lib/shoulda/rails.rb +13 -0
  79. data/test/lib/shoulda/rspec.rb +9 -0
  80. data/test/lib/shoulda/tasks.rb +3 -0
  81. data/test/lib/shoulda/tasks/list_tests.rake +29 -0
  82. data/test/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  83. data/test/lib/shoulda/test_unit.rb +19 -0
  84. data/test/lib/xmlsimple.rb +1021 -0
  85. data/test/loader.rb +25 -0
  86. data/test/unit/activity.rb +26 -0
  87. data/test/unit/util.rb +39 -0
  88. metadata +158 -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 => 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
@@ -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