pcloud_api 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +86 -8
- data/RELEASEING.md +1 -1
- data/lib/pcloud/client.rb +14 -7
- data/lib/pcloud/folder.rb +4 -4
- data/lib/pcloud/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45e0e46ad9b58dd65f1ce2674c247fd72377fcb376bec9bdc29b3cb285216519
|
4
|
+
data.tar.gz: 25a81544a107633c7c3c4459a1ab0f3e7c1a4c6092d5231b59a22ccbce55bb9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd0a131f94f7aec6ec700ad46ade522d37248d5475a23290d46b20f51025a5fd4043ccaf642fecdaeb387ef3cc85811282d0a52436dca6bdab1d8cbf23927211
|
7
|
+
data.tar.gz: 7597d199d6795c480d0b346ed021845993ad3f0bdd01fa9e6df1b129324c12c61dc181fa36f8990d85916016330d389413e6b6bdbeabb373c455e1ff4f3a1dfb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## 0.2.3 2021-12-14
|
2
2
|
|
3
|
+
**Changes**
|
4
|
+
1. You can now specify `recursive: true` on `Pcloud::Folder#find` and `Pcloud::Folder#find_by` methods to load all the folders contents recursively. Note that this may result in long request times for folders with many items in them.
|
5
|
+
2. You can now configure the pCloud API read and connect timeouts via a new `timeout_seconds` argument to `Pcloud::Client.configure()`. The previous way to set this value via a `PCLOUD_API_TIMEOUT_SECONDS` environment variable continues to work as before.
|
6
|
+
|
7
|
+
## 0.2.3 2021-12-14
|
8
|
+
|
3
9
|
**Changes**
|
4
10
|
1. `Pcloud::File`'s `upload` method no longer requires a `:filename` param, since pCloud just reads it off of the file object and ignores the param anyway
|
5
11
|
2. Both `Pcloud::File` and `Pcloud::Folder`'s `update` and `update!` methods now allow either partial paths _(starting and ending with slashes)_ or full paths. This is a little more dangerous if you specify a full path and you meant partial, but it's a reasonable use case to support.
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/pcloud_api.svg)](https://badge.fury.io/rb/pcloud_api)
|
5
5
|
[![Gem Downloads](https://badgen.net/rubygems/dt/pcloud_api)](https://rubygems.org/gems/pcloud_api)
|
6
6
|
|
7
|
-
The `pcloud_api` gem provides an intuitive Ruby interface for interacting with the [pCloud API](https://docs.pcloud.com/) using OAuth2. This gem does not attempt to replicate the entire functionality of the pCloud API but rather to provide quick and easy access for its most
|
7
|
+
The `pcloud_api` gem provides an intuitive Ruby interface for interacting with the [pCloud API](https://docs.pcloud.com/) using OAuth2. This gem does not attempt to replicate the entire functionality of the pCloud API but rather to provide quick and easy access for its most important functionality. If you are looking for a lower-level pCloud API wrapper, [`pcloud`](https://github.com/7urkm3n/pcloud) might be a better fit for you.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -41,6 +41,7 @@ The `Pcloud::Client` can be configured by directly calling the `Pcloud::Client.c
|
|
41
41
|
Pcloud::Client.configure(
|
42
42
|
access_token: "your-pcloud-app-access-token",
|
43
43
|
data_region: "EU"
|
44
|
+
timeout_seconds: 8 # optional integer, defaults to 8 seconds if not specified
|
44
45
|
)
|
45
46
|
```
|
46
47
|
|
@@ -55,8 +56,12 @@ The `Pcloud::File` API includes:
|
|
55
56
|
# Find files by file :id or :path:
|
56
57
|
Pcloud::File.find(1)
|
57
58
|
Pcloud::File.find_by(path: "/images/jack_the_cat.jpg")
|
58
|
-
#
|
59
|
-
#
|
59
|
+
# NOTES:
|
60
|
+
# - `find_by` can also be used with :id, though this will take precedence over
|
61
|
+
# :path so pick only one or the other
|
62
|
+
# - Both `find` and `find_by` take an optional `recursive: true` argument which
|
63
|
+
# will recursively load all the folders contents. NOTE: this may result in
|
64
|
+
# long request times for folders with many items in them.
|
60
65
|
|
61
66
|
# Check if a file exists by :id
|
62
67
|
Pcloud::File.exists?(1)
|
@@ -106,8 +111,9 @@ The `Pcloud::Folder` API is very similar:
|
|
106
111
|
# Find folders by folder :id or :path:
|
107
112
|
Pcloud::Folder.find(1)
|
108
113
|
Pcloud::Folder.find_by(path: "/images")
|
109
|
-
#
|
110
|
-
# over :path so
|
114
|
+
# NOTES:
|
115
|
+
# - `find_by` can also be used with :id, though this will take precedence over :path so pick only one or the other
|
116
|
+
# - When using :path the folder object will have a `path` value, when finding by :id, `path` will be `nil`
|
111
117
|
|
112
118
|
# Check if a folder exists by id
|
113
119
|
Pcloud::Folder.exists?(1)
|
@@ -147,12 +153,12 @@ jack_images.parent_folder
|
|
147
153
|
jack_images.contents
|
148
154
|
```
|
149
155
|
|
150
|
-
**
|
156
|
+
**Params: path vs id**
|
151
157
|
|
152
|
-
pCloud recommends using the `folder_id`, `parent_folder_id` or `file_id` params for API calls whenever possible, rather using an exact path. Folder and file ids are static, so this will make your code less brittle to changes in the file/folder tree. You can simply look up the id for a folder in the console ahead of time and then set it in your code, similar to how you would specify an AWS S3 bucket.
|
158
|
+
pCloud recommends using the `folder_id`, `parent_folder_id` or `file_id` params for API calls whenever possible, rather than using an exact path. Folder and file ids are static, so this will make your code less brittle to changes in the file/folder tree. You can simply look up the id for a folder in the console ahead of time and then set it in your code, similar to how you would specify an AWS S3 bucket. Note that when finding by one of these id values, the `path` value of a folder will come back as `nil`.
|
153
159
|
|
154
160
|
|
155
|
-
**
|
161
|
+
**Off-label client use**
|
156
162
|
|
157
163
|
The `Pcloud::File` and `Pcloud::Folder` APIs cover the most important, common functionality developers will want to access in a way that is easy to use without much onboarding. If you find that you still need to access other parts of the pCloud API that are not included in this gem yet, you can try calling other methods specified in [the pCloud API docs](https://docs.pcloud.com/) by interacting directly with the `Pcloud::Client`:
|
158
164
|
```ruby
|
@@ -160,6 +166,78 @@ Pcloud::Client.execute("listrevisions", query: { fileid: 90000 })
|
|
160
166
|
```
|
161
167
|
_(There are a few methods on the raw pCloud API that require manual login, which this gem does not yet support. If you find that you need access to these methods you may wish to look at using the [`pcloud`](https://github.com/7urkm3n/pcloud) gem instead.)_
|
162
168
|
|
169
|
+
### Example uses
|
170
|
+
|
171
|
+
In addition to the API docs above, here are some real-world ideas of how you might use the `pcloud_api` gem in a project. Feel free to submit a PR if you have an example that you think others would benefit from as well!
|
172
|
+
|
173
|
+
Upload a file from form params in Rails:
|
174
|
+
```ruby
|
175
|
+
Pcloud::File.upload(
|
176
|
+
path: "/Jack",
|
177
|
+
file: File.open(params[:file].path)
|
178
|
+
)
|
179
|
+
```
|
180
|
+
|
181
|
+
Backup a database for a local script:
|
182
|
+
```ruby
|
183
|
+
Pcloud::File.upload(
|
184
|
+
folder_id: PCLOUD_FOLDER_ID,
|
185
|
+
filename: LOCAL_DB_FILENAME,
|
186
|
+
file: File.open("./#{LOCAL_DB_FILENAME}")
|
187
|
+
)
|
188
|
+
```
|
189
|
+
|
190
|
+
Archive old state files and upload a new file for today:
|
191
|
+
```ruby
|
192
|
+
# NOTE: This will overwrite existing archive files for each day such that
|
193
|
+
# there is only ever one database file stored per day.
|
194
|
+
Pcloud::Folder.find(PCLOUD_FOLDER_ID)
|
195
|
+
.contents
|
196
|
+
.filter { |item| item.is_a?(Pcloud::File) }
|
197
|
+
.filter { |file| file.name.match?(PCLOUD_STATE_FILE_REGEX) }
|
198
|
+
.each do |file|
|
199
|
+
file.update(
|
200
|
+
name: "#{file.created_at.strftime("%Y_%m_%d")}_#{file.name}",
|
201
|
+
parent_folder_id: PCLOUD_ARCHIVE_FOLDER_ID
|
202
|
+
)
|
203
|
+
end
|
204
|
+
|
205
|
+
Pcloud::File.upload(
|
206
|
+
folder_id: PCLOUD_FOLDER_ID,
|
207
|
+
filename: LOCAL_DB_FILENAME,
|
208
|
+
file: File.open("./#{LOCAL_DB_FILENAME}")
|
209
|
+
)
|
210
|
+
```
|
211
|
+
|
212
|
+
Safely download previous state files for a local script:
|
213
|
+
```ruby
|
214
|
+
Pcloud::Folder.find(PCLOUD_FOLDER_ID)
|
215
|
+
.contents
|
216
|
+
.filter { |item| item.is_a?(Pcloud::File) }
|
217
|
+
.filter { |file| file.name.match?(PCLOUD_STATE_FILE_REGEX) }
|
218
|
+
.each do |state_file|
|
219
|
+
filename = "./db/#{state_file.name}"
|
220
|
+
# prompt if local file is newer than cloud state file
|
221
|
+
if ::File.exist?(filename) && ::File.ctime(filename) > state_file.created_at
|
222
|
+
puts "Local #{filename} is newer than the version in pCloud. Are you sure you want to overwrite the local file with an older copy? [Y/N]".red
|
223
|
+
print "> ".red
|
224
|
+
unless ["yes", "y"].include?($stdin.gets.chomp.downcase)
|
225
|
+
puts "Skipping download of #{filename}...".yellow
|
226
|
+
next
|
227
|
+
end
|
228
|
+
end
|
229
|
+
# Only proceed with file download after confirmation or if cloud file is
|
230
|
+
# not older than local file.
|
231
|
+
::File.open(filename, "w") do |file|
|
232
|
+
file.binmode
|
233
|
+
puts "Downloading #{filename} from pCloud...".yellow
|
234
|
+
HTTParty.get(state_file.download_url, stream_body: true) do |fragment|
|
235
|
+
file.write(fragment)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
```
|
240
|
+
|
163
241
|
## Development
|
164
242
|
|
165
243
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/RELEASEING.md
CHANGED
@@ -3,5 +3,5 @@
|
|
3
3
|
2. Make any documentation updates.
|
4
4
|
3. Tag a new release in GitHub and summarize the changes since the last release.
|
5
5
|
4. Build the gem locally: `gem build pcloud_api.gemspec`.
|
6
|
-
|
6
|
+
* To test the gem in a local project, you can install it with `gem install --local pcloud_api-<VERSION>.gem`
|
7
7
|
5. Publish the gem to rubygems.org: `gem push pcloud_api-<VERSION>.gem`.
|
data/lib/pcloud/client.rb
CHANGED
@@ -9,20 +9,21 @@ module Pcloud
|
|
9
9
|
].freeze
|
10
10
|
US_API_BASE = "api.pcloud.com".freeze
|
11
11
|
EU_API_BASE = "eapi.pcloud.com".freeze
|
12
|
-
|
12
|
+
DEFAULT_TIMEOUT_SECONDS = 8.freeze
|
13
13
|
|
14
14
|
class << self
|
15
|
-
def configure(access_token: nil, data_region: nil)
|
15
|
+
def configure(access_token: nil, data_region: nil, timeout_seconds: nil)
|
16
16
|
@@access_token = access_token
|
17
17
|
@@data_region = data_region
|
18
|
+
@@timeout_seconds = timeout_seconds.nil? ? nil : timeout_seconds.to_i
|
18
19
|
true # Don't accidentally return any secrets from the configure method
|
19
20
|
end
|
20
21
|
|
21
22
|
def execute(method, query: {}, body: {})
|
22
23
|
verb = ["uploadfile"].include?(method) ? :post : :get
|
23
24
|
options = {
|
24
|
-
headers: { "Authorization" => "Bearer #{
|
25
|
-
timeout:
|
25
|
+
headers: { "Authorization" => "Bearer #{access_token_from_config_or_env}" },
|
26
|
+
timeout: timeout_seconds_from_config_or_env # this sets both the open and read timeouts to the same value
|
26
27
|
}
|
27
28
|
options[:query] = query unless query.empty?
|
28
29
|
options[:body] = body unless body.empty?
|
@@ -34,26 +35,32 @@ module Pcloud
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
37
|
-
def
|
38
|
+
def data_region_from_config_or_env
|
38
39
|
@@data_region ||= ENV["PCLOUD_API_DATA_REGION"]
|
39
40
|
return @@data_region if VALID_DATA_REGIONS.include?(@@data_region)
|
40
41
|
raise ConfigurationError.new("Missing pCloud data region") if @@data_region.nil?
|
41
42
|
raise ConfigurationError.new("Invalid pCloud data region, must be one of #{VALID_DATA_REGIONS}")
|
42
43
|
end
|
43
44
|
|
44
|
-
def
|
45
|
+
def access_token_from_config_or_env
|
45
46
|
@@access_token ||= ENV["PCLOUD_API_ACCESS_TOKEN"]
|
46
47
|
return @@access_token unless @@access_token.nil?
|
47
48
|
raise ConfigurationError.new("Missing pCloud API access token")
|
48
49
|
end
|
49
50
|
|
51
|
+
def timeout_seconds_from_config_or_env
|
52
|
+
@@timeout_seconds ||= ENV.fetch("PCLOUD_API_TIMEOUT_SECONDS", DEFAULT_TIMEOUT_SECONDS).to_i
|
53
|
+
return @@timeout_seconds unless @@timeout_seconds.zero?
|
54
|
+
raise ConfigurationError.new("Invalid pCloud API timeout seconds: cannot be set to 0")
|
55
|
+
end
|
56
|
+
|
50
57
|
# You can manually hit "https://<default_server_for_your_region>/getapiserver"
|
51
58
|
# to get some JSON which will tell you if there is a server in your region
|
52
59
|
# closer to you than the default.
|
53
60
|
def closest_server
|
54
61
|
@@closest_server ||= begin
|
55
62
|
return ENV["PCLOUD_API_BASE_URI"] if ENV["PCLOUD_API_BASE_URI"]
|
56
|
-
case
|
63
|
+
case data_region_from_config_or_env
|
57
64
|
when US_DATA_REGION
|
58
65
|
US_API_BASE
|
59
66
|
when EU_DATA_REGION
|
data/lib/pcloud/folder.rb
CHANGED
@@ -8,7 +8,7 @@ module Pcloud
|
|
8
8
|
include Pcloud::TimeHelper
|
9
9
|
|
10
10
|
SUPPORTED_UPDATE_PARAMS = [:name, :parent_folder_id, :path].freeze
|
11
|
-
SUPPORTED_FIND_BY_PARAMS = [:id, :path].freeze
|
11
|
+
SUPPORTED_FIND_BY_PARAMS = [:id, :path, :recursive].freeze
|
12
12
|
|
13
13
|
attr_reader :id, :path, :name, :parent_folder_id, :is_deleted, :created_at,
|
14
14
|
:modified_at
|
@@ -91,8 +91,8 @@ module Pcloud
|
|
91
91
|
raise e
|
92
92
|
end
|
93
93
|
|
94
|
-
def find(id)
|
95
|
-
parse_one(Client.execute("listfolder", query: { folderid: id }))
|
94
|
+
def find(id, opts={})
|
95
|
+
parse_one(Client.execute("listfolder", query: { folderid: id, recursive: opts[:recursive] == true }))
|
96
96
|
end
|
97
97
|
|
98
98
|
def find_by(params)
|
@@ -100,7 +100,7 @@ module Pcloud
|
|
100
100
|
raise InvalidParameters.new("Must be one of #{SUPPORTED_FIND_BY_PARAMS}")
|
101
101
|
end
|
102
102
|
raise InvalidParameters.new(":id takes precedent over :path, please only use one or the other") if params[:path] && params[:id]
|
103
|
-
query = { path: params[:path], folderid: params[:id] }.compact
|
103
|
+
query = { path: params[:path], folderid: params[:id], recursive: params[:recursive] == true }.compact
|
104
104
|
parse_one(Client.execute("listfolder", query: query))
|
105
105
|
end
|
106
106
|
end
|
data/lib/pcloud/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pcloud_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hunsche Jones
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -149,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
- !ruby/object:Gem::Version
|
150
150
|
version: '0'
|
151
151
|
requirements: []
|
152
|
-
rubygems_version: 3.
|
152
|
+
rubygems_version: 3.3.26
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: A Ruby library for interacting with the pCloud API
|