verticalresponse 0.1.1

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