twb 0.0.24 → 0.0.25
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +12 -0
- data/lib/twb/dashboard.rb +48 -0
- data/lib/twb/dashboard.txt +57 -0
- data/lib/twb/datasource.rb +1 -7
- data/lib/twb/workbook.rb +30 -1
- data/lib/twb/worksheet.rb +36 -0
- data/testTwbGem.rb +7 -12
- data/twb-0.0.24.gem +0 -0
- data/twb.gemspec +1 -1
- metadata +6 -1
data/README.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
A number of Ruby scripts that parse Workbooks and emit a variety of their contents/properties have been published at Tableau Friction, including a couple that identify Calculated fields and the fields they reference:
|
2
|
+
http://tableaufriction.blogspot.ca/2015/02/more-calculated-field-analysis-fields.html
|
3
|
+
http://tableaufriction.blogspot.ca/2014/09/do-you-know-what-your-calculated-fields.html
|
4
|
+
|
5
|
+
Other scripts find and record other useful information, others yet enable Workbook management, e.g. unhiding worksheets and making field comments consistent across workbook. One of them produces HTML pages with dynamic dashboard wire frames, making it easy to see what's in the dashboards and their properties
|
6
|
+
|
7
|
+
There's also TWIS - the Tableau Workbook Inventory System, an app that extracts into CSV files most of the important Workbook elements, allowing one to see things such as which sheets are in which with dashboards, the data sources they connect to, and which Workbooks they're in. TWIS also generates diagrams/maps of the Workbook - Dashboard - Worksheet - Data Source relationships, one for each Workbook in PDF, PNG, and SVG.
|
8
|
+
TWIS is described and available here: http://betterbi.biz/TWIS.html
|
9
|
+
|
10
|
+
I created TWIS in Java and am working to re-implement its functionality in Ruby with the intention of releasing it as a open source project. The initial Ruby Gem - "twb" - is already available on http://rubygems.org - and can be downloaded and used via "gem install twb". At this point it only represents Workbooks and Data Sources, but I'll be extending it pretty regularly and posting updates to Tableau Friction. Anyone who's interested can comment here or there.
|
11
|
+
|
12
|
+
The basic philosophy I'm following is that Tableau Workbook governance should be simple and straightforward in the way that basic data analysis is simple and straightforward in Tableau, and that the tools for it should be free, as in beer and speech, and constantly evolving to incorporate new and interesting things people can think of to see about do with their Workbooks.
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (C) 2014, 2015 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 'nokogiri'
|
17
|
+
require 'digest/md5'
|
18
|
+
|
19
|
+
module Twb
|
20
|
+
|
21
|
+
class Dashboard
|
22
|
+
|
23
|
+
@@hasher = Digest::SHA256.new
|
24
|
+
|
25
|
+
attr_reader :node, :name, :sheets
|
26
|
+
|
27
|
+
def initialize dashboardNode
|
28
|
+
puts "Dashboard initialize"
|
29
|
+
@node = dashboardNode
|
30
|
+
@name = @node.attr('name').text
|
31
|
+
loadSheets
|
32
|
+
return self
|
33
|
+
end
|
34
|
+
|
35
|
+
def loadSheets
|
36
|
+
puts "$$$ in loadSheets"
|
37
|
+
@sheets = []
|
38
|
+
@ndoc.xpath('.//zone[@name]').to_a.each do |sheetNode|
|
39
|
+
sheet = Twb::Worksheet.new sheetNode
|
40
|
+
puts "### :: #{sheet.nil?} :: '#{sheet}'"
|
41
|
+
@dashboards.push sheet unless sheet.name == '' || sheet.name.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright (C) 2014, 2015 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 'nokogiri'
|
17
|
+
require 'digest/md5'
|
18
|
+
|
19
|
+
module Twb
|
20
|
+
|
21
|
+
class Dashboard
|
22
|
+
|
23
|
+
@@hasher = Digest::SHA256.new
|
24
|
+
|
25
|
+
attr_reader :node, :name, :caption, :uiname, :connHash, :class, :connection
|
26
|
+
|
27
|
+
def initialize dataSourceNode
|
28
|
+
@node = dataSourceNode
|
29
|
+
@name = @node.xpath('./@name').text
|
30
|
+
@caption = @node.xpath('./@caption').text
|
31
|
+
@uiname = if @caption.nil? || @caption == '' then @name else @caption end
|
32
|
+
processConnection
|
33
|
+
return self
|
34
|
+
end
|
35
|
+
|
36
|
+
def processConnection
|
37
|
+
@connHash = ''
|
38
|
+
@connection = @node.at_xpath('./connection')
|
39
|
+
if !@connection.nil? then
|
40
|
+
@class = @connection.attribute('class').text
|
41
|
+
dsAttributes = @node.xpath('./connection/@*')
|
42
|
+
dsConnStr = ''
|
43
|
+
dsAttributes.each do |attr|
|
44
|
+
dsConnStr += attr.text
|
45
|
+
# Note: '' attributes with value '' don't contribute to the hash
|
46
|
+
end
|
47
|
+
@connHash = Digest::MD5.hexdigest(dsConnStr)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def Parameters?
|
52
|
+
@name == 'Parameters'
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/twb/datasource.rb
CHANGED
@@ -29,12 +29,6 @@ module Twb
|
|
29
29
|
@name = @node.xpath('./@name').text
|
30
30
|
@caption = @node.xpath('./@caption').text
|
31
31
|
@uiname = if @caption.nil? || @caption == '' then @name else @caption end
|
32
|
-
# puts "DS: n:#{@name}"
|
33
|
-
# puts " caption:#{@caption}"
|
34
|
-
# puts " c.len :#{@caption.length}"
|
35
|
-
# puts " c.nil?:#{@caption.nil?}"
|
36
|
-
# puts " uiname:#{@uiname}"
|
37
|
-
# puts " "
|
38
32
|
processConnection
|
39
33
|
return self
|
40
34
|
end
|
@@ -48,7 +42,7 @@ module Twb
|
|
48
42
|
dsConnStr = ''
|
49
43
|
dsAttributes.each do |attr|
|
50
44
|
dsConnStr += attr.text
|
51
|
-
# Note:
|
45
|
+
# Note: '' attributes with value '' don't contribute to the hash
|
52
46
|
end
|
53
47
|
@connHash = Digest::MD5.hexdigest(dsConnStr)
|
54
48
|
end
|
data/lib/twb/workbook.rb
CHANGED
@@ -19,7 +19,7 @@ module Twb
|
|
19
19
|
|
20
20
|
class Workbook
|
21
21
|
|
22
|
-
attr_reader :name, :dir, :modtime, :version, :build, :ndoc
|
22
|
+
attr_reader :name, :dir, :modtime, :version, :build, :ndoc, :dataSources, :dashboards
|
23
23
|
|
24
24
|
def initialize twbWithDir
|
25
25
|
file = File.new(twbWithDir)
|
@@ -29,9 +29,25 @@ module Twb
|
|
29
29
|
@ndoc = Nokogiri::XML(open(twbWithDir))
|
30
30
|
@version = @ndoc.xpath('/workbook/@version')
|
31
31
|
@build = @ndoc.xpath('/workbook/comment()').text.gsub(/^[^0-9]+/,'').strip
|
32
|
+
loadDataSources
|
32
33
|
return self
|
33
34
|
end
|
34
35
|
|
36
|
+
def loadDataSources
|
37
|
+
@dataSources = []
|
38
|
+
@dataSourceNodes = @ndoc.xpath('//workbook/datasources/datasource').to_a
|
39
|
+
@dataSourceNodes.each do |dsn|
|
40
|
+
@dataSources.push Twb::DataSource.new(dsn)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def loadDashboards
|
45
|
+
@dashboards = []
|
46
|
+
@ndoc.xpath('//workbook/dashboards/dashboard').to_a.each do |dshn|
|
47
|
+
@dashboards.push Twb::Dashboard.new(dshn)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
35
51
|
def dataSourceNodes
|
36
52
|
@ndoc.xpath('//workbook/datasources/datasource').to_a
|
37
53
|
end
|
@@ -44,6 +60,19 @@ module Twb
|
|
44
60
|
return sources
|
45
61
|
end
|
46
62
|
|
63
|
+
def dashboardNodes
|
64
|
+
@ndoc.xpath('//workbook/datasources/datasource').to_a
|
65
|
+
end
|
66
|
+
|
67
|
+
def dashboards
|
68
|
+
sources = []
|
69
|
+
dataSourceNodes.each do |dsn|
|
70
|
+
puts "adding dashboard"
|
71
|
+
sources.push Twb::Dashboard.new(dsn)
|
72
|
+
end
|
73
|
+
return sources
|
74
|
+
end
|
75
|
+
|
47
76
|
end
|
48
77
|
|
49
78
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (C) 2014, 2015 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 'nokogiri'
|
17
|
+
require 'digest/md5'
|
18
|
+
|
19
|
+
module Twb
|
20
|
+
|
21
|
+
class Worksheet
|
22
|
+
|
23
|
+
@@hasher = Digest::SHA256.new
|
24
|
+
|
25
|
+
attr_reader :node, :name
|
26
|
+
|
27
|
+
def initialize sheetNode
|
28
|
+
puts "Worksheet initialize"
|
29
|
+
@node = sheetNode
|
30
|
+
@name = @node.attr('name').text
|
31
|
+
return self
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/testTwbGem.rb
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'nokogiri'
|
4
4
|
require 'open-uri'
|
5
|
-
require 'twb'
|
6
5
|
|
6
|
+
#require 'twb'
|
7
|
+
require 'C:\tech\Tableau\tools\Ruby\gems\twb\lib\twb.rb'
|
7
8
|
|
8
9
|
def processTWB twbWithDir
|
9
10
|
twb = Twb::Workbook.new twbWithDir
|
@@ -11,18 +12,12 @@ def processTWB twbWithDir
|
|
11
12
|
doc = twb.ndoc
|
12
13
|
puts " Data Sources"
|
13
14
|
twb.dataSources.each do |ds|
|
14
|
-
puts "
|
15
|
+
puts "\n\t n\t-#{ds.name}\n\t :: c\t-#{ds.caption}\n\t :: uin\t-#{ds.uiname} \n\t :: ch\t-#{ds.connHash}\n\t :: prms?\t-#{ds.Parameters?} "
|
16
|
+
end
|
17
|
+
puts "\n Dashboards ...."
|
18
|
+
twb.dashboards.each do |dsh|
|
19
|
+
puts "\t n\t-#{dsh.name} "
|
15
20
|
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def getConnectionHash dataSource
|
19
|
-
dsAttributes = dataSource.xpath('./connection/@*')
|
20
|
-
dsConnStr = ''
|
21
|
-
dsAttributes.each do |attr|
|
22
|
-
dsConnStr += attr.text
|
23
|
-
# Note: only collects non-'' attribute values
|
24
|
-
end
|
25
|
-
dsConnStr.hash
|
26
21
|
end
|
27
22
|
|
28
23
|
def getName techName
|
data/twb-0.0.24.gem
ADDED
Binary file
|
data/twb.gemspec
CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'twb'
|
3
3
|
s.summary = "Classes for accessing Tableau Workbooks and their contents - summary."
|
4
4
|
s.description = "Classes for accessing Tableau Workbooks and their contents - description"
|
5
|
-
s.version = '0.0.
|
5
|
+
s.version = '0.0.25'
|
6
6
|
s.date = "2015-03-14"
|
7
7
|
s.author = "Chris Gerrard"
|
8
8
|
s.email = "Chris@Gerrard.net"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.25
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -19,18 +19,23 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- bin/twb.cmd
|
21
21
|
- bin/twb.rb
|
22
|
+
- lib/twb/dashboard.rb
|
23
|
+
- lib/twb/dashboard.txt
|
22
24
|
- lib/twb/datasource.rb
|
23
25
|
- lib/twb/there.rb
|
24
26
|
- lib/twb/TwbTest.rb
|
25
27
|
- lib/twb/workbook.rb
|
28
|
+
- lib/twb/worksheet.rb
|
26
29
|
- lib/twb.rb
|
27
30
|
- LICENSE.txt
|
31
|
+
- README.txt
|
28
32
|
- testTwbGem.rb
|
29
33
|
- twb-0.0.1.gem
|
30
34
|
- twb-0.0.2.gem
|
31
35
|
- twb-0.0.21.gem
|
32
36
|
- twb-0.0.22.gem
|
33
37
|
- twb-0.0.23.gem
|
38
|
+
- twb-0.0.24.gem
|
34
39
|
- twb.gemspec
|
35
40
|
homepage: http://rubygems.org/gems/twb
|
36
41
|
licenses:
|