twb 4.7.1 → 4.9.0

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: 9ba8a4bcf6b220aaf9d3b94a91a903ec055a1637d7d78c063a58a5def3027844
4
- data.tar.gz: a7f76a9e0fb057cf7aee2c38c82b974e0a59575eb955bd41636e79a38a251f65
3
+ metadata.gz: 39d006e0c059121c7c53795a7b2c7b90c425a3809bb0287b215f5950ac4187b8
4
+ data.tar.gz: a49a8f7fb9cbf9a206def1cdc1faf649455dea27d180c88d64e518ae1da3b4e2
5
5
  SHA512:
6
- metadata.gz: 685229ff4ae9181176c42fb85cf9900e64823fa2cbcf4a8ef49a48b0ebbfa96ecf491e27e88c545478a2e4ccad0ba314f648baa28406964032d39e3daefe0904
7
- data.tar.gz: 86eb832a11d3bb87a66835f29d5eb312477f55421e007dea39c8178568573d39f0ff5d529ab22dfbfe53128b6a1b1145948b5f92bd785cc780b57c3df76d7137
6
+ metadata.gz: 8f2983b81057ba13bfa029b4103fac22728f0fe34a7e41346373019161d7f6dc9857a54f67f071ae23f531e6a2a140448bc3c8e9ed95577b0c35ec4bd2e560d8
7
+ data.tar.gz: 9397a53a76c078a36dbfffa170c4a8f91b85a76d5c288e20c38e5a84ea9a3f78d9e7e01488f85d1c917dc6ce4f371671066367550723bd13ba79afa7f98b2b1c
data/lib/twb.rb CHANGED
@@ -37,6 +37,7 @@ require_relative 'twb/quickfilter'
37
37
  # require_relative 'twb/docdashboardimagevert'
38
38
  # require_relative 'twb/docdashboardwebvert'
39
39
  require_relative 'twb/util/twbdashsheetdatadotbuilder'
40
+ require_relative 'twb/util/csvrecordsatomizer'
40
41
  require_relative 'twb/util/dotfilerenderer'
41
42
  # require_relative 'twb/util/htmllistcollapsible'
42
43
  require_relative 'twb/util/xraydashboards'
@@ -59,11 +60,16 @@ require_relative 'twb/analysis/calculatedfields/csvemitter'
59
60
  # require_relative 'twb/analysis/datasources/datasourcefieldscsvemitter'
60
61
  require_relative 'twb/analysis/datasources/datasourcesenumerator.rb'
61
62
  require_relative 'twb/analysis/datasources/datasourcefieldsanalyzer'
62
- require_relative 'twb/analysis/datasources/datasourcetablefieldscsvemitter'
63
+ require_relative 'twb/analysis/datasources/datasourcefilesanalyzer'
64
+ # require_relative 'twb/analysis/datasources/datasourcetablefieldscsvemitter'
65
+ # require_relative 'twb/analysis/datasources/datasourcetablefieldsanalyzer'
63
66
  require_relative 'twb/analysis/datasources/categoricalcolorcodinganalyzer'
64
67
  require_relative 'twb/analysis/datasources/googlesheetdatasourcesanalyzer'
65
68
  require_relative 'twb/analysis/datasources/parametersanalyzer'
66
69
  require_relative 'twb/analysis/datasources/datasourceoriginsanalyzer'
70
+ require_relative 'twb/analysis/datasources/fieldsaliasesanalyzer'
71
+ require_relative 'twb/analysis/datasources/extractsanalyzer'
72
+ require_relative 'twb/analysis/sheets/worksheetsummarizer'
67
73
  require_relative 'twb/analysis/sheets/worksheetdatastructurecsvemitter'
68
74
  require_relative 'twb/analysis/sheets/sheetfiltersanalyzer'
69
75
  require_relative 'twb/analysis/sheets/sheetfieldsanalyzer'
@@ -74,5 +80,5 @@ require_relative 'twb/analysis/sheets/sheetsintooltipanalyzer'
74
80
  # Represents Tableau Workbooks, their contents, and classes that analyze and manipulate them.
75
81
  #
76
82
  module Twb
77
- VERSION = '4.7.1'
83
+ VERSION = '4.9.0'
78
84
  end
@@ -0,0 +1,110 @@
1
+ # fieldsaliasesanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher 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 'csv'
17
+
18
+ module Twb
19
+ module Analysis
20
+
21
+ class FieldsAliasesAnalyzer
22
+
23
+ include TabTool
24
+
25
+ attr_reader :calculatedFieldsCount, :referencedFieldsCount, :metrics
26
+
27
+ @@csvFileName = 'FieldAliases.csv'
28
+ @@csvFileHeader = [
29
+ 'Record #',
30
+ "Record Number",
31
+ "Workbook",
32
+ "Data Source",
33
+ 'Data Source Caption',
34
+ 'Data Source (tech)',
35
+ 'Field',
36
+ 'Field Caption',
37
+ 'Field Name (tech)',
38
+ 'Data Type',
39
+ 'Role',
40
+ 'Type',
41
+ 'Field Value',
42
+ 'Field Alias'
43
+ ]
44
+
45
+
46
+ def initialize(**args)
47
+ emit "initialize FieldsAliasesAnalyzer args #{args}"
48
+ @args = args
49
+ @recordDir = !@args.nil? && @args[:recordDir] == true
50
+ @ttdocdir = @args[:ttdocdir]
51
+ @csvAdd = @args[:csvMode] == :add
52
+ @csvMode = @csvAdd ? 'a' : 'w'
53
+ init
54
+ @funcdoc = {:class=>self.class, :blurb=>"Analyze Fields' Aliases", :description=>'Understanding the aliases for field values can be important and useful.',}
55
+ #-- CSV records collectors
56
+ # @csvFormulaFields = Set.new
57
+ # @csvFormulaLines = Set.new
58
+ #-- Counters setup --
59
+ # @twbCount = 0
60
+ @dataSourcesCount = 0
61
+ @aliasedFieldsCount = 0
62
+ @aliasessCount = 0
63
+ #--
64
+ # @referencedFields = SortedSet.new
65
+ #--
66
+ twbdirLabel = @recordDir.nil? ? nil : 'Workbook Dir'
67
+ @csvFile = initCSV(@@calcFieldsCSVFileName, 'Calculated fields and their formulas.', @@csvFileHeader )
68
+ #--
69
+ @localEmit = false
70
+ # @imageFiles = Array.new
71
+ #--
72
+ # @doGraph = config(:dograph)
73
+ end
74
+
75
+ def processTWB twb
76
+ twb.datasources.each do |ds|
77
+ processDS ds
78
+ end
79
+ end
80
+
81
+ def processDS ds
82
+ @dsUIName = ds.uiname
83
+ @dsCaption = ds.caption
84
+ @dsName = ds.name
85
+ #--
86
+ aliasesNodes = ds.node.xpath('.//aliases')
87
+ aliasesNodes.each do |an|
88
+ processAliases an
89
+ end
90
+ end
91
+
92
+ def processAliases aliasesNode
93
+ #-- Field --
94
+ caption = d.xpath('../../@caption').text
95
+ techName = d.xpath('../../@name').text
96
+ name = if caption == '' then getName(techName) else caption end
97
+ dataType = d.xpath('../../@datatype').text
98
+ role = d.xpath('../../@role').text
99
+ type = d.xpath('../../@type').text
100
+
101
+ #-- Alias --
102
+ aliasKey = d.xpath('./@key').text
103
+ aliasValue = d.xpath('./@value').text
104
+
105
+
106
+
107
+
108
+
109
+
110
+ end # class FieldsAliasesAnalyzer
@@ -0,0 +1,83 @@
1
+ # datasourcefilesanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher 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 'csv'
17
+
18
+ module Twb
19
+ module Analysis
20
+ module DataSources
21
+
22
+ class DataSourceFilesAnalyzer
23
+
24
+ include TabTool
25
+
26
+ attr_reader :filesCount
27
+
28
+ @@csvFileName = 'DataSourceFiles.csv'
29
+ @@csvFileHeader = [ 'Record #',
30
+ 'Workbook',
31
+ 'Workbook Dir',
32
+ 'Data Source',
33
+ 'File Name',
34
+ 'File Dir',
35
+ 'File Modified',
36
+ 'File Size'
37
+ ]
38
+
39
+ def initialize(**args)
40
+ emit "initialize DataSourceFilesAnalyzer args #{args}"
41
+ @args = args
42
+ @recordDir = !@args.nil? && @args[:recordDir] == true
43
+ @ttdocdir = @args[:ttdocdir]
44
+ @csvAdd = @args[:csvMode] == :add
45
+ @csvMode = @csvAdd ? 'a' : 'w'
46
+ init
47
+ @funcdoc = {:class=>self.class, :blurb=>"Analyze Data Sources' Files", :description=>'Identifying the files accessed by Data Sources.',}
48
+ @dataSourcesCount = 0
49
+ @recNum = 0
50
+ #--
51
+ @csvFile = initCSV(@@csvFileName, 'Data Sources and the Files they access.', @@csvFileHeader )
52
+ #--
53
+ @localEmit = false
54
+ end
55
+
56
+ def processTWB twb
57
+ @twbName = twb.name
58
+ @twDir = twb.dir
59
+ twb.datasources.each do |ds|
60
+ processFiles ds
61
+ end
62
+ end
63
+
64
+ def processFiles ds
65
+ dirFiles = Hash.new { |d,fs| d[fs] = Set.new }
66
+ ds.node.xpath('.//connection[@filename]').each do |fnode|
67
+ twbFileDir = fnode['directory']
68
+ twbFileName = fnode['filename']
69
+ fqFileName = twbFileDir.nil? ? twbFileName : twbFileDir + '/' + twbFileName
70
+ fileName = File.basename fqFileName
71
+ fileDir = File.dirname fqFileName
72
+ modtime = File.mtime fqFileName
73
+ size = File.size fqFileName
74
+ data = [$recNum+=1, twbName, twb.dir, ds.uiname, fileName, fileDir, modtime, size]
75
+ @csvFile << data
76
+ end
77
+ end
78
+
79
+ end # class DataSourceFilesAnalyzer
80
+
81
+ end # module DataSources
82
+ end # module Analysis
83
+ end # module Twb
@@ -0,0 +1,117 @@
1
+ # datasourcetablefieldsanalyzer.rb - this Ruby script Copyright 2019 Christopher 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
+
18
+ module Twb
19
+ module Analysis
20
+ module DataSources
21
+
22
+ class require_relative DataSourceTableFieldsAnalyzer
23
+
24
+ attr_reader :csvFileName, :csvRecords
25
+ attr_reader :dsCount, :tablesCount, :fieldsCount
26
+
27
+ @@csvFileName = 'DataSourceTableFields.csv'
28
+ @csvFileDescription = 'Contains CSV records, each containing the details for an individual Field contained in a table in the Data Source. Data Sources are identified within their host Workbook. '
29
+
30
+ @@csvHeader = ['Record #',
31
+ 'Workbook',
32
+ 'Workbook Dir',
33
+ 'Data Source',
34
+ 'Data Source (tech)',
35
+ 'Table',
36
+ 'Field',
37
+ 'Field (code)',
38
+ 'Field (table)',
39
+ ]
40
+
41
+
42
+ def initialize
43
+ @csvFile = CSV.open(@@csvFileName, 'w')
44
+ @csvFile << @@csvHeader
45
+ @outputs = Set.new
46
+ @outputs << @@csvFileName
47
+ @dsCount = 0
48
+ @tablesCount = 0
49
+ @fieldsCount = 0
50
+ @csvRecords = Set.new
51
+ end
52
+
53
+ def doc
54
+ {
55
+ :filedoc => [
56
+ { :file => @@csvFileName,
57
+ :description => @csvFileDescription,
58
+ :header => @@csvHeader
59
+ }
60
+ ],
61
+ :outputs => @outputs
62
+ }
63
+ end
64
+
65
+ def self.csvHeader
66
+ @@csvHeader
67
+ end
68
+
69
+ def self.csvFileType
70
+ @@csvFileName
71
+ end
72
+
73
+ def outputs
74
+ @outputs
75
+ end
76
+
77
+ def processTwb twb
78
+ @recNum = 0
79
+ @twb = twb if twb.instance_of? Twb::Workbook
80
+ @twb = Twb::Workbook.new(twb) if twb.instance_of? String
81
+ # --
82
+ dss = @twb.datasources
83
+ dss.each do |ds|
84
+ tables = Set.new
85
+ @dsCount += 1
86
+ ds.node.xpath('./connection/cols/map').each do |cnode|
87
+ # puts cnode
88
+ key = cnode.attribute('key').text
89
+ codename = key.gsub(/^\[|\]$/,'')
90
+ fielduiname = ds.fieldUIName(codename)
91
+ value = cnode.attribute('value').text.gsub(/^\[|\]$/,'')
92
+ parts = value.split('].[')
93
+ # puts "%-30s %-45s %s \n " % [fielduiname, value, parts]
94
+ csvRecord = [ @fieldsCount += 1,
95
+ @twb.name,
96
+ @twb.dir,
97
+ ds.uiname,
98
+ ds.name,
99
+ parts[0],
100
+ fielduiname,
101
+ codename,
102
+ parts[1]
103
+ ]
104
+ tables.add parts[0]
105
+ @csvRecords.add csvRecord
106
+ @csvFile << csvRecord
107
+ end
108
+ @tablesCount += tables.length
109
+ end
110
+ end
111
+
112
+ end # class CSVEmitter
113
+
114
+
115
+ end # module DataSources
116
+ end # module Analysis
117
+ end # module Twb
@@ -0,0 +1,199 @@
1
+ # worksheetsummarizer.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
+ module DataSources
22
+
23
+ class ExtractsAnalyzer
24
+
25
+ include TabTool
26
+
27
+ attr_accessor :localEmit
28
+
29
+ def initialize(**args)
30
+ @args = args
31
+ @recordDir = !@args.nil? && @args[:recordDir] == true
32
+ @ttdocdir = @args[:ttdocdir]
33
+ @csvAdd = !@args.nil? && args[:csvMode] == :add
34
+ @csvMode = @csvAdd ? 'a' : 'w'
35
+ init
36
+ @funcdoc = {:class=>self.class, :blurb=>'Analyze Extracts', :description=>'Identifies Data Source Extracts & records relevant data.',}
37
+ #--
38
+ docFileName = docFile('Extracts.csv')
39
+ @extractsCSV = CSV.open(docFileName,@csvMode)
40
+ #--
41
+ # <extract count='-1' enabled='true' units='records'>
42
+ # <connection access_mode='readonly'
43
+ # authentication='auth-none'
44
+ # author-locale='en_US'
45
+ # class='hyper'
46
+ # dbname='C:/tech/Tableau/Tableau Tools/Ruby/gems/twb/lib/twb/analysis/datasources/data/Sample - World Bank Indicators (Excel).hyper'
47
+ # default-settings='yes'
48
+ # schema='Extract'
49
+ # sslmode=''
50
+ # update-time='05/17/2019 10:39:21 PM'
51
+ # username='tableau_internal_user'>
52
+ # <relation name='Extract' table='[Extract].[Extract]' type='table' />
53
+ # <refresh>
54
+ # <refresh-event add-from-file-path='Sample - World Bank Indicators (Excel)' increment-value='%null%' refresh-type='create' rows-inserted='2354' timestamp-start='2019-05-17 22:39:21.474' />
55
+ # </refresh>
56
+ # </connection>
57
+ # </extract>
58
+ #--
59
+ unless @csvAdd
60
+ @csvHeader = [ 'Rec #',
61
+ 'Workbook',
62
+ 'Data Source',
63
+ 'Enabled',
64
+ 'Units',
65
+ 'Access Mode',
66
+ 'Authentication',
67
+ 'Class',
68
+ 'Extract Name (FQ)',
69
+ 'Extract Name',
70
+ 'Extract Directory',
71
+ 'Default Settings',
72
+ 'Schema',
73
+ 'SSL Mode',
74
+ 'Updated (UTC)',
75
+ 'User Name'
76
+ ]
77
+ if @recordDir
78
+ @csvHeader.push 'Workbook Dir'
79
+ end
80
+ @extractsCSV << @csvHeader
81
+ end
82
+ addDocFile @extractsCSV, docFileName, "Workbooks and their Data Source Extracts."
83
+ #--
84
+ @twbCount = 0
85
+ @dsCount = 0
86
+ @extractCount = 0
87
+ @recNum = 0
88
+ end
89
+
90
+ def metrics
91
+ {
92
+ '# of Data Sources' => @dsCount,
93
+ '# of Extracts' => @extractCount
94
+ }
95
+ end
96
+
97
+ def processTWB twb
98
+ @twb = twb
99
+ @twbName = @twb.name
100
+ @twbDir = @twb.dir
101
+ emit " -- #{@twbName}"
102
+ @twbCount += 1
103
+ parseDataSources
104
+ finis
105
+ end
106
+
107
+ def parseDataSources
108
+ @dataSources = @twb.datasources
109
+ @dataSources.each do |ds|
110
+ @dsCount += 1
111
+ emit "DATA SOURCE:: #{ds.name}"
112
+ dsNode = ds.node
113
+ exnode = ds.node.at_xpath('./extract')
114
+ unless exnode.nil?
115
+ cnNode = exnode.at_xpath('./connection')
116
+ # emit true, cnNode
117
+ unless cnNode.nil?
118
+ @extractCount += 1
119
+ dbName = cnNode['dbname']
120
+ # emit true, "cnNode['dbname'] :: #{cnNode['dbname']}"
121
+ # unless dbName.nil?
122
+ exName = File.basename dbName
123
+ exDir = File.dirname dbName
124
+ # end
125
+ recordCSV [ @twbName,
126
+ ds.uiname,
127
+ exnode['enabled'],
128
+ exnode['units'],
129
+ cnNode['access_mode'],
130
+ cnNode['authentication'],
131
+ cnNode['class'],
132
+ dbName,
133
+ exName,
134
+ exDir,
135
+ cnNode['default-settings'],
136
+ cnNode['schema'],
137
+ cnNode['sslmode'],
138
+ cnNode['update-time'],
139
+ cnNode['username']
140
+ ]
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ # <extract count='-1' enabled='true' units='records'>
147
+ # <connection access_mode='readonly'
148
+ # authentication='auth-none'
149
+ # author-locale='en_US'
150
+ # class='hyper'
151
+ # dbname='C:/tech/Tableau/Tableau Tools/Ruby/gems/twb/lib/twb/analysis/datasources/data/Sample - World Bank Indicators (Excel).hyper'
152
+ # default-settings='yes'
153
+ # schema='Extract'
154
+ # sslmode=''
155
+ # update-time='05/17/2019 10:39:21 PM'
156
+ # username='tableau_internal_user'>
157
+ # <relation name='Extract' table='[Extract].[Extract]' type='table' />
158
+ # <refresh>
159
+ # <refresh-event add-from-file-path='Sample - World Bank Indicators (Excel)' increment-value='%null%' refresh-type='create' rows-inserted='2354' timestamp-start='2019-05-17 22:39:21.474' />
160
+ # </refresh>
161
+ # </connection>
162
+ # </extract>
163
+ #--
164
+ # unless @csvAdd
165
+ # @csvHeader = [ 'Rec #',
166
+ # 'Workbook',
167
+ # 'Data Source',
168
+ # 'Enabled',
169
+ # 'Units',
170
+ # 'Access Mode',
171
+ # 'Authentication',
172
+ # 'Class',
173
+ # 'Db Name',
174
+ # 'Default Settings',
175
+ # 'Schema',
176
+ # 'SSL Mode',
177
+ # 'Updated',
178
+ # 'User Name'
179
+ # ]
180
+
181
+
182
+
183
+
184
+ private
185
+
186
+ def recordCSV record
187
+ numberedRec = [@recNum+=1] + record
188
+ if @recordDir
189
+ @extractsCSV << numberedRec.push(@twbDir)
190
+ else
191
+ @extractsCSV << numberedRec
192
+ end
193
+ end
194
+
195
+ end # class ExtractsAnalyzer
196
+
197
+ end # module DataSources
198
+ end # module Analysis
199
+ end # module Twb
@@ -0,0 +1,117 @@
1
+ # fieldsaliasesanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher 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 'csv'
17
+
18
+ module Twb
19
+ module Analysis
20
+ module DataSources
21
+
22
+ class FieldsAliasesAnalyzer
23
+
24
+ include TabTool
25
+
26
+ attr_reader :calculatedFieldsCount, :referencedFieldsCount, :metrics
27
+
28
+ @@csvFileName = 'FieldAliases.csv'
29
+ @@csvFileHeader = [
30
+ 'Record #',
31
+ "Workbook",
32
+ "Data Source",
33
+ 'Field',
34
+ 'Value - Db',
35
+ 'Value - Alias'
36
+ ]
37
+
38
+
39
+ def initialize(**args)
40
+ emit "initialize FieldsAliasesAnalyzer args #{args}"
41
+ @args = args
42
+ @recordDir = !@args.nil? && @args[:recordDir] == true
43
+ @ttdocdir = @args[:ttdocdir]
44
+ @csvAdd = @args[:csvMode] == :add
45
+ @csvMode = @csvAdd ? 'a' : 'w'
46
+ init
47
+ @funcdoc = {:class=>self.class, :blurb=>"Analyze Fields' Aliases", :description=>'Understanding the aliases for field values can be important and useful.',}
48
+ #-- CSV records collectors
49
+ # @csvFormulaFields = Set.new
50
+ # @csvFormulaLines = Set.new
51
+ #-- Counters setup --
52
+ # @twbCount = 0
53
+ @dataSourcesCount = 0
54
+ @aliasedFieldsCount = 0
55
+ @aliasessCount = 0
56
+ @recNum = 0
57
+ #--
58
+ # @referencedFields = SortedSet.new
59
+ #--
60
+ @csvFile = initCSV(@@csvFileName, 'Fields and their aliased values.', @@csvFileHeader )
61
+ #--
62
+ @localEmit = false
63
+ # @imageFiles = Array.new
64
+ #--
65
+ # @doGraph = config(:dograph)
66
+ end
67
+
68
+ def processTWB twb
69
+ @twbName = twb.name
70
+ @twDir = twb.dir
71
+ twb.datasources.each do |ds|
72
+ processDS ds
73
+ end
74
+ end
75
+
76
+ def processDS ds
77
+ @dsUIName = ds.uiname
78
+ @dsCaption = ds.caption
79
+ @dsName = ds.name
80
+ #--
81
+ ds.columnFields.each do |fld|
82
+ if fld.hasaliases
83
+ @fieldName = fld.name
84
+ @fieldCaption = fld.caption
85
+ @fieldUIName = fld.uiname
86
+ processAliases(fld)
87
+ end
88
+ end
89
+ end
90
+
91
+ def processAliases field
92
+ aliasNodes = field.node.xpath('./aliases//alias')
93
+ aliasNodes.each do |anode|
94
+ key = anode['key']
95
+ value = anode['value']
96
+ numberedRec = [
97
+ @recNum +=1,
98
+ @twbName,
99
+ @dsUIName,
100
+ @fieldName,
101
+ anode['key'].to_s.gsub(/^["]+/,'').gsub(/["]+$/,''),
102
+ anode['value']
103
+ ]
104
+ #--
105
+ if @recordDir
106
+ @csvFile << numberedRec.push(@twbDir)
107
+ else
108
+ @csvFile << numberedRec
109
+ end
110
+ end
111
+ end
112
+
113
+ end # class FieldsAliasesAnalyzer
114
+
115
+ end # module DataSources
116
+ end # module Analysis
117
+ end # module Twb
@@ -70,10 +70,10 @@ module Analysis
70
70
 
71
71
  def parseSheets
72
72
  @sheets = @twb.worksheets
73
- puts " #Sheets: #{@sheets.length}"
73
+ # puts " #Sheets: #{@sheets.length}"
74
74
  @sheetCount += @sheets.length
75
75
  @sheets.each do |sheet|
76
- puts "SHEET:: #{sheet.name}"
76
+ # puts "SHEET:: #{sheet.name}"
77
77
  # @dashCount += 1
78
78
  ttip = sheet.tooltip
79
79
  runs = ttip.xpath('.//run')
@@ -81,12 +81,12 @@ module Analysis
81
81
  # puts run.text
82
82
  text = run.text
83
83
  isViz = text =~ /.*<Sheet[ ]+name=.*>.*/
84
- puts "\t #{text}"
84
+ # puts "\t #{text}"
85
85
  if isViz
86
86
  vizCode = text.gsub(/^[^<]*/,'').gsub(/[^>]*$/,'')
87
87
  vizNode = Nokogiri::XML(vizCode).at_xpath('./Sheet')
88
- puts "\t #{vizCode}"
89
- puts "\t #{vizNode.class} \t #{vizNode}"
88
+ # puts "\t #{vizCode}"
89
+ # puts "\t #{vizNode.class} \t #{vizNode}"
90
90
  recordCSV [@twbName, sheet.name, vizNode['name'], vizNode['maxwidth'], vizNode['maxheight']]
91
91
  end
92
92
 
@@ -0,0 +1,118 @@
1
+ # worksheetsummarizer.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 WorksheetSummarizer
23
+
24
+ include TabTool
25
+
26
+ attr_accessor :localEmit
27
+
28
+ # Worksheet attributes; from Worksheet.rb
29
+ # attr_reader :node, :name, :datasourcenames, :datasources
30
+ # attr_reader :panesCount
31
+ # attr_reader :fields, :rowFields, :colFields, :paneFields, :datasourceFields, :pageFields, :encodedFields, :slicesFields
32
+ # attr_reader :filters
33
+ # attr_reader :tooltip
34
+ # attr_accessor :hidden, :visible
35
+
36
+ def initialize(**args)
37
+ @args = args
38
+ @recordDir = !@args.nil? && @args[:recordDir] == true
39
+ @ttdocdir = @args[:ttdocdir]
40
+ @csvAdd = !@args.nil? && args[:csvMode] == :add
41
+ @csvMode = @csvAdd ? 'a' : 'w'
42
+ init
43
+ @funcdoc = {:class=>self.class, :blurb=>'Summarize Worksheets', :description=>'Identifies Worksheets & summarizes them.',}
44
+ #--
45
+ docFileName = docFile('WorkheetSummaries.csv')
46
+ @worksheetsCSV = CSV.open(docFileName,@csvMode)
47
+ unless @csvAdd
48
+ @csvHeader = [ 'Rec #',
49
+ 'Workbook',
50
+ 'Worksheet',
51
+ 'Hidden', 'Visible',
52
+ '# Data Sources',
53
+ '# Fields - Data', '# Fields - Rows', '# Fields - Cols',
54
+ 'Tooltip?', 'Filters?'
55
+ ]
56
+ if @recordDir
57
+ @csvHeader.push 'Workbook Dir'
58
+ end
59
+ @worksheetsCSV << @csvHeader
60
+ end
61
+ addDocFile @worksheetsCSV, docFileName, "Workbooks and their Worksheets' summaries."
62
+ #--
63
+ @twbCount = 0
64
+ @sheetCount = 0
65
+ @recNum = 0
66
+ end
67
+
68
+ def metrics
69
+ {
70
+ '# of Worksheets' => @sheetCount
71
+ }
72
+ end
73
+
74
+ def processTWB twb
75
+ @twb = twb
76
+ @twbName = @twb.name
77
+ @twbDir = @twb.dir
78
+ @modTime = @twb.modtime
79
+ emit " -- #{@twbName}"
80
+ @twbCount += 1
81
+ parseSheets
82
+ finis
83
+ end
84
+
85
+ def parseSheets
86
+ @worksheets = @twb.worksheets
87
+ @worksheets.each do |sheet|
88
+ emit "SHEET:: #{sheet.name}"
89
+ @sheetCount += 1
90
+ recordCSV [ @twbName,
91
+ sheet.name,
92
+ sheet.hidden,
93
+ sheet.visible,
94
+ sheet.datasources.length,
95
+ sheet.datasourceFields.length,
96
+ sheet.rowFields.length,
97
+ sheet.colFields.length,
98
+ !sheet.tooltip.nil?,
99
+ !sheet.filters.nil?,
100
+ ]
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def recordCSV record
107
+ numberedRec = [@recNum+=1] + record
108
+ if @recordDir
109
+ @worksheetsCSV << numberedRec.push(@twbDir)
110
+ else
111
+ @worksheetsCSV << numberedRec
112
+ end
113
+ end
114
+
115
+ end #class WorksheetSummarizer
116
+
117
+ end # module Analysis
118
+ end # module Twb
@@ -58,7 +58,8 @@ module Twb
58
58
  # visual-totals
59
59
 
60
60
  attr_reader :node, :properties
61
- attr_reader :name, :caption, :uiname, :alias
61
+ attr_reader :name, :caption, :uiname
62
+ attr_reader :hasaliases, :alias
62
63
  attr_reader :dataType, :defaultFormat, :paramDomainType
63
64
  attr_reader :role, :type, :value
64
65
  attr_reader :alias, :semanticRole, :aggregation
@@ -109,7 +110,7 @@ module Twb
109
110
  return role
110
111
  end
111
112
 
112
- def calcField
113
+ def calcField
113
114
  @calcField ||= loadCalcField
114
115
  end
115
116
 
@@ -137,6 +138,25 @@ module Twb
137
138
  @commentLines ||= loadComment
138
139
  end
139
140
 
141
+ def hasaliases
142
+ @hasaliases ||= !@node.at_xpath('./aliases').nil?
143
+ end
144
+
145
+ def aliases
146
+ @aliases ||= loadAliases
147
+ end
148
+
149
+ def loadAliases
150
+ @aliases = {}
151
+ if hasaliases
152
+ @node.at_xpath('./aliases//alias').each do |an|
153
+ dbvalue = an['key'].to_s.gsub(/^["]+/,'').gsub(/["]+$/,'')
154
+ @aliases[ dbvalue ] = an['value']
155
+ end
156
+ end
157
+ return @aliases
158
+ end
159
+
140
160
  # COMMENTED FIELDS
141
161
  # --------------------------------------
142
162
  # <column caption='Calculation1' datatype='real' name='[Calculation_821344020759588865]' role='measure' type='quantitative'>
@@ -235,8 +235,14 @@ module Twb
235
235
  'Parameters'.eql? @name
236
236
  end
237
237
 
238
+ def columnField fieldName
239
+ loadColumnFields if @columnFieldsMap.nil?
240
+ @columnFieldsMap[ fieldName ]
241
+ end
242
+
243
+
238
244
  def columnFields
239
- @columnFields ||= @columnFields = loadColumnFields
245
+ @columnFields ||= loadColumnFields
240
246
  end
241
247
 
242
248
  def columnFieldsMap
@@ -35,7 +35,7 @@ module TabTool
35
35
 
36
36
  # @logfilename = 'TabTools.ttlog'
37
37
  @@loglevel = Logger::DEBUG #INFO
38
- # @localEmit = false
38
+ @localEmit = false
39
39
  # @docDirSet = false
40
40
 
41
41
  def init
@@ -0,0 +1,105 @@
1
+ # calculatedfieldsanalyzer.rb - this Ruby script Copyright 2017, 2018 Christopher 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 'nokogiri'
17
+ # require 'twb'
18
+ # require 'set'
19
+ require 'csv'
20
+
21
+ module Twb
22
+ module Util
23
+
24
+ class AtomizeCSVRecords
25
+
26
+ include TabTool
27
+ # include Graph
28
+
29
+ attr_reader :metrics
30
+ attr_accessor :ttdocdir
31
+
32
+ @@ttlogfile = 'AtomizeCSVRecords.ttlog'
33
+ @@csvFileName = 'AtomizedCSVRecords.csv'
34
+
35
+ def initialize(**args)
36
+ @ttdocdir = @args[:ttdocdir]
37
+ @csvAdd = @args[:csvMode] == :add
38
+ @csvMode = @csvAdd ? 'a' : 'w'
39
+ init
40
+ @funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.',}
41
+ # --
42
+ @executed = false
43
+ end
44
+
45
+ def loadFields fileName
46
+ fields = Set.new
47
+ file = File.open(fileName)
48
+ unless file.nil?
49
+ file.each_line { |line|
50
+ fields.add line.chomp
51
+ }
52
+ end
53
+ return fields
54
+ end
55
+
56
+ def processTWB workbook
57
+ puts "\n\t ALERT: Utility tool: #{self.class} - does not implement Workbook processing"
58
+ puts "\t - deferring to single execution"
59
+ processData fileName
60
+ end
61
+
62
+ def processData fileName
63
+ unless @executed
64
+ emit true, "initialize AtomizeCSVRecords args #{args}"
65
+ @atomicCSV = CSV.open(@@csvFileName, 'w')
66
+ # --
67
+ inputFileName = fileName.nil? ? 'csvData.csv' : fileName
68
+ keyFields = loadFields 'key.fields'
69
+ excludeFields = loadFields 'exclude.fields'
70
+ puts "\t Using these key fields: #{$keyFields.inspect}"
71
+ puts "\t Excluding these fields: #{$excludeFields.inspect}"
72
+
73
+ $fieldValsCSV = '.csv'
74
+ $atomicCSV = CSV.open($fieldValsCSV, 'w')
75
+ $atomicFields = $keyFields.to_a + [ 'Rec #', 'Field', 'Value' ]
76
+ puts "\n\t CSV output fields: #{$atomicFields.inspect}"
77
+ $atomicCSV << $atomicFields
78
+
79
+
80
+ $recCnt, $fldsCnt = 0, 0
81
+
82
+ $recNum = 0
83
+
84
+ @executed = true
85
+ end
86
+ end
87
+
88
+ def metrics
89
+ @metrics ||= loadMetrics
90
+ end
91
+
92
+ def loadMetrics
93
+ @metrics = {
94
+ '# of Data Sources' => @dataSourcesCount,
95
+ '# of Calculated Fields' => @calculatedFieldsCount,
96
+ '# of Referenced Fields' => @referencedFieldsCount,
97
+ }
98
+ end
99
+
100
+ #-- private methods begin here, to end of class
101
+
102
+ end # class
103
+
104
+ end # module Analysis
105
+ end # module Twb
@@ -0,0 +1,114 @@
1
+ # CSVRecordsAtomizer.rb - this Ruby script Copyright 2019 Christopher 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 'csv'
17
+
18
+ module Twb
19
+ module Util
20
+
21
+ class CSVRecordsAtomizer
22
+
23
+ include TabTool
24
+
25
+ attr_reader :metrics
26
+ attr_accessor :ttdocdir
27
+
28
+ @@ttlogfile = 'AtomizeCSVRecords.ttlog'
29
+ @@csvFileName = 'AtomizedCSVRecords.csv'
30
+ @@atomFields = ['Record #', 'Field Name', 'Field Value']
31
+
32
+ def initialize(**args)
33
+ @args = args
34
+ @ttdocdir = @args[:ttdocdir]
35
+ @csvAdd = @args[:csvMode] == :add
36
+ @csvMode = @csvAdd ? 'a' : 'w'
37
+ init
38
+ @funcdoc = {:class=>self.class, :blurb=>'Analyze Calculated Fields', :description=>'Calculated fields can be complex, this tool provides robust coverage.'}
39
+ # --
40
+ @executed = false
41
+ end
42
+
43
+ def processFile fileName
44
+ emit true, "#{self.class} - processFile: #{fileName} :: #{fileName.class}"
45
+ # --
46
+ srcFields = Set.new CSV.open(fileName, 'r:bom|utf-8', &:readline)
47
+ emit true, "\t Inspecting these #{srcFields.length} #{srcFields.class} fields: "
48
+ keyFields = loadFields(fileName, :keyfields)
49
+ excludeFields = loadFields(fileName, :excludefields)
50
+ recordFields = (srcFields - keyFields - excludeFields).to_a
51
+ emit true, "\t Using these key fields: #{keyFields.inspect}"
52
+ emit true, "\t Excluding these fields: #{excludeFields.inspect}"
53
+ emit true, "\t Recording these fields: #{recordFields.inspect}"
54
+ # --
55
+ atomizedFields = keyFields.to_a + @@atomFields
56
+ dataBaseName = File.basename(fileName, ".*")
57
+ atomizedCSVFile = "#{dataBaseName}.Atomized.csv"
58
+ atomizedCSVFile = CSV.open(atomizedCSVFile,'w')
59
+ atomizedCSVFile << keyFields.to_a + @@atomFields
60
+ # --
61
+ @recNum = 0
62
+ CSV.open(fileName, 'r:bom|utf-8', headers: true) do |csv|
63
+ csv.each do |row|
64
+ @recNum += 1
65
+ atomRec = []
66
+ keyFields.each do |kf|
67
+ atomRec << row.fetch(kf)
68
+ end
69
+ atomRec << @recNum
70
+ recordFields.each do |rf|
71
+ atomizedCSVFile << atomRec + [rf, row.fetch(rf)]
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def loadFields fileName, type
80
+ puts "\n\n\t loadFields -#{fileName}- -#{type}-"
81
+ fields = Set.new
82
+ auxFile = "#{fileName}.#{type}"
83
+ isAuxFile = File.exist?(auxFile)
84
+ emit true, "\t\t Loading auxilary data: %-12s %7s %-s" % [type, isAuxFile, auxFile]
85
+ if isAuxFile
86
+ # file = File.open(fileName)
87
+ File.open(auxFile).each_line { |line|
88
+ fields.add line.chomp
89
+ }
90
+ end
91
+ return fields.to_a
92
+ end
93
+
94
+ def processData fileName
95
+ end
96
+
97
+ def metrics
98
+ @metrics ||= loadMetrics
99
+ end
100
+
101
+ def loadMetrics
102
+ @metrics = {
103
+ '# of Data Sources' => @dataSourcesCount,
104
+ '# of Calculated Fields' => @calculatedFieldsCount,
105
+ '# of Referenced Fields' => @referencedFieldsCount,
106
+ }
107
+ end
108
+
109
+ #-- private methods begin here, to end of class
110
+
111
+ end # class
112
+
113
+ end # module Analysis
114
+ end # module Twb
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.7.1
4
+ version: 4.9.0
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-03-22 00:00:00.000000000 Z
11
+ date: 2019-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: creek
@@ -63,15 +63,20 @@ files:
63
63
  - lib/twb/analysis/annotatedfieldscsvemitter.rb
64
64
  - lib/twb/analysis/calculatedfields/calculatedfieldsanalyzer.rb
65
65
  - lib/twb/analysis/calculatedfields/csvemitter.rb
66
+ - lib/twb/analysis/calculatedfields/fieldsaliasesanalyzer.rb
66
67
  - lib/twb/analysis/calculatedfields/groupfieldsanalyzer.rb
67
68
  - lib/twb/analysis/calculatedfields/markdownemitter.rb
68
69
  - lib/twb/analysis/datasources/categoricalcolorcodinganalyzer.rb
69
70
  - lib/twb/analysis/datasources/datasourcefieldsanalyzer.rb
70
71
  - lib/twb/analysis/datasources/datasourcefieldscsvemitter.rb
72
+ - lib/twb/analysis/datasources/datasourcefilesanalyzer.rb
71
73
  - lib/twb/analysis/datasources/datasourceoriginsanalyzer.rb
72
74
  - lib/twb/analysis/datasources/datasourcesenumerator.rb
73
75
  - lib/twb/analysis/datasources/datasourceslocationsanalyzer.rb
76
+ - lib/twb/analysis/datasources/datasourcetablefieldsanalyzer.rb
74
77
  - lib/twb/analysis/datasources/datasourcetablefieldscsvemitter.rb
78
+ - lib/twb/analysis/datasources/extractsanalyzer.rb
79
+ - lib/twb/analysis/datasources/fieldsaliasesanalyzer.rb
75
80
  - lib/twb/analysis/datasources/googlesheetdatasourcesanalyzer.rb
76
81
  - lib/twb/analysis/datasources/parametersanalyzer.rb
77
82
  - lib/twb/analysis/documentedfieldscsvemitter.rb
@@ -84,6 +89,7 @@ files:
84
89
  - lib/twb/analysis/sheets/sheetsintooltipanalyzer.rb
85
90
  - lib/twb/analysis/sheets/sheetsourcesanalyzer.rb
86
91
  - lib/twb/analysis/sheets/worksheetdatastructurecsvemitter.rb
92
+ - lib/twb/analysis/sheets/worksheetsummarizer.rb
87
93
  - lib/twb/analysis/workbooksummaryanalyzer.rb
88
94
  - lib/twb/calculatedfield.rb
89
95
  - lib/twb/codedfield.rb
@@ -118,6 +124,8 @@ files:
118
124
  - lib/twb/there.rb
119
125
  - lib/twb/twbcodedfield.rb
120
126
  - lib/twb/twbtest.rb
127
+ - lib/twb/util/atomizecsvrecords.rb
128
+ - lib/twb/util/csvrecordsatomizer.rb
121
129
  - lib/twb/util/cypher.rb
122
130
  - lib/twb/util/cypherpython.rb
123
131
  - lib/twb/util/docprep.rb