pcloud_api 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +11 -2
- data/README.md +13 -11
- data/lib/pcloud/file.rb +40 -29
- data/lib/pcloud/folder.rb +26 -8
- data/lib/pcloud/time_helper.rb +26 -0
- data/lib/pcloud/version.rb +1 -1
- data/lib/pcloud_api.rb +2 -0
- data/pcloud_api.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bc6a66525cb7bfd47085851a95dbc1656759f92960611d1d66e5f466025c800
|
4
|
+
data.tar.gz: 3eb54b53ab7c2c97ece4db9a074cbf75d6aa602ba727c917a6f88dbc97997c92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ce986fc8cdedaed9773209c26afbaf08091d4285abbb40126a0fcc0fcac99d77bd1ce1250bed6cdce4dd79e445076ca49469f6ce0c2e3ccfb597a36bf41f79f
|
7
|
+
data.tar.gz: 5aa4fb9d5dd96227b61c18c2bc537ad4b73338509e8a0e6b710cc06415228c41f67efb7719258ae954eb0fe9f36fae55d9151622021fb1f4d8116767aae1cad8
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
+
## 0.2.0 2021-09-26
|
2
|
+
|
3
|
+
New
|
4
|
+
* An `.exists?` method has been added to `Pcloud::Folder` and `Pcloud::File`
|
5
|
+
* The `.find_by` method on `Pcloud::Folder` and `Pcloud::File` can now be called with either `:id` or `:path`. NOTE: pCloud treats `:id` with precedence, so an error will be raised if the method is called with both parameters at once. _(Allowing precedence in a method like this would likely feel like unexpected behavior, so my intention was to make it immediately obvious to the end user.)_
|
6
|
+
|
7
|
+
Change
|
8
|
+
* `Pcloud::Folder` and `Pcloud::File` `created_at` and `modified_at` timestamps are now returned as Ruby `Time` objects
|
9
|
+
* Some error class names and messages have been cleaned up for additional clarity and consistency.
|
10
|
+
|
1
11
|
## 0.1.0 2021-09-26
|
2
12
|
|
3
|
-
|
4
|
-
* Initial release
|
13
|
+
Initial release
|
data/README.md
CHANGED
@@ -25,8 +25,8 @@ Or install it yourself as:
|
|
25
25
|
The `Pcloud::Client` can be configured by directly calling the `Pcloud::Client.configure` method in an initializer or somewhere else in your code at startup:
|
26
26
|
```ruby
|
27
27
|
Pcloud::Client.configure(
|
28
|
-
|
29
|
-
|
28
|
+
access_token: "your-pcloud-app-access-token",
|
29
|
+
data_region: "EU"
|
30
30
|
)
|
31
31
|
```
|
32
32
|
|
@@ -44,9 +44,9 @@ Pcloud::File.find_by(path: "/images/jack_the_cat.jpg")
|
|
44
44
|
|
45
45
|
# Upload a new file, rename if already existing:
|
46
46
|
Pcloud::File.upload(
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
folder_id: 1,
|
48
|
+
filename: "jack_goes_swimming.mp4",
|
49
|
+
file: File.open("/Users/joshua/Downloads/jack_goes_swimming.mp4")
|
50
50
|
)
|
51
51
|
# NOTE: the upload method will allow you to specify either the `path` or the
|
52
52
|
# `folder_id`, or you can choose to pass neither paramenter and your files will
|
@@ -54,9 +54,9 @@ Pcloud::File.upload(
|
|
54
54
|
|
55
55
|
# Upload a file, force overwrite of existing file:
|
56
56
|
Pcloud::File.upload!(
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
folder_id: 1,
|
58
|
+
filename: "jack_goes_swimming.mp4",
|
59
|
+
file: File.open("/Users/joshua/Downloads/jack_goes_swimming.mp4")
|
60
60
|
)
|
61
61
|
|
62
62
|
# Rename a file:
|
@@ -106,16 +106,18 @@ jack_images.parent_folder
|
|
106
106
|
jack_images.contents
|
107
107
|
```
|
108
108
|
|
109
|
-
**Aside: path vs id
|
109
|
+
**Aside: path vs id**
|
110
|
+
|
110
111
|
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.
|
111
112
|
|
112
113
|
|
113
|
-
**Aside: off-label client use
|
114
|
+
**Aside: off-label client use**
|
115
|
+
|
114
116
|
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`:
|
115
117
|
```ruby
|
116
118
|
Pcloud::Client.execute("listrevisions", query: { fileid: 90000 })
|
117
119
|
```
|
118
|
-
_(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.)
|
120
|
+
_(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.)_
|
119
121
|
|
120
122
|
### Generating an access token
|
121
123
|
|
data/lib/pcloud/file.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
module Pcloud
|
2
2
|
class File
|
3
|
-
class UnsuportedUpdateParams < StandardError; end
|
4
3
|
class ManformedUpdateParams < StandardError; end
|
5
4
|
class InvalidParameter < StandardError; end
|
5
|
+
class InvalidParameters < StandardError; end
|
6
|
+
class MissingParameter < StandardError; end
|
6
7
|
class UploadFailed < StandardError; end
|
8
|
+
|
7
9
|
include Parser
|
10
|
+
include Pcloud::TimeHelper
|
8
11
|
|
9
12
|
SUPPORTED_UPDATE_PARAMS = [:name, :parent_folder_id, :path].freeze
|
10
13
|
FILE_CATAGORIES = {
|
@@ -28,16 +31,16 @@ module Pcloud
|
|
28
31
|
@size = params.fetch(:size) # bytes
|
29
32
|
@parent_folder_id = params.fetch(:parent_folder_id)
|
30
33
|
@is_deleted = params.fetch(:is_deleted) || false
|
31
|
-
@created_at = params.fetch(:created_at)
|
32
|
-
@modified_at = params.fetch(:modified_at)
|
34
|
+
@created_at = time_from(params.fetch(:created_at))
|
35
|
+
@modified_at = time_from(params.fetch(:modified_at))
|
33
36
|
end
|
34
37
|
|
35
38
|
def update(params)
|
36
39
|
unless (params.keys - SUPPORTED_UPDATE_PARAMS).empty?
|
37
|
-
raise
|
40
|
+
raise InvalidParameters.new("Must be one of #{SUPPORTED_UPDATE_PARAMS}")
|
38
41
|
end
|
39
42
|
if params[:path] && is_invalid_path_param?(params[:path])
|
40
|
-
raise ManformedUpdateParams.new("
|
43
|
+
raise ManformedUpdateParams.new(":path param must start and end with `/`")
|
41
44
|
end
|
42
45
|
query = {
|
43
46
|
fileid: id,
|
@@ -73,41 +76,46 @@ module Pcloud
|
|
73
76
|
private
|
74
77
|
|
75
78
|
def is_invalid_path_param?(path_param)
|
76
|
-
# Path params have to start and end with
|
79
|
+
# Path params have to start and end with `/`
|
77
80
|
[path_param[0], path_param[-1]] != ["/", "/"]
|
78
81
|
end
|
79
82
|
|
80
83
|
class << self
|
84
|
+
def exists?(id)
|
85
|
+
find(id)
|
86
|
+
true
|
87
|
+
rescue Pcloud::Client::ErrorResponse => e
|
88
|
+
return false if e.message == "File not found."
|
89
|
+
raise e
|
90
|
+
end
|
91
|
+
|
81
92
|
def find(id)
|
82
93
|
parse_one(Client.execute("stat", query: { fileid: id }))
|
83
94
|
end
|
84
95
|
|
85
|
-
def find_by(
|
86
|
-
|
96
|
+
def find_by(params)
|
97
|
+
raise MissingParameter.new(":path or :id is required") unless params[:path] || params[:id]
|
98
|
+
raise InvalidParameters.new(":id takes precedent over :path, please only use one or the other") if params[:path] && params[:id]
|
99
|
+
parse_one(
|
100
|
+
Client.execute(
|
101
|
+
"stat",
|
102
|
+
query: { path: params[:path], fileid: params[:id] }.compact
|
103
|
+
)
|
104
|
+
)
|
87
105
|
end
|
88
106
|
|
89
|
-
def upload(
|
90
|
-
process_upload(
|
91
|
-
filename: filename,
|
92
|
-
file: file,
|
93
|
-
path: path,
|
94
|
-
folder_id: folder_id
|
95
|
-
)
|
107
|
+
def upload(params)
|
108
|
+
process_upload(params)
|
96
109
|
end
|
97
110
|
|
98
|
-
def upload!(
|
99
|
-
process_upload(
|
100
|
-
filename: filename,
|
101
|
-
file: file,
|
102
|
-
path: path,
|
103
|
-
folder_id: folder_id,
|
104
|
-
overwrite: true
|
105
|
-
)
|
111
|
+
def upload!(params)
|
112
|
+
process_upload(params.merge({ overwrite: true }))
|
106
113
|
end
|
107
114
|
|
108
115
|
private
|
109
116
|
|
110
|
-
def process_upload(
|
117
|
+
def process_upload(params)
|
118
|
+
file = params.fetch(:file)
|
111
119
|
raise InvalidParameter.new("The `file` parameter must be an instance of Ruby `File`") unless file.is_a?(::File)
|
112
120
|
|
113
121
|
# === pCloud API behavior notes: ===
|
@@ -118,11 +126,11 @@ module Pcloud
|
|
118
126
|
response = Client.execute(
|
119
127
|
"uploadfile",
|
120
128
|
body: {
|
121
|
-
renameifexists: overwrite ? 0 : 1,
|
122
|
-
path: path,
|
123
|
-
folderid: folder_id,
|
124
|
-
filename: filename,
|
125
|
-
file: file
|
129
|
+
renameifexists: params[:overwrite] ? 0 : 1,
|
130
|
+
path: params[:path],
|
131
|
+
folderid: params[:folder_id],
|
132
|
+
filename: params.fetch(:filename),
|
133
|
+
file: file,
|
126
134
|
}.compact,
|
127
135
|
)
|
128
136
|
# This method on the pCloud API can accept multiple uploads at once.
|
@@ -131,6 +139,9 @@ module Pcloud
|
|
131
139
|
uploaded_file = parse_many(response).first
|
132
140
|
raise UploadFailed if uploaded_file.nil?
|
133
141
|
return uploaded_file
|
142
|
+
rescue KeyError => e
|
143
|
+
missing_param = e.message.gsub("key not found: ", "")
|
144
|
+
raise MissingParameter.new("#{missing_param} is required")
|
134
145
|
end
|
135
146
|
end
|
136
147
|
end
|
data/lib/pcloud/folder.rb
CHANGED
@@ -2,8 +2,11 @@ module Pcloud
|
|
2
2
|
class Folder
|
3
3
|
class UnsuportedUpdateParams < StandardError; end
|
4
4
|
class ManformedUpdateParams < StandardError; end
|
5
|
-
class
|
5
|
+
class InvalidParameters < StandardError; end
|
6
|
+
class MissingParameter < StandardError; end
|
7
|
+
|
6
8
|
include Parser
|
9
|
+
include Pcloud::TimeHelper
|
7
10
|
|
8
11
|
SUPPORTED_UPDATE_PARAMS = [:name, :parent_folder_id, :path].freeze
|
9
12
|
|
@@ -23,8 +26,8 @@ module Pcloud
|
|
23
26
|
# have any contents set yet.
|
24
27
|
@contents_are_confirmed = @contents && @contents.size > 0
|
25
28
|
@is_deleted = params.fetch(:is_deleted) || false
|
26
|
-
@created_at = params.fetch(:created_at)
|
27
|
-
@modified_at = params.fetch(:modified_at)
|
29
|
+
@created_at = time_from(params.fetch(:created_at))
|
30
|
+
@modified_at = time_from(params.fetch(:modified_at))
|
28
31
|
end
|
29
32
|
|
30
33
|
def update(params)
|
@@ -32,7 +35,7 @@ module Pcloud
|
|
32
35
|
raise UnsuportedUpdateParams.new("Must be one of #{SUPPORTED_UPDATE_PARAMS}")
|
33
36
|
end
|
34
37
|
if params[:path] && is_invalid_path_param?(params[:path])
|
35
|
-
raise ManformedUpdateParams.new("
|
38
|
+
raise ManformedUpdateParams.new(":path param must start and end with `/`")
|
36
39
|
end
|
37
40
|
query = {
|
38
41
|
folderid: id,
|
@@ -72,7 +75,7 @@ module Pcloud
|
|
72
75
|
private
|
73
76
|
|
74
77
|
def is_invalid_path_param?(path_param)
|
75
|
-
# Path params have to start and end with
|
78
|
+
# Path params have to start and end with `/`
|
76
79
|
[path_param[0], path_param[-1]] != ["/", "/"]
|
77
80
|
end
|
78
81
|
|
@@ -83,16 +86,31 @@ module Pcloud
|
|
83
86
|
elsif params[:path]
|
84
87
|
parse_one(Client.execute("createfolderifnotexists", query: { path: params[:path] }))
|
85
88
|
else
|
86
|
-
raise
|
89
|
+
raise InvalidParameters.new("either :path or a combination of :parent_folder_id and :name params are required")
|
87
90
|
end
|
88
91
|
end
|
89
92
|
|
93
|
+
def exists?(id)
|
94
|
+
find(id)
|
95
|
+
true
|
96
|
+
rescue Pcloud::Client::ErrorResponse => e
|
97
|
+
return false if e.message == "Directory does not exist."
|
98
|
+
raise e
|
99
|
+
end
|
100
|
+
|
90
101
|
def find(id)
|
91
102
|
parse_one(Client.execute("listfolder", query: { folderid: id }))
|
92
103
|
end
|
93
104
|
|
94
|
-
def find_by(
|
95
|
-
|
105
|
+
def find_by(params)
|
106
|
+
raise MissingParameter.new(":path or :id is required") unless params[:path] || params[:id]
|
107
|
+
raise InvalidParameters.new(":id takes precedent over :path, please only use one or the other") if params[:path] && params[:id]
|
108
|
+
parse_one(
|
109
|
+
Client.execute(
|
110
|
+
"listfolder",
|
111
|
+
query: { path: params[:path], folderid: params[:id] }.compact
|
112
|
+
)
|
113
|
+
)
|
96
114
|
end
|
97
115
|
end
|
98
116
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Pcloud
|
2
|
+
module TimeHelper
|
3
|
+
class UnrecognizedTimeFormat < StandardError; end
|
4
|
+
|
5
|
+
TIMEZONE = TZInfo::Timezone.get(ENV.fetch("TZ", "UTC")).freeze
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def time_from(time)
|
10
|
+
time_object =
|
11
|
+
if time.is_a?(String)
|
12
|
+
Time.parse(time)
|
13
|
+
elsif time.is_a?(Integer)
|
14
|
+
return Time.at(time) if time.digits.size < 13
|
15
|
+
milliseconds = time.to_s[-3..-1].to_i
|
16
|
+
seconds = time.to_s[0..-4].to_i
|
17
|
+
Time.at(seconds, milliseconds, :millisecond)
|
18
|
+
elsif time.is_a?(Time)
|
19
|
+
time
|
20
|
+
else
|
21
|
+
raise Pcloud::TimeHelper::UnrecognizedTimeFormat.new(time.inspect)
|
22
|
+
end
|
23
|
+
TIMEZONE.to_local(time_object)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/pcloud/version.rb
CHANGED
data/lib/pcloud_api.rb
CHANGED
data/pcloud_api.gemspec
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.
|
4
|
+
version: 0.2.0
|
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: 2021-
|
11
|
+
date: 2021-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,6 +86,20 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0.16'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: tzinfo
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
89
103
|
description:
|
90
104
|
email:
|
91
105
|
- joshua@hunschejones.com
|
@@ -110,6 +124,7 @@ files:
|
|
110
124
|
- lib/pcloud/file/parser.rb
|
111
125
|
- lib/pcloud/folder.rb
|
112
126
|
- lib/pcloud/folder/parser.rb
|
127
|
+
- lib/pcloud/time_helper.rb
|
113
128
|
- lib/pcloud/version.rb
|
114
129
|
- lib/pcloud_api.rb
|
115
130
|
- pcloud_api.gemspec
|