chord 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ecdb151eb16d8e1187e7ae8a6bf59cd57895580ba5c578fd166ed5b2c795da16
4
+ data.tar.gz: 33bb400c1a6c0f6df638125ebc86d6fa54f513075e994756e71daf72a1cc198d
5
+ SHA512:
6
+ metadata.gz: cac1d8dfeb749f6e8e5e12776031973755f73e4976ed6bb4505fc464eb92b43942cffed3251ccb34d9013fbfab3ee4b32648c257107bac885b90e11231a27810
7
+ data.tar.gz: 1c95d655de397bd5b0d88c46d924ce8dbdd760bde3e17a16a38bf4dc7c262a8127a7f662ab9eacd5eb91315a5b9645cbea918a09a040eb0df281846f7ed5ab20
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ Major changes for each release. Please see the Git log for complete list of changes.
4
+
5
+ ## 0.0.1
6
+
7
+ * Very rudimentary start, focused on the parts of the API I need to use.
8
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009-2021 Alex Reisner
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Chord OMS
2
+
3
+ These classes provide simple read and write access to the Chord OMS API. Get started like this:
4
+
5
+ CHORD_API_CONFIG = {
6
+ staging: {
7
+ base_url: 'https://<customer>.staging.assembly-api.com/api/',
8
+ api_key: '<key>'
9
+ },
10
+ production: {
11
+ base_url: 'https://<customer>.assembly-api.com/api/',
12
+ api_key: '<key>'
13
+ }
14
+ }
15
+
16
+ u = Chord::User.find(1) # fetch user
17
+ u.attributes # see attributes hash
18
+ u.update(name: 'New Name', notes: 'Etc') # update attributes
19
+ u.update(metadata: {ambassador_id: 415}) # when updating 'metadata' attribute, the given
20
+ # hash is merged into the existing value and
21
+ # keys and values are stringified (since
22
+ # metadata is stored in OMS as a JSON string)
23
+ u.add_role(3) # add role (by ID) to the user
24
+ u.remove_role(3) # remove role (by ID) from the user
25
+ u.subscriptions # fetch the user's subscriptions
26
+
27
+ Objects are constructed in a way that minimizes API calls but occasionally yields objects that seem incomplete. For example:
28
+
29
+ u = Chord::User.find(44)
30
+ s = u.subscriptions.first
31
+ s.user
32
+
33
+ will return a Chord::User object with only two attributes (ID and email) because the API only returns two attributes with a Subscription object.
34
+
data/bin/console ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'chord'
5
+
6
+ if File.exist?('config.yml')
7
+ require 'yaml'
8
+ CHORD_API_CONFIG = YAML.load(File.read('config.yml'), symbolize_names: true)
9
+ end
10
+
11
+ require 'irb'
12
+ IRB.start
@@ -0,0 +1,3 @@
1
+ module Chord
2
+ VERSION = "0.0.1"
3
+ end
data/lib/chord.rb ADDED
@@ -0,0 +1,201 @@
1
+ require 'httparty'
2
+
3
+ module Chord
4
+
5
+ class << self
6
+ attr_writer :env
7
+ def env; @env || :staging; end # :staging by default
8
+ end
9
+
10
+ class Base
11
+ include HTTParty
12
+
13
+ class << self
14
+ attr_writer :per_page
15
+ def per_page; @per_page || 99999; end
16
+ end
17
+
18
+ def self.base_url
19
+ CHORD_API_CONFIG[Chord.env][:base_url]
20
+ end
21
+
22
+ def self.find(id)
23
+ attrs = get(base_url + "#{base_path}/#{id}", http_options).parsed_response
24
+ new(id, attrs)
25
+ end
26
+
27
+ def self.fetch_all_data(query_options = {})
28
+ query_options = {
29
+ per_page: per_page
30
+ }.merge(query_options)
31
+ get(base_url + "#{base_path}?#{hash_to_query(query_options)}", http_options).parsed_response
32
+ end
33
+
34
+ def self.all(query_options = {})
35
+ @all ||= fetch_all_data(query_options)[base_path].map{ |i| new(i['id'], i) }
36
+ end
37
+
38
+ def self.http_options
39
+ {headers: {
40
+ 'Authorization' => "Bearer #{CHORD_API_CONFIG[Chord.env][:api_key]}",
41
+ 'Content-Type' => 'application/json'
42
+ }}
43
+ end
44
+
45
+ def self.hash_to_query(hash)
46
+ require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
47
+ hash.collect{ |p|
48
+ p[1].nil? ? nil : p.map{ |i| CGI.escape i.to_s } * '='
49
+ }.compact.sort * '&'
50
+ end
51
+
52
+ def base_url
53
+ self.class.base_url
54
+ end
55
+
56
+ def base_path
57
+ self.class.base_path
58
+ end
59
+
60
+ def http_options
61
+ self.class.http_options
62
+ end
63
+
64
+ attr_reader :id
65
+ attr_accessor :attributes
66
+
67
+ def initialize(id, attributes = {})
68
+ @id = id
69
+ @attributes = attributes
70
+ end
71
+
72
+ def update(new_attributes)
73
+ new_attributes.stringify_keys!
74
+ # merge values into existing metadata
75
+ if new_attributes.include?('metadata')
76
+ # Chord expects all metadata values to be strings
77
+ new_metadata = new_attributes['metadata'].map{ |k,v| [k.to_s, v.to_s] }.to_h
78
+ new_attributes['metadata'] = (attributes['metadata'] || {}).merge(new_metadata)
79
+ # TODO: delete entries with empty value?
80
+ end
81
+ self.attributes = self.class.patch(base_url + "#{base_path}/#{id}",
82
+ http_options.merge(body: new_attributes.to_json)
83
+ ).parsed_response
84
+ end
85
+
86
+ def delete
87
+ self.class.delete(base_url + "#{base_path}/#{id}", http_options).parsed_response
88
+ end
89
+
90
+ def method_missing(method, *args, &block)
91
+ if attributes.include?(method.to_s)
92
+ attributes[method.to_s]
93
+ else
94
+ super
95
+ end
96
+ end
97
+ end
98
+
99
+
100
+ class User < Base
101
+
102
+ #
103
+ # For avoiding API calls.
104
+ #
105
+ def self.all_by_id
106
+ unless @all_by_id
107
+ @all_by_id = {}
108
+ all.each do |u|
109
+ @all_by_id[u.id] = u
110
+ end
111
+ end
112
+ @all_by_id
113
+ end
114
+
115
+ #
116
+ # For mapping users on our old site to Chord.
117
+ #
118
+ def self.all_by_email
119
+ unless @all_by_email
120
+ @all_by_email = {}
121
+ all.each do |u|
122
+ @all_by_email[u.email] = u
123
+ end
124
+ end
125
+ @all_by_email
126
+ end
127
+
128
+ def self.base_path
129
+ 'users'
130
+ end
131
+
132
+ def add_role(role_id)
133
+ self.class.put(base_url + "roles/#{role_id}/add/#{id}", http_options).parsed_response
134
+ end
135
+
136
+ def remove_role(role_id)
137
+ self.class.put(base_url + "roles/#{role_id}/remove/#{id}", http_options).parsed_response
138
+ end
139
+
140
+ def subscriptions
141
+ self.class.get(base_url + "users/#{id}/subscriptions", http_options).parsed_response['subscriptions'].map{ |s| Chord::Subscription.new(s['id'], s) }
142
+ end
143
+
144
+ def find_subscription(subscription_id)
145
+ self.class.get(base_url + "users/#{id}/subscriptions/#{subscription_id}", http_options).parsed_response
146
+ end
147
+ end
148
+
149
+
150
+ class Order < Base
151
+
152
+ def self.base_path
153
+ 'orders'
154
+ end
155
+
156
+ def user
157
+ Chord::User.find(attributes['user_id'])
158
+ end
159
+
160
+ def payments
161
+ self.class.get(base_url + "orders/#{id}/payments", http_options).parsed_response['payments'].map{ |p| Chord::Payment.new(p['id'], p) }
162
+ end
163
+
164
+ def create_adjustment(order_id, label, discount)
165
+ attributes = {
166
+ label: label,
167
+ discount_by: discount
168
+ }
169
+ self.class.post(base_url + "hub/orders/#{order_id}/adjustments",
170
+ http_options.merge(body: attributes.to_json)
171
+ ).parsed_response
172
+ end
173
+ end
174
+
175
+
176
+ class Role < Base
177
+
178
+ def self.base_path
179
+ 'roles'
180
+ end
181
+ end
182
+
183
+
184
+ class Subscription < Base
185
+
186
+ def user
187
+ u = attributes['user']
188
+ Chord::User.new(u['id'], u)
189
+ end
190
+ end
191
+
192
+ class Payment < Base
193
+ end
194
+
195
+ class Product < Base
196
+
197
+ def self.base_path
198
+ 'products'
199
+ end
200
+ end
201
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chord
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alex Reisner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.20.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.20.0
27
+ description: ActiveRecord-like syntax. Still in alpha-stage early development. Many
28
+ endpoints and features not yet supported. Some bugs.
29
+ email:
30
+ - alex@alexreisner.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - CHANGELOG.md
36
+ - LICENSE
37
+ - README.md
38
+ - bin/console
39
+ - lib/chord.rb
40
+ - lib/chord/version.rb
41
+ homepage: https://www.github.com/alexreisner/chord
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ source_code_uri: https://github.com/alexreisner/chord
46
+ changelog_uri: https://github.com/alexreisner/chord/blob/master/CHANGELOG.md
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.0.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.1.6
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Easy access to Chord Commerce API.
66
+ test_files: []