twb 4.4.4 → 4.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|