cc-cli 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +12 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +186 -0
- data/Rakefile +1 -0
- data/bin/cc-cli +5 -0
- data/cc-cli.gemspec +28 -0
- data/circle.yml +11 -0
- data/config/config.yml +31 -0
- data/lib/cc/api/explorer.rb +175 -0
- data/lib/cc/api/explorer/version.rb +7 -0
- data/lib/cc/api/http/http_requestor.rb +50 -0
- data/lib/cc/api/parser/arguments_mapper.rb +44 -0
- data/lib/cc/api/parser/arguments_parser.rb +65 -0
- data/lib/cc/api/parser/json_parser.rb +38 -0
- data/lib/cc/api/presentor/presentor.rb +47 -0
- data/lib/cc/api/util/config_reader.rb +38 -0
- data/lib/cc/api/util/key_chains_getter.rb +80 -0
- data/spec/dummy_data/catalog_categories.json +1 -0
- data/spec/dummy_data/catalog_product_types.json +1 -0
- data/spec/dummy_data/catalog_products.json +1 -0
- data/spec/dummy_data/catalog_stores.json +1 -0
- data/spec/dummy_data/lattice_offers.json +1 -0
- data/spec/dummy_data/lattice_products.json +1 -0
- data/spec/dummy_data/lattice_stores.json +1 -0
- data/spec/dummy_data/store_products.json +1 -0
- data/spec/explorer_spec.rb +238 -0
- data/spec/http/http_requestor_spec.rb +54 -0
- data/spec/parser/arguments_mapper_spec.rb +78 -0
- data/spec/parser/arguments_parser_spec.rb +81 -0
- data/spec/parser/json_parser_spec.rb +108 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/support/arguments_mapper_returning_blank_json.rb +7 -0
- data/spec/support/arguments_mapper_returning_json_with_id_and_skus.rb +7 -0
- data/spec/support/arguments_mapper_returning_page_params.rb +7 -0
- data/spec/support/arguments_parser_returning_expected_result.rb +6 -0
- data/spec/support/json_parser.rb +43 -0
- data/spec/support/stdout_helper.rb +10 -0
- data/spec/support/table_fields_matcher.rb +16 -0
- data/spec/utils/utils_spec.rb +90 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGUwZWI3ZTk1NTBjOWNiMGZlMjEyYmIwYTY2YzEzMjQwNzNjMTFiYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZjQxMzZkODk4ZDZjYjZjZmEyYjhkMjE0ODk3NWM2ODNkNjgyOWQxOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OGE5MTE4NGE0YTMyZDNkYTBkYjUzNzc4ODRkMzhhN2E5NzI0YTM3ZWUxYzA3
|
10
|
+
NGQ2YzAxOTU0OGU2YTEzNjllMDg3MWVmZDRjN2YzNjkzOWJhNjljYjk0MDZk
|
11
|
+
MDlmMTk3MWQ2MDExN2EwZDJmMzcyMzk1NGNkZmNmNTg1YTQ3ODk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmFlNzQ5YmZhYWIxODk3MjZiYTUyMWRiZTI4NWFjZmY3OWQxMDJhNTA5NjNm
|
14
|
+
MTQ2N2QzNDhjMmMwYzVhNmY3M2VlMDQzY2NhOTBlNDY0ZmRkMjc4MzgwZGYy
|
15
|
+
NGY2YTE1NTZjYmMxZDNiODdlODMwNDYzYTViMDA2Yzg0ZGM3NmU=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Neil Marion dela Cruz
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# CrystalCommerce CLI
|
2
|
+
|
3
|
+
This is a command line client for exploring CrystalCommerce APIs
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'cc-cli', :git => "git@github.com:crystalcommerce/cc-cli.git"
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as (not yet available as of the moment):
|
16
|
+
|
17
|
+
$ gem install cc-cli
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
To view help:
|
22
|
+
|
23
|
+
$ cc-cli
|
24
|
+
|
25
|
+
The license key pair `<ssologin>` and `<key>` are basically just basic auth username and password respectively.
|
26
|
+
To obtain a license key, contact: contact: Jerad Ellison or call (206) 274-7437 Ext. 3.
|
27
|
+
|
28
|
+
Add these lines in your ~/.bashrc (linux) or ~/.profile (mac) file:
|
29
|
+
|
30
|
+
export CC_API_LOGIN=<login>
|
31
|
+
export CC_API_KEY=<key>
|
32
|
+
|
33
|
+
If you are working in a project, you can also install the
|
34
|
+
[dotenv](http://rubygems.org/gems/dotenv) gem and put a .env file in
|
35
|
+
the working directory that looks like:
|
36
|
+
|
37
|
+
CC_API_LOGIN=<login>
|
38
|
+
CC_API_KEY=<key>
|
39
|
+
|
40
|
+
You can then run the program with `dotenv cc-cli`. This approach will
|
41
|
+
be advantageous if you don't want to edit your user's shell config to
|
42
|
+
use this tool.
|
43
|
+
|
44
|
+
These are the available commands:
|
45
|
+
|
46
|
+
$ cc-cli catalog [products] | [product_types] | [stores] | [categories]
|
47
|
+
$ cc-cli help [COMMND]
|
48
|
+
$ cc-cli lattice [products --id <PRODUCT ID> --skus <PRODUCT SKUS separated by ','>] | [offers --id <PRODUCT ID> --skus <PRODUCT SKUS separated by ','>] | [stores]
|
49
|
+
$ cc-cli store [products --token <access token> --store <store name>]
|
50
|
+
|
51
|
+
To choose columns/json keys to display:
|
52
|
+
|
53
|
+
Display the available columns for a given command. Say for example `$ cc-cli catalog products`:
|
54
|
+
|
55
|
+
$ cc-cli catalog products --available-cols
|
56
|
+
|
57
|
+
available columns
|
58
|
+
====================
|
59
|
+
id
|
60
|
+
name
|
61
|
+
seoname
|
62
|
+
category_name
|
63
|
+
weight
|
64
|
+
description
|
65
|
+
asin
|
66
|
+
category_id
|
67
|
+
product_type_id
|
68
|
+
descriptors.*
|
69
|
+
photo.content_type
|
70
|
+
photo.urls.medium
|
71
|
+
photo.urls.thumb
|
72
|
+
photo.urls.large
|
73
|
+
photo.urls.ebay
|
74
|
+
|
75
|
+
USAGE:
|
76
|
+
--cols descriptors.Name,descriptors.Pow/Tgh,seoname
|
77
|
+
|
78
|
+
Then display the table
|
79
|
+
|
80
|
+
$ cc-cli catalog products --cols descriptors.Name,descriptors.Pow/Tgh,seoname
|
81
|
+
GET https://api.crystalcommerce.com/v1/catalog/products?page=1
|
82
|
+
response time: 2.091034343
|
83
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
84
|
+
┃ descriptors.Name ┃ descriptors.Pow/Tgh ┃ seoname ┃
|
85
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
86
|
+
┃ Abyssal Specter ┃ 2/3 ┃ abyssal_specter ┃
|
87
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
88
|
+
┃ Air Elemental ┃ 4/4 ┃ air_elemental ┃
|
89
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
90
|
+
┃ Aladdin's Ring ┃ ┃ aladdins_ring ┃
|
91
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
92
|
+
┃ Ambition's Cost ┃ ┃ ambitions_cost ┃
|
93
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
94
|
+
┃ Anaba Shaman ┃ 2/2 ┃ anaba_shaman ┃
|
95
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
96
|
+
┃ Angel of Mercy ┃ 3/3 ┃ angel_of_mercy ┃
|
97
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
98
|
+
|
99
|
+
When `--cols` is not used, the default `--cols` values will then be selected.
|
100
|
+
|
101
|
+
This is also capable of displaying values from arrays within the JSON object from the API response. For example let's first print `$ cc-cli catalog product_types` available columns:
|
102
|
+
|
103
|
+
$ cc-cli catalog product_types --available-cols
|
104
|
+
GET https://api.crystalcommerce.com/v1/catalog/product_types?page=1
|
105
|
+
response time: 1.654095542
|
106
|
+
|
107
|
+
available columns
|
108
|
+
====================
|
109
|
+
id
|
110
|
+
name
|
111
|
+
default_weight
|
112
|
+
amazon_search_index
|
113
|
+
variant_dimensions.<index>.name
|
114
|
+
variant_dimensions.<index>.product_type_id
|
115
|
+
variant_dimensions.<index>.default_option_id
|
116
|
+
variant_dimensions.<index>.options.<index>.value
|
117
|
+
variant_dimensions.<index>.options.<index>.code
|
118
|
+
descriptors.<index>.*
|
119
|
+
|
120
|
+
The `<index>` must be replaced by an integer:
|
121
|
+
|
122
|
+
$ cc-cli catalog product_types --cols name,variant_dimensions.0.name,variant_dimensions.0.default_option_id --colp 1
|
123
|
+
GET https://api.crystalcommerce.com/v1/catalog/product_types?page=1
|
124
|
+
response time: 1.389229104
|
125
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
126
|
+
┃ name ┃ variant_dimensions.0.name ┃ variant_dimensions.0.default ┃
|
127
|
+
┃ ┃ ┃ _option_id ┃
|
128
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
129
|
+
┃ Pathfinder ┃ Condition ┃ 94 ┃
|
130
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
131
|
+
┃ Horrorclix ┃ Condition ┃ ┃
|
132
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
133
|
+
┃ Misc Products for Mad Al ┃ Condtion ┃ ┃
|
134
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
135
|
+
┃ Miniatures Sealed Product ┃ Condition ┃ ┃
|
136
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
137
|
+
┃ Dragon Ball CCG Sealed ┃ Condition ┃ 753 ┃
|
138
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
139
|
+
┃ Battle Spirits Sealed Produc ┃ Condition ┃ ┃
|
140
|
+
┃ t ┃ ┃ ┃
|
141
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
142
|
+
┃ Other Card Games - Sealed ┃ Condition ┃ ┃
|
143
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
144
|
+
┃ Axis & Allies: Air Force Min ┃ Condition ┃ ┃
|
145
|
+
┃ iatures Singles ┃ ┃ ┃
|
146
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
147
|
+
┃ DVDs ┃ Condition ┃ ┃
|
148
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
149
|
+
┃ Sportscards & Trading Cards ┃ Condition ┃ ┃
|
150
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
151
|
+
┃ Toys ┃ Condition ┃ ┃
|
152
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
153
|
+
┃ Video Game Accessories ┃ Condition ┃ ┃
|
154
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
155
|
+
┃ Kaijudo Sealed Product ┃ Condition ┃ 96 ┃
|
156
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
157
|
+
┃ Candy ┃ Condition ┃ ┃
|
158
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
159
|
+
┃ Marvel Super Hero Squad ┃ Condition ┃ ┃
|
160
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
161
|
+
┃ Pathfinder Miniatures ┃ Condition ┃ ┃
|
162
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
163
|
+
┃ Cardfight! Vanguard Sealed P ┃ Condition ┃ 163 ┃
|
164
|
+
┃ roduct ┃ ┃ ┃
|
165
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
166
|
+
┃ Cthulhu Tech ┃ Condition ┃ ┃
|
167
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
168
|
+
┃ Cardfight!! Vanguard ┃ Condition ┃ 86 ┃
|
169
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
170
|
+
┃ Axis & Allies: War At Sea Mi ┃ Condition ┃ ┃
|
171
|
+
┃ niatures ┃ ┃ ┃
|
172
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
173
|
+
|
174
|
+
Other available options:
|
175
|
+
|
176
|
+
[--offset=N] # Offset of the starting row to be displayed. Nothing is displayed when out of bounds.
|
177
|
+
[--limit=N] # Limit of rows to be displayed.
|
178
|
+
[--colw=N] # Width of every column to be displayed.
|
179
|
+
[--colp=N] # Padding of every cell to be displayed.
|
180
|
+
[--json] # Prints the JSON response body instead.
|
181
|
+
[--page=N] # Page number of the response.
|
182
|
+
[--csv=CSV_FILE_PATH] # Print out the result into a csv file. Columns are separated by comma
|
183
|
+
|
184
|
+
## ISSUES
|
185
|
+
|
186
|
+
There is going to be an issue when trying to include as a `--cols` value a 'available-cols' that has a whitespace within its string. E.g. "descriptors.Set Name" for `$ cc-cli catalog products`
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/cc-cli
ADDED
data/cc-cli.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cc/api/explorer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cc-cli"
|
8
|
+
spec.version = Cc::Api::Explorer::VERSION
|
9
|
+
spec.authors = ["Neil Marion dela Cruz", "Michael Xavier"]
|
10
|
+
spec.email = ["developers@crystalcommerce.com"]
|
11
|
+
spec.summary = %q{CrystalCommerce API Explorer}
|
12
|
+
spec.description = %q{This is a command line client for exploring CrystalCommerce APIs}
|
13
|
+
spec.homepage = "https://github.com/crystalcommerce/cc-cli"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "command_line_reporter"
|
22
|
+
spec.add_runtime_dependency "httparty"
|
23
|
+
spec.add_runtime_dependency "thor"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|
data/circle.yml
ADDED
data/config/config.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
lattice:
|
2
|
+
products:
|
3
|
+
url: https://api.crystalcommerce.com/v1/lattice/products
|
4
|
+
target_key_chain: "product.variants.FIRST.variant.store_variants"
|
5
|
+
stores:
|
6
|
+
url: https://api.crystalcommerce.com/v1/lattice/stores
|
7
|
+
target_key_chain: ""
|
8
|
+
offers:
|
9
|
+
url: https://api.crystalcommerce.com/v1/lattice/offers
|
10
|
+
method: POST
|
11
|
+
target_key_chain: "PRODUCT_ID"
|
12
|
+
catalog:
|
13
|
+
products:
|
14
|
+
url: https://api.crystalcommerce.com/v1/catalog/products
|
15
|
+
target_key_chain: "products"
|
16
|
+
ignores: ["descriptors"]
|
17
|
+
product_types:
|
18
|
+
url: https://api.crystalcommerce.com/v1/catalog/product_types
|
19
|
+
target_key_chain: "product_types"
|
20
|
+
ignores: ["descriptors.<index>"]
|
21
|
+
stores:
|
22
|
+
url: https://api.crystalcommerce.com/v1/catalog/stores
|
23
|
+
target_key_chain: "stores"
|
24
|
+
categories:
|
25
|
+
url: https://api.crystalcommerce.com/v1/catalog/categories
|
26
|
+
target_key_chain: "categories"
|
27
|
+
store:
|
28
|
+
products:
|
29
|
+
url: https://*-api.crystalcommerce.com/v1/products
|
30
|
+
target_key_chain: "paginated_collection.entries"
|
31
|
+
ignores: ["product.descriptors"]
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'cc/api/explorer/version'
|
2
|
+
require 'cc/api/http/http_requestor'
|
3
|
+
require 'cc/api/parser/arguments_parser'
|
4
|
+
require 'cc/api/parser/json_parser'
|
5
|
+
require 'cc/api/presentor/presentor'
|
6
|
+
require 'cc/api/util/config_reader'
|
7
|
+
require 'cc/api/util/key_chains_getter'
|
8
|
+
require 'command_line_reporter'
|
9
|
+
require 'thor'
|
10
|
+
require 'yaml'
|
11
|
+
|
12
|
+
module Cc
|
13
|
+
module Api
|
14
|
+
module Explorer
|
15
|
+
class CLI < Thor
|
16
|
+
DEFAULT_COLS =
|
17
|
+
{
|
18
|
+
"lattice-products" => ["store_variant.store_name", "store_variant.qty", "store_variant.buy_price.money.currency"],
|
19
|
+
"lattice-stores" => ["store.name", "store.state", "store.url"],
|
20
|
+
"lattice-offers" => ["store.name", "buy_price.cents", "sell_price.cents"],
|
21
|
+
"catalog-products" => ["name", "barcode", "weight"],
|
22
|
+
"catalog-product_types" => ["name", "id", "default_weight"],
|
23
|
+
"catalog-stores" => ["name", "postal_code", "url"],
|
24
|
+
"catalog-categories" => ["name", "seoname", "description"],
|
25
|
+
"store-products" => ["product.seoname", "product.weight", "product.description"]
|
26
|
+
}
|
27
|
+
|
28
|
+
DESC =
|
29
|
+
{
|
30
|
+
"cols" => "Columns to display to the output table. To determine the 'available columns' for a selected command use --available_cols",
|
31
|
+
"available_cols" => "Output the available columns for output for a command",
|
32
|
+
"offset" => "Offset of the starting row to be displayed. Nothing is displayed when out of bounds",
|
33
|
+
"limit" => "Limit of rows to be displayed",
|
34
|
+
"colw" => "Width of every column to be displayed",
|
35
|
+
"colp" => "Padding of every cell to be displayed",
|
36
|
+
"json" => "Prints the JSON response body instead",
|
37
|
+
"id" => "Product ID",
|
38
|
+
"skus" => "SKUs separated by ',' if more than one",
|
39
|
+
"page" => "Page number of the response",
|
40
|
+
"token" => "OAuth Token",
|
41
|
+
"store" => "Store name (CrystalCommerce Client)",
|
42
|
+
"csv" => "Print out the result into a csv file. Columns are separated by comma"
|
43
|
+
}
|
44
|
+
|
45
|
+
option :csv, :desc => DESC["csv"], :banner => "CSV_FILE_PATH"
|
46
|
+
option :cols, :desc => DESC["cols"]
|
47
|
+
option :available_cols, :type => :boolean, :desc => DESC["available_cols"]
|
48
|
+
option :offset, :type => :numeric, :desc => DESC["offset"]
|
49
|
+
option :limit, :type => :numeric, :desc => DESC["limit"]
|
50
|
+
option :colw, :type => :numeric, :desc => DESC["colw"]
|
51
|
+
option :colp, :type => :numeric, :desc => DESC["colp"]
|
52
|
+
option :json, :type => :boolean, :desc => DESC["json"]
|
53
|
+
option :id, :desc => DESC["id"]
|
54
|
+
option :skus, :desc => DESC["skus"]
|
55
|
+
desc "lattice [products --id <PRODUCT ID> --skus <PRODUCT SKUS separated by ','>] | [offers --id <PRODUCT ID> --skus <PRODUCT SKUS separated by comma>] | [stores]",
|
56
|
+
"The Market Data APIs track the Prices, Quantities, and similar data. It also indicates which stores in the CrystalCommerce in-network currently has those products for sale."
|
57
|
+
def lattice(subcommand)
|
58
|
+
case subcommand
|
59
|
+
when "products"
|
60
|
+
# { product : { variants : { store_variants : [ { store_variant : { ... } } ] } } }
|
61
|
+
args = {:action => "lattice-products", :params => {:id => options[:id], :skus => options[:skus].to_s.split(',') } }
|
62
|
+
perform(args)
|
63
|
+
when "stores"
|
64
|
+
# { [ { store : { ... } } ] }
|
65
|
+
args = {:action => "lattice-stores"}
|
66
|
+
perform(args)
|
67
|
+
when "offers"
|
68
|
+
# { <PRODUCT ID> : [ { ... } ] }
|
69
|
+
args = {:action => "lattice-offers", :params => {:id => options[:id], :skus => options[:skus].to_s.split(',') } }
|
70
|
+
perform(args)
|
71
|
+
else
|
72
|
+
Cc::Api::Parser::ArgumentsParser.raise_cli_arguments_exception
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
option :csv, :desc => DESC["csv"], :banner => "CSV_FILE_PATH"
|
77
|
+
option :cols, :desc => DESC["cols"]
|
78
|
+
option :available_cols, :type => :boolean, :desc => DESC["available_cols"]
|
79
|
+
option :offset, :type => :numeric, :desc => DESC["offset"]
|
80
|
+
option :limit, :type => :numeric, :desc => DESC["limit"]
|
81
|
+
option :colw, :type => :numeric, :desc => DESC["colw"]
|
82
|
+
option :colp, :type => :numeric, :desc => DESC["colp"]
|
83
|
+
option :json, :type => :boolean, :desc => DESC["json"]
|
84
|
+
option :page, :type => :numeric, :desc => DESC["page"]
|
85
|
+
|
86
|
+
desc "catalog [products] | [product_types] | [stores] | [categories]",
|
87
|
+
"This API will give access to read the catalog of products. This includes what products could be sold but doesn't include prices or quantities, which are stored in the Market Data APIs."
|
88
|
+
def catalog(subcommand)
|
89
|
+
case subcommand
|
90
|
+
when "products"
|
91
|
+
# { products : [ { ... } }
|
92
|
+
args = {:action => "catalog-products", :params => { :page => options[:page] || 1 } }
|
93
|
+
perform(args)
|
94
|
+
when "product_types"
|
95
|
+
# { products : [ { ... } ] }
|
96
|
+
args = {:action => "catalog-product_types", :params => { :page => options[:page] || 1 } }
|
97
|
+
perform(args)
|
98
|
+
when "stores"
|
99
|
+
# { stores : [ { ... } ] }
|
100
|
+
args = {:action => "catalog-stores"}
|
101
|
+
perform(args)
|
102
|
+
when "categories"
|
103
|
+
# { categories : [ { ... } ] }
|
104
|
+
args = {:action => "catalog-categories", :params => { :page => options[:page] || 1} }
|
105
|
+
perform(args)
|
106
|
+
else
|
107
|
+
Cc::Api::Parser::ArgumentsParser.raise_cli_arguments_exception
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
option :csv, :desc => DESC["csv"], :banner => "CSV_FILE_PATH"
|
112
|
+
option :cols, :desc => DESC["cols"]
|
113
|
+
option :available_cols, :type => :boolean, :desc => DESC["available_cols"]
|
114
|
+
option :offset, :type => :numeric, :desc => DESC["offset"]
|
115
|
+
option :limit, :type => :numeric, :desc => DESC["limit"]
|
116
|
+
option :colw, :type => :numeric, :desc => DESC["colw"]
|
117
|
+
option :colp, :type => :numeric, :desc => DESC["colp"]
|
118
|
+
option :json, :type => :boolean, :desc => DESC["json"]
|
119
|
+
option :page, :type => :numeric, :desc => DESC["page"]
|
120
|
+
option :token, :desc => DESC["token"]
|
121
|
+
option :store, :desc => DESC["store"]
|
122
|
+
|
123
|
+
desc "store [products --token <access token> --store <store name>]", "The Store Data API provides access to the data related to a single store whereas the Market Data API applies to all stores."
|
124
|
+
def store(subcommand)
|
125
|
+
case subcommand
|
126
|
+
when "products"
|
127
|
+
# { paginated_collection : { entries : [ { product: { ... } } ] } }
|
128
|
+
args = {:action => "store-products", :params => {:token => options[:token], :store => options[:store], :page => options[:page] || 1} }
|
129
|
+
perform(args)
|
130
|
+
else
|
131
|
+
Cc::Api::Parser::ArgumentsParser.raise_cli_arguments_exception
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def perform(args)
|
138
|
+
|
139
|
+
action = args[:action]
|
140
|
+
|
141
|
+
begin
|
142
|
+
param = Cc::Api::Parser::ArgumentsParser.parse args
|
143
|
+
response = http_requestor.request_for_json param
|
144
|
+
|
145
|
+
if options[:json]
|
146
|
+
puts JSON.pretty_generate response[:body]
|
147
|
+
else
|
148
|
+
target = Cc::Api::Parser::ArgumentsMapper.get_target_key_chain action
|
149
|
+
array = Cc::Api::Util::KeyChainsGetter.get_target_array response[:body], target, options[:id]
|
150
|
+
if options[:available_cols]
|
151
|
+
Cc::Api::Util::KeyChainsGetter.get_key_chains array.first, "", Cc::Api::Parser::ArgumentsMapper.get_ignored_key_chain(action)
|
152
|
+
else
|
153
|
+
puts "response time: #{response[:response_time]}"
|
154
|
+
begin
|
155
|
+
result = Cc::Api::Parser::JsonParser.vanilla_reduce array, options[:cols].split(',')
|
156
|
+
rescue
|
157
|
+
result = Cc::Api::Parser::JsonParser.vanilla_reduce array, DEFAULT_COLS[action]
|
158
|
+
end
|
159
|
+
tabler = Cc::Api::Presentor::Tabler.new
|
160
|
+
tabler.present result, options[:colw], options[:colp], options[:offset], options[:limit]
|
161
|
+
Cc::Api::Presentor::CSVer.to_csv result, options[:csv], options[:offset], options[:limit] if options[:csv]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
rescue => e
|
165
|
+
puts e.message
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def http_requestor
|
170
|
+
Cc::Api::Http::HttpRequestor.new
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|