yam 0.0.6 → 1.0.0

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 (88) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.travis.yml +5 -0
  3. data/.yardopts +10 -0
  4. data/AUTHORS +1 -0
  5. data/CHANGELOG.md +7 -0
  6. data/CONTRIBUTING.md +0 -7
  7. data/Gemfile +27 -1
  8. data/README.md +190 -67
  9. data/Rakefile +9 -3
  10. data/certs/public.pem +20 -0
  11. data/lib/yammer.rb +47 -0
  12. data/lib/yammer/api.rb +29 -0
  13. data/lib/yammer/api/autocomplete.rb +39 -0
  14. data/lib/yammer/api/group.rb +92 -0
  15. data/lib/yammer/api/group_membership.rb +46 -0
  16. data/lib/yammer/api/invitation.rb +39 -0
  17. data/lib/yammer/api/like.rb +57 -0
  18. data/lib/yammer/api/message.rb +227 -0
  19. data/lib/yammer/api/network.rb +35 -0
  20. data/lib/yammer/api/notification.rb +32 -0
  21. data/lib/yammer/api/open_graph_object.rb +92 -0
  22. data/lib/yammer/api/pending_attachment.rb +64 -0
  23. data/lib/yammer/api/search.rb +42 -0
  24. data/lib/yammer/api/subscription.rb +32 -0
  25. data/lib/yammer/api/thread.rb +37 -0
  26. data/lib/yammer/api/topic.rb +37 -0
  27. data/lib/yammer/api/user.rb +168 -0
  28. data/lib/yammer/api_handler.rb +27 -0
  29. data/lib/yammer/api_response.rb +57 -0
  30. data/lib/yammer/base.rb +208 -0
  31. data/lib/yammer/client.rb +100 -0
  32. data/lib/yammer/configurable.rb +81 -0
  33. data/lib/yammer/error.rb +75 -0
  34. data/lib/yammer/group.rb +27 -0
  35. data/lib/yammer/group_membership.rb +25 -0
  36. data/lib/yammer/http_adapter.rb +100 -0
  37. data/lib/yammer/identity_map.rb +56 -0
  38. data/lib/yammer/message.rb +32 -0
  39. data/lib/yammer/message_body.rb +27 -0
  40. data/lib/yammer/pending_attachment.rb +19 -0
  41. data/lib/yammer/thread.rb +58 -0
  42. data/lib/yammer/user.rb +66 -0
  43. data/lib/yammer/version.rb +32 -0
  44. data/{lib/yam/configuration.rb → spec/api/autocomplete_spec.rb} +18 -23
  45. data/spec/api/group_membership_spec.rb +48 -0
  46. data/spec/api/group_spec.rb +76 -0
  47. data/spec/api/invitation_spec.rb +60 -0
  48. data/spec/api/like_spec.rb +46 -0
  49. data/spec/api/message_spec.rb +136 -0
  50. data/spec/api/network_spec.rb +41 -0
  51. data/{lib/yam/client.rb → spec/api/notification_spec.rb} +22 -4
  52. data/spec/api/open_graph_object_spec.rb +67 -0
  53. data/spec/api/pending_attachment_spec.rb +56 -0
  54. data/{lib/yam/constants.rb → spec/api/search_spec.rb} +21 -8
  55. data/spec/api/subscription_spec.rb +41 -0
  56. data/{lib/yam.rb → spec/api/thread_spec.rb} +19 -12
  57. data/{lib/yam/request.rb → spec/api/topic_spec.rb} +19 -15
  58. data/spec/api/user_spec.rb +108 -0
  59. data/spec/api_response.rb +86 -0
  60. data/spec/client_spec.rb +364 -0
  61. data/spec/error_spec.rb +88 -0
  62. data/spec/fixtures/group.json +1 -0
  63. data/spec/fixtures/message.json +1 -0
  64. data/spec/fixtures/messages_in_thread.json +1 -0
  65. data/spec/fixtures/portal_thread.json +1 -0
  66. data/spec/fixtures/private_thread.json +1 -0
  67. data/spec/fixtures/public_thread.json +1 -0
  68. data/spec/fixtures/user.json +1 -0
  69. data/spec/fixtures/users_followed.json +1 -0
  70. data/spec/fixtures/users_following.json +1 -0
  71. data/spec/http_adapter_spec.rb +109 -0
  72. data/spec/identity_map_spec.rb +127 -0
  73. data/spec/mocks/attachment.txt +1 -0
  74. data/spec/model/base_spec.rb +196 -0
  75. data/spec/model/group_membership_spec.rb +57 -0
  76. data/spec/model/group_spec.rb +73 -0
  77. data/spec/model/message_spec.rb +74 -0
  78. data/spec/model/thread_spec.rb +91 -0
  79. data/spec/model/user_spec.rb +222 -0
  80. data/spec/spec_helper.rb +39 -14
  81. data/yam.gemspec +50 -28
  82. metadata +270 -187
  83. metadata.gz.sig +0 -0
  84. data/lib/yam/api.rb +0 -53
  85. data/lib/yam/connection.rb +0 -57
  86. data/lib/yam/version.rb +0 -20
  87. data/spec/yam/client_spec.rb +0 -50
  88. data/spec/yam_spec.rb +0 -87
@@ -0,0 +1,75 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ module Error
17
+
18
+ class << self
19
+ def from_status(status=nil)
20
+ case status
21
+ when 400
22
+ BadRequest
23
+ when 401
24
+ Unauthorized
25
+ when 403
26
+ Forbidden
27
+ when 404
28
+ NotFound
29
+ when 406
30
+ NotAcceptable
31
+ when 429
32
+ RateLimitExceeded
33
+ when 500
34
+ InternalServerError
35
+ when 502
36
+ BadGateway
37
+ when 503
38
+ ServiceUnavailable
39
+ else
40
+ ApiError
41
+ end
42
+ end
43
+ end
44
+
45
+ # Raised when Yammer returns unknown HTTP status code
46
+ class ApiError < StandardError; end
47
+
48
+ # Raised when Yammer returns the HTTP status code 400
49
+ class BadRequest < ApiError; end
50
+
51
+ # Raised when Yammer returns the HTTP status code 401
52
+ class Unauthorized < ApiError; end
53
+
54
+ # Raised when Yammer returns the HTTP status code 403
55
+ class Forbidden < ApiError; end
56
+
57
+ # Raised when Yammer returns the HTTP status code 404
58
+ class NotFound < ApiError; end
59
+
60
+ # Raised when Yammer returns the HTTP status code 406
61
+ class NotAcceptable < ApiError; end
62
+
63
+ # Raised when Yammer returns the HTTP status code 429
64
+ class RateLimitExceeded < ApiError; end
65
+
66
+ # Raised when Yammer returns the HTTP status code 500
67
+ class InternalServerError < ApiError; end
68
+
69
+ # Raised when Yammer returns the HTTP status code 502
70
+ class BadGateway < ApiError; end
71
+
72
+ # Raised when Yammer returns the HTTP status code 503
73
+ class ServiceUnavailable < ApiError; end
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class Group < Yammer::Base
17
+
18
+ attr_accessor_deffered :show_in_directory, :privacy, :description, :creator_type,
19
+ :creator_id, :mugshot_id, :stats, :state, :web_url, :name, :created_at, :type,
20
+ :mugshot_url, :url, :full_name, :mugshot_url_template, :description
21
+
22
+ # @!scope class
23
+ def self.create(params={})
24
+ result = api_handler.create_group(params)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class GroupMembership < Yammer::Base
17
+
18
+ attr_accessor_deffered
19
+
20
+ # @!scope class
21
+ def self.create(id)
22
+ api_handler.create_group_membership(id)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,100 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ require 'restclient'
16
+ require 'multi_json'
17
+ require 'addressable/uri'
18
+
19
+ module Yammer
20
+ class HttpAdapter
21
+
22
+ def self.log=(output)
23
+ RestClient.log = output
24
+ end
25
+
26
+ attr_reader :site_url, :connection_options
27
+
28
+ def initialize(site_url, opts={})
29
+ unless site_url =~ /^https?/
30
+ raise ArgumentError, "site_url must include either http or https scheme"
31
+ end
32
+ @site_url = site_url
33
+ @connection_options = opts
34
+ end
35
+
36
+ # set the url to be used for creating an http connection
37
+ # @param url [string]
38
+ def site_url=(url)
39
+ @site_url = url
40
+ @host = nil
41
+ @scheme = nil
42
+ end
43
+
44
+ def host
45
+ @host ||= parsed_url.host
46
+ end
47
+
48
+ def scheme
49
+ @scheme ||= parsed_url.scheme
50
+ end
51
+
52
+ def absolute_url(path='')
53
+ "#{@site_url}#{path}"
54
+ end
55
+
56
+ def connection_options=(opts)
57
+ raise ArgumentError, 'expected Hash' unless opts.is_a?(Hash)
58
+ @connection_options = opts
59
+ end
60
+
61
+ def send_request(method, path, opts={})
62
+ begin
63
+ params = opts.fetch(:params, {})
64
+
65
+ req_opts = self.connection_options.merge({
66
+ :method => method,
67
+ :headers => opts.fetch(:headers, {})
68
+ })
69
+
70
+ case method
71
+ when :get, :delete
72
+ query = Addressable::URI.form_encode(params)
73
+ normalized_path = query.empty? ? path : [path, query].join("?")
74
+ req_opts[:url] = absolute_url(normalized_path)
75
+ when :post, :put
76
+ req_opts[:payload] = params
77
+ req_opts[:url] = absolute_url(path)
78
+ else
79
+ raise "Unsupported HTTP method, #{method}"
80
+ end
81
+
82
+ resp = RestClient::Request.execute(req_opts)
83
+
84
+ result = Yammer::ApiResponse.new(resp.headers, resp.body, resp.code)
85
+ rescue => e
86
+ if e.is_a?(RestClient::ExceptionWithResponse)
87
+ e.response
88
+ else
89
+ raise e
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+ def parsed_url
96
+ Addressable::URI.parse(@site_url)
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class IdentityMap
17
+
18
+ class InvalidKeyError < StandardError; end
19
+
20
+ def initialize
21
+ @map = {}
22
+ @size = 0
23
+ end
24
+
25
+ # @note retrives key from identity map
26
+ # @return [Hash]
27
+ # @param key [string]
28
+ # @param default [Hash]
29
+ def get(key, default=nil)
30
+ @map["#{key}"] || default
31
+ end
32
+
33
+ # @note inserts a hash of attributes into identity map
34
+ # @return [Hash]
35
+ # @param key [string]
36
+ # @param value [Hash]
37
+ def put(key, value)
38
+ if key.nil? || key.empty?
39
+ raise InvalidKeyError.new
40
+ end
41
+ @map["#{key}"] = value
42
+ end
43
+
44
+ # @note returns the current size of identity map
45
+ # @return [Integer]
46
+ def size
47
+ @map.keys.count
48
+ end
49
+
50
+ # clears the entire identity map
51
+ # @return [Hash]
52
+ def purge!
53
+ @map = {}
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class Message < Yammer::Base
17
+
18
+ attr_accessor_deffered :direct_message, :privacy, :group_id, :created_at,
19
+ :attachments, :liked_by, :chat_client_sequence, :client_url, :content_excerpt,
20
+ :message_type, :url, :web_url, :network_id, :system_message, :client_type,
21
+ :sender_type, :sender_id, :thread_id, :conversation_id, :replied_to_id, :body
22
+
23
+ attr_reader :replied_to_id
24
+
25
+ # Creates a new message
26
+ # @!scope class
27
+ def self.create(body, params={})
28
+ api_handler.create_message(body, params)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class MessageBody
17
+ attr_reader :urls, :parsed, :rich
18
+ attr_accessor :plain
19
+
20
+ def initialize(opts={})
21
+ @plain = opts.fetch(:plain,'')
22
+ @parsed = opts.fetch(:parsed,'')
23
+ @rich = opts.fetch(:rich,'')
24
+ @urls = opts.fetch(:urls,'')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class PendingAttachment
17
+
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ module Yammer
16
+ class Thread < Yammer::Base
17
+
18
+ attr_accessor_deffered :participants, :web_url, :references, :thread_starter_id,
19
+ :type, :privacy, :has_attachments, :attachments_meta, :topics, :url, :attachments,
20
+ :direct_message, :participants_count, :stats
21
+
22
+ def first_reply_id
23
+ stats[:first_reply_id]
24
+ end
25
+
26
+ def first_reply
27
+ @first_reply ||= first_reply_id ? Yammer::Message.new(:id => first_reply_id) : nil
28
+ end
29
+
30
+ def latest_reply_id
31
+ stats[:latest_reply_id]
32
+ end
33
+
34
+ def last_reply
35
+ @latest_reply ||= latest_reply_id ? Yammer::Message.new(:id => latest_reply_id) : nil
36
+ end
37
+
38
+ def people
39
+ @people ||= begin
40
+ @participants.map do |part|
41
+ next unless part[:type] == 'user'
42
+ Yammer::User.new(:id => part[:id])
43
+ end
44
+ end
45
+ @people
46
+ end
47
+
48
+ def messages
49
+ @messages = {}
50
+ result = api_handler.messages_in_thread(self.id)
51
+ msgs = result.body[:messages].each do |message|
52
+ msg = Yammer::Message.new(message)
53
+ @messages["#{msg.id}"] = msg
54
+ end
55
+ @messages
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (c) Microsoft Corporation
2
+ # All rights reserved.
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
8
+ # CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
9
+ # WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE,
10
+ # FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ # See the Apache Version 2.0 License for specific language governing
13
+ # permissions and limitations under the License.
14
+ module Yammer
15
+ class User < Yammer::Base
16
+
17
+
18
+ # Returns authenticated user's details
19
+ # @!scope class
20
+ def self.current
21
+ result = api_handler.current_user
22
+ return nil unless result.success?
23
+ new(result.body)
24
+ end
25
+
26
+ # Creates a new user from email address
27
+ # @!scope class
28
+ def self.create(email)
29
+ result = api_handler.create_user(:email => email)
30
+ return nil unless result.created?
31
+ id = result.headers[:location].split('/').last.to_i
32
+ new(:id => id)
33
+ end
34
+
35
+ attr_accessor_deffered :first_name, :last_name, :full_name, :hire_date, :mugshot, :state,
36
+ :type, :admin, :verified_admin, :expertise, :birth_date, :stats, :show_ask_for_photo, :job_title,
37
+ :web_url, :url, :external_urls, :activated_at, :summary, :department, :previous_companies,
38
+ :follow_general_messages, :schools, :interests, :significant_other, :network_name, :network_id,
39
+ :can_broadcast, :web_preferences, :network_domains, :location, :contact, :kids_names, :guid,
40
+ :name, :mugshot_url, :mugshot_url_template, :settings, :timezone
41
+
42
+ # Returns user's primary email
43
+ def email
44
+ @email ||= begin
45
+ self.contact[:email_addresses].map do |e|
46
+ e[:address] if e[:type] == 'primary'
47
+ end.first
48
+ end
49
+ end
50
+
51
+ # Returns all users that this user is following
52
+ def following
53
+ api_handler.users_followed_by(@id)
54
+ end
55
+
56
+ # Returns all user's follwing this user
57
+ def followers
58
+ api_handler.users_following(@id)
59
+ end
60
+
61
+ # Updates the user attributes
62
+ def update!(params)
63
+ api_handler.update_user(@id, params)
64
+ end
65
+ end
66
+ end