twb 0.5.3 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/twb/workbook.rb CHANGED
@@ -19,14 +19,18 @@ require 'zip'
19
19
  module Twb
20
20
 
21
21
 
22
- # Represents Tableau Workbooks and their parts.
22
+ # A Tableau Workbook and its parts.
23
23
  #
24
24
  class Workbook
25
25
 
26
- attr_reader :workbooknode, :name, :dir, :modtime, :version, :build
27
- attr_reader :datasources, :dashboards, :storyboards, :worksheets, :valid, :ndoc
26
+ attr_reader :workbooknode
27
+ attr_reader :name, :dir
28
+ attr_reader :modtime, :version, :build
29
+ attr_reader :datasources, :datasourceNames, :datasourceUINames
30
+ attr_reader :dashboards, :storyboards, :worksheets, :actions
31
+ attr_reader :valid, :ndoc
28
32
 
29
- # Creates a Workbook, from its file name.
33
+ # Creates a Workbook from its file name.
30
34
  #
31
35
  # == Parameters:
32
36
  # twbWithDir
@@ -67,17 +71,29 @@ module Twb
67
71
  loadDashboards
68
72
  loadStoryboards
69
73
  loadWindows
74
+ loadActions
70
75
  @valid = true
71
76
  end
72
77
 
73
78
  def loaddatasources
74
- @dataSourcesNode = @ndoc.at_xpath('//workbook/datasources')
75
- @datasources = {}
76
- @datasourceNodes = @ndoc.xpath('//workbook/datasources/datasource').to_a
77
- @datasourceNodes.each do |node|
79
+ # puts "LOAD DATA SOURCES"
80
+ # @dataSourcesNode = @ndoc.at_xpath('//workbook/datasources')
81
+ @datasources = Set.new
82
+ @datasourceNames = Set.new
83
+ @datasourceUINames = Set.new
84
+ @dataSourceNamesMap = {}
85
+ datasourceNodes = @ndoc.xpath('//workbook/datasources/datasource')
86
+ # puts "DATASOURCENODES : #{@datasourceNodes.length}"
87
+ datasourceNodes.each do |node|
78
88
  datasource = Twb::DataSource.new(node)
79
- @datasources[datasource.name] = datasource
89
+ @datasources << datasource
90
+ @datasourceNames << datasource.name
91
+ @datasourceNames << datasource.uiname
92
+ @datasourceUINames << datasource.uiname
93
+ @dataSourceNamesMap[datasource.name] = datasource
94
+ @dataSourceNamesMap[datasource.uiname] = datasource
80
95
  end
96
+ # puts "DATASOURCES : #{@datasources.length}"
81
97
  end
82
98
 
83
99
  def loadWorksheets
@@ -92,7 +108,7 @@ module Twb
92
108
  def loadDashboards
93
109
  @dashesNode = @ndoc.at_xpath('//workbook/dashboards')
94
110
  @dashboards = {}
95
- dashes = @ndoc.xpath('//workbook/dashboards/dashboard' ).to_a
111
+ dashes = @ndoc.xpath('//workbook/dashboards/dashboard').to_a
96
112
  dashes.each do |node|
97
113
  unless node.attr('type') == 'storyboard' then
98
114
  dashboard = Twb::Dashboard.new(node, @worksheets)
@@ -120,10 +136,28 @@ module Twb
120
136
  end
121
137
  end
122
138
 
123
- def datasources
124
- @datasources.values
139
+ def loadActions
140
+ @actions = {}
141
+ actionNodes = @ndoc.xpath("//workbook/actions/action")
142
+ actionNodes.each do |anode|
143
+ action = Twb::Action.new(anode, @workbooknode)
144
+ @actions[action.uiname] = action
145
+ end
146
+ end
147
+
148
+ def actions
149
+ @actions.values
150
+ end
151
+
152
+ def actionNames
153
+ @actions.keys
125
154
  end
126
155
 
156
+ # def datasources
157
+ # # puts "ACCESSING DATASOURCES - #{@datasources.class} - #{@datasources.length} - #{@datasources.values.length}"
158
+ # return @datasources.values
159
+ # end
160
+
127
161
  def dashboards
128
162
  @dashboards.values
129
163
  end
@@ -132,6 +166,10 @@ module Twb
132
166
  @dashboards.keys
133
167
  end
134
168
 
169
+ def dashboard name
170
+ @dashboards[name]
171
+ end
172
+
135
173
  def storyboards
136
174
  @storyboards.values
137
175
  end
@@ -140,20 +178,6 @@ module Twb
140
178
  @worksheets.values
141
179
  end
142
180
 
143
- def datasourceNames
144
- @datasources.keys
145
- end
146
-
147
- def datasourceUINames
148
- uiNames = []
149
- @datasources.values.each {|ds| uiNames << ds.uiname}
150
- return uiNames
151
- end
152
-
153
- def dashboardNames
154
- @dashboards.keys
155
- end
156
-
157
181
  def storyboardNames
158
182
  @storyboards.keys
159
183
  end
@@ -163,11 +187,7 @@ module Twb
163
187
  end
164
188
 
165
189
  def datasource name
166
- @datasources[name]
167
- end
168
-
169
- def dashboard name
170
- @dashboards[name]
190
+ @dataSourceNamesMap[name]
171
191
  end
172
192
 
173
193
  def storyboard name
@@ -178,15 +198,6 @@ module Twb
178
198
  @worksheets[name]
179
199
  end
180
200
 
181
- # Make sure that the TWB has a <dashboards> node.
182
- # It's possible for a TWB to have no dashboards, and therefore no <dashboards> node.
183
- def ensureDashboardsNodeExists
184
- if @dashesNode.nil?
185
- @dashesNode = Nokogiri::XML::Node.new "dashboards", @ndoc
186
- # TODO fix this @dataSourcesNode.add_next_sibling(@dashesNode)
187
- end
188
- end
189
-
190
201
  def ensureWindowsNodeExists
191
202
  if @windowsnode.nil?
192
203
  @windowsnode = Nokogiri::XML::Node.new "windows", @ndoc
@@ -207,6 +218,15 @@ module Twb
207
218
  @windowsnode.add_child(docDashboard.winnode)
208
219
  end
209
220
 
221
+ # Make sure that the TWB has a <dashboards> node.
222
+ # It's possible for a TWB to have no dashboards, and therefore no <dashboards> node.
223
+ def ensureDashboardsNodeExists
224
+ if @dashesNode.nil?
225
+ @dashesNode = Nokogiri::XML::Node.new "dashboards", @ndoc
226
+ # TODO fix this @dataSourcesNode.add_next_sibling(@dashesNode)
227
+ end
228
+ end
229
+
210
230
  def getNewDashboardTitle(t)
211
231
  title = t
212
232
  if @datasources.include?(title)
data/lib/twb/worksheet.rb CHANGED
@@ -32,12 +32,14 @@ module Twb
32
32
 
33
33
  @@hasher = Digest::SHA256.new
34
34
 
35
- attr_reader :node, :name, :datasourcenames, :datasources
35
+ attr_reader :node, :name, :datasourcenames, :datasources
36
+ attr_reader :fields, :rowFields, :colFields, :datasourceFields
36
37
 
37
38
  def initialize sheetNode
38
39
  @node = sheetNode
39
40
  @name = @node.attr('name')
40
41
  loadDataSourceNames
42
+ loadFields
41
43
  return self
42
44
  end
43
45
 
@@ -58,6 +60,72 @@ module Twb
58
60
  @datasources[name]
59
61
  end
60
62
 
63
+ def datasourceFields
64
+ @datasourceFields.nil? ? loadFields : @datasourceFields
65
+ end
66
+
67
+ def fields
68
+ @fields.nil? ? loadFields : @fields
69
+ end
70
+
71
+ def loadFields
72
+ # puts "WORKSHEET loadFields"
73
+ @datasourceFields = {}
74
+ dsNodes = @node.xpath('.//datasource-dependencies')
75
+ dsNodes.each do |dsn|
76
+ dsName = dsn.attribute('datasource').text
77
+ dsfs = @datasourceFields[dsName] = []
78
+ fieldNodes = dsn.xpath('./column')
79
+ fieldNodes.each do |fn|
80
+ fname = fn.attribute('name')
81
+ dsfs.push fname.text.gsub(/^\[/,'').gsub(/\]$/,'') unless fname.nil?
82
+ end
83
+ end
84
+ # <rows>([DATA Connection (copy 2)].[none:JIRA HARVEST Correspondence Name:nk] / [DATA Connection (copy 2)].[none:CreatedDate (Issue) (DAY):ok])</rows>
85
+ # <cols>[DATA Connection (copy 2)].[:Measure Names]</cols>
86
+ @fields = {}
87
+ @rowFields = pullRowColFields './/rows' # returns map of data source => (Set of) field names
88
+ @fields[:rows] = @rowFields
89
+ @colFields = pullRowColFields './/cols' # returns map of data source => (Set of) field names
90
+ @fields[:cols] = @colFields
91
+ end
92
+
93
+ def addDSFields fields, usage
94
+ fields.each do
95
+ end
96
+ end
97
+
98
+ def pullRowColFields xpath
99
+ dsFields = {} # data source => (Set of) fields by names
100
+ node = @node.xpath(xpath) # expect only one each of <rows> & <cols> node per <worksheet node
101
+ code = node.text
102
+ # puts "\n CODE: '#{code}'"
103
+ return dsFields if code.nil?
104
+ codeFields = code.gsub(/^[(]|[)]$/,'').split(/] [\/+*] [(]?\[/)
105
+ return dsFields if codeFields.nil? # - commented out, left here for logic clarity
106
+ codeFields.each do |dsf|
107
+ parts = dsf.split('].[')
108
+ if parts.length == 2
109
+ ds = parts[0].gsub(/^\[|\]$/,'')
110
+
111
+ # remove prefix(es), if any
112
+ f1 = parts[1].gsub(/^pcto:|^fVal:/,'').gsub(/^[a-z]+:/,'')
113
+ # /^pcto:|^fVal:/ - special handling based upon actual codings
114
+
115
+ # remove terminating )s
116
+ f2 = f1.gsub(/[\)]+$/,'')
117
+
118
+ # remove suffix(es), if any
119
+ f3 = f2.gsub(/:[0-9]+[\]]?$/,'').gsub(/:[a-z]+[\]]?$|[\]]?$/,'')
120
+ # /:[0-9]+[\]]?$/ - special handling based upon actual codings
121
+
122
+ dsFields[ds] = Set.new unless dsFields.include? ds
123
+ dsFields[ds].add(f3)
124
+ end
125
+ end
126
+ return dsFields
127
+ end
128
+
61
129
  def datasourcenames
62
130
  @datasources.keys
63
131
  end
data/lib/twb.rb CHANGED
@@ -23,15 +23,20 @@ require_relative 'twb/storyboard'
23
23
  require_relative 'twb/window'
24
24
  require_relative 'twb/workbook'
25
25
  require_relative 'twb/worksheet'
26
+ require_relative 'twb/action'
27
+ require_relative 'twb/fieldcalculation'
26
28
  require_relative 'twb/docdashboardimagevert.rb'
27
29
  require_relative 'twb/docdashboardwebvert.rb'
28
30
  require_relative 'twb/util/twbDashSheetDataDotBuilder'
29
31
  require_relative 'twb/util/dotFileRenderer'
30
32
  require_relative 'twb/util/htmllistcollapsible'
31
33
  require_relative 'twb/util/xraydashboards'
34
+ require_relative 'twb/util/graphnode'
35
+ require_relative 'twb/util/graphedge'
36
+ require_relative 'twb/util/graphedges'
32
37
 
33
38
  # Represents Tableau Workbooks and their contents.
34
39
  #
35
40
  module Twb
36
- VERSION = '0.5.3'
41
+ VERSION = '1.0'
37
42
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
5
- prerelease:
4
+ version: '1.0'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Chris Gerrard
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-06-17 00:00:00.000000000 Z
11
+ date: 2016-08-31 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: A sollection of Ruby classes designed for accessing and recording information
15
14
  about, and for manipulating, Tableau Workbooks and their contents.
@@ -18,33 +17,47 @@ executables: []
18
17
  extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
20
+ - LICENSE.md
21
+ - LICENSE.txt
22
+ - README.md
21
23
  - bin/twb.rb
24
+ - lib/twb.rb
25
+ - lib/twb/TwbTest.rb
26
+ - lib/twb/action.rb
22
27
  - lib/twb/apps/X-Ray Dashboards.rb
28
+ - lib/twb/countNodes.rb
23
29
  - lib/twb/dashboard.rb
30
+ - lib/twb/dashboard.txt
24
31
  - lib/twb/datasource.rb
25
32
  - lib/twb/docdashboard.rb
26
33
  - lib/twb/docdashboardimagevert.rb
27
34
  - lib/twb/docdashboardwebvert.rb
28
35
  - lib/twb/field.rb
29
36
  - lib/twb/fieldcalculation.rb
37
+ - lib/twb/findDSFields.rb
38
+ - lib/twb/graph.rb
39
+ - lib/twb/graphedges.rb
40
+ - lib/twb/graphnode.rb
30
41
  - lib/twb/hashtohtml.rb
31
42
  - lib/twb/htmllistcollapsible.rb
43
+ - lib/twb/identifyFields.rb
32
44
  - lib/twb/localfield.rb
33
45
  - lib/twb/metadatafield.rb
34
46
  - lib/twb/storyboard.rb
35
47
  - lib/twb/there.rb
36
- - lib/twb/TwbTest.rb
37
48
  - lib/twb/util/dotFileRenderer.rb
49
+ - lib/twb/util/graphedge.rb
50
+ - lib/twb/util/graphedges.rb
51
+ - lib/twb/util/graphnode.rb
38
52
  - lib/twb/util/hashtohtml.rb
39
53
  - lib/twb/util/htmllistcollapsible.rb
40
- - lib/twb/util/twbDashesSheetDataDotBuilder.rb
41
54
  - lib/twb/util/twbDashSheetDataDotBuilder.rb
42
55
  - lib/twb/util/twbDashSheetDataDotRenderer.rb
56
+ - lib/twb/util/twbDashesSheetDataDotBuilder.rb
43
57
  - lib/twb/util/xraydashboards.rb
44
58
  - lib/twb/window.rb
45
59
  - lib/twb/workbook.rb
46
60
  - lib/twb/worksheet.rb
47
- - lib/twb.rb
48
61
  - test/testDashboardXRay.rb
49
62
  - test/testDocDashboard.rb
50
63
  - test/testDocDashboardCreate.rb
@@ -56,33 +69,28 @@ files:
56
69
  - test/testTwbDashSheetDataDotBuilder.rb
57
70
  - test/testTwbGem.rb
58
71
  - test/testTwbWrite.rb
59
- - LICENSE.md
60
- - README.md
61
- - lib/twb/dashboard.txt
62
- - LICENSE.txt
63
72
  homepage: http://rubygems.org/gems/twb
64
73
  licenses:
65
- - GNU General Public License v3.0
74
+ - GPL-3.0
75
+ metadata: {}
66
76
  post_install_message:
67
77
  rdoc_options: []
68
78
  require_paths:
69
79
  - lib
70
80
  required_ruby_version: !ruby/object:Gem::Requirement
71
- none: false
72
81
  requirements:
73
- - - ! '>='
82
+ - - ">="
74
83
  - !ruby/object:Gem::Version
75
84
  version: '0'
76
85
  required_rubygems_version: !ruby/object:Gem::Requirement
77
- none: false
78
86
  requirements:
79
- - - ! '>='
87
+ - - ">="
80
88
  - !ruby/object:Gem::Version
81
89
  version: '0'
82
90
  requirements: []
83
91
  rubyforge_project:
84
- rubygems_version: 1.8.16
92
+ rubygems_version: 2.6.11
85
93
  signing_key:
86
- specification_version: 3
94
+ specification_version: 4
87
95
  summary: Classes for accessing Tableau Workbooks and their contents.
88
96
  test_files: []