twb 4.7.1 → 4.9.0

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