relateiq 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjFkYmNmMThiNjIzN2IzODMyYWMzNTNkMGQxMjE4NTQ0ZGZhODdmOA==
5
+ data.tar.gz: !binary |-
6
+ ODEwMTQyYzg1MTdiZmUyYWVlOTc3OTJjNTU5NWRmMzE4MjYxMDg2ZQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MDgwZDlkMWNkNDAzYTI4MDNlMjg1ZTIyMzEwMTlkYzhmZmMyNzhhYjNhZWU3
10
+ OGJmZTlhNTRiZmExZDRlODgzMDI2ZmI5ZDc2YWI2Y2VkOTZjYzU1YjhlYzlj
11
+ NTlhMTNlMmY2MTNhM2YxNjJjNmZiMmFkNTg2ZTA5M2FiMjljMzQ=
12
+ data.tar.gz: !binary |-
13
+ ZTc1NTc4OWJmY2UxNzE0N2RkZTk5YTU3OTU0NTg1OTliMzQ1MDc3ZDFjZmNi
14
+ NzNmYWM0YjM2NjM0YWI4ZjIzZjllYThmM2UzOGJkMWY5MTY5YzAxYzRlMzEy
15
+ N2E5MDI0NTFiOWJlODZmMTBiOTJiOTg1MWJhMWZmZjMzYWY5MDg=
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'faraday', '0.8.9'
4
+ gem 'faraday_middleware', '~> 0.9.0'
5
+ gem 'json'
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ actionview (4.1.0.rc2)
5
+ activesupport (= 4.1.0.rc2)
6
+ builder (~> 3.1)
7
+ erubis (~> 2.7.0)
8
+ activesupport (4.1.0.rc2)
9
+ i18n (~> 0.6, >= 0.6.9)
10
+ json (~> 1.7, >= 1.7.7)
11
+ minitest (~> 5.1)
12
+ thread_safe (~> 0.1)
13
+ tzinfo (~> 1.1)
14
+ atomic (1.1.16)
15
+ builder (3.2.2)
16
+ erubis (2.7.0)
17
+ faraday (0.8.9)
18
+ multipart-post (~> 1.2.0)
19
+ faraday_middleware (0.9.0)
20
+ faraday (>= 0.7.4, < 0.9)
21
+ i18n (0.6.9)
22
+ json (1.8.1)
23
+ minitest (5.3.1)
24
+ multipart-post (1.2.0)
25
+ thread_safe (0.3.1)
26
+ atomic (>= 1.1.7, < 2)
27
+ tzinfo (1.1.0)
28
+ thread_safe (~> 0.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ actionview
35
+ faraday (= 0.8.9)
36
+ faraday_middleware (~> 0.9.0)
37
+ json
@@ -0,0 +1,89 @@
1
+ require 'active_support'
2
+ require 'cgi'
3
+ require 'faraday'
4
+ require 'faraday_middleware'
5
+ require 'json'
6
+
7
+ require File.dirname(__FILE__) + '/relateiq/riq_object'
8
+ require File.dirname(__FILE__) + '/relateiq/riq_list'
9
+ require File.dirname(__FILE__) + '/relateiq/api_resource'
10
+
11
+ require File.dirname(__FILE__) + '/relateiq/list'
12
+
13
+ module RelateIQ
14
+ class << self
15
+
16
+ attr_accessor :api_key, :api_secret, :base_url, :version
17
+
18
+ def configure(params)
19
+ raise ArgumentError, "You must include both the api_key and api_secret" unless (params.include?(:api_key) && params.include?(:api_secret))
20
+ @api_key = params[:api_key]
21
+ @api_secret = params[:api_secret]
22
+ @base_url = params[:base_url]
23
+
24
+ @version = 'v1'
25
+ @version = params[:version] if params[:version]
26
+
27
+ true
28
+ end
29
+
30
+ def get(string, params = {})
31
+ string += "#{URI.parse(string).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
32
+ request :get, uri(string)
33
+ end
34
+
35
+ def post(string, params={})
36
+ request :post, uri(string), params
37
+ end
38
+
39
+ def put(string, params={})
40
+ request :put, uri(string), params
41
+ end
42
+
43
+ def delete(string)
44
+ request :delete, uri(string)
45
+ end
46
+
47
+ private
48
+ def uri_encode(params = {})
49
+ params.map { |k,v| "#{k}=#{url_encode(v)}" }.join('&')
50
+ end
51
+
52
+ def url_encode(key)
53
+ URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
54
+ end
55
+
56
+ def uri(string)
57
+ string
58
+ end
59
+
60
+ def request(method,*args)
61
+ conn = Faraday.new(:url => @base_url) do |faraday|
62
+ # faraday.response :logger
63
+ faraday.request :json
64
+ faraday.response :json, :content_type => /\bjson$/
65
+ faraday.use :instrumentation
66
+ faraday.adapter Faraday.default_adapter
67
+ end
68
+ conn.basic_auth(@api_key, @api_secret)
69
+ conn.headers.update({'Content-Type' => 'application/json'})
70
+
71
+ res = conn.send method.to_sym, *args
72
+
73
+ case res.status
74
+ when 401
75
+ raise "Invalid credentials"
76
+ when 400...599
77
+ if res.body.include? 'error'
78
+ raise [res.body['error'], *args].join(' ')
79
+ else
80
+ #raise 'Unknown error'
81
+ raise [res.body, *args].join(' ')
82
+ end
83
+ else
84
+ res.body
85
+ end
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,76 @@
1
+ module RelateIQ
2
+ class APIResource < RiqObject
3
+ def self.name
4
+ n = self.to_s.split('::')[-1]
5
+ # Hyphenize
6
+ n.scan(/([A-Z][a-z]*)/).join('-').downcase
7
+ end
8
+
9
+ def name
10
+ n = self.class.to_s.split('::')[-1]
11
+ # Hyphenize
12
+ n.scan(/([A-Z][a-z]*)/).join('-').downcase
13
+ end
14
+
15
+ def self.find(id, params = {}, url = nil)
16
+ path = url.nil? ? "#{name}s/#{id}" : url
17
+ instance = self.new(id)
18
+ response = RelateIQ.get(path, params)
19
+ instance.refresh_from(response)
20
+ instance
21
+ end
22
+
23
+ def self.all(params = {}, url = nil)
24
+ params = {} unless params.is_a? Hash
25
+ plural = "#{name}s"
26
+ path = url.nil? ? "#{plural}" : url
27
+ response = RelateIQ.get(path, params)
28
+ objects = response['objects'] || []
29
+ list = Array.new
30
+ objects.each do |v|
31
+ if v.class == Hash && v['id'].nil?
32
+ c = self.new(v['id'])
33
+ else
34
+ c = self.new
35
+ end
36
+ c.refresh_from(v)
37
+ list.push(c)
38
+ end
39
+ return RiqList.new(list)
40
+ end
41
+
42
+ def update(params = {})
43
+ path = "#{self.name}s/#{self.id}"
44
+ p = { self.name => params }.to_json
45
+ response = RelateIQ.put(path, p)
46
+ end
47
+
48
+ def self.update(id, params = {})
49
+ plural = "#{name}s"
50
+ path = "#{plural}/#{id}"
51
+ p = { self.name => params }.to_json
52
+ response = RelateIQ.put(path, p)
53
+ end
54
+
55
+
56
+ def create(params = {})
57
+ plural = "#{name}s"
58
+ path = "#{plural}/#{self.id}"
59
+ p = { self.name => params }.to_json
60
+ resonse = RelateIQ.post(path, p)
61
+ end
62
+
63
+ def delete(params = {})
64
+ plural = "#{name}s"
65
+ path = "#{plural}/#{self.id}"
66
+ RelateIQ.delete(path)
67
+ end
68
+
69
+ def self.delete(id, params = {})
70
+ plural = "#{name}s"
71
+ path = "#{plural}/#{id}"
72
+ RelateIQ.delete(path)
73
+ end
74
+ end
75
+ end
76
+
@@ -0,0 +1,7 @@
1
+ module RelateIQ
2
+ class List < APIResource
3
+
4
+ # No Custom Functions
5
+
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module RelateIQ
2
+ class RiqList
3
+ include Enumerable
4
+
5
+ attr_accessor :list
6
+
7
+ def initialize(list)
8
+ @list = list
9
+ end
10
+
11
+ def <<(val)
12
+ @list << val
13
+ end
14
+
15
+ def each(&block)
16
+ @list.each(&block)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,110 @@
1
+ module RelateIQ
2
+ class RiqObject
3
+ include Enumerable
4
+
5
+ attr_accessor :api_key, :values
6
+ @@permanent_attributes = Set.new([:id])
7
+
8
+ def initialize(id=nil, api_key=nil)
9
+ # parameter overloading!
10
+ if id.kind_of?(Hash)
11
+ @retrieve_options = id.dup
12
+ @retrieve_options.delete(:id)
13
+ id = id[:id]
14
+ else
15
+ @retrieve_options = {}
16
+ end
17
+
18
+ @api_key = api_key
19
+ @values = {}
20
+ # This really belongs in APIResource, but not putting it there allows us
21
+ # to have a unified inspect method
22
+ @unsaved_values = Set.new
23
+ @transient_values = Set.new
24
+ @values[:id] = id if id
25
+ end
26
+
27
+ def refresh_from(values)
28
+
29
+ @previous_metadata = values[:metadata]
30
+ removed = Set.new(@values.keys - values.keys)
31
+ added = Set.new(values.keys - @values.keys)
32
+ # Wipe old state before setting new. This is useful for e.g. updating a
33
+ # customer, where there is no persistent card parameter. Mark those values
34
+ # which don't persist as transient
35
+
36
+ instance_eval do
37
+ add_accessors(added)
38
+ end
39
+ values.each do |k, v|
40
+ @values[k.to_sym] = v
41
+ end
42
+ self
43
+ end
44
+
45
+ def self.construct_from(values, api_key=nil)
46
+ obj = self.new(values[:id], api_key)
47
+ obj.refresh_from(values, api_key)
48
+ obj
49
+ end
50
+
51
+ def inspect()
52
+ id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
53
+ "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
54
+ end
55
+
56
+ def metaclass
57
+ class << self; self; end
58
+ end
59
+
60
+ def add_accessors(keys)
61
+ metaclass.instance_eval do
62
+ keys.each do |k|
63
+ next if @@permanent_attributes.include?(k)
64
+ k_eq = :"#{k}="
65
+ #define_method(k) { @values[k] }
66
+ define_method(k_eq) do |v|
67
+ if v == ""
68
+ raise ArgumentError.new(
69
+ "You cannot set #{k} to an empty string." +
70
+ "We interpret empty strings as nil in requests." +
71
+ "You may set #{self}.#{k} = nil to delete the property.")
72
+ end
73
+ @values[k.to_sym] = v
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def method_missing(name, *args)
80
+ # TODO: only allow setting in updateable classes.
81
+ if name.to_s.end_with?('=')
82
+ attr = name.to_s[0...-1].to_sym
83
+ # Set the value if it's not a permanent attribute
84
+ if @@permanent_attributes.include?(k)
85
+ raise NoMethodError.new("Cannot set #{attr} on this object. HINT: you can't set: #{@@permanent_attributes.to_a.join(', ')}")
86
+ else
87
+ add_accessors([attr])
88
+ end
89
+ else
90
+ return @values[name]
91
+ end
92
+
93
+ begin
94
+ # Let's not get all crazy now
95
+ nil
96
+ #super
97
+ rescue NoMethodError => e
98
+ if @transient_values.include?(name)
99
+ raise NoMethodError.new(e.message + ". HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: #{@values.keys.join(', ')}")
100
+ else
101
+ raise
102
+ end
103
+ end
104
+ end
105
+
106
+ def respond_to_missing?(symbol, include_private = false)
107
+ @values.has_key?(symbol.to_sym) || nil
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'relateiq'
3
+ s.version = '0.0.1'
4
+ s.date = '2014-04-01'
5
+ s.summary = "RelateIQ Ruby Client"
6
+ s.description = "A lightweight ruby wrapper for the RelateIQ API"
7
+ s.authors = ["Michael Revell"]
8
+ s.email = 'michael@crowditlt.com'
9
+ s.homepage = 'https://github.com/MichaelRevell/relateiq'
10
+ s.license = 'MIT'
11
+
12
+ s.add_development_dependency 'bundler', '~> 1.0'
13
+
14
+ s.add_runtime_dependency 'faraday', ['~> 0.8', '< 0.10']
15
+ s.add_runtime_dependency 'faraday_middleware', '~> 0.9.0'
16
+ s.add_runtime_dependency 'activesupport'
17
+ s.add_runtime_dependency 'actionview'
18
+ s.add_runtime_dependency 'json'
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.require_paths = ['lib']
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: relateiq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Revell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ version: '0.10'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '0.8'
44
+ - - <
45
+ - !ruby/object:Gem::Version
46
+ version: '0.10'
47
+ - !ruby/object:Gem::Dependency
48
+ name: faraday_middleware
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: 0.9.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: activesupport
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: actionview
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: json
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: A lightweight ruby wrapper for the RelateIQ API
104
+ email: michael@crowditlt.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - .gitignore
110
+ - Gemfile
111
+ - Gemfile.lock
112
+ - lib/relateiq.rb
113
+ - lib/relateiq/api_resource.rb
114
+ - lib/relateiq/list.rb
115
+ - lib/relateiq/riq_list.rb
116
+ - lib/relateiq/riq_object.rb
117
+ - relateiq.gemspec
118
+ homepage: https://github.com/MichaelRevell/relateiq
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.0.6
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: RelateIQ Ruby Client
142
+ test_files: []