verticalresponse 0.1.1

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.
data/lib/resource.rb ADDED
@@ -0,0 +1,152 @@
1
+ # This is the base class for a VerticalResponse resource.
2
+ # It contains common object oriented functionality that other resource classes
3
+ # can use to interact with the API.
4
+
5
+ require_relative 'client'
6
+
7
+ module VerticalResponse
8
+ module API
9
+ class Resource < Client
10
+ class << self
11
+ def class_for_resource(original_class, id = nil)
12
+ # Create a new anonymous class to prevent conflicts with other classes
13
+ new_class = Class.new(original_class)
14
+ new_class.embed_resource(resource_name, id)
15
+ new_class
16
+ end
17
+
18
+ # Exclude methods that are not supported by the current resource API.
19
+ # This applies for common methods that are shared across all classes:
20
+ # - Class methods: all, find, create
21
+ # - Instance methods: update, delete, stats
22
+ def exclude_methods(*methods)
23
+ @excluded_methods = methods
24
+ end
25
+
26
+ def validate_supported_method!(method)
27
+ if @excluded_methods && @excluded_methods.include?(method.to_sym)
28
+ raise NotImplementedError,
29
+ "This method is not supported for the #{ class_name } class"
30
+ end
31
+ end
32
+
33
+ def class_name
34
+ # Use the superclass name if the current class name is not defined
35
+ # (e.g. for anonymous classes)
36
+ name || superclass.name
37
+ end
38
+
39
+ def resource_name
40
+ # Manually pluralize just by adding an 's' and underscore manually
41
+ # We want this wrapper to be Rails-independent
42
+ "#{ class_name.split('::').last.gsub(/(.)([A-Z])/,'\1_\2').downcase }s"
43
+ end
44
+
45
+ def id_regexp
46
+ /\d+/
47
+ end
48
+
49
+ def id_attribute_name
50
+ 'id'
51
+ end
52
+
53
+ # Get the ID of a resource based on a given URL
54
+ def resource_id_from_url(url)
55
+ url.match(/#{ resource_name }\/(#{ id_regexp })/)[1]
56
+ end
57
+
58
+ ##################################
59
+ # Common object oriented methods #
60
+ ##################################
61
+
62
+ # Returns a collection of current class objects.
63
+ # Useful for when we need to have an object oriented way to
64
+ # handle a list of items from an API response
65
+ def object_collection(response)
66
+ response.handle_collection do |response_item|
67
+ self.new(response_item)
68
+ end
69
+ end
70
+
71
+ # Returns all the objects of the current class
72
+ def all(options = {})
73
+ validate_supported_method!(:all)
74
+
75
+ response = Response.new get(resource_uri, build_query_params(options))
76
+
77
+ object_collection(response)
78
+ end
79
+
80
+ # Find and return an object of the current class based on its ID
81
+ def find(id, options = {})
82
+ validate_supported_method!(:find)
83
+
84
+ response = Response.new get(resource_uri(id), build_query_params(options))
85
+
86
+ self.new(response)
87
+ end
88
+
89
+ # Creates a new object of the current class with the parameters provided
90
+ def create(params)
91
+ validate_supported_method!(:create)
92
+
93
+ response = Response.new post(
94
+ resource_uri,
95
+ build_params(params)
96
+ )
97
+ self.new(response)
98
+ end
99
+ end
100
+
101
+ # Returns the ID of the current object based on the response
102
+ def id
103
+ if @id.nil? && response
104
+ if response.attributes && response.attributes.has_key?(self.class::id_attribute_name)
105
+ @id = response.attributes[self.class::id_attribute_name]
106
+ elsif url
107
+ # This case is useful if we need the ID right after a call
108
+ # that does not return any atributes, like create
109
+ @id = self.class.resource_id_from_url(url)
110
+ end
111
+ end
112
+ @id
113
+ end
114
+
115
+ def url
116
+ response.url
117
+ end
118
+
119
+ def update(params)
120
+ self.class.validate_supported_method!(:update)
121
+
122
+ response = Response.new self.class.put(
123
+ self.class.resource_uri(id),
124
+ self.class.build_params(params)
125
+ )
126
+ self.class.new(response)
127
+ end
128
+
129
+ def delete(params = {})
130
+ self.class.validate_supported_method!(:delete)
131
+
132
+ Response.new self.class.delete(
133
+ self.class.resource_uri(id),
134
+ self.class.build_params(params)
135
+ )
136
+ end
137
+
138
+ # Returns the summary stats for the current object
139
+ def stats(options = {})
140
+ self.class.validate_supported_method!(:stats)
141
+
142
+ if response.links && response.links.has_key?('stats')
143
+ uri = response.links['stats']['url']
144
+ else
145
+ uri = self.class.resource_uri(id, 'stats')
146
+ end
147
+
148
+ Response.new self.class.get(uri, self.class.build_query_params(options))
149
+ end
150
+ end
151
+ end
152
+ end
data/lib/response.rb ADDED
@@ -0,0 +1,48 @@
1
+ # Class that represents the response you can get from calling any action
2
+ # of the VerticalResponse API.
3
+
4
+ require_relative 'error'
5
+
6
+ module VerticalResponse
7
+ module API
8
+ class Response
9
+ attr_reader :url, :items, :attributes, :links, :success, :error, :raw_response
10
+
11
+ def initialize(response)
12
+ @url = response['url']
13
+ @items = response['items']
14
+ @attributes = response['attributes']
15
+ @links = response['links']
16
+ @success = response['success']
17
+ @error = response['error']
18
+ @raw_response = response
19
+
20
+ handle_error unless success?
21
+ end
22
+
23
+ # Iterate through the collection of items and yield a new Response object
24
+ # for each one of them
25
+ def handle_collection
26
+ items.map do |item|
27
+ yield(Response.new(item))
28
+ end
29
+ end
30
+
31
+ # Determines if the response is a successful one or not
32
+ def success?
33
+ !error
34
+ end
35
+
36
+ # Handles the case of an error response
37
+ def handle_error
38
+ api_error = Error.new(error['message'] || error.inspect)
39
+ # Keep track of the original error code and response object
40
+ # for clients to have access to them if they rescue the exception
41
+ api_error.code = error['code']
42
+ api_error.api_response = self
43
+
44
+ raise api_error
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ # Class that represents a social post resource from the VerticalResponse API.
2
+ # It has the ability to make REST calls to the API, as well as to wrap
3
+ # the social post objects we get as response.
4
+ #
5
+ # NOTE: This class does not necessarily include all the available methods
6
+ # the API has for the social post resource. You can consider this an initial approach
7
+ # for an object oriented solution that you can expand according to your needs.
8
+
9
+ require_relative 'resource'
10
+ require_relative 'message'
11
+
12
+ module VerticalResponse
13
+ module API
14
+ class SocialPost < Resource
15
+ class << self
16
+ # Base URI for the Email resource
17
+ def base_uri(*args)
18
+ @base_uri ||= File.join(super.to_s, 'messages', 'social_posts')
19
+ end
20
+
21
+ # Overwrite from parent class since it's a special type of
22
+ # resource name (with messages at the beginning)
23
+ def resource_name
24
+ 'messages/social_posts'
25
+ end
26
+
27
+ # The SocialPost API does not support the 'all' method on its own for now.
28
+ # To get all social posts we need to do it through the Message API
29
+ def all(options = {})
30
+ Message.all(options.merge({ :message_type => MESSAGE_TYPE }))
31
+ end
32
+ end
33
+
34
+ MESSAGE_TYPE = 'social_post'
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ require 'httparty'
2
+
3
+ require_relative 'client.rb'
4
+ require_relative 'contact.rb'
5
+ require_relative 'custom_field.rb'
6
+ require_relative 'email.rb'
7
+ require_relative 'error.rb'
8
+ require_relative 'list.rb'
9
+ require_relative 'message.rb'
10
+ require_relative 'oauth.rb'
11
+ require_relative 'resource.rb'
12
+ require_relative 'response.rb'
13
+ require_relative 'social_post.rb'
14
+
15
+ module VerticalResponse
16
+ CONFIG = {
17
+ host: 'vrapi.verticalresponse.com',
18
+ port: "",
19
+ protocol: 'https'
20
+ }
21
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: verticalresponse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Cosmin Atanasiu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Gem used to connect to VerticalResponse.com''s API '
14
+ email: cosmin@wishpond.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files:
18
+ - LICENSE
19
+ - README.md
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - lib/client.rb
24
+ - lib/contact.rb
25
+ - lib/custom_field.rb
26
+ - lib/email.rb
27
+ - lib/error.rb
28
+ - lib/list.rb
29
+ - lib/message.rb
30
+ - lib/oauth.rb
31
+ - lib/resource.rb
32
+ - lib/response.rb
33
+ - lib/social_post.rb
34
+ - lib/verticalresponse.rb
35
+ homepage:
36
+ licenses:
37
+ - GPLv3
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.2.2
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Gem used to connect to VerticalResponse.com's API
59
+ test_files: []