jive_api 0.0.2.pre

Sign up to get free protection for your applications and to get access to all the features.
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: