twb 3.7.2 → 3.7.5

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
  SHA1:
3
- metadata.gz: fd921c477a3ab3ef1de872935a8057bd4fd5ea27
4
- data.tar.gz: de2bc297a944a544bb0f251ac5cc9f972e1f763c
3
+ metadata.gz: 183bcd3f582a9939faf1544d4b4ecfda0cd36f0a
4
+ data.tar.gz: 3daae7542ce46541dd310e6f27d717530db9ac95
5
5
  SHA512:
6
- metadata.gz: 46becdab0ca9837b76ddd7ffc46e26433ab130bda120c5150ddce3575da04e80309874dfef9ca69531556b6185b46131889b62fe3f0a05e58b341be83ef04d56
7
- data.tar.gz: 41f15a08b3b9971c4ca237ea5a166c212488c6e13a5ee3ca59613b8894d7b23d619e9d54fbc3c41280b4fc543c9109af1985befb92a7b42dc2bea00dc14f865a
6
+ metadata.gz: aa968978835cf31847e3446bc02107662b00e3213e4d1345104ace41b6cddd3d2c6d7756bd6ec4ae9a6bcae22acb4904e53771658b210d1847852558f29d43f8
7
+ data.tar.gz: c19335e986bbbf10166e96b97bb2e0064091fe2e71af00bbc0bc17c4e87b01fa51eefc019ea19e3e23149efaf341d2d95484ffdd06aa19b7e9122713439e639a
data/lib/twb.rb CHANGED
@@ -60,5 +60,5 @@ require_relative 'twb/analysis/Sheets/sheetfieldsanalyzer'
60
60
  # Represents Tableau Workbooks and their contents.
61
61
  #
62
62
  module Twb
63
- VERSION = '3.7.2'
63
+ VERSION = '3.7.5'
64
64
  end
@@ -21,9 +21,10 @@ require 'csv'
21
21
  module Twb
22
22
  module Analysis
23
23
 
24
- class CalculatedFieldsAnalyzer < Twb::Util::Graph
24
+ class CalculatedFieldsAnalyzer # < Twb::Util::Graph
25
25
 
26
26
  include TabTool
27
+ include Graph
27
28
 
28
29
  attr_reader :calculatedFieldsCount, :formulaFieldsCount, :dataFiles
29
30
  attr_accessor :ttdocdir
@@ -81,12 +82,7 @@ module Analysis
81
82
  DOTHEADER
82
83
 
83
84
  def initialize
84
- #-- Logging setup --
85
- @ttdocdir = 'ttdoc'
86
- # logfile = docFile(@@ttlogfile)
87
- # @logger = Logger.new(logfile)
88
- # @logger.level = Logger::DEBUG
89
- emit ' Initializing CalculatedFieldsAnalyzer'
85
+ @funcdoc = {:class=>self.class, :blurb=>'Analyzing Calculated Fields from Tableau Workbooks.', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
90
86
  #-- CSV records collectors
91
87
  @csvCalculatedFields = []
92
88
  @csvFormulaFields = []
@@ -98,43 +94,12 @@ DOTHEADER
98
94
  #--
99
95
  @referencedFields = SortedSet.new
100
96
  #--
101
- emit "init CSV #{@@calcFieldsCSVFileName}"
102
- @csvCF = File.open(docFile(@@calcFieldsCSVFileName), 'w')
103
- @csvCF.puts @@calcFieldsCSVFileHeader.to_csv
104
- # @csvCF.close
105
- #--
106
- emit "init CSV #{@@calcLinesCSVFileName}"
107
- @csvCFLs = File.open(docFile(@@calcLinesCSVFileName), 'w')
108
- @csvCFLs.puts @@calcLinesCSVFileHeader.to_csv
109
- # @csvCFLs.close
110
- #--
111
- emit "init CSV #{@@formFieldsCSVFileName}"
112
- @csvFF = File.open(docFile(@@formFieldsCSVFileName), 'w')
113
- @csvFF.puts @@formFieldsCSVFileHeader.to_csv
114
- # @csvFF.close
115
- #--
116
- @dataFiles = { @@calcFieldsCSVFileName => 'Calculated Fields & their Formulas',
117
- @@calcLinesCSVFileName => 'Calculated Fields & individual Formula Lines',
118
- @@formFieldsCSVFileName => 'Fields referenced in Formulas'
119
- }
97
+ @csvCF = initCSV(@@calcFieldsCSVFileName, 'Calculated fields and their formulas.', @@calcFieldsCSVFileHeader)
98
+ @csvCFLs = initCSV(@@calcLinesCSVFileName, "Calculated fields and their formulas' individual lines.", @@calcLinesCSVFileHeader)
99
+ @csvFF = initCSV(@@formFieldsCSVFileName, 'Calculated fields and the fields their formulas reference.', @@formFieldsCSVFileHeader)
120
100
  #--
121
101
  @localEmit = false
122
- @imageFiles = []
123
- end
124
-
125
- def initDocDir
126
- return if $ttdocdir.nil?
127
- return if ''.eql? $ttdocdir
128
- return if Dir.exists?($ttdocdir)
129
- if File.exists? $ttdocdir
130
- $ttdocdir = nil
131
- return
132
- end
133
- Dir.mkdir $ttdocdir
134
- end
135
-
136
- def docFile name
137
- @ttdocdir.nil? ? name : "#{@ttdocdir}\\#{name}"
102
+ @imageFiles = []
138
103
  end
139
104
 
140
105
  def processTWB workbook
@@ -221,19 +186,19 @@ DOTHEADER
221
186
  emit "@@ FL: #{calcField.uiname}"
222
187
  calculation.formulaResolvedLines.each do |fl|
223
188
  emit "@@ FL: => '#{fl}'"
224
- fieldFormulaLines.push [ @calculatedFieldsCount, # 'Calc Field #',
225
- @twb.name, # 'Workbook',
226
- @twbDir, # 'Workbook Dir',
227
- ds.uiname, # 'Data Source',
228
- ds.caption, # 'Data Source Caption',
229
- ds.name, # 'Data Source Name (tech)',
230
- calcField.uiname, # 'Field Name',
231
- calcField.caption, # 'Field Caption',
232
- calcField.name, # 'Field Name (tech)',
233
- calcField.calculation.formulaFlatResolved, # 'Formula'
234
- flnum += 1, # 'Formula Line #',
235
- fl.start_with?(" ") ? "'#{fl}" : fl # 'Formula Line' - THIS IS A STUPID HACK NEEDED BECAUSE TABLEAU STRIPS LEADING BLANKS FROM CSV VALUES
236
- ]
189
+ fieldFormulaLines << [ @calculatedFieldsCount, # 'Calc Field #',
190
+ @twb.name, # 'Workbook',
191
+ @twbDir, # 'Workbook Dir',
192
+ ds.uiname, # 'Data Source',
193
+ ds.caption, # 'Data Source Caption',
194
+ ds.name, # 'Data Source Name (tech)',
195
+ calcField.uiname, # 'Field Name',
196
+ calcField.caption, # 'Field Caption',
197
+ calcField.name, # 'Field Name (tech)',
198
+ calcField.calculation.formulaFlatResolved, # 'Formula'
199
+ flnum += 1, # 'Formula Line #',
200
+ fl.start_with?(" ") ? "'#{fl}" : fl # 'Formula Line' - THIS IS A STUPID HACK NEEDED BECAUSE TABLEAU STRIPS LEADING BLANKS FROM CSV VALUES
201
+ ]
237
202
  end
238
203
  #-- collect fields referenced in formula
239
204
  calculation.calcFields.each do |rf|
@@ -256,19 +221,19 @@ DOTHEADER
256
221
  @edges.add fieldFieldEdge
257
222
  # fldToDsNode = tableNode
258
223
  end
259
- @csvFormulaFields.push [
260
- @formulaFieldsCount += 1,
261
- @twb.name,
262
- @twbDir,
263
- ds.uiname,
264
- calcField.uiname,
265
- calculation.formulaFlat,
266
- calculation.formulaResolved,
267
- rf.name,
268
- rf.uiname,
269
- rf.id,
270
- refFieldTable
271
- ]
224
+ @csvFormulaFields << [
225
+ @formulaFieldsCount += 1,
226
+ @twb.name,
227
+ @twbDir,
228
+ ds.uiname,
229
+ calcField.uiname,
230
+ calculation.formulaFlat,
231
+ calculation.formulaResolved,
232
+ rf.name,
233
+ rf.uiname,
234
+ rf.id,
235
+ refFieldTable
236
+ ]
272
237
  end # resolvedFields.each do
273
238
  end # if calculation.has_formula
274
239
  end # ds.calculatedFields.each
@@ -280,35 +245,24 @@ DOTHEADER
280
245
  cypherPy @twb.name
281
246
  emit "#######################"
282
247
  #-- record calculated fields
283
- # @csvCF = File.open(docFile(@@calcFieldsCSVFileName), 'a')
284
- # @csvCF.puts @@calcFieldsCSVFileHeader.to_csv
285
248
  emit "@@ record calculated fields ds: #{ds.uiname}"
286
- # @csvCF.open('a')
287
249
  @csvCalculatedFields.each do |r|
288
- @csvCF.puts r.to_csv
250
+ @csvCF << r
289
251
  end
290
252
  #-- record individual formula lines
291
- # @csvCFLs = File.open(docFile(@@calcLinesCSVFileName), 'a')
292
- # @csvCFLs.puts @@calcLinesCSVFileHeader.to_csv
293
253
  emit "@@ individual formula lines ds: #{ds.uiname}"
294
254
  fieldFormulaLines.each do |ffl|
295
- emit "@@@@ FFLA: #{ffl}"
296
- emit "@@@@ FFLB: #{ffl.to_csv}"
297
- emit "@@@@ FFLc: "
298
- @csvCFLs.puts ffl.to_csv
255
+ @csvCFLs << ffl
299
256
  end
300
257
  #-- record formula-referenced fields
301
- # @csvFF = File.open(docFile(@@formFieldsCSVFileName), 'a')
302
- # @csvFF.puts @@formFieldsCSVFileHeader.to_csv
303
258
  emit "@@ formula-referenced fields ds: #{ds.uiname}"
304
259
  @csvFormulaFields.each do |r|
305
- @csvFF.puts r.to_csv
260
+ @csvFF << r
306
261
  end
307
262
  #--
308
263
  return @imageFiles
309
264
  end # def processDataSource
310
265
 
311
-
312
266
  def emitCalcfield calcField
313
267
  emit "\t FIELD cap :: #{calcField.caption} "
314
268
  emit "\t tname:: #{calcField.name}"
@@ -32,13 +32,13 @@ module CalculatedFields
32
32
  @twb = twb #Twb::Workbook.new twb
33
33
  @docFileName = './ttdoc/' + @twb.name + '.CalculatedFields.md'
34
34
  @docFile = File.open(@docFileName,'w')
35
- @docFile.puts "## #{twb.name}"
35
+ @docFile.puts "# #{twb.name}"
36
36
  dsNames = @twb.datasourceUINames
37
37
  @docFile.puts "#{dsNames.length} Data Sources"
38
38
 
39
39
 
40
40
  @twb.datasources.each do |ds|
41
- @docFile.puts "# #{ds.uiname}"
41
+ @docFile.puts "## #{ds.uiname}"
42
42
  @docFile.puts "__has #{ds.calculatedFields.length} calculated fields__\n "
43
43
  cnt = 0
44
44
  ds.calculatedFields.each do |cf|
@@ -28,14 +28,21 @@ module Analysis
28
28
  attr_reader :twbname, :twbcount
29
29
 
30
30
  def initialize
31
+ #-- set up metrics
31
32
  @twbcount = 0
32
- @sheetCnt = 0
33
- @filterCnt = 0
33
+ @dscount = 0
34
+ @sheetcount = 0
35
+ @metrics = {
36
+ '# of Workbooks' => @twbcount ,
37
+ '# of Worksheets' => @dscount ,
38
+ '# of Worksheets' => @sheetcount
39
+ }
40
+ #--
34
41
  @funcdoc = {:class=>self.class, :blurb=>'Analyzing Google Sheet Data Sources from Tableau Workbooks.', :description=>nil,}
35
42
  docFileName = docFile('TWBGoogleSheetDataSources.csv')
36
43
  @csv = CSV.open(docFileName, 'w')
37
44
  @csv << ["Workbook",'Data Source','Connection','File Name','Type','Table Name','Field']
38
- @docfiles = [{:name=>docFileName,:desc=>"CSV File containing the data relating Google Sheet-based Data Sources."}]
45
+ @docfiles = [{:name=>docFileName,:description=>"CSV File containing the data relating Google Sheet-based Data Sources."}]
39
46
  end
40
47
 
41
48
  def processTWB twb
@@ -15,7 +15,6 @@
15
15
 
16
16
  require 'twb'
17
17
  require 'csv'
18
- require 'set'
19
18
 
20
19
  module Twb
21
20
  module Analysis
@@ -34,7 +33,7 @@ module Analysis
34
33
  docFileName = docFile('TWBWorksheetFields.csv')
35
34
  @sheetFieldsCSV = CSV.open(docFileName,'w')
36
35
  @sheetFieldsCSV << ['Workbook','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)']
37
- @docfiles = [{:name=>docFileName,:desc=>"CSV File containing the data relating Workbooks,Worksheets, and the sheets' Data Sources and Fields"}]
36
+ addDocFile docFileName, "CSV File containing the data relating Workbooks,Worksheets, and the sheets' Data Sources and Fields"
38
37
  end
39
38
 
40
39
  def processTWB twb
@@ -45,7 +44,6 @@ module Analysis
45
44
  parseSheets
46
45
  end
47
46
 
48
-
49
47
  def parseSheets
50
48
  @worksheets = @twb.worksheets
51
49
  @worksheets.each do |sheet|
@@ -17,29 +17,75 @@ require 'logger'
17
17
 
18
18
  module TabTool
19
19
 
20
- attr_accessor :ttdocdir, :logger, :loglevel, :logfilename
21
- attr_reader :funcdoc, :docfiles
20
+ attr_accessor :ttdocdir, :logger, :loglevel, :logfilename
21
+ attr_reader :funcdoc, :docfiles, :metrics
22
22
 
23
23
  TTDOCDIR = './ttdoc'
24
24
 
25
25
  @funcdoc = {:class=>nil, :blurb=>nil, :description=>nil,}
26
- @docfiles = {}
26
+ @docfiles = [] # should be of form [{:name=>'docFileName',:description=>'doc file description'}]
27
27
 
28
28
  @ttdocdir = './ttdoc'
29
29
  @logfilename = 'TabTools.ttlog'
30
30
  @loglevel = Logger::DEBUG
31
31
  @localEmit = false
32
+ @docDirSet = false
32
33
 
33
34
  def funcdoc
34
35
  @funcdoc.nil? ? {:class=>'n/a', :blurb=>'generic TabTool blurb', :description=>'A useful Tableau Tool.'} : @funcdoc
35
36
  end
36
37
 
37
38
  def docFile name
38
- # emit "docFile: TTDOCDIR: #{TTDOCDIR} name:'#{name}'"
39
- TTDOCDIR.nil? ? name : "#{TTDOCDIR}/#{name}"
39
+ initDocDir unless @docDirSet
40
+ @docDir.nil? ? name : "#{@docDir}/#{name}"
41
+ end
42
+
43
+ def docfiles
44
+ @docfiles ||= @docfiles = []
45
+ end
46
+
47
+ def addDocFile name, description
48
+ @docfiles = [] if @docfiles.nil?
49
+ @docfiles << {:name=>name,:description=>description}
50
+ end
51
+
52
+ def docFileMaxNameLen
53
+ maxlen = 0
54
+ docfiles.each do |f|
55
+ nameLen = f[:name].class == String ? [maxlen, f[:name].length].max : 0
56
+ maxlen = nameLen.nil? ? maxlen : [maxlen,nameLen].max
57
+ end
58
+ return maxlen
59
+ end
60
+
61
+ def docfilesdoc
62
+ lines = SortedSet.new
63
+ unless @docfiles.nil? || @docfiles.empty?
64
+ nameLen = docFileMaxNameLen
65
+ docfiles.each do |dfi|
66
+ lines << " - %-#{nameLen}s %-s " % [ dfi[:name], dfi[:description] ]
67
+ end
68
+ end
69
+ docLines = lines.empty? ? [] : [' ','For documentation and generated data see the following:',' ']
70
+ lines.each do |l|
71
+ docLines << l
72
+ end
73
+ return docLines
74
+ end
75
+
76
+ def initCSV(fileName, desc=nil, header=nil)
77
+ # puts 'initCSV'
78
+ # puts " @docDirSet: #{@docDirSet} "
79
+ csvName = docFile(fileName)
80
+ emit "init CSV #{csvName}"
81
+ csvFile = CSV.open(csvName, 'w')
82
+ csvFile << header unless header.nil?
83
+ addDocFile csvName,desc
84
+ return csvFile
40
85
  end
41
86
 
42
87
  def emit(local=@localEmit, stuff)
88
+ initDocDir if @docDirSet.nil? || !@docDirSet
43
89
  initLogger if @logger.nil?
44
90
  if stuff.is_a? String then
45
91
  lines = stuff.split(/\n/)
@@ -54,10 +100,35 @@ module TabTool
54
100
  end
55
101
 
56
102
  def initLogger
57
- lfn = docFile("#{self.class.to_s.split('::').last}.ttlog")
58
- @logger = Logger.new(lfn)
103
+ initDocDir unless @docDirSet
104
+ initDocDir
105
+ logFileName = docFile("#{self.class.to_s.split('::').last}.ttlog")
106
+ @logger = Logger.new(logFileName)
59
107
  @logger.level = Logger::DEBUG
60
108
  end
61
109
 
110
+ def initDocDir
111
+ # puts 'initDocDir - begin'
112
+ # puts " @docDirSet: #{@docDirSet} "
113
+ # puts " TTDOCDIR : #{TTDOCDIR} "
114
+ # puts " $ttdocdir : #{$ttdocdir} "
115
+ # puts " @docDir : #{@docDir} "
116
+ return if @docDirSet
117
+ return if TTDOCDIR.nil? && $ttdocdir.nil?
118
+ return if ''.eql?($ttdocdir) && ''.eql?(TTDOCDIR)
119
+ @docDir = $ttdocdir.nil? ? TTDOCDIR : $ttdocdir
120
+ return if Dir.exists?(@docDir)
121
+ if File.exists? @docDir
122
+ @docDir = nil
123
+ return
124
+ end
125
+ Dir.mkdir @docDir
126
+ @docDirSet = true
127
+ # puts " @docDirSet: #{@docDirSet} "
128
+ # puts " @docDir : #{@docDir} "
129
+ # puts 'initDocDir - end'
130
+ end
131
+
132
+
62
133
  end # module TabTool
63
134
 
@@ -13,18 +13,16 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- module Twb
17
- module Util
16
+ module Graph
18
17
 
19
- class Graph
20
18
  attr_accessor :nodes, :edges
19
+
21
20
  def nodes
22
21
  @nodes ||= @nodes = []
23
22
  end
23
+
24
24
  def edges
25
25
  @edges ||= @edges = []
26
26
  end
27
- end
28
27
 
29
- end # module Util
30
- end # module Twb
28
+ end # module Graph
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.2
4
+ version: 3.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Gerrard