tableau_server_client 0.0.18 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ba668508020022716e60c4cc1e5edfe95f81386f62f494b7aac2c72423953ac
4
- data.tar.gz: 3c82d0e46452aefebc1f37d4cd470c2ac7e0a348706f9b8a0307f97f0f636bbb
3
+ metadata.gz: 9f4255306f228031f6c4db6e6b747c64daf9fcf6266529c10fd7b9a4f2ae4679
4
+ data.tar.gz: ef2fafcc87bb2d45ce457082efe8e4625e7c5cabae312ff6bb887feb429216b1
5
5
  SHA512:
6
- metadata.gz: 2f7ea02ebaa3d5f65b151af60e5d3fd8a0a218a46489283d591e8ba5a847b3ab915e391cc09cbeb5990a30033b0271719de9d27c1266c32e4cc8afcf73548826
7
- data.tar.gz: abe017026bc3a66e044826e875e4f33314a6816a74ee209be92e7508f247a299c279b12a31874c467e08b972831e7f946f6e7fa16f1204ac94b4e39f73ca6fb2
6
+ metadata.gz: 8402b65fd6e2c6a0645310a7707618dafd907038cc18c4fef0ba4e6c061dc1fd9568a4c21bfba20466e33a80fd5dece452c3e8d6a4acb912fd60ba7b85461dca
7
+ data.tar.gz: 547bec151a48a0a2d01943f1ab990b8800d3ce512beb141a6789c9b2a4de952fa6a6694b71f678374f99d7b6c7fcb366fdde6eba8f360a8e4bed6acc122e6be7
@@ -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)
@@ -58,6 +58,10 @@ module TableauServerClient
58
58
  Job.from_response(@client, Job.location(site_path, id = job_id).path, resp)
59
59
  end
60
60
 
61
+ def delete!
62
+ resp = @client.delete(self)
63
+ end
64
+
61
65
  end
62
66
  end
63
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,47 @@
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 site_by_name(site_name)
40
+ sites.select { |s| s.name == site_name }.first
41
+ end
42
+
43
+ def full_site(id)
44
+ client_for_site(client.get(Resources::Site.location(path, id)).content_url).get Resources::Site.location(path, id)
23
45
  end
24
46
 
25
47
  def schedules
@@ -32,7 +54,35 @@ module TableauServerClient
32
54
 
33
55
  private
34
56
 
35
- attr_reader :client
57
+ attr_reader :password
58
+
59
+ def client
60
+ @client ||= client_for_site(content_url)
61
+ end
62
+
63
+ def client_for_site(_content_url)
64
+ Client.new(server_url, username, password, _content_url, api_version, token_lifetime, @logger, impersonation_user_id)
65
+ end
66
+
67
+ def site_id
68
+ admin_client.get_collection(Resources::Site.location(path)).each do |site|
69
+ if site.content_url == content_url
70
+ return site.id
71
+ end
72
+ end
73
+ end
74
+
75
+ def impersonation_user_id
76
+ return @impersonation_user_id if @impersonation_user_id
77
+ return nil unless impersonation_username
78
+ user = admin_client.get(Resources::Site.location(path, site_id)).users(filter: ["name:eq:#{impersonation_username}"]).first
79
+ return @impersonation_user_id = user.id if user
80
+ raise TableauServerClientError.new("User '#{username}' not found.")
81
+ end
82
+
83
+ def admin_client
84
+ @admin_client ||= Client.new(server_url, username, password, content_url, api_version, token_lifetime, @logger, nil)
85
+ end
36
86
 
37
87
  end
38
88
  end
@@ -1,3 +1,3 @@
1
1
  module TableauServerClient
2
- VERSION = "0.0.18"
2
+ VERSION = "0.3.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.18
4
+ version: 0.3.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-07-17 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