tableau_server_client 0.0.17 → 0.2.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: 002d3eb5a6e6a504c3eba7abf7910f161d5ae5ddbd1253978444a251117084bd
4
- data.tar.gz: a50e3f36b5538a27d7c3026d8947ed55b032b89129919e55224f76e8d977ad4e
3
+ metadata.gz: b1558ccb1a6e4e24c51290e44d1731769cbd4097ba15f7234b109182ad9104e8
4
+ data.tar.gz: 7d64b81492f87d2f180cf7ca0e744dda911af13b9aa3e7646a7f8ccbf9c51b2a
5
5
  SHA512:
6
- metadata.gz: 7d1a387be9b4e864c3eb01dde59d7b589240e2eccfab1debe1c50e2b1409126655a1e1cdac9df270cb9551a3fb07aec32466871d312af039093cbbc1b952098c
7
- data.tar.gz: f163b5763430fc45882e26c0bca32f203a73b51525ce23a8575089f2ab8c06febfe5190993759ca8544b9da2f4b82fc425814c3c8680ac0e2a565ce5acad3da8
6
+ metadata.gz: 47b55e561f1b3a4d4d793c902fe4ed68812371abc8d0a787db0601d49875b788ca46ac352e53852d7a7a6ed9807e8c84ffdee5c82c0d32f3371bc27ae7e2e9de
7
+ data.tar.gz: a975ceace9239d04b36eb5c392b34ae1a8b6df969f1c564b58feb9d5a500ae83691aa09fc88d6813552f3c5bc4447c08a261d8a2fcedb78b1b197765362a97e7
@@ -14,17 +14,18 @@ module TableauServerClient
14
14
  class Client
15
15
  include RequestBuilder
16
16
 
17
- def initialize(server_url, username, password, site_name, api_version, token_lifetime, logger)
17
+ def initialize(server_url, username, password, content_url, api_version, token_lifetime, logger, impersonation_user_id)
18
18
  @server_url = server_url
19
19
  @username = username
20
20
  @password = password
21
- @site_name = site_name
21
+ @content_url = content_url
22
22
  @api_version = api_version
23
23
  @token_lifetime = token_lifetime
24
24
  @logger = logger
25
+ @impersonation_user_id = impersonation_user_id
25
26
  end
26
27
 
27
- attr_reader :site_name, :username, :api_version, :token_lifetime, :logger
28
+ attr_reader :content_url, :username, :api_version, :token_lifetime, :logger, :impersonation_user_id
28
29
 
29
30
  def server_url
30
31
  @_server_url ||= URI(@server_url.chomp("/"))
@@ -65,15 +66,27 @@ module TableauServerClient
65
66
  return response
66
67
  end
67
68
 
68
- def update(resource)
69
+ def download_image(resource_location, file_path: nil)
70
+ req_url = request_url("#{resource_location.path}/image", resource_location.query_params)
71
+ response = session.get req_url.to_s
72
+ if file_path
73
+ File.write(file_path, response.body)
74
+ end
75
+ return response.body
76
+ end
77
+
78
+ def update(resource, path: nil, request: nil)
79
+ path = path || resource.path
80
+ request = request || resource.to_request
69
81
  session.put do |req|
70
- req.url request_url(resource.path).to_s
71
- req.body = resource.to_request
82
+ req.url request_url(path).to_s
83
+ req.body = request
72
84
  end
73
85
  end
74
86
 
75
- def delete(resource)
76
- session.delete request_url(resource.path).to_s
87
+ def delete(resource, path: nil)
88
+ path = path || resource.path
89
+ session.delete request_url(path).to_s
77
90
  end
78
91
 
79
92
  def session
@@ -104,6 +117,7 @@ module TableauServerClient
104
117
  request = request_body {|b|
105
118
  b.credentials(name: username, password: password) {
106
119
  b.site(contentUrl: content_url)
120
+ b.user(id: impersonation_user_id) if impersonation_user_id
107
121
  }
108
122
  }
109
123
  # POST without Token
@@ -114,10 +128,6 @@ module TableauServerClient
114
128
  @token = TableauServerClient::Token.parse(res.body, token_lifetime)
115
129
  end
116
130
 
117
- def content_url
118
- site_name == 'default' ? "" : site_name
119
- end
120
-
121
131
  def faraday
122
132
  @faraday ||= Faraday.new(request: {params_encoder: EmptyEncoder.new}, headers: {'Content-Type' => 'application/xml'}) do |f|
123
133
  f.response :raise_error
@@ -0,0 +1,5 @@
1
+ module TableauServerClient
2
+
3
+ class TableauServerClientError < StandardError; end
4
+
5
+ end
@@ -9,7 +9,7 @@ module TableauServerClient
9
9
  class Datasource < Resource
10
10
  include Downloadable
11
11
 
12
- attr_reader :id, :name, :content_url, :type, :created_at, :updated_at, :is_certified
12
+ attr_reader :id, :name, :webpage_url, :content_url, :type, :created_at, :updated_at, :is_certified
13
13
  attr_writer :owner
14
14
 
15
15
  def self.from_response(client, path, xml)
@@ -41,7 +41,15 @@ module TableauServerClient
41
41
  end
42
42
 
43
43
  def schedule
44
- @client.get_collection(Resources::Schedule.location(nil)).first {|s| s.id == schedule_id }
44
+ @client.get_collection(Resources::Schedule.location(nil)).find {|s| s.id == schedule_id }
45
+ end
46
+
47
+ def workbook
48
+ @client.get_collection(Workbook.location(site_path)).find {|w| w.id == workbook_id }
49
+ end
50
+
51
+ def datasource
52
+ @client.get_collection(Datasource.location(site_path)).find {|d| d.id == datasource_id }
45
53
  end
46
54
 
47
55
  def run_now
@@ -50,6 +58,10 @@ module TableauServerClient
50
58
  Job.from_response(@client, Job.location(site_path, id = job_id).path, resp)
51
59
  end
52
60
 
61
+ def delete!
62
+ resp = @client.delete(self)
63
+ end
64
+
53
65
  end
54
66
  end
55
67
  end
@@ -1,4 +1,5 @@
1
1
  require 'tableau_server_client/resources/resource'
2
+ require 'tableau_server_client/resources/workbook'
2
3
 
3
4
  module TableauServerClient
4
5
  module Resources
@@ -59,6 +60,12 @@ module TableauServerClient
59
60
  @hierarchy ||= (parent_projects << self).map {|p| p.name }.join('/')
60
61
  end
61
62
 
63
+ def workbooks
64
+ @client.get_collection(Workbook.location(site_path, filter: [])).select {|w|
65
+ w.project_id == id
66
+ }
67
+ end
68
+
62
69
  def extract_values_in_description
63
70
  @values_in_description ||=\
64
71
  description.lines.map { |l|/^(.*):\s*(.*)$/.match(l) }.reject { |m| m.nil? }.map { |m| m[1,2] }.to_h
@@ -61,6 +61,14 @@ module TableauServerClient
61
61
  self.class.extract_site_path(path)
62
62
  end
63
63
 
64
+ def site_id
65
+ site_path.split('/')[1]
66
+ end
67
+
68
+ def server_url
69
+ @client.server_url
70
+ end
71
+
64
72
  def delete!
65
73
  @client.delete self
66
74
  end
@@ -4,6 +4,7 @@ require 'tableau_server_client/resources/workbook'
4
4
  require 'tableau_server_client/resources/user'
5
5
  require 'tableau_server_client/resources/subscription'
6
6
  require 'tableau_server_client/resources/extract_refresh'
7
+ require 'tableau_server_client/resources/view'
7
8
 
8
9
  module TableauServerClient
9
10
  module Resources
@@ -40,6 +41,14 @@ module TableauServerClient
40
41
  @client.get Workbook.location(path, id)
41
42
  end
42
43
 
44
+ def views(filter: [])
45
+ @client.get_collection View.location(path, filter: filter)
46
+ end
47
+
48
+ def view(id)
49
+ @client.get View.location(path, id)
50
+ end
51
+
43
52
  def users(filter: [])
44
53
  @client.get_collection User.location(path, filter: filter)
45
54
  end
@@ -0,0 +1,45 @@
1
+ require 'tableau_server_client/resources/resource'
2
+ require 'tableau_server_client/resources/workbook'
3
+
4
+ module TableauServerClient
5
+ module Resources
6
+
7
+ class View < Resource
8
+
9
+ attr_reader :id, :name, :content_url, :workbook_id
10
+ attr_writer :owner
11
+
12
+ def self.from_response(client, path, xml)
13
+ attrs = extract_attributes(xml)
14
+ attrs['workbook_id'] = xml.xpath("xmlns:workbook")[0]['id']
15
+ new(client, path, attrs)
16
+ end
17
+
18
+ def self.from_collection_response(client, path, xml)
19
+ xml.xpath("//xmlns:views/xmlns:view").each do |s|
20
+ id = s['id']
21
+ yield from_response(client, "#{path}/#{id}", s)
22
+ end
23
+ end
24
+
25
+ def workbook
26
+ client.get Workbook.location(site_path, workbook_id)
27
+ end
28
+
29
+ def webpage_url
30
+ "#{server_url}#{content}/#/views/#{webpage_path}"
31
+ end
32
+
33
+ def webpage_path
34
+ content_url.gsub('/sheets/', '/')
35
+ end
36
+
37
+ def image(query_params: {}, file_path: nil)
38
+ return @image if @iamge
39
+ @image = client.download_image(location(query_params: query_params), file_path: file_path)
40
+ @image
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -3,6 +3,7 @@ require 'tableau_server_client/resources/project'
3
3
  require 'tableau_server_client/resources/connection'
4
4
  require 'tableau_server_client/resources/downloadable'
5
5
  require 'tableau_server_client/resources/datasource'
6
+ require 'tableau_server_client/resources/view'
6
7
 
7
8
  module TableauServerClient
8
9
  module Resources
@@ -10,13 +11,14 @@ module TableauServerClient
10
11
  class Workbook < Resource
11
12
  include Downloadable
12
13
 
13
- attr_reader :id, :name, :content_url, :show_tabs, :size, :created_at, :updated_at
14
+ attr_reader :id, :name, :webpage_url, :content_url, :show_tabs, :size, :created_at, :updated_at, :project_id, :owner_id, :tags
14
15
  attr_writer :owner
15
16
 
16
17
  def self.from_response(client, path, xml)
17
18
  attrs = extract_attributes(xml)
18
19
  attrs['project_id'] = xml.xpath("xmlns:project")[0]['id']
19
- attrs['owner_id'] = xml.xpath("xmlns:owner")[0]['id']
20
+ attrs['owner_id'] = xml.xpath("xmlns:owner")[0]['id']
21
+ attrs['tags'] = xml.xpath("xmlns:tags/xmlns:tag").map {|t| t['label'] }
20
22
  new(client, path, attrs)
21
23
  end
22
24
 
@@ -32,13 +34,17 @@ module TableauServerClient
32
34
  end
33
35
 
34
36
  def project
35
- @project ||= @client.get_collection(Project.location(site_path)).find {|p| p.id == @project_id }
37
+ @project ||= @client.get_collection(Project.location(site_path)).find {|p| p.id == project_id }
36
38
  end
37
39
 
38
40
  def owner
39
41
  @owner ||= @client.get User.location(site_path, @owner_id)
40
42
  end
41
43
 
44
+ def views
45
+ @views ||= @client.get_collection(View.location(site_path)).select {|v| v.workbook_id == id }
46
+ end
47
+
42
48
  def to_request
43
49
  request = build_request {|b|
44
50
  b.workbook {|w|
@@ -52,6 +58,21 @@ module TableauServerClient
52
58
  @client.update self
53
59
  end
54
60
 
61
+ def add_tags!(tags)
62
+ request = build_request {|b|
63
+ b.tags {
64
+ tags.each do |t|
65
+ b.tag(label: t)
66
+ end
67
+ }
68
+ }
69
+ resp = @client.update(self, path: "#{path}/tags", request: request)
70
+ end
71
+
72
+ def delete_tag!(tag)
73
+ @client.delete(self, path: "#{path}/tags/#{tag}")
74
+ end
75
+
55
76
  def embedded_datasources
56
77
  download.xpath('//datasources//datasource').map do |ds|
57
78
  Datasource::DatasourceContent.new(ds)
@@ -1,25 +1,43 @@
1
1
  require 'tableau_server_client/client'
2
2
  require 'tableau_server_client/resources/site'
3
3
  require 'tableau_server_client/resources/schedule'
4
+ require 'tableau_server_client/exception'
4
5
  require 'logger'
5
6
 
6
7
  module TableauServerClient
7
8
  class Server
8
9
 
10
+ #Implement for_token
11
+ #def for_token(token)
12
+
9
13
  def initialize(server_url, username, password,
10
- site_name: "default", api_version: "3.1", token_lifetime: 240,
11
- log_level: :info)
14
+ content_url: "", api_version: "3.1", token_lifetime: 240,
15
+ log_level: :info, impersonation_username: nil)
16
+ @server_url = server_url
17
+ @username = username
18
+ @password = password
19
+ @content_url = content_url
20
+ @api_version = api_version
21
+ @token_lifetime = token_lifetime
12
22
  @logger = ::Logger.new(STDOUT)
13
23
  @logger.level = ::Logger.const_get(log_level.upcase.to_sym)
14
- @client = Client.new(server_url, username, password, site_name, api_version, token_lifetime, @logger)
24
+ @impersonation_username = impersonation_username
15
25
  end
16
26
 
27
+ attr_reader :server_url, :username, :content_url, :api_version, :token_lifetime, :logger, :impersonation_username
28
+
17
29
  def sites
18
- client.get_collection Resources::Site.location(path)
30
+ client.get_collection(Resources::Site.location(path)).map {|s|
31
+ client_for_site(s.content_url).get_collection(Resources::Site.location(path)).select {|x| x.id == s.id }.first
32
+ }
19
33
  end
20
34
 
21
35
  def site(id)
22
- client.get Resources::Site.location(path, id)
36
+ sites.select { |s| s.id == id }.first
37
+ end
38
+
39
+ def full_site(id)
40
+ client_for_site(client.get(Resources::Site.location(path, id)).content_url).get Resources::Site.location(path, id)
23
41
  end
24
42
 
25
43
  def schedules
@@ -32,7 +50,35 @@ module TableauServerClient
32
50
 
33
51
  private
34
52
 
35
- attr_reader :client
53
+ attr_reader :password
54
+
55
+ def client
56
+ @client ||= client_for_site(content_url)
57
+ end
58
+
59
+ def client_for_site(_content_url)
60
+ Client.new(server_url, username, password, _content_url, api_version, token_lifetime, @logger, impersonation_user_id)
61
+ end
62
+
63
+ def site_id
64
+ admin_client.get_collection(Resources::Site.location(path)).each do |site|
65
+ if site.content_url == content_url
66
+ return site.id
67
+ end
68
+ end
69
+ end
70
+
71
+ def impersonation_user_id
72
+ return @impersonation_user_id if @impersonation_user_id
73
+ return nil unless impersonation_username
74
+ user = admin_client.get(Resources::Site.location(path, site_id)).users(filter: ["name:eq:#{impersonation_username}"]).first
75
+ return @impersonation_user_id = user.id if user
76
+ raise TableauServerClientError.new("User '#{username}' not found.")
77
+ end
78
+
79
+ def admin_client
80
+ @admin_client ||= Client.new(server_url, username, password, content_url, api_version, token_lifetime, @logger, nil)
81
+ end
36
82
 
37
83
  end
38
84
  end
@@ -1,3 +1,3 @@
1
1
  module TableauServerClient
2
- VERSION = "0.0.17"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = ["console"]
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.13"
25
- spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "bundler", "~> 2.1"
25
+ spec.add_development_dependency "rake", "~> 12.3.3"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
  spec.add_development_dependency "byebug"
28
28
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tableau_server_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - shimpeko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-20 00:00:00.000000000 Z
11
+ date: 2020-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.13'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.13'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +137,7 @@ files:
137
137
  - bin/console
138
138
  - lib/tableau_server_client.rb
139
139
  - lib/tableau_server_client/client.rb
140
+ - lib/tableau_server_client/exception.rb
140
141
  - lib/tableau_server_client/paginatable_response.rb
141
142
  - lib/tableau_server_client/request_builder.rb
142
143
  - lib/tableau_server_client/request_url.rb
@@ -151,6 +152,7 @@ files:
151
152
  - lib/tableau_server_client/resources/site.rb
152
153
  - lib/tableau_server_client/resources/subscription.rb
153
154
  - lib/tableau_server_client/resources/user.rb
155
+ - lib/tableau_server_client/resources/view.rb
154
156
  - lib/tableau_server_client/resources/workbook.rb
155
157
  - lib/tableau_server_client/server.rb
156
158
  - lib/tableau_server_client/token.rb
@@ -175,8 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
177
  - !ruby/object:Gem::Version
176
178
  version: '0'
177
179
  requirements: []
178
- rubyforge_project:
179
- rubygems_version: 2.7.7
180
+ rubygems_version: 3.0.3
180
181
  signing_key:
181
182
  specification_version: 4
182
183
  summary: Tableau Server REST API Client