twb 0.5.3 → 1.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.
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: []