twb 4.3.3 → 4.4.1

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