twb 4.4.4 → 4.4.6
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 +4 -4
- data/lib/twb.rb +2 -1
- data/lib/twb/analysis/CalculatedFields/CalculatedFieldsAnalyzer.rb +32 -21
- data/lib/twb/analysis/CalculatedFields/MarkdownEmitter.rb +1 -2
- data/lib/twb/analysis/Sheets/dashsheetsanalyzer.rb +5 -4
- data/lib/twb/analysis/Sheets/sheetfieldsanalyzer.rb +17 -15
- data/lib/twb/analysis/Sheets/sheetfiltersanalyzer.rb +7 -4
- data/lib/twb/analysis/WorkbookSummaryAnalyzer.rb +97 -0
- data/lib/twb/tabtool.rb +28 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99a5530880ab68f71e94e0456ad8367fa00516e7f55e869028eaac3986f17141
|
4
|
+
data.tar.gz: 59a2dfe98f0e177fd7426e70fa9d08659d4748997bd13144784a321de0df2c07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9e89a013d3c6888ef1de3acbce3b811b79c56e5d542dd6cfee6b3bebe218455a16a8cc00c60c558dbcc67a07b5087301a27fe746f5133344983452332fe4b39
|
7
|
+
data.tar.gz: 8fc758bae510b0c55ba9b3121c4d845c12e78916cddeb01911bd6bde3e96f6918f6cb2d6c6d5611ca8eca6038a424647b1aa64c801d64eb249355afe26c7fe34
|
data/lib/twb.rb
CHANGED
@@ -51,6 +51,7 @@ require_relative 'twb/util/fielddomainloader'
|
|
51
51
|
require_relative 'twb/util/docprep'
|
52
52
|
require_relative 'twb/analysis/documentedfieldsmarkdownemitter'
|
53
53
|
require_relative 'twb/analysis/annotatedfieldsCSVEmitter'
|
54
|
+
require_relative 'twb/analysis/WorkbookSummaryAnalyzer'
|
54
55
|
require_relative 'twb/analysis/calculatedfields/calculatedfieldsanalyzer'
|
55
56
|
require_relative 'twb/analysis/calculatedfields/groupfieldsanalyzer'
|
56
57
|
require_relative 'twb/analysis/calculatedfields/markdownemitter'
|
@@ -70,5 +71,5 @@ require_relative 'twb/analysis/Sheets/dashsheetsanalyzer'
|
|
70
71
|
# Represents Tableau Workbooks, their contents, and classes that analyze and manipulate them.
|
71
72
|
#
|
72
73
|
module Twb
|
73
|
-
VERSION = '4.4.
|
74
|
+
VERSION = '4.4.6'
|
74
75
|
end
|
@@ -35,7 +35,8 @@ module Analysis
|
|
35
35
|
|
36
36
|
@@calcFieldsCSVFileName = 'CalculatedFields.csv'
|
37
37
|
@@calcFieldsCSVFileHeader = ['Record #',
|
38
|
-
'Workbook',
|
38
|
+
'Workbook',
|
39
|
+
'Workbook Modified',
|
39
40
|
'Data Source', 'Data Source Caption', 'Data Source Name (tech)',
|
40
41
|
'Field Name', 'Field Caption', 'Field Name (tech)',
|
41
42
|
'Data Source + Field Name (tech)',
|
@@ -49,17 +50,19 @@ module Analysis
|
|
49
50
|
'Formula LOD?'
|
50
51
|
]
|
51
52
|
|
52
|
-
@@calcLinesCSVFileName = '
|
53
|
-
@@calcLinesCSVFileHeader = ['
|
54
|
-
'Workbook',
|
53
|
+
@@calcLinesCSVFileName = 'CalculatedFieldsFormulaLines.csv'
|
54
|
+
@@calcLinesCSVFileHeader = ['Record #',
|
55
|
+
'Workbook',
|
56
|
+
'Workbook Modified',
|
55
57
|
'Data Source', 'Data Source Caption', 'Data Source Name (tech)',
|
56
58
|
'Field Name', 'Field Caption', 'Field Name (tech)',
|
57
59
|
'Formula', 'Formula Line #', 'Formula Line'
|
58
60
|
]
|
59
61
|
|
60
62
|
@@formFieldsCSVFileName = 'CalculatedFieldsReferenced.csv'
|
61
|
-
@@formFieldsCSVFileHeader = ['
|
62
|
-
'Workbook',
|
63
|
+
@@formFieldsCSVFileHeader = ['Record #',
|
64
|
+
'Workbook',
|
65
|
+
'Workbook Modified',
|
63
66
|
'Data Source',
|
64
67
|
'Field - Calculated',
|
65
68
|
'Formula (tech)',
|
@@ -82,11 +85,11 @@ module Analysis
|
|
82
85
|
DOTHEADER
|
83
86
|
|
84
87
|
def initialize(**args)
|
85
|
-
@args
|
86
|
-
@
|
87
|
-
@
|
88
|
-
|
89
|
-
|
88
|
+
@args = args
|
89
|
+
@recordDir = !@args.nil? && @args[:recordDir] == true
|
90
|
+
@ttdocdir = @args[:ttdocdir]
|
91
|
+
@csvAdd = args[:csvMode] == :add
|
92
|
+
@csvMode = @csvAdd ? 'a' : 'w'
|
90
93
|
init
|
91
94
|
@funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
|
92
95
|
#-- CSV records collectors
|
@@ -95,14 +98,17 @@ DOTHEADER
|
|
95
98
|
@csvFormulaLines = []
|
96
99
|
#-- Counters setup --
|
97
100
|
@twbCount = 0
|
101
|
+
@dataSourcesCount = 0
|
98
102
|
@calculatedFieldsCount = 0
|
99
103
|
@referencedFieldsCount = 0
|
100
104
|
#--
|
101
105
|
@referencedFields = SortedSet.new
|
102
106
|
#--
|
103
|
-
|
104
|
-
@
|
105
|
-
@
|
107
|
+
twbdirLabel = @recordDir.nil? ? nil : 'Workbook Dir'
|
108
|
+
@csvCF = initCSV(@@calcFieldsCSVFileName, 'Calculated fields and their formulas.', @@calcFieldsCSVFileHeader )
|
109
|
+
@csvCFLs = initCSV(@@calcLinesCSVFileName, "Calculated fields and their formulas' individual lines.", @@calcLinesCSVFileHeader )
|
110
|
+
@csvFF = initCSV(@@formFieldsCSVFileName, 'Calculated fields and the fields their formulas reference.', @@formFieldsCSVFileHeader )
|
111
|
+
# TODO migrate addition of 'Workbook Dir' to CSV header to TabTool
|
106
112
|
#--
|
107
113
|
@localEmit = false
|
108
114
|
@imageFiles = []
|
@@ -116,6 +122,7 @@ DOTHEADER
|
|
116
122
|
emit "- Workbook: #{workbook}"
|
117
123
|
emit " version: #{@twb.version}"
|
118
124
|
@twbDir = @twb.dir #File.dirname(File.expand_path(workbook))
|
125
|
+
@modTime = @twb.modtime
|
119
126
|
@edges = Set.new
|
120
127
|
#-- processing
|
121
128
|
dss = @twb.datasources
|
@@ -124,6 +131,7 @@ DOTHEADER
|
|
124
131
|
@twbFields = {}
|
125
132
|
@nodes = Set.new
|
126
133
|
dss.each do |ds|
|
134
|
+
@dataSourcesCount += 1
|
127
135
|
# puts "\t\t - #{ds.uiname} \t\t #{ds.calculatedFields.length}"
|
128
136
|
next if ds.Parameters? # don't process the Parameters data source - Parameters' fields aren't Calculated fields for our purposes
|
129
137
|
# dataSourceNode = Twb::Util::Graphnode.new(name: ds.uiname, id: ds.id, type: ds, properties: {workbook: workbook})
|
@@ -145,6 +153,7 @@ DOTHEADER
|
|
145
153
|
def loadMetrics
|
146
154
|
@metrics = {
|
147
155
|
'# of Workbooks' => @twbCount,
|
156
|
+
'# of Data Sources' => @dataSourcesCount,
|
148
157
|
'# of Calculated Fields' => @calculatedFieldsCount,
|
149
158
|
'# of Referenced Fields' => @referencedFieldsCount,
|
150
159
|
}
|
@@ -191,8 +200,8 @@ DOTHEADER
|
|
191
200
|
#-- collect field formulas as single lines
|
192
201
|
@csvCalculatedFields.push [
|
193
202
|
@calculatedFieldsCount += 1,
|
194
|
-
@twb.name,
|
195
|
-
@
|
203
|
+
@twb.name,
|
204
|
+
@modTime,
|
196
205
|
ds.uiname,
|
197
206
|
ds.caption,
|
198
207
|
ds.name,
|
@@ -217,8 +226,8 @@ DOTHEADER
|
|
217
226
|
calculation.formulaResolvedLines.each do |fl|
|
218
227
|
emit "@@ resolved line:: => '#{fl}'"
|
219
228
|
fieldFormulaLines << [ @calculatedFieldsCount, # 'Calc Field #',
|
220
|
-
@twb.name, # 'Workbook',
|
221
|
-
@
|
229
|
+
@twb.name, # 'Workbook',
|
230
|
+
@modTime,
|
222
231
|
ds.uiname, # 'Data Source',
|
223
232
|
ds.caption, # 'Data Source Caption',
|
224
233
|
ds.name, # 'Data Source Name (tech)',
|
@@ -261,8 +270,8 @@ DOTHEADER
|
|
261
270
|
end
|
262
271
|
@csvFormulaFields << [
|
263
272
|
@referencedFieldsCount += 1,
|
264
|
-
@twb.name,
|
265
|
-
@
|
273
|
+
@twb.name,
|
274
|
+
@modTime,
|
266
275
|
ds.uiname,
|
267
276
|
calcField.uiname,
|
268
277
|
calculation.formulaFlat,
|
@@ -284,7 +293,9 @@ DOTHEADER
|
|
284
293
|
cypherPy @twb.name
|
285
294
|
end
|
286
295
|
emit "#######################"
|
287
|
-
#--
|
296
|
+
#--
|
297
|
+
#-- record calculated fields
|
298
|
+
twbDirCSV = @recordDir.nil? ? nil : @twbDir
|
288
299
|
emit "@@ record calculated fields ds: #{ds.uiname}"
|
289
300
|
@csvCalculatedFields.each do |r|
|
290
301
|
@csvCF << r
|
@@ -27,8 +27,7 @@ module CalculatedFields
|
|
27
27
|
def initialize(**args)
|
28
28
|
@args = args
|
29
29
|
init
|
30
|
-
|
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
|
+
@funcdoc = {:class=>self.class, :blurb=>'Create Markdown files (one per Workbook) documenting Calculated Fields', :description=>'Analyze Calculated Fields - create Markdown files, one per Workbook' }
|
32
31
|
@metrics = {}
|
33
32
|
end
|
34
33
|
|
@@ -28,7 +28,8 @@ module Analysis
|
|
28
28
|
def initialize(**args)
|
29
29
|
@args = args
|
30
30
|
@recordDir = !@args.nil? && @args[:recordDir] == true
|
31
|
-
@
|
31
|
+
@ttdocdir = @args[:ttdocdir]
|
32
|
+
@csvAdd = !@args.nil? && args[:csvMode] == :add
|
32
33
|
@csvMode = @csvAdd ? 'a' : 'w'
|
33
34
|
init
|
34
35
|
@funcdoc = {:class=>self.class, :blurb=>'Analyze Dashboard Worksheets', :description=>'Identifies the Worksheets present in Dashboards.',}
|
@@ -37,9 +38,9 @@ module Analysis
|
|
37
38
|
@dashSheetsCSV = CSV.open(docFileName,@csvMode)
|
38
39
|
unless @csvAdd
|
39
40
|
if @recordDir
|
40
|
-
@dashSheetsCSV << ['Workbook','Modified','Dashboard','Worksheet','Hidden','Visible', 'Workbook Dir']
|
41
|
+
@dashSheetsCSV << ['Rec #','Workbook','Workbook Modified','Workbook Modified','Dashboard','Worksheet','Hidden','Visible', 'Workbook Dir']
|
41
42
|
else
|
42
|
-
@dashSheetsCSV << ['Workbook','Modified','Dashboard','Worksheet','Hidden','Visible' ]
|
43
|
+
@dashSheetsCSV << ['Rec #','Workbook','Workbook Modified','Dashboard','Worksheet','Hidden','Visible' ]
|
43
44
|
end
|
44
45
|
end
|
45
46
|
addDocFile @dashSheetsCSV, docFileName, "Workbooks, Dashboards, and their Worksheets"
|
@@ -77,7 +78,7 @@ module Analysis
|
|
77
78
|
dash.worksheets.each do |sheet|
|
78
79
|
@sheetCount += 1
|
79
80
|
emit "SHEET: #{sheet.name}"
|
80
|
-
recordCSV [@twbName, @
|
81
|
+
recordCSV [@twbName, @modTime, dash.name, sheet.name, sheet.hidden, sheet.visible ]
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
@@ -44,6 +44,7 @@ module Analysis
|
|
44
44
|
def initialize(**args)
|
45
45
|
@args = args
|
46
46
|
@recordDir = !@args.nil? && @args[:recordDir] == true
|
47
|
+
@ttdocdir = @args[:ttdocdir]
|
47
48
|
@csvAdd = args[:csvMode] == :add
|
48
49
|
@csvMode = @csvAdd ? 'a' : 'w'
|
49
50
|
init
|
@@ -53,9 +54,9 @@ module Analysis
|
|
53
54
|
@sheetFieldsCSV = CSV.open(docFileName,@csvMode)
|
54
55
|
unless @csvAdd
|
55
56
|
if @recordDir
|
56
|
-
@sheetFieldsCSV << ['Rec #',
|
57
|
+
@sheetFieldsCSV << ['Rec #','Workbook','Workbook Modified','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code','Workbook Dir']
|
57
58
|
else
|
58
|
-
@sheetFieldsCSV << ['Rec #',
|
59
|
+
@sheetFieldsCSV << ['Rec #','Workbook','Workbook Modified','Worksheet','Data Source','Data Source (tech)','Field','Field (tech)','Usage','Usage - code' ]
|
59
60
|
end
|
60
61
|
end
|
61
62
|
addDocFile @sheetFieldsCSV, docFileName, "Workbooks, Worksheets, and the Sheets' Data Sources and Fields"
|
@@ -76,6 +77,7 @@ module Analysis
|
|
76
77
|
|
77
78
|
def processTWB twb
|
78
79
|
@twb = twb
|
80
|
+
@modTime = @twb.modtime
|
79
81
|
emit " -- twb:: #{@twb.name}"
|
80
82
|
@twbCnt += 1
|
81
83
|
@twbDomainsLoaded = false
|
@@ -98,7 +100,7 @@ module Analysis
|
|
98
100
|
def showFields sheet
|
99
101
|
@sheetFields = Hash.new { |ds,fields| ds[fields] = Set.new }
|
100
102
|
# recordCSV [@twb.name, @sheetName, nil, nil, nil, nil, nil]
|
101
|
-
|
103
|
+
emit "Sheet: #{@sheetName}"
|
102
104
|
recordDBFields sheet
|
103
105
|
recordRCFields sheet.rowFields, :row
|
104
106
|
recordRCFields sheet.colFields, :column
|
@@ -122,7 +124,7 @@ module Analysis
|
|
122
124
|
emit " f: #{sheetField}"
|
123
125
|
emit " c: #{sheetField.class}"
|
124
126
|
fuiName = ds.fieldUIName sheetField #Fields[sheetField]
|
125
|
-
recordCSV [@twb.name, @sheetName, ds.uiname, dsName, sheetField.uiname, sheetField.name, 'DB ref', ftc('DB ref')]
|
127
|
+
recordCSV [@twb.name, @modTime, @sheetName, ds.uiname, dsName, sheetField.uiname, sheetField.name, 'DB ref', ftc('DB ref')]
|
126
128
|
end
|
127
129
|
end
|
128
130
|
end
|
@@ -139,7 +141,7 @@ module Analysis
|
|
139
141
|
emit " ds: #{dsName}"
|
140
142
|
emit " - #{ds.uiname}"
|
141
143
|
emit " : #{ds.class}"
|
142
|
-
recordCSV [@twb.name, @sheetName, ds.uiname, dsName, fuiName, fldName, usage, ftc(usage)]
|
144
|
+
recordCSV [@twb.name, @modTime, @sheetName, ds.uiname, dsName, fuiName, fldName, usage, ftc(usage)]
|
143
145
|
end
|
144
146
|
end
|
145
147
|
|
@@ -150,7 +152,7 @@ module Analysis
|
|
150
152
|
dsName = field.dataSource
|
151
153
|
ds = @twb.datasource dsName
|
152
154
|
fuiName = ds.fieldUIName field.name
|
153
|
-
recordCSV [@twb.name, @sheetName, ds.uiname, dsName, fuiName, field.name, type, ftc(type)]
|
155
|
+
recordCSV [@twb.name, @modTime, @sheetName, ds.uiname, dsName, fuiName, field.name, type, ftc(type)]
|
154
156
|
end
|
155
157
|
end
|
156
158
|
end
|
@@ -161,7 +163,7 @@ module Analysis
|
|
161
163
|
filters.each do |filter|
|
162
164
|
dsName = filter.dataSource.name
|
163
165
|
dsUIName = filter.dataSource.uiname
|
164
|
-
recordCSV [@twb.name, @sheetName, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter')]
|
166
|
+
recordCSV [@twb.name, @modTime, @sheetName, dsUIName, dsName, filter.uiname, filter.name, 'filter', ftc('filter')]
|
165
167
|
end
|
166
168
|
end
|
167
169
|
|
@@ -169,7 +171,7 @@ module Analysis
|
|
169
171
|
sheet.pageFields.each do |pfield|
|
170
172
|
ds = @twb.datasource pfield.dataSource
|
171
173
|
fuiname = ds.fieldUIName pfield.name
|
172
|
-
recordCSV [@twb.name, @sheetName, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('page')]
|
174
|
+
recordCSV [@twb.name, @modTime, @sheetName, ds.uiname, ds.name, fuiname, pfield.name, 'page', ftc('page')]
|
173
175
|
end
|
174
176
|
end
|
175
177
|
|
@@ -179,7 +181,7 @@ module Analysis
|
|
179
181
|
ds = @twb.datasource dsName
|
180
182
|
dsUIName = ds.uiname
|
181
183
|
ds.filters.each do |filter|
|
182
|
-
recordCSV [@twb.name, @sheetName, dsUIName, dsName, filter.uiname, filter.name, 'dsfilter', ftc('dsfilter')]
|
184
|
+
recordCSV [@twb.name, @modTime, @sheetName, dsUIName, dsName, filter.uiname, filter.name, 'dsfilter', ftc('dsfilter')]
|
183
185
|
end
|
184
186
|
end
|
185
187
|
end
|
@@ -191,15 +193,15 @@ module Analysis
|
|
191
193
|
dsuiname = ds.uiname
|
192
194
|
fuiName = ds.fieldUIName field.name
|
193
195
|
recorded = @sheetFields.key?(dsuiname) && @sheetFields[dsuiname].include?(fuiName)
|
194
|
-
|
195
|
-
|
196
|
+
emit " # #{@sheetFields.inspect}"
|
197
|
+
emit " - %-6s %-25s -> %-s" % [recorded, dsuiname, fuiName]
|
196
198
|
unless recorded
|
197
|
-
recordCSV [@twb.name, @sheetName, dsuiname, dsName, fuiName, field.name, 'slice', ftc('slice')]
|
198
|
-
|
199
|
+
recordCSV [@twb.name, @modTime, @sheetName, dsuiname, dsName, fuiName, field.name, 'slice', ftc('slice')]
|
200
|
+
emit " - recorded"
|
199
201
|
end
|
200
|
-
|
202
|
+
emit "--"
|
201
203
|
end
|
202
|
-
|
204
|
+
emit "\n "
|
203
205
|
end
|
204
206
|
|
205
207
|
def recordCSV record
|
@@ -27,7 +27,9 @@ module Analysis
|
|
27
27
|
|
28
28
|
def initialize(**args)
|
29
29
|
@args = args
|
30
|
+
# puts "@args: #{@args}"
|
30
31
|
@recordDir = !@args.nil? && @args[:recordDir] == true
|
32
|
+
@ttdocdir = @args[:ttdocdir]
|
31
33
|
@csvAdd = args[:csvMode] == :add
|
32
34
|
@csvMode = @csvAdd ? 'a' : 'w'
|
33
35
|
init
|
@@ -37,9 +39,9 @@ module Analysis
|
|
37
39
|
@sheetFieldsCSV = CSV.open( docFileName,@csvMode)
|
38
40
|
unless @csvAdd
|
39
41
|
if @recordDir
|
40
|
-
@sheetFieldsCSV << ['Rec #','Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind','Workbook Dir']
|
42
|
+
@sheetFieldsCSV << ['Rec #','Workbook','Workbook Modified','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind','Workbook Dir']
|
41
43
|
else
|
42
|
-
@sheetFieldsCSV << ['Rec #','Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
|
44
|
+
@sheetFieldsCSV << ['Rec #','Workbook','Workbook Modified','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?','Kind']
|
43
45
|
end
|
44
46
|
end
|
45
47
|
addDocFile @sheetFieldsCSV, docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
|
@@ -60,6 +62,7 @@ module Analysis
|
|
60
62
|
@twb = twb
|
61
63
|
@twbName = @twb.name
|
62
64
|
@twbDir = @twb.dir
|
65
|
+
@modTime = @twb.modtime
|
63
66
|
emit " -- #{@twbName}"
|
64
67
|
@twbDomainsLoaded = false
|
65
68
|
parseFilters
|
@@ -74,14 +77,14 @@ module Analysis
|
|
74
77
|
filter.emit "-----------------------------\nWORKSHEET:: #{sheet.name}\n-----------------------------"
|
75
78
|
if filter.values.empty?
|
76
79
|
# @sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation' ,'Data Source','Field','Value','Alias', 'Alias?']
|
77
|
-
recordCSV [@twbName, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, nil, nil, nil, filter.inexMode, filter.includeNull, filter.kind]
|
80
|
+
recordCSV [@twbName, @modTime, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, nil, nil, nil, filter.inexMode, filter.includeNull, filter.kind]
|
78
81
|
end
|
79
82
|
filter.values.each do |valueMap|
|
80
83
|
value = valueMap[:value]
|
81
84
|
valias = valueMap[:alias]
|
82
85
|
same = value.eql? valias
|
83
86
|
emit "RECORDING FILTER VALUES: %-35s -- %-25s same? %s " % [value,valias,same]
|
84
|
-
recordCSV [@twbName, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, value, valias, same, filter.inexMode, filter.includeNull, filter.kind]
|
87
|
+
recordCSV [@twbName, @modTime, sheet.name, filter.type, filter.inexclude, filter.dataSource.uiname, filter.uiname, value, valias, same, filter.inexMode, filter.includeNull, filter.kind]
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# sheetfieldsanalyzer.rb Copyright (C) 2018 Chris Gerrard
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require 'twb'
|
17
|
+
require 'csv'
|
18
|
+
|
19
|
+
module Twb
|
20
|
+
module Analysis
|
21
|
+
|
22
|
+
class WorkbookSummaryAnalyzer
|
23
|
+
|
24
|
+
include TabTool
|
25
|
+
|
26
|
+
attr_accessor :localEmit
|
27
|
+
|
28
|
+
def initialize(**args)
|
29
|
+
@args = args
|
30
|
+
@recordDir = !@args.nil? && @args[:recordDir] == true
|
31
|
+
@ttdocdir = @args[:ttdocdir]
|
32
|
+
@csvAdd = !@args.nil? && args[:csvMode] == :add
|
33
|
+
@csvMode = @csvAdd ? 'a' : 'w'
|
34
|
+
init
|
35
|
+
@funcdoc = {:class=>self.class, :blurb=>'Analyze Workbooks', :description=>'Workbook summary data: # Data Sources; Dashboards; Sheets; etc.'}
|
36
|
+
#--
|
37
|
+
docFileName = docFile('WorkbookSummary.csv')
|
38
|
+
addDocFile @dashSheetsCSV, docFileName, "Workbook summary data."
|
39
|
+
@dashSheetsCSV = CSV.open(docFileName,@csvMode)
|
40
|
+
unless @csvAdd
|
41
|
+
csvHeader = ['Rec #', 'Workbook','Type','Version','Build','Modified','# Data Sources','# Dashboards','# Worksheets']
|
42
|
+
if @recordDir
|
43
|
+
csvHeader.push('Workbook Directory')
|
44
|
+
end
|
45
|
+
@dashSheetsCSV << csvHeader
|
46
|
+
end
|
47
|
+
#--
|
48
|
+
@twbCount = 0
|
49
|
+
@dashCount = 0
|
50
|
+
@dsCount = 0
|
51
|
+
@sheetCount = 0
|
52
|
+
@recNum = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def metrics
|
56
|
+
{
|
57
|
+
'# of Workbooks' => @twbCount,
|
58
|
+
'# of Data Sources' => @dsCount,
|
59
|
+
'# of Dashboards' => @dashCount,
|
60
|
+
'# of Worksheets' => @sheetCount
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def processTWB twb
|
65
|
+
@twb = twb
|
66
|
+
emit " -- #{@twbName}"
|
67
|
+
recordCSV [ @twb.name,
|
68
|
+
@twb.type,
|
69
|
+
@twb.version,
|
70
|
+
@twb.build,
|
71
|
+
@twb.modtime,
|
72
|
+
@twb.datasources.length,
|
73
|
+
@twb.dashboards.length,
|
74
|
+
@twb.worksheets.length
|
75
|
+
]
|
76
|
+
@twbCount += 1
|
77
|
+
@dsCount += @twb.datasources.length
|
78
|
+
@dashCount += @twb.dashboards.length
|
79
|
+
@sheetCount += @twb.worksheets.length
|
80
|
+
finis
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def recordCSV record
|
86
|
+
numberedRec = [@recNum+=1] + record
|
87
|
+
if @recordDir
|
88
|
+
@dashSheetsCSV << numberedRec.push(@twb.dir)
|
89
|
+
else
|
90
|
+
@dashSheetsCSV << numberedRec
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end #class SheetFieldsAnalyzer
|
95
|
+
|
96
|
+
end # module Analysis
|
97
|
+
end # module Twb
|
data/lib/twb/tabtool.rb
CHANGED
@@ -25,9 +25,10 @@ module TabTool
|
|
25
25
|
@@TTDOCDIR = './ttdoc'
|
26
26
|
@configFile = './ttconfig.yml'
|
27
27
|
|
28
|
-
attr_accessor :ttdocdir,
|
29
|
-
attr_accessor :
|
30
|
-
|
28
|
+
attr_accessor :ttdocdir, :docDir, :docfiles
|
29
|
+
attr_accessor :ttdocdir, :logger, :loglevel, :logfilename
|
30
|
+
attr_accessor :uuid, :type, :id, :properties
|
31
|
+
attr_reader :licensed, :funcdoc, :metrics, :alerts
|
31
32
|
|
32
33
|
@funcdoc = {:class=>nil, :blurb=>nil, :description=>nil,}
|
33
34
|
@docfiles = [] # should be of form [{:name=>'docFileName',:description=>'doc file description'}]
|
@@ -43,12 +44,23 @@ module TabTool
|
|
43
44
|
initLogger
|
44
45
|
end
|
45
46
|
|
47
|
+
def ttdocdir= docdir
|
48
|
+
# puts "def ttdocdir= #{docdir}"
|
49
|
+
@ttdocdir = docdir
|
50
|
+
init
|
51
|
+
end
|
52
|
+
|
46
53
|
def initDocDir
|
54
|
+
# puts "def initDocDir"
|
47
55
|
# return if @@TTDOCDIR.nil?
|
48
56
|
# return if ''.eql?($ttdocdir) && ''.eql?(@@TTDOCDIR)
|
49
|
-
@docDir = @@TTDOCDIR
|
57
|
+
@docDir = @ttdocdir.nil? ? @@TTDOCDIR : @ttdocdir
|
58
|
+
# puts " @@TTDOCDIR: #{@@TTDOCDIR}"
|
59
|
+
# puts " @ttdocdir: #{@ttdocdir}"
|
60
|
+
# puts " @docDir : #{@docDir}"
|
61
|
+
# puts ""
|
50
62
|
return if Dir.exists?(@docDir)
|
51
|
-
if File.exists? @docDir
|
63
|
+
if File.exists? @docDir # on the off chance that the doc dir is already present as a file
|
52
64
|
@docDir = ''
|
53
65
|
else
|
54
66
|
Dir.mkdir @docDir
|
@@ -154,10 +166,19 @@ module TabTool
|
|
154
166
|
# end
|
155
167
|
|
156
168
|
def initCSV(fileName, desc=nil, header=nil)
|
169
|
+
emit "def initCSV"
|
157
170
|
csvName = docFile(fileName)
|
158
|
-
emit "
|
171
|
+
emit " @recordDir: #{@recordDir.nil?} \t :: #{@recordDir}"
|
172
|
+
emit " header: #{@header.nil?} \t :: #{header}"
|
173
|
+
emit " csvName: #{csvName.nil?} :: #{csvName}"
|
159
174
|
csvFile = CSV.open(csvName, 'w')
|
160
|
-
|
175
|
+
unless header.nil?
|
176
|
+
if @recordDir
|
177
|
+
csvFile << header.push('Workbook Directory')
|
178
|
+
else
|
179
|
+
csvFile << header
|
180
|
+
end
|
181
|
+
end
|
161
182
|
addDocFile csvFile, csvName, desc
|
162
183
|
return csvFile
|
163
184
|
end
|
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.
|
4
|
+
version: 4.4.6
|
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-
|
11
|
+
date: 2019-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: creek
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- lib/twb/analysis/Sheets/sheetfiltersanalyzer.rb
|
82
82
|
- lib/twb/analysis/Sheets/sheetfiltersanalyzerA.rb
|
83
83
|
- lib/twb/analysis/Sheets/sheetsourcesanalyzer.rb
|
84
|
+
- lib/twb/analysis/WorkbookSummaryAnalyzer.rb
|
84
85
|
- lib/twb/calculatedfield.rb
|
85
86
|
- lib/twb/codedfield.rb
|
86
87
|
- lib/twb/columnfield.rb
|