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,191 @@
1
+ module Gnip
2
+
3
+ # TODO - doc the api
4
+
5
+ module Api
6
+ #
7
+ #
8
+ def username(*arg)
9
+ default.config.username = arg.first.to_s unless arg.empty?
10
+ default.config.username
11
+ end
12
+ alias_method 'username=', 'username'
13
+
14
+ def password(*arg)
15
+ default.config.password = arg.first.to_s unless arg.empty?
16
+ default.config.password
17
+ end
18
+ alias_method 'password=', 'password'
19
+
20
+ def uri(*arg)
21
+ default.config.uri = arg.first.to_s unless arg.empty?
22
+ default.config.uri
23
+ end
24
+ alias_method 'uri=', 'uri'
25
+
26
+ #
27
+ #
28
+ def ping(*args)
29
+ args, options = Gnip.args_for(args)
30
+ path = args.shift || Gnip.default.ping_path
31
+ options = Gnip.options_for(options)
32
+ resource = options.getopt(:resource, Gnip.default.resource)
33
+ endpoint = resource.endpoint(path)
34
+ !!endpoint.get
35
+ rescue
36
+ raise if options.getopt(:raise)
37
+ false
38
+ end
39
+
40
+ #
41
+ #
42
+ def publisher
43
+ Publisher
44
+ end
45
+
46
+ #
47
+ #
48
+ def resource
49
+ Resource
50
+ end
51
+
52
+ #
53
+ #
54
+ def activity
55
+ Activity
56
+ end
57
+
58
+ #
59
+ #
60
+ def filter
61
+ Filter
62
+ end
63
+
64
+ #
65
+ #
66
+ def util
67
+ Util
68
+ end
69
+
70
+ #
71
+ #
72
+ def config
73
+ Config
74
+ end
75
+
76
+ #
77
+ #
78
+ def orderedhash
79
+ OrderedHash
80
+ end
81
+
82
+ #
83
+ #
84
+ def clock_drift(*args)
85
+ args, options = Gnip.args_for(args)
86
+ path = args.shift || Gnip.default.ping_path
87
+ options = Gnip.options_for(options)
88
+ resource = options.getopt(:resource, Gnip.default.resource)
89
+ force = options.getopt(:force, false)
90
+ endpoint = resource.endpoint(path)
91
+ @clock_drift = nil if force
92
+ @clock_drift ||= ( Time.httpdate(endpoint.get.headers[:date]).utc - Time.now.utc )
93
+ end
94
+
95
+ #
96
+ #
97
+ def Gnip.time
98
+ Time.now.utc + clock_drift
99
+ end
100
+
101
+ #
102
+ #
103
+ attr_writer 'scope'
104
+
105
+ def scope *arg, &block
106
+ @scope ||= Gnip.default.scope
107
+ if block
108
+ scope = @scope
109
+ begin
110
+ @scope = arg.first.to_s unless arg.empty?
111
+ block.call(@scope)
112
+ ensure
113
+ @scope = scope
114
+ end
115
+ end
116
+ @scope
117
+ end
118
+
119
+ #
120
+ #
121
+ def args_for(args)
122
+ Arguments.for(args)
123
+ end
124
+ def argify!(args)
125
+ Arguments.for(args)
126
+ end
127
+
128
+ def options_for(args)
129
+ Options.for(args)
130
+ end
131
+ def optify!(args)
132
+ Options.for(args)
133
+ end
134
+
135
+ #
136
+ #
137
+ def compress(data)
138
+ util.compress(data)
139
+ end
140
+
141
+ #
142
+ #
143
+ def decompress(data)
144
+ util.decompress(data)
145
+ end
146
+
147
+ #
148
+ #
149
+ def encode(data)
150
+ util.encode(data)
151
+ end
152
+
153
+ #
154
+ #
155
+ def decode(data)
156
+ util.decode(data)
157
+ end
158
+
159
+
160
+ #
161
+ #
162
+ module Default
163
+ @uri = 'https://api-v21.gnip.com/'
164
+ attr_accessor :uri
165
+
166
+ @scope = 'gnip'
167
+ attr_accessor :scope
168
+
169
+ @ping_path = '/my/publishers.xml'
170
+ attr_accessor :ping_path
171
+
172
+ attr_writer :config
173
+ def config
174
+ @config ||= Config.default
175
+ end
176
+
177
+ attr_writer :resource
178
+ def resource
179
+ @resource ||= Resource.default
180
+ end
181
+
182
+ extend self
183
+ end
184
+
185
+ def default
186
+ Default
187
+ end
188
+ end
189
+
190
+ extend Api
191
+ end
@@ -0,0 +1,21 @@
1
+ module Gnip
2
+ module Arguments
3
+ def options
4
+ @options ||= Options.for(last.is_a?(Hash) ? pop : {})
5
+ end
6
+
7
+ %w[ getopt getopts hasopt hasopts delopt delopts ].each do |method|
8
+ module_eval <<-code
9
+ def #{ method }(*args, &block)
10
+ options.#{ method }(*args, &block)
11
+ end
12
+ code
13
+ end
14
+
15
+ def Arguments.for(args)
16
+ raise ArgumentError unless args.is_a?(Array)
17
+ args.extend(Arguments)
18
+ [args, args.options]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Gnip
2
+ class BlankSlate
3
+ instance_methods.each{|m| undef_method m unless m =~ /^__/}
4
+ end
5
+ end
@@ -0,0 +1,144 @@
1
+ module Gnip
2
+ class Config
3
+ def Config.for(arg)
4
+ config = new
5
+ updates =
6
+ case arg
7
+ when Hash
8
+ arg
9
+ when NilClass
10
+ {}
11
+ else
12
+ if arg.respond_to?(:read)
13
+ YAML.load(arg.read)
14
+ else
15
+ YAML.load(IO.read(arg.to_s))
16
+ end
17
+ end
18
+ config.update(updates)
19
+ config
20
+ end
21
+
22
+ def Config.default_path
23
+ File.join(Gnip.util.homedir, '.gnip.yml')
24
+ end
25
+
26
+ def Config.default
27
+ @default ||= (
28
+ update_from_env(
29
+ begin
30
+ Config.for(default_path)
31
+ rescue Errno::ENOENT
32
+ Config.for(nil)
33
+ end
34
+ )
35
+ )
36
+ end
37
+
38
+ def Config.update_from_env config
39
+ username = ENV['GNIP_USERNAME']
40
+ password = ENV['GNIP_PASSWORD']
41
+ auth = ENV['GNIP_AUTH']
42
+ if(auth and not (username and password))
43
+ username, password = auth.split(%r/:/, 2)
44
+ end
45
+ uri = ENV['GNIP_URI'] || Gnip.default.uri
46
+ config.username = username if username
47
+ config.password = password if password
48
+ config.uri = uri if uri
49
+ config
50
+ end
51
+
52
+ def Config.normalized hash
53
+ stringified_keys(hash)
54
+ end
55
+
56
+ def Config.stringified_keys hash
57
+ hash.keys.inject(Hash.new){|h,k| h.update(k.to_s => hash.fetch(k))}
58
+ end
59
+
60
+ attr :config
61
+
62
+ def initialize options = {}
63
+ @config = {}
64
+ options.each do |key, value|
65
+ msg = "#{ key }="
66
+ if respond_to?(msg)
67
+ send msg, value
68
+ else
69
+ @config[key.to_s] = value
70
+ end
71
+ end
72
+ end
73
+
74
+ alias_method 'to_hash', 'config'
75
+
76
+ def to_yaml(*args, &block)
77
+ to_hash.to_yaml(*args, &block)
78
+ end
79
+
80
+ def username= username
81
+ config['username'] = username.to_s
82
+ end
83
+ def username
84
+ config['username'].to_s
85
+ end
86
+
87
+ def password= password
88
+ config['password'] = password.to_s
89
+ end
90
+ def password
91
+ config['password'].to_s
92
+ end
93
+
94
+ def uri= uri
95
+ config['uri'] = uri.to_s
96
+ end
97
+ def uri
98
+ URI.parse(config['uri'].to_s) if config['uri']
99
+ end
100
+
101
+ def inspect
102
+ config.inspect
103
+ end
104
+
105
+ def normalize!
106
+ config.replace normalized
107
+ end
108
+
109
+ def normalized hash = config
110
+ Config.normalized(hash)
111
+ end
112
+
113
+ def [] key
114
+ config[key.to_s]
115
+ end
116
+ alias_method 'get', '[]'
117
+
118
+ def []= key, val
119
+ config[key.to_s] = val
120
+ end
121
+ alias_method 'set', '[]='
122
+
123
+ def has_key? key
124
+ config.has_key? key.to_s
125
+ end
126
+
127
+ def update hash
128
+ config.update normalized(hash)
129
+ self
130
+ end
131
+
132
+ def method_missing m, *a, &b
133
+ key, setter = m.to_s.split(/(=)/)
134
+ if setter
135
+ val = a.first
136
+ return(set(key, val))
137
+ end
138
+ if has_key?(key)
139
+ return(get(key))
140
+ end
141
+ super
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,311 @@
1
+ module Gnip
2
+ class Filter
3
+ def Filter.list_from_xml(xml, options = {}, &block)
4
+ list = []
5
+ parse_xml(xml, options) do |filter|
6
+ block ? block.call(filter) : list.push(filter)
7
+ end
8
+ block ? nil : list
9
+ end
10
+
11
+ def Filter.parse_xml(xml, options = {}, &block)
12
+ doc = Nokogiri::XML.parse(xml)
13
+ list = []
14
+ selectors = 'filter'
15
+ selectors.each do |selector|
16
+ search = doc.search(selector)
17
+ next unless search.size > 0
18
+ search.each do |node|
19
+ filter = Filter.from_node(node, options)
20
+ block ? block.call(filter) : list.push(filter)
21
+ end
22
+ end
23
+ block ? nil : list
24
+ end
25
+
26
+ def Filter.from_node(node, options = {})
27
+ full_data = node['fullData'] =~ /true/ ? true : false
28
+ name = node['name']
29
+ post_url = nil
30
+ rules = []
31
+ node.search('rule').each do |rule_node|
32
+ type = rule_node['type']
33
+ value = rule_node.content
34
+ rules << {:type => type, :value => value}
35
+ end
36
+ if post_url_node = node.at('postURL')
37
+ post_url = post_url_node.content
38
+ end
39
+ new(name, rules, :full_data => full_data, :post_url => post_url)
40
+ end
41
+
42
+ def Filter.from_xml(xml, options = {})
43
+ parse_xml(xml, options){|filter| return filter}
44
+ end
45
+
46
+ Attributes = []
47
+
48
+ Attributes << 'name'
49
+ def name
50
+ @name ||= nil
51
+ end
52
+ def name= value
53
+ @name = String(value)
54
+ ensure
55
+ raise ArgumentError, @name unless @name =~ %r/^[a-zA-Z0-9.+-]+$/
56
+ end
57
+
58
+ Attributes << 'post_url'
59
+ def post_url
60
+ @post_url ||= nil
61
+ end
62
+ def post_url= value
63
+ @post_url = String(value)
64
+ end
65
+
66
+ Attributes << 'rules'
67
+ def rules
68
+ @rules ||= List.of(Rule)
69
+ end
70
+ def rules= value
71
+ rules.replace(value)
72
+ end
73
+
74
+ Attributes << 'full_data'
75
+ def full_data
76
+ @full_data ||= nil
77
+ end
78
+ def full_data= value
79
+ @full_data = !!value
80
+ end
81
+
82
+ attr_accessor :publisher
83
+
84
+ def initialize(*args)
85
+ args, options = Gnip.args_for(args)
86
+ self.name = args.shift unless args.empty?
87
+ self.rules = args unless args.empty?
88
+ options.each{|key, value| send("#{ key }=", value)}
89
+ end
90
+
91
+ class Rule
92
+ def Rule.from_xml(xml, options = {})
93
+ parse_xml(xml, options){|rule| return rule}
94
+ end
95
+
96
+ def Rule.parse_xml(xml, options = {}, &block)
97
+ doc = Nokogiri::XML.parse(xml)
98
+ list = []
99
+ selectors = 'rule'
100
+ selectors.each do |selector|
101
+ search = doc.search(selector)
102
+ next unless search.size > 0
103
+ search.each do |node|
104
+ rule = Rule.from_node(node, options)
105
+ block ? block.call(rule) : list.push(rule)
106
+ end
107
+ end
108
+ block ? nil : list
109
+ end
110
+
111
+ def Rule.from_node(node, options = {})
112
+ type = node['type']
113
+ value = node.content
114
+ new(:type => type, :value => value)
115
+ end
116
+
117
+ def Rule.for(*args)
118
+ arg = args.first if args.size == 1
119
+ if Rule === arg
120
+ arg
121
+ elsif Hash === arg
122
+ new(arg)
123
+ else
124
+ new(*args)
125
+ end
126
+ end
127
+
128
+ attr_accessor :type
129
+ attr_accessor :value
130
+
131
+ def initialize(*args)
132
+ args, options = Gnip.args_for(args)
133
+ type = value = nil
134
+ case args.size
135
+ when 1
136
+ type, value = args.first.to_s.split(%r/:/, 2)
137
+ when 2
138
+ type, value = args
139
+ end
140
+ self.type = Publisher.rule.for options.getopt(:type, type)
141
+ self.value = options.getopt(:value, value)
142
+ end
143
+
144
+ def inspect
145
+ "#{ type }:#{ value }"
146
+ end
147
+
148
+ def to_s
149
+ inspect
150
+ end
151
+
152
+ def to_yaml(*a, &b)
153
+ to_s.to_yaml(*a, &b)
154
+ end
155
+
156
+ =begin
157
+ def Rule.template
158
+ @template ||=
159
+ Template.new do
160
+ "
161
+ <rule type=<%= type.inspect %>>
162
+ <%= value %>
163
+ </rule>
164
+ "
165
+ end
166
+ end
167
+
168
+ def to_xml(options = {})
169
+ Rule.template.expand(self)
170
+ end
171
+ =end
172
+
173
+ include Tagz
174
+ def to_xml(*args)
175
+ args, options = Gnip.args_for(args)
176
+ doc = args.shift
177
+
178
+ tagz(doc) {
179
+ rule_(:type => type){ value }
180
+ }
181
+ end
182
+
183
+ attr_accessor :filter
184
+
185
+ def resource
186
+ raise 'filter not set!' unless filter
187
+ rule = self
188
+ filter.publisher.filter.resource["filters/#{ filter.name }/rules?type=#{ rule.type }&value=#{ rule.value }"]
189
+ end
190
+
191
+ def delete(options = {})
192
+ Gnip.optify!(options)
193
+ filter = options.getopt(:filter, self.filter)
194
+ resource.delete
195
+ self
196
+ end
197
+ end
198
+
199
+ include Tagz
200
+ def to_xml(*args)
201
+ tagz {
202
+ filter_(:name => name, :fullData => !!full_data){
203
+ postURL_{ post_url } if post_url
204
+ rules.each do |rule|
205
+ rule_(:type => rule.type){ rule.value }
206
+ end
207
+ nil
208
+ }
209
+ }
210
+ end
211
+
212
+ =begin
213
+ def Filter.template
214
+ @template ||=
215
+ Template.new do
216
+ "
217
+ <filter name=<%= name.inspect %> fullData=<%= (!!full_data).to_s.inspect %>>
218
+ % if post_url
219
+ <postURL><%= post_url %></postURL>
220
+ % end
221
+ % rules.each do |rule|
222
+ <rule type=<%= rule.type.inspect %>><%= rule.value %></rule>
223
+ % end
224
+ </filter>
225
+ "
226
+ end
227
+ end
228
+
229
+ def to_xml(options = {})
230
+ Filter.template.expand(self)
231
+ end
232
+ =end
233
+
234
+ def resource
235
+ raise 'publisher not set!' unless publisher
236
+ publisher.filter.resource["filters/#{ name }.xml"]
237
+ end
238
+
239
+ def get(*args, &block)
240
+ resource.get(*args, &block)
241
+ end
242
+
243
+ def delete(*args, &block)
244
+ resource.delete(*args, &block)
245
+ end
246
+
247
+ def put(*args, &block)
248
+ resource.put(*args, &block)
249
+ end
250
+
251
+ def post(*args, &block)
252
+ resource.post(*args, &block)
253
+ end
254
+
255
+ def replace(other)
256
+ put(other.to_xml)
257
+ publisher.filter.for(name)
258
+ end
259
+
260
+ def rule
261
+ @rule ||= RuleResource.new(self)
262
+ end
263
+
264
+ class RuleResource
265
+ attr_accessor :filter
266
+
267
+ def initialize filter
268
+ @filter = filter
269
+ end
270
+
271
+ def publisher
272
+ filter.publisher
273
+ end
274
+
275
+ def resource
276
+ publisher.resource
277
+ end
278
+
279
+ def list options = {}
280
+ Gnip.optify!(options)
281
+ type = options.getopt(:type) or raise 'no type'
282
+ value = options.getopt(:value) or raise 'no type'
283
+ xml = resource["filters/#{ filter.name }/rules?type=#{ type }&value=#{ value }"].get
284
+ rule = Rule.from_xml(xml)
285
+ rule.filter = filter
286
+ rule
287
+ end
288
+
289
+ def for(*args)
290
+ rule = Rule.for(*args)
291
+ list(:type => rule.type, :value => rule.value)
292
+ end
293
+
294
+ def delete options = {}
295
+ list(options).delete(:filter => filter)
296
+ end
297
+
298
+ def create(*rules)
299
+ rules = rules.map{|rule| Rule.for(rule)}
300
+ slices = [] and rules.each_slice(5000){|slice| slices << slice}
301
+ msg = slices.size > 1 ? 'threadify' : 'each'
302
+ slices.send(msg) do |slice|
303
+ xml = slice.map{|rule| rule.to_xml(:declaration => false)}.join
304
+ resource["filters/#{ filter.name }/rules"].post("<rules>#{ xml }</rules>")
305
+ end
306
+ rules.each{|rule| rule.filter = filter}
307
+ rules
308
+ end
309
+ end
310
+ end
311
+ end