twb 1.9.1 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44eeddf556df0d517a68f5b4a1af89ae52138f37
4
- data.tar.gz: 46d6c474f5d6d5b020d7849463733c66bfb724fe
3
+ metadata.gz: 0ac4493d38cdcff16c2d5cb96873ba8356e80271
4
+ data.tar.gz: 8f77ffab827d962ec69aae1061d72978a65111ed
5
5
  SHA512:
6
- metadata.gz: 6ba98c71c6cd2ccfa8bb6800e20541e90d1e8c9d8da2a420b93a8b8ba5b91912228185fd4a9d6ae20e66ea0da98b62c24b1f24cb9d631fbae9de028742c9fbef
7
- data.tar.gz: 5d06d43f7367afc011bb3dce3c33c95cbbc7205238e08bdf2f494426e2c6fc90088c6854a55f8a49712bec79a54ed01aacb7358d42e1e0bb50ec5fc68d9b8126
6
+ metadata.gz: 0f146956037bfdbd37161ee9a631dc86827afa4af34470199beb2553b152cdeb95201994b088a2028ac89cb5d54e728ff70af4c794e1f9d7a1a903d3af9ab5a2
7
+ data.tar.gz: ef4a7e6e3435b0e3bfa4d9ba096f8f055ec40ffc865196f0923b04cbd9818a9047c62799fb0f505ae1d940269719c71446e0227c44d79f15285fef058770bed8
data/lib/twb.rb CHANGED
@@ -16,6 +16,7 @@
16
16
  require_relative 'twb/dashboard'
17
17
  require_relative 'twb/datasource'
18
18
  require_relative 'twb/docdashboard'
19
+ require_relative 'twb/dbfield'
19
20
  require_relative 'twb/localfield'
20
21
  require_relative 'twb/metadatafield'
21
22
  require_relative 'twb/storyboard'
@@ -35,14 +36,17 @@ require_relative 'twb/util/xraydashboards'
35
36
  require_relative 'twb/util/graphnode'
36
37
  require_relative 'twb/util/graphedge'
37
38
  require_relative 'twb/util/graphedges'
39
+ require_relative 'twb/analysis/documentedfieldsmarkdownemitter'
40
+ require_relative 'twb/analysis/annotatedfieldsCSVEmitter'
38
41
  require_relative 'twb/analysis/calculatedfields/calculatedfieldsanalyzer'
39
42
  require_relative 'twb/analysis/calculatedfields/markdownemitter'
40
43
  require_relative 'twb/analysis/calculatedfields/csvemitter'
44
+ require_relative 'twb/analysis/datasources/DataSourceFieldsCSVEmitter'
41
45
  require_relative 'twb/analysis/datasources/DataSourceTableFieldsCSVEmitter'
42
- require_relative 'twb/analysis/Sheets/WorksheetDataStructureCSVEmitter.rb'
46
+ require_relative 'twb/analysis/Sheets/WorksheetDataStructureCSVEmitter'
43
47
 
44
48
  # Represents Tableau Workbooks and their contents.
45
49
  #
46
50
  module Twb
47
- VERSION = '1.9.1'
51
+ VERSION = '2.2.1'
48
52
  end
@@ -0,0 +1,182 @@
1
+ # DocumentedFieldsCSVEmitter.rb - this Ruby script Copyright 2017 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
+ require 'csv'
18
+
19
+ module Twb
20
+ module Analysis
21
+
22
+ class AnnotatedFieldsCSVEmitter
23
+
24
+ attr_reader :csvFileName, :csvRecords
25
+ attr_reader :dsCount, :fieldsCount
26
+
27
+ @@csvHeader = ['Record #',
28
+ 'Workbook',
29
+ 'Workbook Dir',
30
+ 'Data Source',
31
+ 'Field',
32
+ 'Doc Type',
33
+ 'Doc Line #',
34
+ 'Doc Line'
35
+ ]
36
+ @@csvFileType = 'TwbAnnotatedFields'
37
+ @@csvFileName = @@csvFileType + '.csv'
38
+
39
+ def initialize
40
+ @csvFile = CSV.open(@@csvFileName,'w')
41
+ @csvFile << @@csvHeader
42
+ @csvRecords = Set.new
43
+ # --
44
+ @recNum = 0
45
+ @dsCount = 0
46
+ @fieldNum = 0
47
+ end
48
+
49
+ def self.csvHeader
50
+ @@csvHeader
51
+ end
52
+
53
+ def self.csvFileType
54
+ @@csvFileType
55
+ end
56
+
57
+ def self.csvFileNaame
58
+ @@csvFileName
59
+ end
60
+
61
+ def processTwb twb
62
+ @twb = nil
63
+ @twb = twb if twb.instance_of? Twb::Workbook
64
+ @twb = Twb::Workbook.new(twb) if twb.instance_of? String
65
+ raise ArgumentError.new("ERROR in Workbok processing: '#{twb}' must be a Workbook (class) or the name of a Workbook (String), is a #{twb.class} \n ") unless @twb.is_a? Twb::Workbook
66
+ # --
67
+ dss = @twb.datasources
68
+ dss.each do |ds|
69
+ @dsname = ds.uiname
70
+ # puts "\n -- #{ds.uiname} "
71
+ # tables = Set.new
72
+ fields = {}
73
+ @dsCount += 1
74
+ ds.columnFields.each do |field|
75
+ recordField field
76
+ end
77
+ end
78
+ end # def processTwb twb
79
+
80
+ def recordField field
81
+ @fieldNum += 1
82
+ @lineNum = 0
83
+ field.comment.each do |line|
84
+ # dispLine = if ''.eql?(line) the ? '' : line
85
+ @csvFile << [ @recNum+=1,
86
+ @twb.name,
87
+ @twb.dir,
88
+ @dsname,
89
+ field.uiname,
90
+ 'Comment',
91
+ @lineNum+=1,
92
+ # ''.eql?(line) ? " " : line
93
+ line
94
+ ]
95
+ end
96
+ unless field.calcField.nil?
97
+ @lineNum = 0
98
+ field.calcField.formulaResolvedLines.each do |line|
99
+ @csvFile << [ @recNum+=1,
100
+ @twb.name,
101
+ @twb.dir,
102
+ @dsname,
103
+ field.uiname,
104
+ 'Formula',
105
+ @lineNum+=1,
106
+ line
107
+ ]
108
+ end
109
+ end
110
+ end
111
+
112
+ # def recordField fields, field, props
113
+ # # puts "%-65s :: %s " % [fieldName,props]
114
+ # return if field.uiname.nil?
115
+ # if fields.has_key? field.uiname
116
+ # fields[field.uiname].merge! field.properties
117
+ # else
118
+ # fields[field.uiname] = field.properties
119
+ # end
120
+ # end
121
+
122
+ def emitFields fields
123
+ fields.each do |fieldName,props|
124
+ # puts "FIELD:: %-40s :: %s" % [fieldName,props.inspect]
125
+ # class = props[]
126
+ csvRec = [ @recNum+=1,
127
+ @twb.name,
128
+ @twb.dir,
129
+ @dsname,
130
+ fieldName,
131
+ props[:type],
132
+ props['hidden'],
133
+ props[:columnField],
134
+ props[:calculatedField],
135
+ props[:dbField],
136
+ props[:mappedField],
137
+ props[:metadataField]
138
+ ]
139
+ @csvFile << csvRec
140
+ @csvRecords.add csvRec
141
+ end
142
+ end
143
+
144
+ def recordTech field, type
145
+ @recNum+=1
146
+ field.properties.each do |name,value|
147
+ @csvFileTech << [ @recNum,
148
+ @twb.name,
149
+ @twb.dir,
150
+ @dsname,
151
+ field.uiname,
152
+ type,
153
+ name,
154
+ value
155
+ ]
156
+ end
157
+ end
158
+
159
+ def emitTech dataSource, fieldName, type, properties
160
+ # puts "XX #{dataSource.uiname} :: #{fieldName} #{} :: #{type} :: #{properties}"
161
+ @recNum+=1
162
+ properties.each do |name,value|
163
+ @csvFileTech << [ @recNum,
164
+ @twb.name,
165
+ @twb.dir,
166
+ dataSource.uiname,
167
+ fieldName,
168
+ type,
169
+ name,
170
+ value
171
+ ]
172
+ end
173
+ end
174
+
175
+ def cleanup
176
+ @csvFile.close unless @csvFile.nil?
177
+ end
178
+
179
+ end # class DocumentedFieldsCSVEmitter
180
+
181
+ end # module Analysis
182
+ end # module Twb
@@ -28,7 +28,7 @@ module CalculatedFields
28
28
  end
29
29
 
30
30
  def processTwb twb
31
- twb = File.basename(twb)
31
+ twb = File.basename(twb)
32
32
  @twb = Twb::Workbook.new twb
33
33
  @docFileName = twb + '.CalculatedFields.md'
34
34
  @docFile = File.open(@docFileName,'w')
@@ -46,6 +46,7 @@ module CalculatedFields
46
46
  calcFields.each do |fldname, field|
47
47
  calculation = field.calculation
48
48
  @docFile.puts "\n##### #{fldname} "
49
+ @docFile.puts "###### ...description..."
49
50
  @docFile.puts "```"
50
51
  if calculation.has_formula
51
52
  @docFile.puts calculation.formulaResolved
@@ -0,0 +1,250 @@
1
+ # calculatedfieldsanalyzer.rb - this Ruby script Copyright 2017 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
+ require 'csv'
18
+
19
+ module Twb
20
+ module Analysis
21
+ module DataSources
22
+
23
+ class DataSourceFieldsCSVEmitter
24
+
25
+ attr_reader :csvFileName, :csvRecords
26
+ attr_reader :dsCount, :fieldsCount
27
+
28
+ @@csvHeader = ['Record #',
29
+ 'Workbook',
30
+ 'Workbook Dir',
31
+ 'Data Source',
32
+ 'Field',
33
+ 'Twb Type',
34
+ 'Hidden', # props[:hidden],
35
+ 'Type - Column', # props[:columnField],
36
+ 'Type - Calculated', # props[:calculatedField],
37
+ 'Type - Db', # props[:dbField],
38
+ 'Type - Mapped', # props[:mappedField]
39
+ 'Type - MetaData', # props[:mappedField]
40
+ ]
41
+ @@csvFileType = 'TwbDataSourceFields'
42
+ @@csvFileName = @@csvFileType + '.csv'
43
+
44
+ @@tallHeader = ['Field #',
45
+ 'Workbook',
46
+ 'Workbook Dir',
47
+ 'Data Source',
48
+ 'Field',
49
+ 'Field Type',
50
+ 'Property - Name',
51
+ 'Property - Value'
52
+ ]
53
+ @@fullFileType = 'TwbDataSourceFieldsDetails'
54
+ @@fullFileName = @@fullFileType + '.csv'
55
+
56
+
57
+ @@fullHeader = ['Field #',
58
+ 'Workbook',
59
+ 'Workbook Dir',
60
+ 'Data Source',
61
+ 'Field',
62
+ 'Field - source',
63
+ 'Field - class',
64
+ 'Field - path',
65
+ 'Property - Name',
66
+ 'Property - Value'
67
+ ]
68
+ @@tallFileType = 'TwbDataSourceFieldsTech'
69
+ @@tallFileName = @@tallFileType + '.csv'
70
+
71
+ def initialize
72
+ @csvFile = CSV.open(@@csvFileName,'w')
73
+ @csvFile << @@csvHeader
74
+ @csvRecords = Set.new
75
+ puts "Opened: #{!@csvFile.nil?} - #{@@csvFileName}"
76
+ # --
77
+ @csvFileFull = CSV.open(@@fullFileName,'w')
78
+ @csvFileFull << @@fullHeader
79
+ puts "Opened: #{!@csvFileFull.nil?} - #{@@fullFileName} "
80
+ # --
81
+ @csvFileTech = CSV.open(@@tallFileName,'w')
82
+ @csvFileTech << @@tallHeader
83
+ puts "Opened: #{!@csvFileTech.nil?} - #{@@tallFileName}"
84
+ # --
85
+ @recNum = 0
86
+ @dsCount = 0
87
+ @fieldsCount = 0
88
+ end
89
+
90
+ def self.csvHeader
91
+ @@csvHeader
92
+ end
93
+
94
+ def self.csvFileType
95
+ @@csvFileType
96
+ end
97
+
98
+ def self.csvFileNaame
99
+ @@csvFileName
100
+ end
101
+
102
+ def processTwb twb
103
+ @twb = nil
104
+ @twb = twb if twb.instance_of? Twb::Workbook
105
+ @twb = Twb::Workbook.new(twb) if twb.instance_of? String
106
+ raise ArgumentError.new("ERROR in Workbok processing: '#{twb}' must be a Workbook (class) or the name of a Workbook (String), is a #{twb.class} \n ") unless @twb.is_a? Twb::Workbook
107
+ # --
108
+ dss = @twb.datasources
109
+ dss.each do |ds|
110
+ @dsname = ds.uiname
111
+ # puts "\n -- #{ds.uiname} "
112
+ # tables = Set.new
113
+ fields = {}
114
+ @dsCount += 1
115
+ fclasses = Set.new
116
+ ds.localFields.each do |field|
117
+ recordFieldFull field, :local
118
+ # recordField( fields, field, {:type=>:local,:columnField=>true,:hidden=>field.hidden} )
119
+ # emitTech( ds, field.uiname, 'Local', field.properties)
120
+ # recordTech( field, 'LocalA')
121
+ end
122
+ ds.columnFields.each do |field|
123
+ recordFieldFull field, :column
124
+ # recordField( fields, field, {:type=>'column',:columnField=>true,:hidden=>field.hidden} )
125
+ # emitTech( ds, field.uiname, 'Column', field.properties)
126
+ # recordTech( field, 'ColumnA')
127
+ end
128
+ ds.calculatedFields.each do |field|
129
+ recordFieldFull field, :calc
130
+ # puts "WWW #{field.class} :: #{field} ::prop:: #{field.properties.class} :: #{field.properties}"
131
+ # recordField( fields, field, {:type=>'calc',:calculatedField=>true,:hidden=>field.hidden} )
132
+ # emitTech( ds, field.uiname, 'Calculated', field.properties)
133
+ # recordTech( field, 'CalcA')
134
+ end
135
+ ds.metadataFields.each do |field|
136
+ recordFieldFull field, :metadata
137
+ # recordField( fields, field, {:type=>'metadata',:metadataField=>true} )
138
+ # emitTech( ds, field.uiname, 'MetaData', field.properties)
139
+ # recordTech( field, 'MetadataA')
140
+ end
141
+ ds.dbFields.each do |field|
142
+ recordFieldFull field, :db
143
+ # recordField( fields, field, {:type=>'database',:dbField=>true} )
144
+ # emitTech( ds, field.uiname, 'Db', field.properties)
145
+ # recordTech( field, 'DbA')
146
+ end
147
+ ds.mappedFields.each do |field|
148
+ recordFieldFull field, :mapped
149
+ # recordField( fields, field, {:type=>'mapped',:mappedField=>true} )
150
+ # emitTech( ds, field.uiname, 'Mapped', field.properties)
151
+ # recordTech( field, 'MappedA')
152
+ end
153
+ emitFields(fields)
154
+ end
155
+ end # def processTwb twb
156
+
157
+ def recordFieldFull field, source
158
+ # print field.properties.nil? ? '-' : ":#{field.properties.length}"
159
+ # puts field.properties
160
+ @recNum+=1
161
+ field.properties.each do |name,value|
162
+ # print name
163
+ @csvFileFull << [ @recNum,
164
+ @twb.name,
165
+ @twb.dir,
166
+ @dsname,
167
+ field.uiname,
168
+ source,
169
+ field.class,
170
+ field.node.path.to_s.gsub(/[0-9]/,'').gsub('[]',''),
171
+ name,
172
+ value
173
+ ]
174
+ # @csvFileFull << csvRec
175
+ end
176
+ end
177
+
178
+ def recordField fields, field, props
179
+ # puts "%-65s :: %s " % [fieldName,props]
180
+ return if field.uiname.nil?
181
+ if fields.has_key? field.uiname
182
+ fields[field.uiname].merge! field.properties
183
+ else
184
+ fields[field.uiname] = field.properties
185
+ end
186
+ end
187
+
188
+ def emitFields fields
189
+ fields.each do |fieldName,props|
190
+ # puts "FIELD:: %-40s :: %s" % [fieldName,props.inspect]
191
+ # class = props[]
192
+ csvRec = [ @recNum+=1,
193
+ @twb.name,
194
+ @twb.dir,
195
+ @dsname,
196
+ fieldName,
197
+ props[:type],
198
+ props['hidden'],
199
+ props[:columnField],
200
+ props[:calculatedField],
201
+ props[:dbField],
202
+ props[:mappedField],
203
+ props[:metadataField]
204
+ ]
205
+ @csvFile << csvRec
206
+ @csvRecords.add csvRec
207
+ end
208
+ end
209
+
210
+ def recordTech field, type
211
+ @recNum+=1
212
+ field.properties.each do |name,value|
213
+ @csvFileTech << [ @recNum,
214
+ @twb.name,
215
+ @twb.dir,
216
+ @dsname,
217
+ field.uiname,
218
+ type,
219
+ name,
220
+ value
221
+ ]
222
+ end
223
+ end
224
+
225
+ def emitTech dataSource, fieldName, type, properties
226
+ # puts "XX #{dataSource.uiname} :: #{fieldName} #{} :: #{type} :: #{properties}"
227
+ @recNum+=1
228
+ properties.each do |name,value|
229
+ @csvFileTech << [ @recNum,
230
+ @twb.name,
231
+ @twb.dir,
232
+ dataSource.uiname,
233
+ fieldName,
234
+ type,
235
+ name,
236
+ value
237
+ ]
238
+ end
239
+ end
240
+
241
+ def cleanup
242
+ @csvFile.close unless @csvFile.nil?
243
+ end
244
+
245
+ end # class DataSourceFieldsCSVEmitter
246
+
247
+
248
+ end # module DataSources
249
+ end # module Analysis
250
+ end # module Twb