globus_client 0.7.0 → 0.9.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: d1fb97800b48bd1cd82b00c43cc82ea71e24212a4d1385bb84ffb432aaa61715
4
- data.tar.gz: e29d9c2ee049c83d0e3c63fbcee2abedbdb1706f3fc29ad907870acad06e88e9
3
+ metadata.gz: 98ab11c317225b75273064fa994c5959d2dd5de9e5276f0c3cc81e264d52140c
4
+ data.tar.gz: 445c5c522f4e41a735331f3cf3c47a07a6854cc39c308e028bab616759f07703
5
5
  SHA512:
6
- metadata.gz: 1b2fd795460970e2eb1449d1053a6baafa14a584d892ec2fa00c778e0921a5f23e7d6824cf98641a1c9d0a54c8d5644a563bcde93e935a42f21f4e0f0bd5e743
7
- data.tar.gz: deb0f58b722e3c12208bbede68147d6d0311e0a3bbc85740dcfa764fdf46b2a57836e6e6391306aade37f93c182b7e3865ae37700485bdb17b5746b2a36a3b21
6
+ metadata.gz: 332fdd907867b012edb68cdb145241dcd666f264a8afc806eaf41028af8af3addcd76b16560c79a2db49c69ecce1d9b3cc5cdb4a718e07fe6ede80b117dc7387
7
+ data.tar.gz: f614098b8258b8598f92fe4fd1e73257e1b413cb8573bb2ccb84235278ebe93f0c249392a5113bc56dae88f3b55b09dc876ed11c20e40fabd0ee4d55b7ec18a4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- globus_client (0.7.0)
4
+ globus_client (0.9.0)
5
5
  activesupport (>= 4.2, < 8)
6
6
  faraday
7
7
  zeitwerk
@@ -23,7 +23,7 @@ GEM
23
23
  rexml
24
24
  diff-lcs (1.5.0)
25
25
  docile (1.4.0)
26
- faraday (2.7.1)
26
+ faraday (2.7.2)
27
27
  faraday-net_http (>= 2.0, < 3.1)
28
28
  ruby2_keywords (>= 0.0.4)
29
29
  faraday-net_http (3.0.2)
@@ -32,9 +32,9 @@ GEM
32
32
  concurrent-ruby (~> 1.0)
33
33
  json (2.6.3)
34
34
  language_server-protocol (3.17.0.2)
35
- minitest (5.16.3)
35
+ minitest (5.17.0)
36
36
  parallel (1.22.1)
37
- parser (3.1.3.0)
37
+ parser (3.2.0.0)
38
38
  ast (~> 2.4.1)
39
39
  public_suffix (5.0.1)
40
40
  rainbow (3.1.1)
@@ -47,45 +47,45 @@ GEM
47
47
  rspec-mocks (~> 3.12.0)
48
48
  rspec-core (3.12.0)
49
49
  rspec-support (~> 3.12.0)
50
- rspec-expectations (3.12.0)
50
+ rspec-expectations (3.12.2)
51
51
  diff-lcs (>= 1.2.0, < 2.0)
52
52
  rspec-support (~> 3.12.0)
53
- rspec-mocks (3.12.1)
53
+ rspec-mocks (3.12.2)
54
54
  diff-lcs (>= 1.2.0, < 2.0)
55
55
  rspec-support (~> 3.12.0)
56
56
  rspec-support (3.12.0)
57
- rubocop (1.39.0)
57
+ rubocop (1.42.0)
58
58
  json (~> 2.3)
59
59
  parallel (~> 1.10)
60
60
  parser (>= 3.1.2.1)
61
61
  rainbow (>= 2.2.2, < 4.0)
62
62
  regexp_parser (>= 1.8, < 3.0)
63
63
  rexml (>= 3.2.5, < 4.0)
64
- rubocop-ast (>= 1.23.0, < 2.0)
64
+ rubocop-ast (>= 1.24.1, < 2.0)
65
65
  ruby-progressbar (~> 1.7)
66
66
  unicode-display_width (>= 1.4.0, < 3.0)
67
- rubocop-ast (1.24.0)
67
+ rubocop-ast (1.24.1)
68
68
  parser (>= 3.1.1.0)
69
- rubocop-performance (1.15.1)
69
+ rubocop-performance (1.15.2)
70
70
  rubocop (>= 1.7.0, < 2.0)
71
71
  rubocop-ast (>= 0.4.0)
72
- rubocop-rspec (2.15.0)
72
+ rubocop-rspec (2.16.0)
73
73
  rubocop (~> 1.33)
74
74
  ruby-progressbar (1.11.0)
75
75
  ruby2_keywords (0.0.5)
76
- simplecov (0.21.2)
76
+ simplecov (0.22.0)
77
77
  docile (~> 1.1)
78
78
  simplecov-html (~> 0.11)
79
79
  simplecov_json_formatter (~> 0.1)
80
80
  simplecov-html (0.12.3)
81
81
  simplecov_json_formatter (0.1.4)
82
- standard (1.19.1)
82
+ standard (1.21.1)
83
83
  language_server-protocol (~> 3.17.0.2)
84
- rubocop (= 1.39.0)
85
- rubocop-performance (= 1.15.1)
84
+ rubocop (= 1.42.0)
85
+ rubocop-performance (= 1.15.2)
86
86
  tzinfo (2.0.5)
87
87
  concurrent-ruby (~> 1.0)
88
- unicode-display_width (2.3.0)
88
+ unicode-display_width (2.4.2)
89
89
  webmock (3.18.1)
90
90
  addressable (>= 2.8.0)
91
91
  crack (>= 0.3.2)
data/api_test.rb CHANGED
@@ -30,6 +30,10 @@ Benchmark.bm(20) do |benchmark|
30
30
  @before_permissions = GlobusClient::Endpoint.new(GlobusClient.config, user_id:, path:).send(:access_rule)["permissions"]
31
31
  end
32
32
 
33
+ benchmark.report("has_files?:") do
34
+ @has_files = GlobusClient.has_files?(user_id:, path:)
35
+ end
36
+
33
37
  benchmark.report("list_files:") do
34
38
  GlobusClient.list_files(user_id:, path:) do |files|
35
39
  @files_count = files.count
@@ -49,6 +53,7 @@ Benchmark.bm(20) do |benchmark|
49
53
 
50
54
  puts "User #{user_id} exists: #{@user_exists}"
51
55
  puts "Initial directory permissions: #{@before_permissions}"
56
+ puts "Directory has files? #{@has_files}"
52
57
  puts "Number of files in directory: #{@files_count}"
53
58
  puts "Total size of files in directory: #{@total_size}"
54
59
  puts "List of files in directory: #{@files_list}"
@@ -16,6 +16,10 @@ class GlobusClient
16
16
  @path = path
17
17
  end
18
18
 
19
+ def has_files?
20
+ ls_path(full_path, [], return_presence: true)
21
+ end
22
+
19
23
  def list_files
20
24
  ls_path(full_path, []).tap do |files|
21
25
  yield files if block_given?
@@ -90,25 +94,38 @@ class GlobusClient
90
94
  end
91
95
 
92
96
  def path_segments
97
+ raise ArgumentError, "Unexpected path provided: #{path.inspect}" unless path.respond_to?(:split)
98
+
93
99
  path.split(PATH_SEPARATOR)
94
100
  end
95
101
 
102
+ # List files recursively at an endpoint https://docs.globus.org/api/transfer/file_operations/#list_directory_contents
96
103
  # @param filepath [String] an absolute path to look up contents e.g. /uploads/example/work123/version1
97
104
  # @param files [Array<FileInfo>] an array of FileInfo structs, each of which has a name and a size
98
- def ls_path(filepath, files)
99
- # List files recursively at an endpoint https://docs.globus.org/api/transfer/file_operations/#list_directory_contents
105
+ # @param return_presence [Boolean] if true, return a boolean to indicate if any files at all are present, short-circuiting the recursive operation
106
+ def ls_path(filepath, files, return_presence: false)
100
107
  response = connection.get("#{transfer_path}/ls?path=#{filepath}")
101
- if response.success?
102
- data = JSON.parse(response.body)["DATA"]
103
- data
104
- .select { |object| object["type"] == "file" }
105
- .each { |file| files << FileInfo.new("#{filepath}#{file["name"]}", file["size"]) }
106
- data
107
- .select { |object| object["type"] == "dir" }
108
- .each { |dir| ls_path("#{filepath}#{dir["name"]}/", files) }
109
- else
110
- UnexpectedResponse.call(response)
108
+ return UnexpectedResponse.call(response) unless response.success?
109
+
110
+ data = JSON.parse(response.body)["DATA"]
111
+ data
112
+ .select { |object| object["type"] == "file" }
113
+ .each do |file|
114
+ return true if return_presence
115
+
116
+ files << FileInfo.new("#{filepath}#{file["name"]}", file["size"])
117
+ end
118
+ data
119
+ .select { |object| object["type"] == "dir" }
120
+ .each do |dir|
121
+ # NOTE: This allows the recursive method to short-circuit iff ls_path
122
+ # returns true, which only happens when return_presence is true
123
+ # and the first file is found in the ls operation.
124
+ return true if ls_path("#{filepath}#{dir["name"]}/", files, return_presence:) == true
111
125
  end
126
+
127
+ return false if return_presence
128
+
112
129
  files
113
130
  end
114
131
 
@@ -20,7 +20,8 @@ class GlobusClient
20
20
  def exists?(user_id)
21
21
  get_identity_id(user_id)
22
22
  true
23
- rescue
23
+ # if no active user is returned
24
+ rescue RuntimeError
24
25
  false
25
26
  end
26
27
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GlobusClient
4
+ # Wraps API operations to request new access token if expired
5
+ class TokenWrapper
6
+ def self.refresh(config, &block)
7
+ yield
8
+ rescue UnexpectedResponse::UnauthorizedError
9
+ config.token = Authenticator.token(config.client_id, config.client_secret, config.auth_url)
10
+ yield
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GlobusClient
4
- VERSION = "0.7.0"
4
+ VERSION = "0.9.0"
5
5
  end
data/lib/globus_client.rb CHANGED
@@ -23,6 +23,8 @@ class GlobusClient
23
23
  def configure(client_id:, client_secret:, uploads_directory:, transfer_endpoint_id:, transfer_url: default_transfer_url, auth_url: default_auth_url)
24
24
  instance.config = OpenStruct.new(
25
25
  token: Authenticator.token(client_id, client_secret, auth_url),
26
+ client_id:,
27
+ client_secret:,
26
28
  uploads_directory:,
27
29
  transfer_endpoint_id:,
28
30
  transfer_url:,
@@ -32,7 +34,8 @@ class GlobusClient
32
34
  self
33
35
  end
34
36
 
35
- delegate :config, :disallow_writes, :file_count, :list_files, :mkdir, :total_size, :user_exists?, :get_filenames, to: :instance
37
+ delegate :config, :disallow_writes, :file_count, :list_files, :mkdir, :total_size,
38
+ :user_exists?, :get_filenames, :has_files?, to: :instance
36
39
 
37
40
  def default_transfer_url
38
41
  "https://transfer.api.globusonline.org"
@@ -46,41 +49,62 @@ class GlobusClient
46
49
  attr_accessor :config
47
50
 
48
51
  def mkdir(...)
49
- endpoint = Endpoint.new(config, ...)
50
- endpoint.mkdir
51
- endpoint.allow_writes
52
+ TokenWrapper.refresh(config) do
53
+ endpoint = Endpoint.new(config, ...)
54
+ endpoint.mkdir
55
+ endpoint.allow_writes
56
+ end
52
57
  end
53
58
 
54
59
  def disallow_writes(...)
55
- endpoint = Endpoint.new(config, ...)
56
- endpoint.disallow_writes
60
+ TokenWrapper.refresh(config) do
61
+ endpoint = Endpoint.new(config, ...)
62
+ endpoint.disallow_writes
63
+ end
57
64
  end
58
65
 
59
66
  # NOTE: Can't use the `...` (argument forwarding) operator here because we
60
67
  # want to route the keyword args to `Endpoint#new` and the block arg to
61
68
  # `Endpoint#list_files`
62
69
  def list_files(**keywords, &block)
63
- endpoint = Endpoint.new(config, **keywords)
64
- endpoint.list_files(&block)
70
+ TokenWrapper.refresh(config) do
71
+ endpoint = Endpoint.new(config, **keywords)
72
+ endpoint.list_files(&block)
73
+ end
65
74
  end
66
75
 
67
76
  def file_count(...)
68
- endpoint = Endpoint.new(config, ...)
69
- endpoint.list_files { |files| return files.count }
77
+ TokenWrapper.refresh(config) do
78
+ endpoint = Endpoint.new(config, ...)
79
+ endpoint.list_files { |files| return files.count }
80
+ end
70
81
  end
71
82
 
72
83
  def total_size(...)
73
- endpoint = Endpoint.new(config, ...)
74
- endpoint.list_files { |files| return files.sum(&:size) }
84
+ TokenWrapper.refresh(config) do
85
+ endpoint = Endpoint.new(config, ...)
86
+ endpoint.list_files { |files| return files.sum(&:size) }
87
+ end
75
88
  end
76
89
 
77
90
  def get_filenames(...)
78
- endpoint = Endpoint.new(config, ...)
79
- endpoint.list_files { |files| return files.map(&:name) }
91
+ TokenWrapper.refresh(config) do
92
+ endpoint = Endpoint.new(config, ...)
93
+ endpoint.list_files { |files| return files.map(&:name) }
94
+ end
95
+ end
96
+
97
+ def has_files?(...)
98
+ TokenWrapper.refresh(config) do
99
+ endpoint = Endpoint.new(config, ...)
100
+ endpoint.has_files?
101
+ end
80
102
  end
81
103
 
82
104
  def user_exists?(...)
83
- identity = Identity.new(config)
84
- identity.exists?(...)
105
+ TokenWrapper.refresh(config) do
106
+ identity = Identity.new(config)
107
+ identity.exists?(...)
108
+ end
85
109
  end
86
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: globus_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Collier
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-12-16 00:00:00.000000000 Z
13
+ date: 2023-01-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -170,6 +170,7 @@ files:
170
170
  - lib/globus_client/authenticator.rb
171
171
  - lib/globus_client/endpoint.rb
172
172
  - lib/globus_client/identity.rb
173
+ - lib/globus_client/token_wrapper.rb
173
174
  - lib/globus_client/unexpected_response.rb
174
175
  - lib/globus_client/version.rb
175
176
  homepage: https://github.com/sul-dlss/globus_client