jive_api 0.0.2.pre

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 (2) hide show
  1. data/lib/jive_api.rb +449 -0
  2. metadata +79 -0
data/lib/jive_api.rb ADDED
@@ -0,0 +1,449 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'date'
6
+ require 'hashery/lru_hash'
7
+
8
+ module Jive
9
+ module GettableBinaryURL
10
+ def get_binary
11
+ binary_uri = URI @binary_url
12
+ http = Net::HTTP.new(binary_uri.host, binary_uri.port)
13
+ req = Net::HTTP::Get.new binary_uri.request_uri
14
+ req.basic_auth @api_instance.auth[:username], @api_instance.auth[:password]
15
+ response = http.request req
16
+ response.body
17
+ end
18
+ end
19
+
20
+ class Container
21
+ attr_reader :name, :type, :id, :raw_data, :self_uri, :subject, :display_name, :html_uri
22
+
23
+ def initialize instance, data
24
+ @raw_data = data
25
+ @api_instance = instance
26
+ @name = data["name"]
27
+ @type = data["type"]
28
+ @id = data["id"] if data.has_key? 'id'
29
+ @display_name = data["displayName"] if data.has_key? 'displayName'
30
+ @self_uri = data["resources"]["self"]["ref"] if data.has_key? 'resources'
31
+ @parent_uri = data["parent"] if data.has_key? 'parent_uri'
32
+ @subject = data["subject"] if data.has_key? 'subject'
33
+ @html_uri = data["resources"]["html"]["ref"] if (data.has_key?('resources') && data["resources"].has_key?('html'))
34
+ end
35
+
36
+ def display_path
37
+ if parent.nil?
38
+ "#{self.class}:#{@display_name}"
39
+ else
40
+ "#{parent.display_path}/#{self.class}:#{@display_name}"
41
+ end
42
+ end
43
+
44
+ def uri
45
+ @self_uri
46
+ end
47
+
48
+ def parent
49
+ @api_instance.get_container_by_uri @parent_uri if @parent_uri
50
+ end
51
+ end
52
+
53
+ class Attachment < Container
54
+ include GettableBinaryURL
55
+ attr_reader :size, :mime_type
56
+
57
+ def initialize instance, data
58
+ super instance, data
59
+ @mime_type = data['contentType']
60
+ @size = data['size']
61
+ @binary_url = data['url']
62
+ end
63
+ end
64
+
65
+ class Content < Container
66
+ attr_reader :updated_at, :visibility, :content_id
67
+
68
+ def initialize instance, data
69
+ super instance, data
70
+ @display_name = data["name"]
71
+ @updated_at = DateTime.iso8601 data["updated"]
72
+ @visibility = data['visibility']
73
+ @content = data['content']['text']
74
+ @ref = data["resources"]["self"]["ref"]
75
+ @content_id = @ref.match(/\/api\/core\/v3\/contents\/([0-9]+)$/)[1]
76
+ end
77
+
78
+ def author
79
+ # Let's try being clever here and including the data Jive already sent back
80
+ Jive.const_get("#{@raw_data['author']['type'].capitalize}").new @api_instance, @raw_data['author']
81
+ end
82
+
83
+ def comments
84
+ @api_instance.get_container_by_uri @comments_uri if @comments_uri
85
+ end
86
+
87
+ def get
88
+ @content
89
+ end
90
+
91
+ end
92
+
93
+ class Document < Content
94
+ def initialize instance, data
95
+ super instance, data
96
+ @attachments_count = data['attachments'].length
97
+ @content = data['content']['text']
98
+ @content_type = data['content']['type']
99
+ @display_name = data["subject"]
100
+ @attachments_uri = data["resources"]["attachments"]["ref"] if data["resources"].has_key? "attachments"
101
+ end
102
+
103
+ def get
104
+ @content
105
+ end
106
+
107
+ def attachments
108
+ @api_instance.get_container_by_uri @attachments_uri if @attachments_uri
109
+ end
110
+
111
+ def has_attachments?
112
+ @attachments_count > 0
113
+ end
114
+
115
+ end
116
+
117
+ class Discussion < Content
118
+ def initialize instance, data
119
+ super instance, data
120
+ @display_name = data['subject']
121
+ @messages_uri = data['resources']['messages']['ref']
122
+ end
123
+
124
+ def messages
125
+ @api_instance.get_container_by_uri @messages_uri if @messages_uri
126
+ end
127
+ end
128
+
129
+ class File < Content
130
+ include GettableBinaryURL
131
+ attr_reader :mime_type
132
+
133
+ def initialize instance, data
134
+ super instance, data
135
+ @binary_url = data['binaryURL']
136
+ @mime_type = data['contentType']
137
+ end
138
+
139
+
140
+ end
141
+
142
+ class Poll < Content
143
+ def initialize instance, data
144
+ super instance, data
145
+ @display_name = data['subject']
146
+ end
147
+ end
148
+
149
+ class Comment < Content
150
+ end
151
+
152
+ class Post < Content
153
+ def initialize instance, data
154
+ super instance, data
155
+ @display_name = data["subject"]
156
+ @comments_uri = data["resources"]["comments"]["ref"] if data["resources"].has_key? "comments"
157
+ @attachments_uri = data["resources"]["attachments"]["ref"] if data["resources"].has_key? "attachments"
158
+ end
159
+
160
+ def attachments
161
+ @api_instance.get_container_by_uri @attachments_uri if @attachments_uri
162
+ end
163
+ end
164
+
165
+ class Message < Content
166
+ def initialize instance, data
167
+ super instance, data
168
+ @content = data["content"]["text"]
169
+ end
170
+
171
+ def get
172
+ @content
173
+ end
174
+ end
175
+
176
+ class Update < Content
177
+ def initialize instance, data
178
+ super instance, data
179
+ @display_name = data['subject']
180
+ end
181
+ end
182
+
183
+ class Favorite < Content
184
+ end
185
+
186
+ class Task < Content
187
+ end
188
+
189
+ class Idea < Content
190
+ end
191
+
192
+ class Person < Container
193
+ attr_reader :display_name, :userid, :status
194
+
195
+ def initialize instance, data
196
+ super instance, data
197
+ @userid = data["jive"]["username"]
198
+ @status = data["status"]
199
+ @blog_uri = data["resources"]["blog"]["ref"] if data["resources"].has_key? 'blog'
200
+ end
201
+
202
+ def blog
203
+ @blog_uri ? @api_instance.get_container_by_uri(@blog_uri) : nil
204
+ end
205
+
206
+ def content filters = []
207
+ filters += ["author(#{uri})"]
208
+ @api_instance.contents :query => { :filter => filters }
209
+ end
210
+ end
211
+
212
+ class Place < Container
213
+ attr_reader :description, :status, :ref, :place_id
214
+
215
+ def initialize instance, data
216
+ super instance, data
217
+ @description = data["description"]
218
+ @status = data["status"]
219
+ @ref = data["resources"]["self"]["ref"]
220
+ @place_id = @ref.match(/\/api\/core\/v3\/places\/([0-9]+)$/)[1]
221
+ end
222
+
223
+ def content
224
+ filter = "place(#{@self_uri})"
225
+ @api_instance.paginated_get('/api/core/v3/contents', :query => { :filter => "#{filter}" }).map do |item|
226
+ object_class = Jive.const_get "#{item['type'].capitalize}"
227
+ object_class.new @api_instance, item
228
+ end
229
+ end
230
+
231
+ def places(filter = [], options = {})
232
+ options.merge!({ :filter => filter })
233
+ @api_instance.paginated_get("#{uri}/places", :query => options).map do |item|
234
+ object_class = Jive.const_get "#{item['type'].capitalize}"
235
+ object_class.new @api_instance, item
236
+ end
237
+ end
238
+
239
+ end
240
+
241
+ class Group < Place
242
+ def initialize instance, data
243
+ super instance, data
244
+ end
245
+
246
+ def creator
247
+ Jive.const_get("#{@raw_data['creator']['type'].capitalize}").new @api_instance, @raw_data['creator']
248
+ end
249
+ end
250
+
251
+ class Space < Place
252
+ def initialize instance, data
253
+ super instance, data
254
+ end
255
+
256
+ def sub_spaces
257
+ places ["type(space)"]
258
+ end
259
+ end
260
+
261
+ class Project < Place
262
+ def initialize instance, data
263
+ super instance, data
264
+ end
265
+ end
266
+
267
+ class Blog < Place
268
+ def initialize instance, data
269
+ super instance, data
270
+ @display_name = data["name"]
271
+ @contents_uri = data["resources"]["contents"]["ref"]
272
+ end
273
+
274
+ def posts
275
+ @api_instance.paginated_get(@contents_uri).map { |post| Post.new @api_instance, post }
276
+ end
277
+
278
+ end
279
+
280
+ class Api
281
+ attr_reader :object_cache, :auth
282
+ include HTTParty
283
+
284
+ disable_rails_query_string_format
285
+
286
+ def inspect
287
+ # Don't show the attribute cache. It gets enormous.
288
+ attributes_no_object_cache = self.instance_variables.reject { |var| var.to_s == '@object_cache' }
289
+ attributes_as_nice_string = attributes_no_object_cache.map { |attr| "#{attr}: #{self.instance_variable_get(attr).inspect}" }.join ", "
290
+ "#<#{self.class}:#{'%x' % (self.object_id << 1)} #{attributes_as_nice_string}>"
291
+ end
292
+
293
+ class JSONResponseParser < HTTParty::Parser
294
+ SupportFormats = { "application/json" => :json }
295
+ def parse
296
+ body.slice!(/throw.*;\s*/)
297
+ super
298
+ end
299
+ end
300
+
301
+ def initialize username, password, uri
302
+ @object_cache = Hashery::LRUHash.new 10000
303
+ @auth = { :username => username, :password => password }
304
+ self.class.base_uri uri
305
+ end
306
+
307
+ def api_version
308
+ self.class.get '/api/version', {:basic_auth => @auth}
309
+ end
310
+
311
+ def paginated_get path, options = {}, &block
312
+ result = []
313
+ next_uri = path
314
+
315
+ options.merge!({:basic_auth => @auth})
316
+ limit = 0
317
+ # count doesn't work as expected in paginated requests, so we have a limit option
318
+ if options.has_key? :limit
319
+ limit = options[:limit].to_i
320
+ options.delete :limit
321
+ end
322
+
323
+ results_so_far = 0
324
+ begin
325
+ response = self.class.get next_uri, options
326
+ raise Error if response.parsed_response.has_key? 'error'
327
+ options.delete :query
328
+ next_uri = (response.parsed_response["links"] and response.parsed_response["links"]["next"] ) ? response.parsed_response["links"]["next"] : nil
329
+ list = response.parsed_response["list"]
330
+ list = list ? list : []
331
+ result.concat list
332
+ if block_given?
333
+ list.map do |item|
334
+ yield ((Jive.const_get "#{item['type'].capitalize}").new self, item)
335
+ end
336
+ end
337
+ results_so_far+=list.count
338
+ end while next_uri && ((limit == 0) || (results_so_far < limit))
339
+ result
340
+ end
341
+
342
+ def people options = {}, &block
343
+ get_containers_by_type 'people', options, &block
344
+ end
345
+
346
+ def person_by_username username
347
+ get_container_by_uri "/api/core/v3/people/username/#{username}"
348
+ end
349
+
350
+ def place_by_id place_id
351
+ get_container_by_uri "/api/core/v3/places/#{place_id}"
352
+ end
353
+
354
+ def content_by_id content_id
355
+ get_container_by_uri "/api/core/v3/contents/#{content_id}"
356
+ end
357
+
358
+ def places options = {}, &block
359
+ get_containers_by_type 'places', options, &block
360
+ end
361
+
362
+ def contents options = {}, &block
363
+ get_containers_by_type 'contents', options, &block
364
+ end
365
+
366
+ def activities options = {}, &block
367
+ get_containers_by_type 'activity', options, &block
368
+ end
369
+
370
+ def get_containers_by_type type, options, &block
371
+ next_uri = "/api/core/v3/#{type}"
372
+ if block_given?
373
+ paginated_get(next_uri,options, &block)
374
+ else
375
+ paginated_get(next_uri, options).map do |data|
376
+ object_class = Jive.const_get "#{data['type'].capitalize}"
377
+ o = object_class.new self, data
378
+ @object_cache[o.uri] = o
379
+ end
380
+ end
381
+ end
382
+
383
+ def get_container_by_uri uri
384
+ # Deliver from the object cache if we have it
385
+ return @object_cache[uri] if @object_cache.has_key? uri
386
+ data = self.class.get uri, { :basic_auth => @auth }
387
+ # raise Error if data.parsed_response.has_key? 'error'
388
+ return nil if data.parsed_response.has_key? 'error'
389
+ # We handle both lists and single items with this
390
+ if data.parsed_response.has_key? "list"
391
+ data.parsed_response['list'].map do |item|
392
+ object_class = Jive.const_get "#{item['type'].capitalize}"
393
+ o = object_class.new self, item
394
+ @object_cache[o.uri] = o
395
+ o
396
+ end
397
+ else
398
+ object_class = Jive.const_get "#{data.parsed_response['type'].capitalize}"
399
+ o = object_class.new self, data
400
+ @object_cache[o.uri] = o
401
+ o
402
+ end
403
+ end
404
+
405
+ def places_by_filter filter, options = {}
406
+ options.merge!({ :query => { :filter => filter }})
407
+ places options
408
+ end
409
+
410
+ def places_by_type object_type, options = {}
411
+ places_by_filter "type(#{object_type})", options
412
+ end
413
+
414
+ def blogs(options = {})
415
+ places_by_type "blog", options
416
+ end
417
+
418
+ def spaces(options = {})
419
+ places_by_type "space", options
420
+ end
421
+
422
+ def groups(options = {})
423
+ places_by_type "group", options
424
+ end
425
+
426
+ def contents_by_username username
427
+ user = person_by_username username
428
+ contents :query => { :filter => "author(#{user.self_uri})" }
429
+ end
430
+
431
+ def search type, query, filters = []
432
+ filters += ["search(#{query})"]
433
+ paginated_get("/api/core/v3/search/#{type}", { :query => { :filter => filters } } ).map do |data|
434
+ object_class = Jive.const_get "#{data['type'].capitalize}"
435
+ object_class.new self, data
436
+ end
437
+ end
438
+
439
+ def main_space
440
+ places_by_filter("entityDescriptor(14,1)")[0]
441
+ end
442
+
443
+ headers 'Accept' => 'application/json'
444
+ headers 'Content-Type' => 'application/json'
445
+ format :json
446
+ parser JSONResponseParser
447
+
448
+ end
449
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jive_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2.pre
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Beresford
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: &70148430451680 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.10.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70148430451680
25
+ - !ruby/object:Gem::Dependency
26
+ name: hashery
27
+ requirement: &70148430451060 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 2.1.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70148430451060
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70148430450660 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70148430450660
47
+ description: Jive API Connector for Ruby
48
+ email: beezly@beezly.org.uk
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/jive_api.rb
54
+ homepage: http://github.com/beezly/jive-ruby
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>'
70
+ - !ruby/object:Gem::Version
71
+ version: 1.3.1
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Jive API
78
+ test_files: []
79
+ has_rdoc: