tableau_server_client 0.0.17 → 0.2.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: 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