twb 4.3.3 → 4.4.1

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: 150eff5c8dea70f1bb4a81416ba1097fe200e76ae173976f2cb6991f3b62fd02
4
- data.tar.gz: 9238b3a04c9fc93d173743fdd15f9274b8b0f4a01dea00dcaa5cee27cf981c68
3
+ metadata.gz: 812d81d15bb4830be9ebb74ff7542bec21ba2fd3e2a4ecf6326ed1cc8be8c523
4
+ data.tar.gz: 6802c24ee1c8477c718b248c3e81a5d46edcabcaa23f5051eec303efd7bbe24c
5
5
  SHA512:
6
- metadata.gz: 025cc5a832adcf6b550808affe56077a2b8a605080424a57ce0f4f1138887c4ce8d5646f6505e9dcf114364bd8f9e58a40743b450cc1f51188aa10ad35c906b8
7
- data.tar.gz: 69b0a5f7ba2cb26a88925c86ada6b7aad6ab6df9bb3ee4ffd04845842657df4037273d9df994c8439043ee29528f375549894f7ec68f5dafec33488809841269
6
+ metadata.gz: 6277f3d28b0b4810e0ac370fbd282048a6278bb71415bd40a6426ce4f47187a0feead4d85280f752e080fe4355127bfa651233d087ac9eeb04a8190382f854d1
7
+ data.tar.gz: 7b56029d3fee19cb4549d1433ff55201e3cf787abaecc40c9cf3d5b6cbbcda6cd49e8fcf2316f7543705b598a3d148270d94890fe3f92b93ac645fa477f00eac
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.3.3'
73
+ VERSION = '4.4.1'
74
74
  end
@@ -81,7 +81,11 @@ module Analysis
81
81
 
82
82
  DOTHEADER
83
83
 
84
- def initialize
84
+ def initialize(**args)
85
+ @csvAdd = args[:csvMode] == :add
86
+ @csvMode = @csvAdd ? 'a' : 'w'
87
+ emit true, "@csvAdd : #{@csvAdd}"
88
+ emit true, "@csvMode: #{@csvMode}"
85
89
  init
86
90
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
87
91
  #-- CSV records collectors
@@ -53,7 +53,7 @@ module CalculatedFields
53
53
  @twb = twb #Twb::Workbook.new twb
54
54
  @docFileName = './ttdoc/' + @twb.name + '.CalculatedFields.md'
55
55
  @docFile = File.open(@docFileName,'w')
56
- addDocFile @docFileName,"Markdown file of Calculated fields for Workbook '#{@twb.name}'"
56
+ addDocFile @docFile, @docFileName, "Markdown file of Calculated fields for Workbook '#{@twb.name}'"
57
57
  @docFile.puts "# #{twb.name}"
58
58
  dsNames = @twb.datasourceUINames
59
59
  @docFile.puts "#{dsNames.length} Data Sources"
@@ -63,37 +63,37 @@ module CalculatedFields
63
63
  cnt = 0
64
64
  ds.calculatedFields.each do |cf|
65
65
  cnt += 1
66
- @docFile.puts "### '#{cf.uiname}'"
67
- @docFile.puts "```"
68
- cf.formulaResolvedLines.each do
69
- |l|@docFile.puts "#{l.gsub('<<','[').gsub('>>',']')}"
66
+ @docFile.puts "### '#{cf.uiname}'"
67
+ @docFile.puts "```"
68
+ cf.formulaResolvedLines.each do |l|
69
+ @docFile.puts "#{l.gsub('<<','[').gsub('>>',']')}"
70
+ end
71
+ @docFile.puts "```"
72
+ if cf.calcFields.length > 0
73
+ fieldsRefOrder = []
74
+ fieldsSortSet = SortedSet.new
75
+ cf.calcFields.each do |field|
76
+ fieldsRefOrder.push field.uiname
77
+ fieldsSortSet << field.uiname
70
78
  end
71
- @docFile.puts "```"
72
- if cf.calcFields.length > 0
73
- fieldsRefOrder = []
74
- fieldsSortSet = SortedSet.new
75
- cf.calcFields.each do |field|
76
- fieldsRefOrder.push field.uiname
77
- fieldsSortSet << field.uiname
78
- end
79
- if fieldsRefOrder != fieldsSortSet.to_a
80
- @docFile.puts "```"
81
- @docFile.puts "Fields - reference order:"
82
- fieldsRefOrder.each do |field|
83
- @docFile.puts " '#{field}'"
84
- end
85
- @docFile.puts "```"
86
- end
87
- if fieldsSortSet.length > 0
88
- @docFile.puts "```"
89
- @docFile.puts "Fields:"
90
- fieldsSortSet.each do |field|
91
- @docFile.puts " '#{field}'"
92
- end
93
- @docFile.puts "```"
94
- end
95
- end
96
- @docFile.puts "\n "
79
+ if fieldsRefOrder != fieldsSortSet.to_a
80
+ @docFile.puts "```"
81
+ @docFile.puts "Fields - reference order:"
82
+ fieldsRefOrder.each do |field|
83
+ @docFile.puts " '#{field}'"
84
+ end
85
+ @docFile.puts "```"
86
+ end
87
+ if fieldsSortSet.length > 0
88
+ @docFile.puts "```"
89
+ @docFile.puts "Fields:"
90
+ fieldsSortSet.each do |field|
91
+ @docFile.puts " '#{field}'"
92
+ end
93
+ @docFile.puts "```"
94
+ end
95
+ end
96
+ @docFile.puts "\n "
97
97
  end
98
98
  @docFile.puts "counted #{cnt} calculated fields\n "
99
99
  end # twb.datasources.each
@@ -27,14 +27,22 @@ module Analysis
27
27
 
28
28
  attr_accessor :localEmit
29
29
 
30
- def initialize
30
+ def initialize(**args)
31
+ #-- TODO move @csvAdd * #csvMode resolution to TabTool
32
+ @csvAdd = args[:csvMode] == :add
33
+ @csvMode = @csvAdd ? 'a' : 'w'
34
+ emit "@csvAdd : #{@csvAdd}"
35
+ emit "@csvMode: #{@csvMode}"
36
+ #--
31
37
  init
32
38
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Data Source Origins, i.e. where the data comes from', :description=>nil,}
33
39
  #--
34
40
  docFileName = docFile('DataSourceOrigins.csv')
35
41
  @csvFile = CSV.open(docFileName,'w')
36
- @csvFile << ['Workbook', 'Workbook Version', 'Workbook Directory', 'Data Source', 'Data Source (tech)', 'Is Published?', "Rec #"]
37
- addDocFile docFileName, "Workbooks, Data Sources, and the Data Sources' origins"
42
+ unless @csvAdd
43
+ @csvFile << ['Workbook', 'Workbook Version', 'Workbook Directory', 'Data Source', 'Data Source (tech)', 'Is Published?', "Rec #"]
44
+ end
45
+ addDocFile @csvFile, docFileName, "Workbooks, Data Sources, and the Data Sources' origins"
38
46
  #--
39
47
  @twbCnt = 0
40
48
  @dsCnt = 0
@@ -27,7 +27,13 @@ module Analysis
27
27
  attr_accessor :localEmit
28
28
  attr_reader :twbname, :twbcount
29
29
 
30
- def initialize
30
+ def initialize(**args)
31
+ #-- TODO move @csvAdd * #csvMode resolution to TabTool
32
+ @csvAdd = args[:csvMode] == :add
33
+ @csvMode = @csvAdd ? 'a' : 'w'
34
+ emit "@csvAdd : #{@csvAdd}"
35
+ emit "@csvMode: #{@csvMode}"
36
+ #--
31
37
  init
32
38
  #-- set up metrics
33
39
  @twbcount = 0
@@ -38,8 +44,11 @@ module Analysis
38
44
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Google Sheet Data Sources', :description=>nil,}
39
45
  docFileName = docFile('GoogleSheetDataSources.csv')
40
46
  @csv = CSV.open(docFileName, 'w')
41
- @csv << ["Workbook",'Data Source','Connection','File Name','Type','Table Name','Field']
42
- @docfiles = [{:name=>docFileName,:description=>"CSV File containing the data relating Google Sheet-based Data Sources."}]
47
+ unless @csvAdd
48
+ @csv << ["Workbook",'Data Source','Connection','File Name','Type','Table Name','Field']
49
+ end
50
+ # @docfiles = [{:name=>docFileName,:description=>"CSV File containing the data relating Google Sheet-based Data Sources."}]
51
+ addDocFile @dashSheetsCSV, docFileName, "Workbooks, Dashboards, and their Worksheets"
43
52
  end
44
53
 
45
54
  def processTWB twb
@@ -25,14 +25,22 @@ module Analysis
25
25
 
26
26
  attr_accessor :localEmit
27
27
 
28
- def initialize
28
+ def initialize(**args)
29
+ #-- TODO move @csvAdd * #csvMode resolution to TabTool
30
+ @csvAdd = args[:csvMode] == :add
31
+ @csvMode = @csvAdd ? 'a' : 'w'
32
+ emit "@csvAdd : #{@csvAdd}"
33
+ emit "@csvMode: #{@csvMode}"
34
+ #--
29
35
  init
30
36
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Dashboard Worksheets', :description=>'Identifies the Worksheets present in Dashboards.',}
31
37
  #--
32
- docFileName = docFile('DashboardSheets.csv')
33
- @dashSheetsCSV = CSV.open(docFileName,'w')
34
- @dashSheetsCSV << ['Workbook','Workbook Dir','Modified','Dashboard','Worksheet','Hidden','Visible']
35
- addDocFile docFileName, "Workbooks, Dashboards, and their Worksheets"
38
+ docFileName = docFile('DashboardSheets.csv')
39
+ @dashSheetsCSV = CSV.open(docFileName,@csvMode)
40
+ unless @csvAdd
41
+ @dashSheetsCSV << ['Workbook','Workbook Dir','Modified','Dashboard','Worksheet','Hidden','Visible']
42
+ end
43
+ addDocFile @dashSheetsCSV, docFileName, "Workbooks, Dashboards, and their Worksheets"
36
44
  #--
37
45
  @twbCount = 0
38
46
  @dashCount = 0
@@ -40,14 +40,21 @@ module Analysis
40
40
 
41
41
  attr_accessor :localEmit
42
42
 
43
- def initialize
43
+ def initialize(**args)
44
+ @csvAdd = args[:csvMode] == :add
45
+ @csvMode = @csvAdd ? 'a' : 'w'
46
+ emit true, "@csvAdd : #{@csvAdd}"
47
+ emit true, "@csvMode: #{@csvMode}"
48
+
44
49
  init
45
50
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Worksheet Fields', :description=>nil,}
46
51
  #--
47
52
  docFileName = docFile('WorksheetFields.csv')
48
53
  @sheetFieldsCSV = CSV.open(docFileName,'w')
49
- @sheetFieldsCSV << ['Rec #', 'Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code']
50
- addDocFile docFileName, "Workbooks, Worksheets, and the Sheets' Data Sources and Fields"
54
+ unless @csvAdd
55
+ @sheetFieldsCSV << ['Rec #', 'Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code']
56
+ end
57
+ addDocFile @sheetFieldsCSV, docFileName, "Workbooks, Worksheets, and the Sheets' Data Sources and Fields"
51
58
  #--
52
59
  @twbCnt = 0
53
60
  @sheetCnt = 0
@@ -25,14 +25,20 @@ module Analysis
25
25
 
26
26
  attr_accessor :localEmit
27
27
 
28
- def initialize
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
33
  init
30
34
  @funcdoc = {:class=>self.class, :blurb=>'Analyze Worksheet Filters', :description=>'Documents Quick Filters and the values they employ, if any. Work in progess.',}
31
35
  #--
32
36
  docFileName = docFile('WorksheetFilters.csv')
33
37
  $sheetFieldsCSV = CSV.open( docFileName ,'w')
34
- $sheetFieldsCSV << ['Workbook','Workbook Dir','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
35
- addDocFile docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
38
+ unless @csvAdd
39
+ $sheetFieldsCSV << ['Workbook','Workbook Dir','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
40
+ end
41
+ addDocFile $sheetFieldsCSV, docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
36
42
  #--
37
43
  @sheetCount = 0
38
44
  @filterCount = 0
@@ -103,9 +103,19 @@ module TabTool
103
103
  @docfiles ||= @docfiles = []
104
104
  end
105
105
 
106
- def addDocFile name, description
106
+ def addDocFile file, name, description
107
107
  @docfiles = [] if @docfiles.nil?
108
- @docfiles << {:name=>name,:description=>description}
108
+ @docfiles << {:file=>file, :name=>name, :description=>description}
109
+ end
110
+
111
+ def closeDocFiles
112
+ emit "Closing doc files"
113
+ @docfiles.each do |dfh|
114
+ docfile = dfh[:file]
115
+ emit " -- #{dfh[:name]}"
116
+ docfile.close unless docfile.nil?
117
+ end
118
+ emit "-----------------"
109
119
  end
110
120
 
111
121
  def docFileMaxNameLen
@@ -148,7 +158,7 @@ module TabTool
148
158
  emit "init CSV #{csvName}"
149
159
  csvFile = CSV.open(csvName, 'w')
150
160
  csvFile << header unless header.nil?
151
- addDocFile csvName,desc
161
+ addDocFile csvFile, csvName, desc
152
162
  return csvFile
153
163
  end
154
164
 
@@ -64,6 +64,106 @@ module Twb
64
64
  @id ||= @id = @name.hash
65
65
  end
66
66
 
67
+ def build
68
+ @build ||= loadBuild
69
+ end
70
+
71
+ def release
72
+ @build ||= loadBuild
73
+ end
74
+
75
+ def worksheets
76
+ @worksheets.values
77
+ end
78
+
79
+ def worksheet name
80
+ @worksheets[name]
81
+ end
82
+
83
+ def worksheetNames
84
+ @worksheets.keys
85
+ end
86
+
87
+ def dashboards
88
+ @dashboards.values
89
+ end
90
+
91
+ def dashboardNames
92
+ @dashboards.keys
93
+ end
94
+
95
+ def dashboard name
96
+ @dashboards[name]
97
+ end
98
+
99
+ def actions
100
+ @actions.values
101
+ end
102
+
103
+ def actionNames
104
+ @actions.keys
105
+ end
106
+
107
+ def datasource name
108
+ @dataSourceNamesMap[name]
109
+ end
110
+
111
+ def parameters
112
+ @parameters ||= loadParameters
113
+ end
114
+
115
+ def orphanDataSources
116
+ @orphanDataSources ||= identifyOrphandatasoUrceS
117
+ end
118
+
119
+ def storyboards
120
+ @storyboards.values
121
+ end
122
+
123
+ def storyboardNames
124
+ @storyboards.keys
125
+ end
126
+
127
+ def storyboard name
128
+ @storyboards[name]
129
+ end
130
+
131
+ # Add a new Documentation Dashboard to the TWB.
132
+ # Ensure that the TWB has a <dashboards> node (it may not).
133
+ # Make sure that the new Doc Dashboard's name doesn't conflict with an existing Dashboard - increment the incoming name if necessary.
134
+ # Add Doc Dashboard's <dashboard> and <window> nodes to the TWB; there's always a <windows> node in the TWB.
135
+ def addDocDashboard docDashboard
136
+ ensureDashboardsNodeExists
137
+ ensureWindowsNodeExists
138
+ title = getNewDashboardTitle(docDashboard.title)
139
+ docDashboard.title=(title) unless title == docDashboard.title
140
+ @dashesNode.add_child(docDashboard.dashnode)
141
+ @windowsnode.add_child(docDashboard.winnode)
142
+ end
143
+
144
+ # Write the TWB to a file, with an optional name.
145
+ # Can be used to write over the existing TWB (dangerous), or to a new file (preferred).
146
+ def write(name=@name)
147
+ case @type
148
+ when :twb
149
+ writeTwb(name)
150
+ when :twbx
151
+ writeTwbx(name)
152
+ else
153
+ emit "Cannot write this Workbook - it has an invalid type: #{@type}"
154
+ raise "Cannot write this Workbook - it has an invalid type: #{@type}"
155
+ end
156
+ end
157
+
158
+ # Write the TWB to a file, appending the base name with the provided string.
159
+ # Intended for use when making adjustments to the TWB without overwriting the original.
160
+ def writeAppend(str)
161
+ newName = @name.sub(/[.]twb$/,'') + str.gsub(/^[.]*/,'.') + '.twb'
162
+ write newName
163
+ end
164
+
165
+ private
166
+
67
167
  def processTWBX(twbxWithDir)
68
168
  Zip::File.open(twbxWithDir) do |zip_file|
69
169
  twb = zip_file.glob('*.twb').first
@@ -92,14 +192,6 @@ module Twb
92
192
  @valid = true
93
193
  end
94
194
 
95
- def build
96
- @build ||= loadBuild
97
- end
98
-
99
- def release
100
- @build ||= loadBuild
101
- end
102
-
103
195
  def loadBuild
104
196
  # - earlier Version, need to confirm when source-build began
105
197
  # @build = @ndoc.xpath('/workbook/comment()').text.gsub(/^[^0-9]+/,'').strip
@@ -189,35 +281,6 @@ module Twb
189
281
  end
190
282
  end
191
283
 
192
- def actions
193
- @actions.values
194
- end
195
-
196
- def actionNames
197
- @actions.keys
198
- end
199
-
200
- # def datasources
201
- # # puts "ACCESSING DATASOURCES - #{@datasources.class} - #{@datasources.length} - #{@datasources.values.length}"
202
- # return @datasources.values
203
- # end
204
-
205
- def dashboards
206
- @dashboards.values
207
- end
208
-
209
- def dashboardNames
210
- @dashboards.keys
211
- end
212
-
213
- def dashboard name
214
- @dashboards[name]
215
- end
216
-
217
- def orphanDataSources
218
- @orphanDataSources ||= identifyOrphandatasoUrceS
219
- end
220
-
221
284
  def identifyOrphandatasoUrceS
222
285
  sheetDataSources = Set.new
223
286
  @worksheets.values.each do |sheet|
@@ -228,56 +291,17 @@ module Twb
228
291
  @orphanDataSources = @datasourceUINames - sheetDataSources
229
292
  end
230
293
 
231
- def storyboards
232
- @storyboards.values
233
- end
234
-
235
- def worksheets
236
- @worksheets.values
237
- end
238
-
239
- def storyboardNames
240
- @storyboards.keys
241
- end
242
-
243
- def worksheetNames
244
- @worksheets.keys
245
- end
246
-
247
- def datasource name
248
- @dataSourceNamesMap[name]
249
- end
250
-
251
- def storyboard name
252
- @storyboards[name]
253
- end
254
-
255
- def worksheet name
256
- @worksheets[name]
257
- end
258
-
259
- def parameters
260
- @parameters ||= loadParameters
261
- end
262
-
263
- def ensureWindowsNodeExists
264
- if @windowsnode.nil?
265
- @windowsnode = Nokogiri::XML::Node.new "windows", @ndoc
266
- # TODO fix this @dataSourcesNode.add_next_sibling(@windowsnode)
294
+ def writeTwb(name=@name)
295
+ $f = File.open(name,'w')
296
+ if $f
297
+ $f.puts @ndoc
298
+ $f.close
267
299
  end
300
+ return name
268
301
  end
269
302
 
270
- # Add a new Documentation Dashboard to the TWB.
271
- # Ensure that the TWB has a <dashboards> node (it may not).
272
- # Make sure that the new Doc Dashboard's name doesn't conflict with an existing Dashboard - increment the incoming name if necessary.
273
- # Add Doc Dashboard's <dashboard> and <window> nodes to the TWB; there's always a <windows> node in the TWB.
274
- def addDocDashboard docDashboard
275
- ensureDashboardsNodeExists
276
- ensureWindowsNodeExists
277
- title = getNewDashboardTitle(docDashboard.title)
278
- docDashboard.title=(title) unless title == docDashboard.title
279
- @dashesNode.add_child(docDashboard.dashnode)
280
- @windowsnode.add_child(docDashboard.winnode)
303
+ def writeTwbx(name=@name)
304
+ emit "Writing the Workbook, need implementation"
281
305
  end
282
306
 
283
307
  # Make sure that the TWB has a <dashboards> node.
@@ -289,6 +313,13 @@ module Twb
289
313
  end
290
314
  end
291
315
 
316
+ def ensureWindowsNodeExists
317
+ if @windowsnode.nil?
318
+ @windowsnode = Nokogiri::XML::Node.new "windows", @ndoc
319
+ # TODO fix this @dataSourcesNode.add_next_sibling(@windowsnode)
320
+ end
321
+ end
322
+
292
323
  def getNewDashboardTitle(t)
293
324
  title = t
294
325
  if @datasources.include?(title)
@@ -304,44 +335,6 @@ module Twb
304
335
  return title
305
336
  end
306
337
 
307
- # Write the TWB to a file, with an optional name.
308
- # Can be used to write over the existing TWB (dangerous), or to a new file (preferred).
309
- def write(name=@name)
310
- case @type
311
- when :twb
312
- writeTwb(name)
313
- when :twbx
314
- writeTwbx(name)
315
- else
316
- emit "Cannot write this Workbook - it has an invalid type: #{@type}"
317
- raise "Cannot write this Workbook - it has an invalid type: #{@type}"
318
- end
319
- end
320
-
321
- # Write the TWB to a file, appending the base name with the provided string.
322
- # Intended for use when making adjustments to the TWB without overwriting the original.
323
- def writeAppend(str)
324
- newName = @name.sub(/[.]twb$/,'') + str.gsub(/^[.]*/,'.') + '.twb'
325
- write newName
326
- end
327
-
328
- private
329
-
330
- def writeTwb(name=@name)
331
- $f = File.open(name,'w')
332
- if $f
333
- $f.puts @ndoc
334
- $f.close
335
- end
336
- return name
337
- end
338
-
339
- def writeTwbx(name=@name)
340
- emit "Writing the Workbook, need implementation"
341
- end
342
-
343
-
344
-
345
338
  def loadParameters
346
339
  @parameters = {}
347
340
  paramsDS = ndoc.at_xpath('./workbook/datasources/datasource[@name="Parameters"]')
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.3.3
4
+ version: 4.4.1
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-01-26 00:00:00.000000000 Z
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: creek