tableau_server_client 0.0.19 → 0.4.1

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: e9ece5e128410a403cebb77343a1efecfcaa11af7943e63e0f5cd4742a7b86e8
4
- data.tar.gz: 26692e9b42d023e71498afaa938daf96886af823eb24100bb48a790e34369830
3
+ metadata.gz: a2b753dc351bba7fa961e4772449b2ef68789fd24f6ca632983f506c729d596e
4
+ data.tar.gz: a6de27794f5a2fcf43f393f4f259cda8250860c30176852b586d458d87e2e60b
5
5
  SHA512:
6
- metadata.gz: 15ce18273d3ef76cb0db3978ad7c246520e22e114c53a72f7d08d9502d6422217fd52ddafc2649d2503c4a1184e731f620505a58e6e4575d98643691b3276ea0
7
- data.tar.gz: 0ea42f4fe5dfcaac59a08e7ceb5b24e5ae4f9959f588d4b05b7cca0b52eab52dda5ebc7b0329d9d9f2f434990fad3b5e7604e4097a7b95673c0759eb5ddd3562
6
+ metadata.gz: cc52e212245271db396f36989401102e78377e5b794977e580d17d65394033bd36398dcf50249a96c7f595ef4cbc07f447dcf92d7a28c090d19264a2019d98f3
7
+ data.tar.gz: 5f4a6ea560350dcc8641b9ad1c8b04187d8973d14ac5679546ec66f595e7decc65aafda880b2021aca962c2d88b265950b58e14defb7012c31aed802bcc53eb8
@@ -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
@@ -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
@@ -0,0 +1,31 @@
1
+ require 'tableau_server_client/resources/resource'
2
+
3
+ module TableauServerClient
4
+ module Resources
5
+
6
+ class Group < Resource
7
+
8
+ attr_reader :id, :name, :site_role
9
+
10
+ def self.from_response(client, path, xml)
11
+ attrs = extract_attributes(xml)
12
+ if xml.xpath("xmlns:import")[0]
13
+ attrs['site_role'] = xml.xpath("xmlns:import")[0]['siteRole']
14
+ end
15
+ new(client, path, attrs)
16
+ end
17
+
18
+ def self.from_collection_response(client, path, xml)
19
+ xml.xpath("//xmlns:groups/xmlns:group").each do |s|
20
+ id = s['id']
21
+ yield from_response(client, "#{path}/#{id}", s)
22
+ end
23
+ end
24
+
25
+ def users
26
+ @client.get_collection(User.location(path))
27
+ end
28
+
29
+ end
30
+ end
31
+ 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,8 @@ 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'
8
+ require 'tableau_server_client/resources/group'
7
9
 
8
10
  module TableauServerClient
9
11
  module Resources
@@ -40,6 +42,14 @@ module TableauServerClient
40
42
  @client.get Workbook.location(path, id)
41
43
  end
42
44
 
45
+ def views(filter: [])
46
+ @client.get_collection View.location(path, filter: filter)
47
+ end
48
+
49
+ def view(id)
50
+ @client.get View.location(path, id)
51
+ end
52
+
43
53
  def users(filter: [])
44
54
  @client.get_collection User.location(path, filter: filter)
45
55
  end
@@ -68,6 +78,11 @@ module TableauServerClient
68
78
  @client.get_collection ExtractRefresh.location("#{path}/tasks")
69
79
  end
70
80
 
81
+ def groups(filter: [])
82
+ @client.get_collection Group.location(path, filter: filter)
83
+ end
84
+
85
+
71
86
  end
72
87
  end
73
88
  end
@@ -20,7 +20,7 @@ module TableauServerClient
20
20
  end
21
21
 
22
22
  def reload
23
- @client.get User.location(site_path, id)
23
+ @client.get location
24
24
  end
25
25
 
26
26
  def full_name
@@ -39,6 +39,23 @@ module TableauServerClient
39
39
  end
40
40
  end
41
41
 
42
+ def to_request
43
+ request = build_request {|b|
44
+ b.user(siteRole: site_role)
45
+ }
46
+ end
47
+
48
+ def update_site_role!(role)
49
+ @site_role = role
50
+ # Using location to get corretct path
51
+ # When initialized from Group path will be groups/group_id/users/user_id
52
+ @client.update(self, path: location.path)
53
+ end
54
+
55
+ def location
56
+ User.location(site_path, id)
57
+ end
58
+
42
59
  end
43
60
  end
44
61
  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, :webpage_url, :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.19"
2
+ VERSION = "0.4.1"
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.19
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - shimpeko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-17 00:00:00.000000000 Z
11
+ date: 2020-09-04 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
@@ -144,6 +145,7 @@ files:
144
145
  - lib/tableau_server_client/resources/datasource.rb
145
146
  - lib/tableau_server_client/resources/downloadable.rb
146
147
  - lib/tableau_server_client/resources/extract_refresh.rb
148
+ - lib/tableau_server_client/resources/group.rb
147
149
  - lib/tableau_server_client/resources/job.rb
148
150
  - lib/tableau_server_client/resources/project.rb
149
151
  - lib/tableau_server_client/resources/resource.rb
@@ -151,6 +153,7 @@ files:
151
153
  - lib/tableau_server_client/resources/site.rb
152
154
  - lib/tableau_server_client/resources/subscription.rb
153
155
  - lib/tableau_server_client/resources/user.rb
156
+ - lib/tableau_server_client/resources/view.rb
154
157
  - lib/tableau_server_client/resources/workbook.rb
155
158
  - lib/tableau_server_client/server.rb
156
159
  - lib/tableau_server_client/token.rb
@@ -175,8 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
178
  - !ruby/object:Gem::Version
176
179
  version: '0'
177
180
  requirements: []
178
- rubyforge_project:
179
- rubygems_version: 2.7.7
181
+ rubygems_version: 3.0.3
180
182
  signing_key:
181
183
  specification_version: 4
182
184
  summary: Tableau Server REST API Client