twb 4.4.1 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 812d81d15bb4830be9ebb74ff7542bec21ba2fd3e2a4ecf6326ed1cc8be8c523
4
- data.tar.gz: 6802c24ee1c8477c718b248c3e81a5d46edcabcaa23f5051eec303efd7bbe24c
3
+ metadata.gz: 8330ec06a3076b01a2e2f6958b630ae2312c74d1fd0fdb6a575d2271ffdb745d
4
+ data.tar.gz: 7db555e49b52c9f0bc218aff47ab4a1af2b6a03064d5ce5f8fe04ee7323d3b4f
5
5
  SHA512:
6
- metadata.gz: 6277f3d28b0b4810e0ac370fbd282048a6278bb71415bd40a6426ce4f47187a0feead4d85280f752e080fe4355127bfa651233d087ac9eeb04a8190382f854d1
7
- data.tar.gz: 7b56029d3fee19cb4549d1433ff55201e3cf787abaecc40c9cf3d5b6cbbcda6cd49e8fcf2316f7543705b598a3d148270d94890fe3f92b93ac645fa477f00eac
6
+ metadata.gz: 801ed0a3f287f170f1d6f477641fa9c8ee761eb879a317ec779be9a9c4886a1f4dd78145b26b9e7dec9534d353ad583a3e4ceaaf8d9cf3f0781be657c364c19c
7
+ data.tar.gz: 22e0fc10a913f1fe27a0aac56c2230d35d8483dfeeea7ee8a8d28d1d8b67c05073eb1f925b5abda8e3dd8de98d1c704b0b1b93f242b3ad73b1aafaaf7987a9b9
data/lib/twb.rb CHANGED
@@ -70,5 +70,5 @@ require_relative 'twb/analysis/Sheets/dashsheetsanalyzer'
70
70
  # Represents Tableau Workbooks, their contents, and classes that analyze and manipulate them.
71
71
  #
72
72
  module Twb
73
- VERSION = '4.4.1'
73
+ VERSION = '4.4.2'
74
74
  end
@@ -82,10 +82,11 @@ module Analysis
82
82
  DOTHEADER
83
83
 
84
84
  def initialize(**args)
85
+ @args = args
85
86
  @csvAdd = args[:csvMode] == :add
86
87
  @csvMode = @csvAdd ? 'a' : 'w'
87
- emit true, "@csvAdd : #{@csvAdd}"
88
- emit true, "@csvMode: #{@csvMode}"
88
+ # emit true, "@csvAdd : #{@csvAdd}"
89
+ # emit true, "@csvMode: #{@csvMode}"
89
90
  init
90
91
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
91
92
  #-- CSV records collectors
@@ -24,30 +24,14 @@ module CalculatedFields
24
24
 
25
25
  attr_reader :docFileName
26
26
 
27
- def initialize
27
+ def initialize(**args)
28
+ @args = args
28
29
  init
30
+ puts "RECORD DOC: "
29
31
  @funcdoc = {:class=>self.class, :blurb=>'Create Markdown files (one per Workbook) documenting Calculated Fields', :description=>'Create Markdown files (one per Workbook) documenting Calculated Fields' }
30
32
  @metrics = {}
31
33
  end
32
34
 
33
- def kramdownAvailable
34
- gem_name, *gem_ver_reqs = 'kramdown', '~> 1.17.0'
35
- gdep = Gem::Dependency.new(gem_name, *gem_ver_reqs)
36
- # find latest that satisifies
37
- found_gspec = gdep.matching_specs.max_by(&:version)
38
- # instead of using Gem::Dependency, you can also do:
39
- # Gem::Specification.find_all_by_name(gem_name, *gem_ver_reqs)
40
- # if found_gspec
41
- # puts "Requirement '#{gdep}' already satisfied by #{found_gspec.name}-#{found_gspec.version}"
42
- # else
43
- # puts "Requirement '#{gdep}' not satisfied; could be installing..."
44
- # # reqs_string will be in the format: "> 1.0, < 1.2"
45
- # # reqs_string = gdep.requirements_list.join(', ')
46
- # # multi-arg is safer, to avoid injection attacks
47
- # # system('gem', 'install', gem_name, '-v', reqs_string)
48
- # end
49
- end
50
-
51
35
  def processTWB twb
52
36
  # twb = File.basename(twb)
53
37
  @twb = twb #Twb::Workbook.new twb
@@ -103,6 +87,26 @@ module CalculatedFields
103
87
  finis
104
88
  end # def processTwb twb
105
89
 
90
+ private
91
+
92
+ def kramdownAvailable
93
+ gem_name, *gem_ver_reqs = 'kramdown', '~> 1.17.0'
94
+ gdep = Gem::Dependency.new(gem_name, *gem_ver_reqs)
95
+ # find latest that satisifies
96
+ found_gspec = gdep.matching_specs.max_by(&:version)
97
+ # instead of using Gem::Dependency, you can also do:
98
+ # Gem::Specification.find_all_by_name(gem_name, *gem_ver_reqs)
99
+ # if found_gspec
100
+ # puts "Requirement '#{gdep}' already satisfied by #{found_gspec.name}-#{found_gspec.version}"
101
+ # else
102
+ # puts "Requirement '#{gdep}' not satisfied; could be installing..."
103
+ # # reqs_string will be in the format: "> 1.0, < 1.2"
104
+ # # reqs_string = gdep.requirements_list.join(', ')
105
+ # # multi-arg is safer, to avoid injection attacks
106
+ # # system('gem', 'install', gem_name, '-v', reqs_string)
107
+ # end
108
+ end
109
+
106
110
  end # class MarkdownEmitter
107
111
 
108
112
  end # nodule CalculatedFields
@@ -28,11 +28,12 @@ module Analysis
28
28
  attr_accessor :localEmit
29
29
 
30
30
  def initialize(**args)
31
+ @args = args
31
32
  #-- TODO move @csvAdd * #csvMode resolution to TabTool
32
33
  @csvAdd = args[:csvMode] == :add
33
34
  @csvMode = @csvAdd ? 'a' : 'w'
34
- emit "@csvAdd : #{@csvAdd}"
35
- emit "@csvMode: #{@csvMode}"
35
+ # emit "@csvAdd : #{@csvAdd}"
36
+ # emit "@csvMode: #{@csvMode}"
36
37
  #--
37
38
  init
38
39
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Data Source Origins, i.e. where the data comes from', :description=>nil,}
@@ -28,6 +28,7 @@ module Analysis
28
28
  attr_reader :twbname, :twbcount
29
29
 
30
30
  def initialize(**args)
31
+ @args = args
31
32
  #-- TODO move @csvAdd * #csvMode resolution to TabTool
32
33
  @csvAdd = args[:csvMode] == :add
33
34
  @csvMode = @csvAdd ? 'a' : 'w'
@@ -27,10 +27,11 @@ module Analysis
27
27
 
28
28
  def initialize(**args)
29
29
  #-- TODO move @csvAdd * #csvMode resolution to TabTool
30
+ @args = args
30
31
  @csvAdd = args[:csvMode] == :add
31
32
  @csvMode = @csvAdd ? 'a' : 'w'
32
- emit "@csvAdd : #{@csvAdd}"
33
- emit "@csvMode: #{@csvMode}"
33
+ # emit "@csvAdd : #{@csvAdd}"
34
+ # emit "@csvMode: #{@csvMode}"
34
35
  #--
35
36
  init
36
37
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Dashboard Worksheets', :description=>'Identifies the Worksheets present in Dashboards.',}
@@ -25,34 +25,42 @@ module Analysis
25
25
 
26
26
  @@fieldTypeCodes = { 'DB ref' => 'Db',
27
27
  'color' => 'Clr',
28
- 'filter' => 'F',
29
- 'lod' => 'L',
30
- 'page' => 'Pg',
31
- 'path' => 'Pt',
32
- 'shape' => 'Sh',
33
- 'size' => 'Sz',
34
- 'text' => 'Tx',
35
- 'tooltip' => 'Tt',
36
- :column => 'Cm',
37
- :row => 'R',
28
+ 'filter' => 'Flt',
29
+ 'lod' => 'LoD',
30
+ 'page' => 'Pge',
31
+ 'path' => 'Pth',
32
+ 'shape' => 'Shp',
33
+ 'size' => 'Siz',
34
+ 'text' => 'Tex',
35
+ 'tooltip' => 'TTp',
36
+ :column => 'Clm',
37
+ :row => 'Row',
38
+ 'slice' => 'Slc',
38
39
  }
39
40
 
40
41
 
41
42
  attr_accessor :localEmit
42
43
 
43
44
  def initialize(**args)
44
- @csvAdd = args[:csvMode] == :add
45
- @csvMode = @csvAdd ? 'a' : 'w'
46
- emit true, "@csvAdd : #{@csvAdd}"
47
- emit true, "@csvMode: #{@csvMode}"
48
-
45
+ @args = args
46
+ @csvAdd = args[:csvMode] == :add
47
+ @recordDir = !@args.nil? && @args[:recordDir] == true
48
+ # puts " args: #{@args}"
49
+ # puts " @recordDir: #{@recordDir}"
50
+ # @csvMode = @csvAdd ? 'a' : 'w'
51
+ # emit true, "@csvAdd : #{@csvAdd}"
52
+ # emit true, "@csvMode: #{@csvMode}"
49
53
  init
50
54
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Worksheet Fields', :description=>nil,}
51
55
  #--
52
56
  docFileName = docFile('WorksheetFields.csv')
53
57
  @sheetFieldsCSV = CSV.open(docFileName,'w')
54
58
  unless @csvAdd
55
- @sheetFieldsCSV << ['Rec #', 'Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code']
59
+ if @recordDir
60
+ @sheetFieldsCSV << ['Rec #', 'Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code','Workbook Dir']
61
+ else
62
+ @sheetFieldsCSV << ['Rec #', 'Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code' ]
63
+ end
56
64
  end
57
65
  addDocFile @sheetFieldsCSV, docFileName, "Workbooks, Worksheets, and the Sheets' Data Sources and Fields"
58
66
  #--
@@ -92,37 +100,65 @@ module Analysis
92
100
  end
93
101
 
94
102
  def showFields sheet
95
- showDBFields sheet
96
- showRCFields sheet.rowFields, :row
97
- showRCFields sheet.colFields, :column
98
- showEncodedFields sheet
99
- showFilterFields sheet
100
- showPageFields sheet
103
+ recordDBFields sheet
104
+ recordRCFields sheet.rowFields, :row
105
+ recordRCFields sheet.colFields, :column
106
+ recordEncodedFields sheet
107
+ recordFilterFields sheet
108
+ recordPageFields sheet
109
+ recordSlicesFields sheet
110
+ recordDSFilterFields sheet
101
111
  end
102
112
 
103
- def showPageFields sheet
113
+ def recordPageFields sheet
104
114
  sheet.pageFields.each do |pfield|
105
115
  ds = @twb.datasource pfield.dataSource
106
- fuiname = ds.fieldUIName pfield.name
107
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('filter')]
116
+ fuiname = ds.fieldUIName pfield.name
117
+ # if @recordDir
118
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('filter'), @twb.dir]
119
+ # else
120
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('filter') ]
121
+ # end
122
+ recordCSV [@twb.name, @sheet, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('page')]
108
123
  end
109
124
  end
110
125
 
111
- def showFilterFields sheet
126
+ def recordFilterFields sheet
112
127
  filters = sheet.filters
113
128
  filters.each do |filter|
114
129
  dsName = filter.dataSource.name
115
130
  dsUIName = filter.dataSource.uiname
116
131
  # puts "Filter field: #{filter.dataSource.name} ui:'#{}'"
117
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter')]
132
+ # if @recordDir
133
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter'), @twb.dir]
134
+ # else
135
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter') ]
136
+ # end
137
+ recordCSV [@twb.name, @sheet, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter')]
118
138
  end
119
139
  end
120
140
 
121
- def showDBFields sheet
141
+ def recordDSFilterFields sheet
142
+ sheet.slicesFields.each do |field|
143
+ dsName = field.dataSource
144
+ ds = @twb.datasource dsName
145
+ dsUIName = ds.uiname
146
+ ds.filters.each do |filter|
147
+ recordCSV [@twb.name, @sheet, dsUIName, dsName, filter.uiname, filter.name, 'dsfilter', ftc('dsfilter')]
148
+ end
149
+ end
150
+ end
151
+
152
+ def recordDBFields sheet
122
153
  fields = sheet.datasourceFields
123
- emit "def showDBFields sheet: #{sheet.name} #FIELDS: #{fields.length}"
154
+ emit "def recordDBFields sheet: #{sheet.name} #FIELDS: #{fields.length}"
124
155
  if fields.nil?
125
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, nil, nil, nil, nil, nil]
156
+ # if @recordDir
157
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, nil, nil, nil, nil, nil, @twb.dir]
158
+ # else
159
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, nil, nil, nil, nil, nil]
160
+ # end
161
+ recordCSV [@twb.name, @sheet, nil, nil, nil, nil, nil]
126
162
  end
127
163
  fields.each do |dsName, dsfields|
128
164
  ds = @twb.datasource dsName
@@ -134,16 +170,18 @@ module Analysis
134
170
  emit " f: #{sheetField}"
135
171
  emit " c: #{sheetField.class}"
136
172
  fuiName = ds.fieldUIName sheetField #Fields[sheetField]
137
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, sheetField.uiname, sheetField.name, 'DB ref', ftc('DB ref')]
173
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, sheetField.uiname, sheetField.name, 'DB ref', ftc('DB ref')]
174
+ recordCSV [@twb.name, @sheet, ds.uiname, dsName, sheetField.uiname, sheetField.name, 'DB ref', ftc('DB ref')]
138
175
  # emit true, " : #{dsFields[field].class}"
139
176
  end
140
177
  end
141
178
  end
142
179
 
143
- def showRCFields fields, usage
144
- emit "def showRCFields #fields: #{fields.length} \t #{fields}"
180
+ def recordRCFields fields, usage
181
+ emit "def recordRCFields #fields: #{fields.length} \t #{fields}"
145
182
  if fields.nil?
146
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, nil, nil, nil, nil, nil]
183
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, nil, nil, nil, nil, nil]
184
+ recordCSV [@twb.name, @sheet, nil, nil, nil, nil, nil]
147
185
  else
148
186
  fields.each do |cf|
149
187
  emit "coded field: #{cf}"
@@ -155,23 +193,46 @@ module Analysis
155
193
  emit " ds: #{dsName}"
156
194
  emit " - #{ds.uiname}"
157
195
  emit " : #{ds.class}"
158
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, fuiName, fldName, usage, ftc(usage)]
196
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, fuiName, fldName, usage, ftc(usage)]
197
+ recordCSV [@twb.name, @sheet, ds.uiname, dsName, fuiName, fldName, usage, ftc(usage)]
159
198
  end
160
199
  end
161
200
  end
162
201
 
163
- def showEncodedFields sheet
202
+ def recordEncodedFields sheet
164
203
  unless sheet.encodedFields.nil?
165
204
  sheet.encodedFields.each do |type,fields|
166
205
  fields.each do |field|
167
206
  dsName = field.dataSource
168
207
  ds = @twb.datasource dsName
169
208
  fuiName = ds.fieldUIName field.name
170
- @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, fuiName, field.name, type, ftc(type)]
209
+ # @sheetFieldsCSV << [@recNum+=1, @twb.name, @sheet, ds.uiname, dsName, fuiName, field.name, type, ftc(type)]
210
+ recordCSV [@twb.name, @sheet, ds.uiname, dsName, fuiName, field.name, type, ftc(type)]
171
211
  end
172
212
  end
173
213
  end
174
- end #def showEncodedFields
214
+ end #def recordEncodedFields
215
+
216
+ def recordSlicesFields sheet
217
+ # puts "recordSlicesFields"
218
+ unless sheet.slicesFields.nil?
219
+ sheet.slicesFields.each do |field|
220
+ dsName = field.dataSource
221
+ ds = @twb.datasource dsName
222
+ fuiName = ds.fieldUIName field.name
223
+ recordCSV [@twb.name, @sheet, ds.uiname, dsName, fuiName, field.name, 'slice', ftc('slice')]
224
+ end
225
+ end
226
+ end
227
+
228
+ def recordCSV record
229
+ numberedRec = [@recNum+=1] + record
230
+ if @recordDir
231
+ @sheetFieldsCSV << numberedRec.push(@twb.dir)
232
+ else
233
+ @sheetFieldsCSV << numberedRec
234
+ end
235
+ end
175
236
 
176
237
  def ftc type # ftc : abbr for fieldTypeCode, for brevity
177
238
  @@fieldTypeCodes[type].nil? ? type : @@fieldTypeCodes[type]
@@ -26,22 +26,29 @@ module Analysis
26
26
  attr_accessor :localEmit
27
27
 
28
28
  def initialize(**args)
29
- @csvAdd = args[:csvMode] == :add
30
- @csvMode = @csvAdd ? 'a' : 'w'
31
- emit true, "@csvAdd : #{@csvAdd}"
32
- emit true, "@csvMode: #{@csvMode}"
29
+ @args = args
30
+ @recordDir = !@args.nil? && @args[:recordDir] == true
31
+ @csvAdd = args[:csvMode] == :add
32
+ # @csvMode = @csvAdd ? 'a' : 'w'
33
+ # emit "@csvAdd : #{@csvAdd}"
34
+ # emit "@csvMode: #{@csvMode}"
33
35
  init
34
36
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Worksheet Filters', :description=>'Documents Quick Filters and the values they employ, if any. Work in progess.',}
35
37
  #--
36
38
  docFileName = docFile('WorksheetFilters.csv')
37
- $sheetFieldsCSV = CSV.open( docFileName ,'w')
39
+ @sheetFieldsCSV = CSV.open( docFileName ,'w')
38
40
  unless @csvAdd
39
- $sheetFieldsCSV << ['Workbook','Workbook Dir','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
41
+ if @recordDir
42
+ @sheetFieldsCSV << ['Rec #','Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind','Workbook Dir']
43
+ else
44
+ @sheetFieldsCSV << ['Rec #','Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
45
+ end
40
46
  end
41
- addDocFile $sheetFieldsCSV, docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
47
+ addDocFile @sheetFieldsCSV, docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
42
48
  #--
43
49
  @sheetCount = 0
44
50
  @filterCount = 0
51
+ @recNum = 0
45
52
  end
46
53
 
47
54
  def metrics
@@ -68,20 +75,31 @@ module Analysis
68
75
  filters.each do |filter|
69
76
  filter.emit "-----------------------------\nWORKSHEET:: #{sheet.name}\n-----------------------------"
70
77
  if filter.values.empty?
71
- # $sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation' ,'Data Source','Field','Value','Alias', 'Alias?']
72
- $sheetFieldsCSV << [@twbName, @twbDir, sheet.name, filter.type ,filter.inexclude, filter.dataSource.uiname, filter.uiname,nil,nil,nil,filter.inexMode,filter.includeNull,filter.kind]
78
+ # @sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation' ,'Data Source','Field','Value','Alias', 'Alias?']
79
+ recordCSV [@twbName, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, nil, nil, nil, filter.inexMode, filter.includeNull, filter.kind]
73
80
  end
74
81
  filter.values.each do |valueMap|
75
82
  value = valueMap[:value]
76
83
  valias = valueMap[:alias]
77
84
  same = value.eql? valias
78
85
  emit "RECORDING FILTER VALUES: %-35s -- %-25s same? %s " % [value,valias,same]
79
- $sheetFieldsCSV << [@twbName, @twbDir, sheet.name, filter.type ,filter.inexclude, filter.dataSource.uiname, filter.uiname, value, valias, same,filter.inexMode,filter.includeNull,filter.kind]
86
+ recordCSV [@twbName, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, value, valias, same, filter.inexMode, filter.includeNull, filter.kind]
80
87
  end
81
88
  end
82
89
  end
83
90
  end
84
91
 
92
+ private
93
+
94
+ def recordCSV record
95
+ numberedRec = [@recNum+=1] + record
96
+ if @recordDir
97
+ @sheetFieldsCSV << numberedRec.push(@twbDir)
98
+ else
99
+ @sheetFieldsCSV << numberedRec
100
+ end
101
+ end
102
+
85
103
  end # class SheetFiltersAnalyzerA
86
104
 
87
105
  end # module Twb
@@ -27,10 +27,10 @@ module Twb
27
27
  attr_reader :name, :techCode, :function, :rawCode
28
28
 
29
29
  def initialize code
30
- #puts "\n\nCodedField :: #{code}"
30
+ # puts "...CodedField :: #{code}"
31
31
  @rawCode = code
32
- trimmed = code.gsub(/^['"]|['"]$/,'').gsub(/^\[|\]$/,'')
33
- # puts "trimmed: #{trimmed}"
32
+ trimmed = code.gsub(/^['"]|['"]$/,'').gsub(/^\[|\]$/,'').gsub(/:[0-9]+$/,'')
33
+ # puts " trimmed :: #{trimmed}"
34
34
  parts = trimmed.split('].[')
35
35
  #puts "Field: #{code} parts: #{parts.length} - #{parts.inspect}"
36
36
  #puts " p1: #{parts[0]}"
@@ -70,7 +70,7 @@ module Twb
70
70
  @uiname = @caption.nil? ? @name : @caption
71
71
  # puts "DATASOURCE: #{@uiname}"
72
72
  processConnection
73
- processFilters
73
+ # processFilters
74
74
  loadTableFields
75
75
  loadFieldUINames
76
76
  return self
@@ -503,10 +503,16 @@ module Twb
503
503
  end
504
504
  end
505
505
 
506
+ def filters
507
+ @filters ||= loadFilters
508
+ end
509
+
506
510
  def groups
507
511
  @groups ||= loadGroups
508
512
  end
509
513
 
514
+ private
515
+
510
516
  def loadGroups
511
517
  @groups = []
512
518
  groupNodes = @node.xpath('.//group')
@@ -517,25 +523,37 @@ module Twb
517
523
  return @groups
518
524
  end
519
525
 
520
- def processFilters
521
- if @filters.nil?
522
- @filters = {}
523
- fnodes = @node.xpath('./filter')
524
- fnodes.each do |fn|
525
- columnN = fn.attribute('column')
526
- unless columnN.nil?
527
- memberNodes = fn.xpath('.//groupfilter/@member')
528
- unless memberNodes.nil?
529
- members = []
530
- memberNodes.each do |m|
531
- members.push m.text
532
- end
533
- @filters[columnN.text] = members
534
- end
535
- end
536
- end
526
+ # def processFilters
527
+ def loadFilters
528
+ @filters = []
529
+ sharedFilters = @workbook.node.xpath('./shared-views/shared-view[@name="excel.41269.481293159719"]//filter')
530
+ sharedFilters.each do |sf|
531
+ filter = QuickFilter.new(sf,@workbook)
532
+ @filters << filter
537
533
  end
538
- end
534
+ return @filters
535
+ end
536
+
537
+ # @filters <<
538
+ # if @filters.nil?
539
+ # @filters = {}
540
+ # fnodes = @node.xpath('./filter')
541
+ # fnodes.each do |fn|
542
+ # columnN = fn.attribute('column')
543
+ # unless columnN.nil?
544
+ # memberNodes = fn.xpath('.//groupfilter/@member')
545
+ # unless memberNodes.nil?
546
+ # members = []
547
+ # memberNodes.each do |m|
548
+ # members.push m.text
549
+ # end
550
+ # @filters[columnN.text] = members
551
+ # end
552
+ # end
553
+ # end
554
+ # end
555
+ # end
556
+
539
557
 
540
558
  end # class DataSource
541
559
 
@@ -86,6 +86,10 @@ module Twb
86
86
  end
87
87
  end # def initialize
88
88
 
89
+ def context?
90
+ @iscontext ||= @node['context']
91
+ end
92
+
89
93
  def to_s
90
94
  "%s => %s" % [uiname, values]
91
95
  end
data/lib/twb/worksheet.rb CHANGED
@@ -28,7 +28,7 @@ module Twb
28
28
 
29
29
  attr_reader :node, :name, :datasourcenames, :datasources
30
30
  attr_reader :panesCount
31
- attr_reader :fields, :rowFields, :colFields, :paneFields, :datasourceFields, :pageFields, :encodedFields
31
+ attr_reader :fields, :rowFields, :colFields, :paneFields, :datasourceFields, :pageFields, :encodedFields, :slicesFields
32
32
  attr_reader :filters
33
33
  attr_reader :tooltip
34
34
  attr_accessor :hidden, :visible
@@ -38,8 +38,7 @@ module Twb
38
38
  @node = sheetNode
39
39
  @name = @node['name']
40
40
  emit "########################## Worksheet initialize name: #{@name}"
41
-
42
- loadDataSourceNames
41
+ loadDataSources
43
42
  loadFields
44
43
  return self
45
44
  end
@@ -48,15 +47,6 @@ module Twb
48
47
  @id ||= @name.hash
49
48
  end
50
49
 
51
- def loadDataSourceNames
52
- @datasources = {}
53
- dsNodes = @node.xpath('.//datasource')
54
- dsNodes.each do |dsn|
55
- ds = WorksheetDataSource.new dsn
56
- @datasources[ds.name] = ds
57
- end
58
- end
59
-
60
50
  def workbook
61
51
  @workbook ||= @node.at_xpath('/').root
62
52
  end
@@ -78,6 +68,10 @@ module Twb
78
68
  # @fields.nil? ? loadFields : @fields
79
69
  end
80
70
 
71
+ def slicesFields
72
+ @slicesFields ||= loadSlicesFields
73
+ end
74
+
81
75
  def filters
82
76
  @filters ||= loadFilters
83
77
  end
@@ -94,6 +88,36 @@ module Twb
94
88
  @visible ||= !hidden
95
89
  end
96
90
 
91
+ def addDSFields fields, usage
92
+ fields.each do
93
+ end
94
+ end
95
+
96
+ def panesCount
97
+ @panesCount ||= @node.xpath('.//panes/pane').length
98
+ end
99
+
100
+ def paneFields
101
+ @paneFields ||= loadPaneFields
102
+ end
103
+
104
+ def pageFields
105
+ @pageFields ||= loadpageFields
106
+ end
107
+
108
+ def datasourcenames
109
+ @datasources.keys
110
+ end
111
+
112
+ private
113
+
114
+ # def resolveHidden
115
+ # xpath = "//windows/window[@name=\"#{@name}\"]"
116
+ # emit true, "resolveHidden: #{xpath}"
117
+ # windowNode = @node.at_xpath(xpath)
118
+ # @hidden = !windowNode.nil? && 'true' == windowNode['hidden']
119
+ # end
120
+
97
121
  def loadFields
98
122
  # puts "WORKSHEET loadFields"
99
123
  @fields = {}
@@ -117,43 +141,29 @@ module Twb
117
141
  loadFieldEncodings
118
142
  end
119
143
 
120
- def loadFieldEncodings
121
- @encodedFields = Hash.new { |h,k| h[k] = [] }
122
- enodes = @node.xpath('.//table/panes/pane/encodings')
123
- enodes.each do |enode|
124
- enode.children.each do |child|
125
- unless child['column'].nil?
126
- @encodedFields[child.name] << CodedField.new(child['column'])
127
- end
128
- end
129
- end
130
- @encodedFields.each do |type, fields|
131
- @fields[type] = fields
132
- end
144
+ def loadPaneFields
145
+ @paneFields = Set.new
146
+ panes = @node.xpath('.//pane')
133
147
  end
134
148
 
135
- # def loadFieldEncodings node
136
- # $encodedFields = Hash.new { |h,k| h[k] = [] }
137
- # enodes = node.xpath('.//table/panes/pane/encodings')
138
- # enodes.each do |enode|
139
- # enode.children.each do |child|
140
- # unless child['column'].nil?
141
- # $encodedFields[child.name] << CodedField.new(child['column'])
142
- # end
143
- # end
144
- # end
145
- # $encodedFields.each do |type, fields|
146
- # $fields[type] = fields
147
- # end
148
- # end
149
-
150
- def addDSFields fields, usage
151
- fields.each do
149
+ def loadFilters
150
+ emit ""########################## loadFilters"
151
+ @filters = []
152
+ filterNodes = @node.xpath('./table/view//filter[@column]')
153
+ filterNodes.each do |fnode|
154
+ filter = QuickFilter.new(fnode,@twb)
155
+ @filters << filter
152
156
  end
157
+ return @filters
153
158
  end
154
159
 
155
- def panesCount
156
- @panesCount ||= @node.xpath('.//panes/pane').length
160
+ def loadDataSources
161
+ @datasources = {}
162
+ dsNodes = @node.xpath('.//datasource')
163
+ dsNodes.each do |dsn|
164
+ ds = WorksheetDataSource.new dsn
165
+ @datasources[ds.name] = ds
166
+ end
157
167
  end
158
168
 
159
169
  def loadRowColFields(type)
@@ -174,17 +184,8 @@ module Twb
174
184
  return fields
175
185
  end
176
186
 
177
- def paneFields
178
- @paneFields ||= loadPaneFields
179
- end
180
-
181
- def loadPaneFields
182
- @paneFields = Set.new
183
- panes = @node.xpath('.//pane')
184
- end
185
-
186
- def pageFields
187
- @pageFields ||= loadpageFields
187
+ def loadTooltip
188
+ @tooltip = @node.xpath('./table/panes/pane/customized-tooltip')
188
189
  end
189
190
 
190
191
  def loadpageFields
@@ -196,33 +197,47 @@ module Twb
196
197
  return @pageFields
197
198
  end
198
199
 
199
- def datasourcenames
200
- @datasources.keys
200
+ def loadSlicesFields
201
+ @slicesFields = []
202
+ nodes = @node.xpath('./table/view/slices//column')
203
+ nodes.each do |node|
204
+ # puts "Slice field: #{node.text}"
205
+ @slicesFields << CodedField.new(node.text)
206
+ end
207
+ return @slicesFields
201
208
  end
202
209
 
203
- private
210
+ def loadFieldEncodings
211
+ @encodedFields = Hash.new { |h,k| h[k] = [] }
212
+ enodes = @node.xpath('.//table/panes/pane/encodings')
213
+ enodes.each do |enode|
214
+ enode.children.each do |child|
215
+ unless child['column'].nil?
216
+ @encodedFields[child.name] << CodedField.new(child['column'])
217
+ end
218
+ end
219
+ end
220
+ @encodedFields.each do |type, fields|
221
+ @fields[type] = fields
222
+ end
223
+ end
204
224
 
205
- # def resolveHidden
206
- # xpath = "//windows/window[@name=\"#{@name}\"]"
207
- # emit true, "resolveHidden: #{xpath}"
208
- # windowNode = @node.at_xpath(xpath)
209
- # @hidden = !windowNode.nil? && 'true' == windowNode['hidden']
225
+ # def loadFieldEncodings node
226
+ # $encodedFields = Hash.new { |h,k| h[k] = [] }
227
+ # enodes = node.xpath('.//table/panes/pane/encodings')
228
+ # enodes.each do |enode|
229
+ # enode.children.each do |child|
230
+ # unless child['column'].nil?
231
+ # $encodedFields[child.name] << CodedField.new(child['column'])
232
+ # end
233
+ # end
234
+ # end
235
+ # $encodedFields.each do |type, fields|
236
+ # $fields[type] = fields
237
+ # end
210
238
  # end
211
239
 
212
- def loadFilters
213
- emit ""########################## loadFilters"
214
- @filters = []
215
- filterNodes = @node.xpath('./table/view//filter[@column]')
216
- filterNodes.each do |fnode|
217
- filter = QuickFilter.new(fnode,@twb)
218
- @filters << filter
219
- end
220
- return @filters
221
- end
222
240
 
223
- def loadTooltip
224
- @tooltip = @node.xpath('./table/panes/pane/customized-tooltip')
225
- end
226
241
 
227
242
  end # class Worksheet
228
243
 
@@ -273,65 +288,4 @@ module Twb
273
288
  end # class RowsColsSplitter
274
289
 
275
290
 
276
-
277
- class CodedField
278
-
279
- include Comparable
280
-
281
- attr_reader :code, :dataSource, :prefix, :name, :suffix
282
-
283
- def initialize incode
284
- # puts "CF: #{incode}"
285
- @code = incode
286
- trimCode = code.gsub(/^\[/,'').gsub(/\]$/,'')
287
- # puts " : '#{trimCode}'"
288
- @dataSource = nil
289
- dsFldBits = trimCode.split('].[')
290
- if dsFldBits.length == 2
291
- @dataSource = dsFldBits[0]
292
- fieldCode = dsFldBits[1]
293
- else
294
- fieldCode = dsFldBits[0]
295
- end
296
- # puts "fc: #{fieldCode}"
297
- parts = fieldCode.split(':')
298
- bits =
299
- if ':Measure Names'.eql?(fieldCode)
300
- {:prefix => nil, :name => fieldCode, :suffix => nil }
301
- else
302
- case parts.length
303
- when 1
304
- bits = {:prefix => nil, :name => parts[0], :suffix => nil}
305
- when 3
306
- bits = {:prefix => parts[0], :name => parts[1], :suffix => parts[2]}
307
- when 4
308
- if parts[-1].match(/^(\d)+$/)
309
- bits = {:prefix => parts[0], :name => parts[1], :suffix => "#{parts[2]}:#{parts[3]}"}
310
- else
311
- bits = {:prefix => "#{parts[0]}:#{parts[1]}", :name => parts[2], :suffix => parts[3]}
312
- end
313
- when 5
314
- bits = {:prefix => "#{parts[0]}:#{parts[1]}", :name => parts[2], :suffix => "#{parts[3]}:#{parts[4]}"}
315
- else
316
- bits = {:prefix => "OOPS #{parts.inspect}", :name => '', :suffix => '' }
317
- end
318
- end
319
- @prefix = bits[:prefix]
320
- @name = bits[:name]
321
- @suffix = bits[:suffix]
322
- # puts " l: #{parts.length} == #{bits}"
323
- # bits.each { |k,v| puts " l: %-7s %s" % [k,v] }
324
- end
325
- # --
326
- def to_s
327
- @code
328
- end
329
-
330
- def <=>(other)
331
- @code <=> other.code
332
- end
333
-
334
- end #class CodedField
335
-
336
-
337
291
  end # module Twb
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twb
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.1
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Gerrard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-04 00:00:00.000000000 Z
11
+ date: 2019-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: creek