sfdc 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +8 -8
  2. data/lib/sfdc.rb +39 -1
  3. data/lib/sfdc/attachment.rb +23 -0
  4. data/lib/sfdc/chatter/comment.rb +10 -0
  5. data/lib/sfdc/chatter/conversation.rb +100 -0
  6. data/lib/sfdc/chatter/feed.rb +64 -0
  7. data/lib/sfdc/chatter/feed_item.rb +40 -0
  8. data/lib/sfdc/chatter/feeds.rb +5 -0
  9. data/lib/sfdc/chatter/filter_feed.rb +14 -0
  10. data/lib/sfdc/chatter/group.rb +45 -0
  11. data/lib/sfdc/chatter/group_membership.rb +9 -0
  12. data/lib/sfdc/chatter/like.rb +9 -0
  13. data/lib/sfdc/chatter/message.rb +29 -0
  14. data/lib/sfdc/chatter/photo_methods.rb +55 -0
  15. data/lib/sfdc/chatter/record.rb +122 -0
  16. data/lib/sfdc/chatter/subscription.rb +9 -0
  17. data/lib/sfdc/chatter/user.rb +153 -0
  18. data/lib/sfdc/client.rb +98 -0
  19. data/lib/sfdc/client/api.rb +320 -0
  20. data/lib/sfdc/client/authentication.rb +40 -0
  21. data/lib/sfdc/client/caching.rb +26 -0
  22. data/lib/sfdc/client/canvas.rb +12 -0
  23. data/lib/sfdc/client/connection.rb +74 -0
  24. data/lib/sfdc/client/picklists.rb +90 -0
  25. data/lib/sfdc/client/streaming.rb +31 -0
  26. data/lib/sfdc/client/verbs.rb +68 -0
  27. data/lib/sfdc/collection.rb +40 -0
  28. data/lib/sfdc/config.rb +136 -0
  29. data/lib/sfdc/mash.rb +65 -0
  30. data/lib/sfdc/middleware.rb +29 -0
  31. data/lib/sfdc/middleware/authentication.rb +63 -0
  32. data/lib/sfdc/middleware/authentication/password.rb +20 -0
  33. data/lib/sfdc/middleware/authentication/token.rb +15 -0
  34. data/lib/sfdc/middleware/authorization.rb +19 -0
  35. data/lib/sfdc/middleware/caching.rb +24 -0
  36. data/lib/sfdc/middleware/gzip.rb +31 -0
  37. data/lib/sfdc/middleware/instance_url.rb +18 -0
  38. data/lib/sfdc/middleware/logger.rb +40 -0
  39. data/lib/sfdc/middleware/mashify.rb +18 -0
  40. data/lib/sfdc/middleware/multipart.rb +53 -0
  41. data/lib/sfdc/middleware/raise_error.rb +23 -0
  42. data/lib/sfdc/signed_request.rb +48 -0
  43. data/lib/sfdc/sobject.rb +64 -0
  44. data/lib/sfdc/upload_io.rb +20 -0
  45. data/lib/sfdc/version.rb +1 -1
  46. metadata +59 -4
  47. data/lib/sfdc/sfdc.rb +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MWE4YzU3MmM5ZTliOWY4YjI0OTY0ZWFlZmFhMjA2YWUzMTllNTViZQ==
4
+ MGU4YWYxYWM2Nzg5MmVlNWJlZGZmYTJkNDA1NWVjNDBhNGM1ODdjOQ==
5
5
  data.tar.gz: !binary |-
6
- MTNkMmNlNjM0Y2YzMmVkMDcyOGFlOTQ4N2NiOWYyYWIyMmI3YzRlZA==
6
+ ZWY5NTg2NmZlMWVjNTNkMGFiNTMwNTg3ZjM3ZTkyZjUxYmNjNGI1Yw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZGFhNDM4N2Y3MzRhNzRiNDgzYzYzNDMxNjJjMWU5NjA0YWViNmM3MmVjMTlk
10
- ODZkNjcyMDJjNTQxNDU4ZTA4OWZhMjFmNDU1MTE4ZjM2YzM3ZWQ5M2E3Njg4
11
- ZGI3ZjkxNjFhN2I0ZGRlMGJlZmI4NGI5YmI3NThjM2JiZjhhYWM=
9
+ NWFiYTBhMjhhYTU4YmY1ZDQ4MzIyYmY1NDEyZDM5ZmY3MThmOGZkZTlhYzNi
10
+ MGI1MjYxMGVkYTBmNGQzOWEyZTFlNzNmMTIyZjJkMDdkMWY1NjVhODMwM2Yz
11
+ YjIxNzM4MTE0NDExZjI5YmNmOTQyODBlMTYyMjA1NTE5N2I3YzA=
12
12
  data.tar.gz: !binary |-
13
- NGNkNzA2ZTFlZGUzZDg3ZTI3ZWY4NzU5YWNjMjQxYzViNWU0MTIxODM1NGY0
14
- YWVmZTA4OGRhMDNjZjg0MzNiNTc4OTljY2M1NzZlN2FlNjgyMDM0NDcyYWZh
15
- ZWFlNDlkODA2ZTJkZGJkYTg0MTIxNmNjMDM5ZDA5ZThkMTgxMTI=
13
+ MGE3N2E4MDc5ODQyZGQ3NDg3ZDgwOGQxZjExNzUwMGQ3MDFhNzM5MDQ2MTUy
14
+ Y2RhZTUzYTkzNWJhZGJlNzQzNTg1ODhkYTRkZDQ3NGY1ZTVhZTgyYWQ2ZDll
15
+ MGNkMjIyMjZjMDk1OTFhMzNmMjk3NGNiMTZlY2E5MWZmMDdiNTY=
data/lib/sfdc.rb CHANGED
@@ -1,5 +1,43 @@
1
1
  require "sfdc/version"
2
2
 
3
+ require 'faraday'
4
+ require 'faraday_middleware'
5
+ require 'json'
6
+
7
+ require 'sfdc/version'
8
+ require 'sfdc/config'
9
+
3
10
  module Sfdc
4
- # Your code goes here...
11
+ autoload :SignedRequest, 'sfdc/signed_request'
12
+ autoload :Collection, 'sfdc/collection'
13
+ autoload :Middleware, 'sfdc/middleware'
14
+ autoload :Attachment, 'sfdc/attachment'
15
+ autoload :UploadIO, 'sfdc/upload_io'
16
+ autoload :SObject, 'sfdc/sobject'
17
+ autoload :Client, 'sfdc/client'
18
+ autoload :Mash, 'sfdc/mash'
19
+
20
+ AuthenticationError = Class.new(StandardError)
21
+ UnauthorizedError = Class.new(StandardError)
22
+
23
+ class << self
24
+ # Alias for Sfdc::Client.new
25
+ def new(options = {}, &block)
26
+ Sfdc::Client.new(options, &block)
27
+ end
28
+
29
+ # Helper for decoding signed requests.
30
+ def decode_signed_request(*args)
31
+ SignedRequest.decode(*args)
32
+ end
33
+ end
34
+
35
+ # Add .tap method in Ruby 1.8
36
+ module CoreExtensions
37
+ def tap
38
+ yield self
39
+ self
40
+ end
41
+ end
42
+ Object.send :include, Sfdc::CoreExtensions unless Object.respond_to? :tap
5
43
  end
@@ -0,0 +1,23 @@
1
+ module Sfdc
2
+ class Attachment < Sfdc::SObject
3
+
4
+ # Public: Returns the body of the attachment.
5
+ #
6
+ # Examples
7
+ #
8
+ # attachment = client.query('select Id, Name, Body from Attachment').first
9
+ # File.open(attachment.Name, 'wb') { |f| f.write(attachment.Body) }
10
+ def Body
11
+ ensure_id && ensure_body
12
+ @client.get(super).body
13
+ end
14
+
15
+ private
16
+
17
+ def ensure_body
18
+ return true if self.Body?
19
+ raise 'You need to query the Body for the record first.'
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ require 'sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+
6
+ # A comment posted on a FeedItem.
7
+ class Comment < Record
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,100 @@
1
+ require 'sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+ # A thread of private messages. When calling +Conversation.find+ or +Conversation.all+, you must pass +:user_id => <my_user_id>+ in the _parameters_
6
+ #
7
+ # Conversation.all(@client, :user_id => "me")
8
+ # Conversation.find(@client, "conversationId", :user_id => "f80ad89f9d98d89dfd89")
9
+ class Conversation < Record
10
+
11
+ # Creates a new Conversation and sets its +id+ and +url+ to values obtained from the server response.
12
+ def initialize(client, response)
13
+ super
14
+ @id ||= @raw_hash["conversationId"]
15
+ @url ||= @raw_hash["conversationUrl"]
16
+ end
17
+
18
+ # Find the Conversation identified by _cid_ and archive it. Returns the updated Conversation.
19
+ #
20
+ # Conversation.archive(@client, "fakeid")
21
+ def self.archive(client, cid)
22
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
23
+ response = client.http_patch(url, nil, :archived => "true")
24
+ Conversation.new(client, response.body)
25
+ end
26
+
27
+ # Find the Conversation identified by _cid_ and unarchive it. Returns the updated Conversation.
28
+ #
29
+ # Conversation.unarchive(@client, "fakeid")
30
+ def self.unarchive(client, cid)
31
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
32
+ response = client.http_patch(url, nil, :archived => "false")
33
+ Conversation.new(client, response.body)
34
+ end
35
+
36
+ # Find the Conversation identified by _cid_ and mark it as read. Returns the updated Conversation.
37
+ #
38
+ # Conversation.mark_read(@client, "fakeid")
39
+ def self.mark_read(client, cid)
40
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
41
+ response = client.http_patch(url, nil, :read => "true")
42
+ Conversation.new(client, response.body)
43
+ end
44
+
45
+ # Find the Conversation identified by _cid_ and mark it as unread. Returns the updated Conversation.
46
+ #
47
+ # Conversation.mark_unread(@client, "fakeid")
48
+ def self.mark_unread(client, cid)
49
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
50
+ response = client.http_patch(url, nil, :read => "false")
51
+ Conversation.new(client, response.body)
52
+ end
53
+
54
+ # Gets all messages for the Conversation specified by _cid_ and the User specified by _uid_. Returns a Collection of Message objects.
55
+ def self.messages(client, uid, cid)
56
+ conversation = self.find(client, cid, :user_id => uid)
57
+ collection = Sfdc::Collection.new(client, nil, conversation.raw_hash["messages"]["nextPageUrl"], conversation.raw_hash["messages"]["previousPageUrl"], conversation.raw_hash["messages"]["currentPageUrl"])
58
+ conversation.raw_hash["messages"]["messages"].each do |item|
59
+ collection << Message.new(client, item)
60
+ end
61
+ collection
62
+ end
63
+
64
+ # Archive this Conversation.
65
+ def archive
66
+ self.class.archive(self.client, self.id)
67
+ end
68
+
69
+ # Unarchive this Conversation.
70
+ def unarchive
71
+ self.class.unarchive(self.client, self.id)
72
+ end
73
+
74
+ # Mark this Conversation as read.
75
+ def mark_read
76
+ self.class.mark_read(self.client, self.id)
77
+ end
78
+
79
+ # Mark this Conversation as unread.
80
+ def mark_unread
81
+ self.class.mark_unread(self.client, self.id)
82
+ end
83
+
84
+ # Return a Collection of messages from this Conversation.
85
+ def messages
86
+ collection = Sfdc::Collection.new(client, nil, self.raw_hash["messages"]["nextPageUrl"], self.raw_hash["messages"]["previousPageUrl"], self.raw_hash["messages"]["currentPageUrl"])
87
+ self.raw_hash["messages"]["messages"].each do |item|
88
+ collection << Message.new(client, item)
89
+ end
90
+ collection
91
+ end
92
+
93
+ protected
94
+
95
+ def self.search_parameter_name
96
+ :Q
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,64 @@
1
+ require 'json'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+ # Parent class of all feeds and inherits from Collection. This class is not intended to be instantiated. Methods should be called on subclasses, which are all are dynamically defined (except for FilterFeed). Defined feeds are *NewsFeed*, *UserProfileFeed*, *RecordFeed*, *ToFeed*, *PeopleFeed*, *GroupsFeed*, *FilesFeed*, *CompanyFeed*, and *FilterFeed*.
6
+ class Feed < Collection
7
+
8
+ # Returns an enumerable Feed of FeedItem objects that make up the feed with the specified _id_. Should not be called as a class method on Feed, but as a method on subclasses.
9
+ #
10
+ # NewsFeed.find(@client) #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
11
+ # PeopleFeed.find(@client, "userid") #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
12
+ # FilterFeed.find(@client, "me", "000") #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
13
+ #
14
+ # _id_prefix_ is only applicable for FilterFeed.
15
+ def self.find(client, id="me", id_prefix=nil)
16
+ path_components = %w(services data)
17
+ path_components << "v#{client.version}"
18
+ path_components.concat(%w(chatter feeds))
19
+ path_components << feed_type
20
+ path_components << id unless feed_type == "company"
21
+ path_components << id_prefix
22
+ path_components << "feed-items"
23
+ path = "/" + path_components.compact.join('/')
24
+ result = client.http_get(path)
25
+ response = JSON.parse(result.body)
26
+ collection = self.new(client, nil, response["nextPageUrl"], response["previousPageUrl"], response["currentPageUrl"])
27
+ response["items"].each do |item|
28
+ collection << FeedItem.new(client, item)
29
+ end
30
+ collection
31
+ end
32
+
33
+ # Posts a FeedItem to a Feed specified by _user_id_. Should not be called as a class method on Feed, but as a method on subclasses.
34
+ #
35
+ # UserProfileFeed.post(@client, "me", :text => "This is a status update about Salesforce.", :url => "http://www.salesforce.com")
36
+ #
37
+ # Returns the newly created FeedItem.
38
+ def self.post(client, user_id, parameters)
39
+ url = "/services/data/v#{client.version}/chatter/feeds/#{feed_type}/#{user_id}/feed-items"
40
+ response = client.http_post(url, nil, parameters)
41
+ Sfdc::Chatter::FeedItem.new(client, response.body)
42
+ end
43
+
44
+ # Posts a file to a Feed specified by _user_id_. Should not be called as a class method on Feed, but as a method on subclasses.
45
+ #
46
+ # UserProfileFeed.post_file(@client, "me", File.open("MyFile"), "text/plain", "MyFile", :desc => "This is an uploaded text file.")
47
+ #
48
+ # Returns the newly created FeedItem.
49
+ def self.post_file(client, user_id, io, file_type, file_name, parameters={})
50
+ url = "/services/data/v#{client.version}/chatter/feeds/#{feed_type}/#{user_id}/feed-items"
51
+ response = client.http_multipart_post(url, {"feedItemFileUpload" => UploadIO.new(io, file_type, file_name), "fileName" => file_name}, parameters)
52
+ Sfdc::Chatter::FeedItem.new(client, response.body)
53
+ end
54
+
55
+ private
56
+
57
+ def self.feed_type
58
+ self.name.match(/.+::(.+)Feed$/)[1].resourcerize
59
+ end
60
+ end
61
+
62
+ FEED_TYPES = %w(News UserProfile Record To People Groups Files Company)
63
+ end
64
+ end
@@ -0,0 +1,40 @@
1
+ require 'Sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+
6
+ # An item in a Feed.
7
+ class FeedItem < Record
8
+
9
+ # Returns a Collection of comments that were posted on this FeedItem instance.
10
+ def comments
11
+ collection = Sfdc::Collection.new(self.client, self.raw_hash["comments"]["total"], self.raw_hash["comments"]["nextPageUrl"], nil, self.raw_hash["comments"]["currentPageUrl"])
12
+ collection.concat(self.raw_hash["comments"]["comments"])
13
+ end
14
+
15
+ # Returns a Collection of likes for this FeedItem instance.
16
+ def likes
17
+ collection = Sfdc::Collection.new(self.client, self.raw_hash["likes"]["total"], self.raw_hash["likes"]["nextPageUrl"], self.raw_hash["likes"]["previousPageUrl"], self.raw_hash["likes"]["currentPageUrl"])
18
+ collection.concat(self.raw_hash["likes"]["likes"])
19
+ end
20
+
21
+ # Like this FeedItem.
22
+ def like
23
+ result = self.client.http_post("/services/data/v#{self.client.version}/chatter/feed-items/#{self.id}/likes")
24
+ Like.new(self.client, result.body)
25
+ end
26
+
27
+ # Post a Comment on this FeedItem with content _text_.
28
+ def comment(text)
29
+ result = self.client.http_post("/services/data/v#{self.client.version}/chatter/feed-items/#{self.id}/comments", nil, :text => text)
30
+ Comment.new(self.client, result.body)
31
+ end
32
+
33
+ protected
34
+
35
+ def self.collection_from_response(response)
36
+ response["items"]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ require 'Sfdc/chatter/feed'
2
+
3
+ Sfdc::Chatter::FEED_TYPES.each do |feed_type|
4
+ Sfdc::Chatter.const_set("#{feed_type}Feed", Class.new(Sfdc::Chatter::Feed))
5
+ end
@@ -0,0 +1,14 @@
1
+ module Sfdc
2
+ module Chatter
3
+ # Filter feeds contain items pertaining to both a user and another specified resource.
4
+ class FilterFeed < Feed
5
+
6
+ # Lists all FilterFeeds for the user with id _user_id_.
7
+ def self.feeds(client, user_id="me")
8
+ url = "/services/data/v#{client.version}/chatter/feeds/filter/#{user_id}"
9
+ result = client.http_get(url)
10
+ JSON.parse(result.body)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,45 @@
1
+ require 'Sfdc/chatter/record'
2
+ require 'Sfdc/chatter/photo_methods'
3
+
4
+ module Sfdc
5
+ module Chatter
6
+ # A group of Users
7
+ class Group < Record
8
+ include PhotoMethods
9
+
10
+ # Returns a Collection of GroupMembership instances for the Group identified by _group_id_.
11
+ def self.members(client, group_id)
12
+ url = "/services/data/v#{client.version}/chatter/groups/#{group_id}/members"
13
+ result = client.http_get(url)
14
+ response = JSON.parse(result.body)
15
+ collection = Sfdc::Collection.new(client, response["totalMemberCount"], response["nextPageUrl"], response["previousPageUrl"], response["currentPageUrl"])
16
+ response["members"].each do |member|
17
+ collection << GroupMembership.new(client, member)
18
+ end
19
+ collection
20
+ end
21
+
22
+ # Join the group identified by _group_id_ as the user identified by _user_id_.
23
+ def self.join(client, group_id, user_id="me")
24
+ url = "/services/data/v#{client.version}/chatter/groups/#{group_id}/members"
25
+ response = client.http_post(url, nil, :userId => user_id)
26
+ GroupMembership.new(client, response.body)
27
+ end
28
+
29
+ # Get a Collection of GroupMembership objects for this Group. Always makes a call to the server.
30
+ def members!
31
+ self.class.members(self.client, self.id)
32
+ end
33
+
34
+ # Get a Collection of GroupMembership objects for this Group. Returns cached data if it has been called before.
35
+ def members
36
+ @members ||= members!
37
+ end
38
+
39
+ # Join this Group as the user identified by _user_id_.
40
+ def join(user_id="me")
41
+ self.class.join(self.client, self.id, user_id)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,9 @@
1
+ require 'Sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+ # A GroupMembership represents the membership of a certain User in a certain Group.
6
+ class GroupMembership < Record
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'Sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+ # A like on a FeedItem
6
+ class Like < Record
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ require 'Sfdc/chatter/record'
2
+
3
+ module Sfdc
4
+ module Chatter
5
+ # A private message between two or more Users
6
+ class Message < Record
7
+
8
+ # Send a private message with the content _text_ to each user in the _recipients_ list.
9
+ def self.send_message(client, recipients, text)
10
+ url = "/services/data/v#{client.version}/chatter/users/me/messages"
11
+ recipients = recipients.is_a?(Array) ? recipients : [recipients]
12
+ response = client.http_post(url, nil, :text => text, :recipients => recipients.join(','))
13
+ Message.new(client, response.body)
14
+ end
15
+
16
+ # Send a reply to the message identified by _in_reply_to_message_id_ with content _text_.
17
+ def self.reply(client, in_reply_to_message_id, text)
18
+ url = "/services/data/v#{client.version}/chatter/users/me/messages"
19
+ response = client.http_post(url, nil, :text => text, :inReplyTo => in_reply_to_message_id)
20
+ Message.new(client, response.body)
21
+ end
22
+
23
+ # Send a reply to this Message with content _text_.
24
+ def reply(text)
25
+ self.class.reply(self.client, self.id, text)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,55 @@
1
+ module Sfdc
2
+ module Chatter
3
+ # Defines methods for entities that can have photos i.e. Users, Groups.
4
+ module PhotoMethods
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ # Defines class methods for resources that can have photos.
10
+ module ClassMethods
11
+ # Returns a Hash with urls for the small and large versions of the photo for a resource.
12
+ def photo(client, resource_id)
13
+ url = "/services/data/v#{client.version}/chatter/#{self.resource_name}/#{resource_id}/photo"
14
+ result = client.http_get(url)
15
+ JSON.parse(result.body)
16
+ end
17
+
18
+ # Uploads a photo for a resource with id _resource_id_.
19
+ #
20
+ # User.upload_photo(@client, "me", File.open("SomePicture.png"), "image/png")
21
+ def upload_photo(client, resource_id, io, file_type)
22
+ url = "/services/data/v#{client.version}/chatter/#{self.resource_name}/#{resource_id}/photo"
23
+ result = client.http_multipart_post(url, {"fileUpload" => UploadIO.new(io, file_type)})
24
+ JSON.parse(result.body)
25
+ end
26
+
27
+ # Deletes the photo for the resource with id _resource_id_.
28
+ def delete_photo(client, resource_id)
29
+ client.http_delete "/services/data/v#{client.version}/chatter/#{self.resource_name}/#{resource_id}/photo"
30
+ end
31
+ end
32
+
33
+ # Returns a Hash with urls for the small and large versions of the photo for this resource.
34
+ #
35
+ # User.find(@client, "me").photo #=> {"smallPhotoUrl"=>"/small/photo/url", "largePhotoUrl"=>"/large/photo/url"}
36
+ def photo
37
+ self.raw_hash["photo"]
38
+ end
39
+
40
+ # Uploads a photo for this resource.
41
+ #
42
+ # me = User.find(@client)
43
+ # me.upload_photo(File.open("SomePicture.png"), "image/png")
44
+ def upload_photo(io, file_type)
45
+ self.class.upload_photo(self.client, self.id, io, file_type)
46
+ end
47
+
48
+ # Deletes the photo for this resource.
49
+ def delete_photo
50
+ self.class.delete_photo(self.client, self.id)
51
+ photo
52
+ end
53
+ end
54
+ end
55
+ end