twb 4.4.1 → 4.4.2

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: 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