gazer 0.2.40 → 0.2.41

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 417b013d1a277bbb0f15622d80475dd2371a306323156ef46a60b9730fefc159
4
- data.tar.gz: eaa6ed298f737c3fa29b59b04f783b3278f4c3731f00fefc40cb39820505fd05
3
+ metadata.gz: 63f0133a6db8baa3e1cbb77432444b11b51a9d3f63746b1e18018b9da52ffba1
4
+ data.tar.gz: b1128abc82113482b0bbc5956f680b4b6e633d26ab9204988e87ce45a83f5cdb
5
5
  SHA512:
6
- metadata.gz: 31d6d7d1fbec05153cd86db80c7556b9de2e774d10b0cbea10d8403fead584a6f47eb21b0d78d5424c6b219bf4d8950ec9c446bb3e9bab879715ef9f9a55557c
7
- data.tar.gz: e813f21a9aef2ea51d88536ebfa4286e62fcbc6a0fe78e64fb23dc33c3877ea762d2260f022638dee4b57919daeab77f520f37ade199d060ec969c023ba3ac53
6
+ metadata.gz: 0c94dda1c71d32c8441c7eeba27c230a5ec35e5b96e3b8b3dd897aa1f4c38f685c4edee7961beb8fe67e4e091922d697e55fd36d8f47fd907c1fa0f4f3a92c48
7
+ data.tar.gz: 5e56640ba557897596eec20cf99b5465ec8760dba904bc01d0e82e67af97ce559dcc85f7e5a2b286c0aa3c96bd882d350d04c6cac3b431ab8bc44fc12656b188
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gazer (0.2.40)
4
+ gazer (0.2.41)
5
5
  looker-sdk (~> 0.0.7)
6
6
  netrc (~> 0.11.0)
7
7
  pastel (~> 0.7.2)
data/README.md CHANGED
@@ -34,6 +34,18 @@ machine foo.bar.mycompany.com
34
34
 
35
35
  Make sure that the `~/.netrc` file has restricted permissions by running `chmod 600 ~/.netrc`.
36
36
 
37
+ ### API port
38
+ Most instances of Looker use port 19999 for the API. Gazer will use that port by default when executing a command.
39
+ Looker instances that are hosted in Google Cloud direct both the API and the web
40
+ interface traffic through port 443, the standard https port. Some other
41
+ installations may also use port 443.
42
+
43
+ If your Looker instance is GCP-hosted (*.cloud.looker.com), you must specify `--port 443`, eg:
44
+
45
+ ```
46
+ $ gzr user me --host mycompany.cloud.looker.com --port 443
47
+ ```
48
+
37
49
  ### Options that apply to many commands
38
50
 
39
51
  #### --su option
@@ -116,6 +116,146 @@ module Gzr
116
116
  data
117
117
  end
118
118
 
119
+ def all_color_collections()
120
+ data = nil
121
+ begin
122
+ data = @sdk.all_color_collections()
123
+ rescue NoMethodError => nme
124
+ say_warning "The api endpoint all_color_collections() is not implemented on this Looker instance"
125
+ rescue LookerSDK::NotFound => nf
126
+ say_warning "The current user can't query all color collections"
127
+ rescue LookerSDK::Error => e
128
+ say_error "Error querying all_color_collections()"
129
+ say_error e.message
130
+ raise
131
+ end
132
+ data
133
+ end
134
+
135
+ def default_color_collection()
136
+ return @dcc if @dcc
137
+ data = nil
138
+ begin
139
+ data = @sdk.default_color_collection()
140
+ @dcc = data
141
+ rescue NoMethodError => nme
142
+ say_warning "The api endpoint default_color_collection() is not implemented on this Looker instance"
143
+ rescue LookerSDK::NotFound => nf
144
+ say_warning "The current user can't query the default color collection"
145
+ rescue LookerSDK::Error => e
146
+ say_error "Error querying default_color_collection()"
147
+ say_error e.message
148
+ raise
149
+ end
150
+ data
151
+ end
152
+
153
+ def color_collection(collection_id)
154
+ data = nil
155
+ begin
156
+ data = @sdk.color_collection(collection_id)
157
+ rescue NoMethodError => nme
158
+ say_warning "The api endpoint color_collection(collection_id) is not implemented on this Looker instance"
159
+ rescue LookerSDK::NotFound => nf
160
+ say_warning "The color_collection(#{collection_id}) is not found"
161
+ rescue LookerSDK::Error => e
162
+ say_error "Error querying color_collection(#{collection_id})"
163
+ say_error e.message
164
+ raise
165
+ end
166
+ data
167
+ end
168
+
169
+ def find_vis_config_reference(obj, &block)
170
+ if obj.respond_to?(:'has_key?') && obj.has_key?(:vis_config)
171
+ yield (obj[:vis_config])
172
+ end
173
+ if obj.is_a? Enumerable
174
+ obj.each { |o| find_vis_config_reference(o,&block) }
175
+ end
176
+ end
177
+
178
+ def find_color_palette_reference(obj, default_colors=nil, &block)
179
+ begin
180
+ dcc = default_color_collection()
181
+ if dcc.nil?
182
+ say_warning "You do not have access to query color palettes so these won't be processed."
183
+ return
184
+ end
185
+ default_colors=color_palette_lookup!(dcc)
186
+ end unless default_colors
187
+
188
+ if obj.respond_to?(:'has_key?') && obj.has_key?(:collection_id) && obj.has_key?(:palette_id)
189
+ yield(obj,default_colors)
190
+ end
191
+ if obj.is_a? Enumerable
192
+ obj.each { |o| find_color_palette_reference(o,default_colors,&block) }
193
+ end
194
+ end
195
+
196
+ def color_palette_lookup!(obj)
197
+ return nil unless obj
198
+ palettes = []
199
+ palettes += obj[:categoricalPalettes] if obj[:categoricalPalettes]
200
+ palettes += obj[:sequentialPalettes] if obj[:sequentialPalettes]
201
+ palettes += obj[:divergingPalettes] if obj[:divergingPalettes]
202
+ obj[:palettes]=palettes
203
+ obj
204
+ end
205
+
206
+ def rewrite_color_palette!(o,default_colors)
207
+ cc = nil
208
+ if o[:collection_id] == default_colors[:id]
209
+ o[:collection_default] = true
210
+ cc = default_colors
211
+ else
212
+ o[:collection_default] = false
213
+ cc = color_palette_lookup!(color_collection(o[:collection_id]))
214
+ end
215
+ return unless cc
216
+ o[:collection_label] = cc[:label]
217
+ ps = cc[:palettes].select { |p| p[:id] == o[:palette_id] }
218
+ if ps.length > 0
219
+ o[:palette_label] = ps.first[:label]
220
+ o[:palette_type] = ps.first[:type]
221
+ end
222
+ end
223
+
224
+ def update_color_palette!(o,default_colors,force_default=false)
225
+ return unless o.has_key?(:collection_label) && o.has_key?(:palette_type)
226
+
227
+ cc = default_colors
228
+ if !(force_default && o[:collection_default])
229
+ # look up color collection by id
230
+ cc = color_palette_lookup!(color_collection(o[:collection_id]))
231
+ if cc.nil?
232
+ # find color collection by name
233
+ ccs = all_color_collections()&.select { |cc| o[:collection_label] == cc[:label]}
234
+ if ccs.nil? || ccs.length == 0
235
+ # no color collection found. Use default.
236
+ say_warning "Color collection #{o[:collection_label]} not found. Using default."
237
+ cc = default_colors
238
+ else
239
+ cc = color_palette_lookup!(ccs.first)
240
+ end
241
+ end
242
+ end
243
+ o[:collection_id] = cc[:id]
244
+
245
+ # look up palette by id
246
+ ps = cc[:palettes].select {|p| p[:id] == o[:palette_id]}
247
+ if ps.length == 0
248
+ # find palette by type
249
+ ps = cc[:palettes].select {|p| p[:type] == o[:palette_type]}
250
+ if ps.length > 0
251
+ o[:palette_id] = ps.first[:id]
252
+ else
253
+ # no palette found
254
+ say_warning "Color palette #{o[:palette_type]} not found."
255
+ o.delete(:palette_id)
256
+ end
257
+ end
258
+ end
119
259
 
120
260
  ##
121
261
  # This method accepts the name of an sdk operation, then finds the parameter for that
@@ -131,7 +271,7 @@ module Gzr
131
271
  # new_obj_hash = existing_obj_hash.select do |k,v|
132
272
  # keys_to_keep('create_new_obj').include? k
133
273
  # end
134
-
274
+
135
275
  def keys_to_keep(operation)
136
276
  o = @sdk.operations[operation]
137
277
  begin
@@ -145,12 +285,12 @@ module Gzr
145
285
  schema_ref = parameters[0][:schema][:$ref].split(/\//)
146
286
  return @sdk.swagger[schema_ref[1].to_sym][schema_ref[2].to_sym][:properties].reject { |k,v| v[:readOnly] }.keys
147
287
  end
148
-
288
+
149
289
  ##
150
290
  # The tty-table gem is normally used to output tabular data. This method accepts a Table
151
291
  # object as used by the tty-table gem, and generates CSV output. It returns a string
152
292
  # with crlf encoding
153
-
293
+
154
294
  def render_csv(t)
155
295
  io = StringIO.new
156
296
  io.puts (
@@ -46,12 +46,22 @@ module Gzr
46
46
  data = query_dashboard(@dashboard_id).to_attrs
47
47
  data[:dashboard_elements].each_index do |i|
48
48
  element = data[:dashboard_elements][i]
49
+ find_vis_config_reference(element) do |vis_config|
50
+ find_color_palette_reference(vis_config) do |o,default_colors|
51
+ rewrite_color_palette!(o,default_colors)
52
+ end
53
+ end
49
54
  merge_result = merge_query(element[:merge_result_id])&.to_attrs if element[:merge_result_id]
50
55
  if merge_result
51
56
  merge_result[:source_queries].each_index do |j|
52
57
  source_query = merge_result[:source_queries][j]
53
58
  merge_result[:source_queries][j][:query] = query(source_query[:query_id]).to_attrs
54
59
  end
60
+ find_vis_config_reference(merge_result) do |vis_config|
61
+ find_color_palette_reference(vis_config) do |o,default_colors|
62
+ rewrite_color_palette!(o,default_colors)
63
+ end
64
+ end
55
65
  data[:dashboard_elements][i][:merge_result] = merge_result
56
66
  end
57
67
  end
@@ -86,7 +96,7 @@ module Gzr
86
96
  elsif e[:position] === 'bottom'
87
97
  row = max_row.to_s
88
98
  end
89
-
99
+
90
100
  column = '0'
91
101
  width = e[:width].to_s
92
102
  height = e[:height].to_s
@@ -42,10 +42,16 @@ module Gzr
42
42
  def execute(input: $stdin, output: $stdout)
43
43
  say_warning("options: #{@options.inspect}") if @options[:debug]
44
44
  with_session do
45
- data = query_look(@look_id)
46
- data[:scheduled_plans] = query_scheduled_plans_for_look(@look_id,"all") if @options[:plans]
47
- write_file(@options[:dir] ? "Look_#{data.id}_#{data.title}.json" : nil, @options[:dir],nil, output) do |f|
48
- f.puts JSON.pretty_generate(data.to_attrs)
45
+ data = query_look(@look_id).to_attrs
46
+ find_vis_config_reference(data) do |vis_config|
47
+ find_color_palette_reference(vis_config) do |o,default_colors|
48
+ rewrite_color_palette!(o,default_colors)
49
+ end
50
+ end
51
+
52
+ data[:scheduled_plans] = query_scheduled_plans_for_look(@look_id,"all").to_attrs if @options[:plans]
53
+ write_file(@options[:dir] ? "Look_#{data[:id]}_#{data[:title]}.json" : nil, @options[:dir],nil, output) do |f|
54
+ f.puts JSON.pretty_generate(data)
49
55
  end
50
56
  end
51
57
  end
@@ -47,7 +47,7 @@ module Gzr
47
47
  with_session do
48
48
 
49
49
  @me ||= query_me("id")
50
-
50
+
51
51
  read_file(@file) do |data|
52
52
  look = upsert_look(@me.id,create_fetch_query(data[:query]).id,@dest_space_id,data,output: output)
53
53
  upsert_plans_for_look(look.id,@me.id,data[:scheduled_plans]) if data[:scheduled_plans]
@@ -84,33 +84,48 @@ module Gzr
84
84
  end
85
85
 
86
86
  def process_space(space_id, base, rel_path = nil)
87
- space = query_space(space_id)
88
- name = space.name
87
+ space = query_space(space_id).to_attrs
88
+ name = space[:name]
89
89
  name = "nil (#{space_id})" if name.nil?
90
90
  path = Pathname.new(name.gsub('/',"\u{2215}"))
91
91
  path = rel_path + path if rel_path
92
92
 
93
- write_file("Space_#{space.id}_#{name}.json", base, path) do |f|
94
- f.write JSON.pretty_generate(space.to_attrs.reject do |k,v|
93
+ write_file("Space_#{space[:id]}_#{name}.json", base, path) do |f|
94
+ f.write JSON.pretty_generate(space.reject do |k,v|
95
95
  [:looks, :dashboards].include?(k)
96
96
  end)
97
97
  end
98
- space.looks.each do |l|
99
- look = query_look(l.id)
100
- write_file("Look_#{look.id}_#{look.title}.json", base, path) do |f|
101
- f.write JSON.pretty_generate(look.to_attrs)
98
+ space[:looks].each do |l|
99
+ look = query_look(l[:id]).to_attrs
100
+ find_vis_config_reference(look) do |vis_config|
101
+ find_color_palette_reference(vis_config) do |o,default_colors|
102
+ rewrite_color_palette!(o,default_colors)
103
+ end
104
+ end
105
+ write_file("Look_#{look[:id]}_#{look[:title]}.json", base, path) do |f|
106
+ f.write JSON.pretty_generate(look)
102
107
  end
103
108
  end
104
- space.dashboards.each do |d|
105
- data = query_dashboard(d.id).to_attrs()
109
+ space[:dashboards].each do |d|
110
+ data = query_dashboard(d[:id]).to_attrs()
106
111
  data[:dashboard_elements].each_index do |i|
107
112
  element = data[:dashboard_elements][i]
113
+ find_vis_config_reference(element) do |vis_config|
114
+ find_color_palette_reference(vis_config) do |o,default_colors|
115
+ rewrite_color_palette!(o,default_colors)
116
+ end
117
+ end
108
118
  merge_result = merge_query(element[:merge_result_id])&.to_attrs() if element[:merge_result_id]
109
119
  if merge_result
110
120
  merge_result[:source_queries].each_index do |j|
111
121
  source_query = merge_result[:source_queries][j]
112
122
  merge_result[:source_queries][j][:query] = query(source_query[:query_id]).to_attrs()
113
123
  end
124
+ find_vis_config_reference(merge_result) do |vis_config|
125
+ find_color_palette_reference(vis_config) do |o,default_colors|
126
+ rewrite_color_palette!(o,default_colors)
127
+ end
128
+ end
114
129
  data[:dashboard_elements][i][:merge_result] = merge_result
115
130
  end
116
131
  end
@@ -120,7 +135,7 @@ module Gzr
120
135
  end
121
136
  space_children = query_space_children(space_id)
122
137
  space_children.each do |child_space|
123
- process_space(child_space.id, base, path)
138
+ process_space(child_space[:id], base, path)
124
139
  end
125
140
  end
126
141
  end
@@ -136,34 +136,44 @@ module Gzr
136
136
  new_look = source.select do |k,v|
137
137
  (keys_to_keep('update_look') - [:space_id,:folder_id,:user_id,:query_id,:slug]).include? k
138
138
  end
139
- new_look[:slug] = source[:slug] if source[:slug] && !slug_used
140
- new_look[:deleted] = false if existing_look[:deleted]
141
- new_look[:query_id] = query_id
142
- return update_look(existing_look.id,new_look)
143
- else
144
- new_look = source.select do |k,v|
145
- (keys_to_keep('create_look') - [:space_id,:folder_id,:user_id,:query_id,:slug]).include? k
139
+ new_look[:slug] = source[:slug] if source[:slug] && !slug_used
140
+ new_look[:deleted] = false if existing_look[:deleted]
141
+ new_look[:query_id] = query_id
142
+ return update_look(existing_look.id,new_look)
143
+ else
144
+ new_look = source.select do |k,v|
145
+ (keys_to_keep('create_look') - [:space_id,:folder_id,:user_id,:query_id,:slug]).include? k
146
+ end
147
+ new_look[:slug] = source[:slug] unless slug_used
148
+ new_look[:query_id] = query_id
149
+ new_look[:user_id] = user_id
150
+ new_look[:space_id] = space_id
151
+
152
+ find_vis_config_reference(new_look) do |vis_config|
153
+ find_color_palette_reference(vis_config) do |o,default_colors|
154
+ update_color_palette!(o,default_colors)
146
155
  end
147
- new_look[:slug] = source[:slug] unless slug_used
148
- new_look[:query_id] = query_id
149
- new_look[:user_id] = user_id
150
- new_look[:space_id] = space_id
151
-
152
- return create_look(new_look)
156
+ end
157
+ return create_look(new_look)
153
158
  end
154
159
  end
155
160
 
156
161
  def create_fetch_query(source_query)
157
162
  new_query = source_query.select do |k,v|
158
163
  (keys_to_keep('create_query') - [:client_id]).include? k
159
- end
164
+ end
165
+ find_vis_config_reference(new_query) do |vis_config|
166
+ find_color_palette_reference(vis_config) do |o,default_colors|
167
+ update_color_palette!(o,default_colors)
168
+ end
169
+ end
160
170
  return create_query(new_query)
161
171
  end
162
172
 
163
173
  def create_merge_result(merge_result)
164
174
  new_merge_result = merge_result.select do |k,v|
165
175
  (keys_to_keep('create_merge_query') - [:client_id,:source_queries]).include? k
166
- end
176
+ end
167
177
  new_merge_result[:source_queries] = merge_result[:source_queries].map do |query|
168
178
  new_query = {}
169
179
  new_query[:query_id] = create_fetch_query(query[:query]).id
@@ -171,6 +181,11 @@ module Gzr
171
181
  new_query[:merge_fields] = query[:merge_fields]
172
182
  new_query
173
183
  end
184
+ find_vis_config_reference(new_merge_result) do |vis_config|
185
+ find_color_palette_reference(vis_config) do |o,default_colors|
186
+ update_color_palette!(o,default_colors)
187
+ end
188
+ end
174
189
  return create_merge_query(new_merge_result)
175
190
  end
176
191
  end
@@ -116,15 +116,15 @@ module Gzr
116
116
  http.headers[:accept] = 'application/json'
117
117
  http.headers[:user_agent] = conn_hash[:user_agent]
118
118
  end
119
-
120
- begin
119
+
120
+ begin
121
121
  versions_response = agent.call(:get,"/versions")
122
122
  versions = versions_response.data.supported_versions
123
123
  current_version = versions_response.data.current_version
124
124
  rescue Faraday::SSLError => e
125
125
  raise Gzr::CLI::Error, "SSL Certificate could not be verified\nDo you need the --no-verify-ssl option or the --no-ssl option?"
126
126
  rescue Faraday::ConnectionFailed => cf
127
- raise Gzr::CLI::Error, "Connection Failed.\nDid you specify the --no-ssl option for an ssl secured server?"
127
+ raise Gzr::CLI::Error, "Connection Failed.\nDid you specify the --no-ssl option for an ssl secured server?\nYou may need to use --port=443 in some cases as well."
128
128
  rescue LookerSDK::NotFound => nf
129
129
  say_warning "endpoint #{root}/versions was not found"
130
130
  end
@@ -20,5 +20,5 @@
20
20
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  module Gzr
23
- VERSION = "0.2.40"
23
+ VERSION = "0.2.41"
24
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.40
4
+ version: 0.2.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike DeAngelo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-05 00:00:00.000000000 Z
11
+ date: 2020-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-reader
@@ -357,7 +357,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
357
357
  - !ruby/object:Gem::Version
358
358
  version: '0'
359
359
  requirements: []
360
- rubygems_version: 3.0.6
360
+ rubygems_version: 3.0.8
361
361
  signing_key:
362
362
  specification_version: 4
363
363
  summary: Command line tool to manage the content of a Looker instance.