yandex_client 0.1.1 → 1.1.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/.github/workflows/main.yml +30 -0
- data/.gitignore +2 -0
- data/.pryrc +6 -0
- data/.rubocop.yml +39 -0
- data/Gemfile +2 -0
- data/README.md +33 -83
- data/dip.yml +9 -8
- data/docker/Dockerfile.dip +8 -0
- data/docker/docker-compose.yml +16 -8
- data/docker/prepare_env.sh +11 -0
- data/lib/yandex_client/auth.rb +62 -0
- data/lib/yandex_client/configurable.rb +26 -0
- data/lib/yandex_client/dav/prop_find_response.rb +70 -0
- data/lib/yandex_client/dav.rb +104 -0
- data/lib/yandex_client/disk.rb +72 -0
- data/lib/yandex_client/error_handler.rb +20 -0
- data/lib/yandex_client/passport.rb +45 -0
- data/lib/yandex_client/version.rb +1 -1
- data/lib/yandex_client.rb +38 -19
- data/yandex_client.gemspec +2 -1
- metadata +30 -14
- data/.travis.yml +0 -12
- data/docker/Dockerfile.2.6 +0 -13
- data/docker/docker-compose.development.yml +0 -18
- data/lib/yandex_client/api_request_error.rb +0 -15
- data/lib/yandex_client/auth/client.rb +0 -57
- data/lib/yandex_client/client.rb +0 -98
- data/lib/yandex_client/dav/client.rb +0 -117
- data/lib/yandex_client/dav/propfind_parser.rb +0 -51
- data/lib/yandex_client/not_found_error.rb +0 -6
- data/lib/yandex_client/passport/client.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8b82741c31dd638b0ff6793b208d6c7ab33e9b5dc613f6c9ffd3482fb5dcde3
|
4
|
+
data.tar.gz: 510f836e9b6566ba397342544c9430232f7c88a39607261450d413c82b998367
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91e69d64b589fc868bb0bc18956cb81c85031e6f4bef8ffd8619a2578f1f5f4e269635b11d818f801230b0e7c0b491a6cd55a7a98bcab1cb6021e92d49f7f677
|
7
|
+
data.tar.gz: 2fff713b5cc2fe4dae297347edb3a54d4ee93c31d233d1406ad61a8d2f76ec1792c7693e5c56422b2f9a4011131c5d49454c4d9c3f44c0040d08f490298ad005
|
@@ -0,0 +1,30 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: ['*']
|
6
|
+
pull_request:
|
7
|
+
branches: [master]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version: ["2.5", "2.6", "2.7", "3.0"]
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v2
|
18
|
+
|
19
|
+
- name: Set up Ruby
|
20
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
21
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
22
|
+
# uses: ruby/setup-ruby@v1
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby-version }}
|
26
|
+
bundler-cache: true
|
27
|
+
- name: rubocop
|
28
|
+
run: bundle exec ./rubocop --display-style-guide --extra-details
|
29
|
+
- name: tests
|
30
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/.pryrc
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 3.0
|
3
|
+
NewCops: enable
|
4
|
+
SuggestExtensions: false
|
5
|
+
Exclude:
|
6
|
+
- 'bin/**/*'
|
7
|
+
- '.pryrc'
|
8
|
+
- 'vendor/**/*'
|
9
|
+
|
10
|
+
Layout/LineLength:
|
11
|
+
Max: 120
|
12
|
+
|
13
|
+
Style/AsciiComments:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Layout/SpaceInsideHashLiteralBraces:
|
17
|
+
EnforcedStyle: no_space
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Layout/DotPosition:
|
23
|
+
EnforcedStyle: trailing
|
24
|
+
|
25
|
+
Style/EmptyMethod:
|
26
|
+
EnforcedStyle: expanded
|
27
|
+
|
28
|
+
Layout/MultilineMethodCallIndentation:
|
29
|
+
EnforcedStyle: indented
|
30
|
+
|
31
|
+
Metrics/BlockLength:
|
32
|
+
Exclude:
|
33
|
+
- spec/**/*
|
34
|
+
|
35
|
+
Gemspec/RequiredRubyVersion:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Gemspec/RequireMFA:
|
39
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,114 +1,64 @@
|
|
1
|
-
[](https://travis-ci.org/yamax2/yandex_client)
|
2
|
-
|
3
1
|
# YandexClient
|
4
2
|
|
5
3
|
## Installation
|
6
4
|
|
7
5
|
Add this line to your application's Gemfile:
|
8
|
-
|
9
6
|
```ruby
|
10
|
-
gem 'yandex_client'
|
7
|
+
gem 'yandex_client', '>= 1'
|
11
8
|
```
|
12
9
|
|
13
10
|
And then execute:
|
14
|
-
|
15
|
-
|
11
|
+
```bash
|
12
|
+
$ bundle install
|
13
|
+
```
|
16
14
|
|
17
15
|
Or install it yourself as:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
## Usage
|
22
|
-
|
23
|
-
### [Auth](https://yandex.ru/dev/oauth/doc/dg/concepts/about-docpage/)
|
24
|
-
```ruby
|
25
|
-
cli = YandexClient::Auth::Client.new
|
16
|
+
```bash
|
17
|
+
$ gem install yandex_client
|
26
18
|
```
|
27
19
|
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
cli.create_token(code: 'your_code')
|
31
|
-
```
|
20
|
+
## Disk webdav
|
32
21
|
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
cli.refresh_token(refresh_token: 'your_token')
|
36
|
-
```
|
22
|
+
https://tech.yandex.ru/disk/doc/dg/reference/put-docpage/
|
37
23
|
|
38
|
-
|
24
|
+
Chainable client:
|
39
25
|
```ruby
|
40
|
-
|
26
|
+
YandexClient::Dav['your_access_token']
|
27
|
+
.put('1.txt', '/a/b/c/1.txt')
|
28
|
+
.put(File.open('1.txt', 'rb'), '/path/to/1.txt')
|
29
|
+
.put(Tempfile.new.tap { |t| t.write('say ni'); t.rewind }, '/path/to/tmp.txt')
|
30
|
+
.delete('/a/b/c/1.txt')
|
31
|
+
.mkcol('/a/b/c')
|
32
|
+
.propfind('/a/dip.yml', depth: 0)
|
33
|
+
.propfind('/a', depth: 1)
|
34
|
+
.propfind.to_a
|
41
35
|
```
|
42
36
|
|
43
|
-
|
44
|
-
```ruby
|
45
|
-
cli.info
|
46
|
-
```
|
37
|
+
## Disk rest api
|
47
38
|
|
48
|
-
|
49
|
-
|
50
|
-
cli = YandexClient::Dav::Client.new(access_token: 'your_token')
|
51
|
-
```
|
39
|
+
https://yandex.ru/dev/disk/api/reference/capacity-docpage/
|
40
|
+
https://yandex.ru/dev/disk/api/reference/content-docpage/
|
52
41
|
|
53
|
-
[put](https://yandex.ru/dev/disk/doc/dg/reference/put-docpage/)
|
54
42
|
```ruby
|
55
|
-
|
43
|
+
YandexClient::Disk['access_token'].info
|
44
|
+
YandexClient::Disk['access_token'].download_url('path/to/file')
|
45
|
+
YandexClient::Disk['access_token'].upload_url('path/to/file')
|
56
46
|
```
|
57
47
|
|
58
|
-
|
59
|
-
```ruby
|
60
|
-
cli.delete(name: '/a/b/c/1.txt')
|
61
|
-
```
|
48
|
+
## Auth
|
62
49
|
|
63
|
-
|
64
|
-
|
65
|
-
cli.mkcol(name: '/a/b/c')
|
66
|
-
```
|
67
|
-
|
68
|
-
[file props](https://yandex.ru/dev/disk/doc/dg/reference/property-request-docpage/)
|
69
|
-
```ruby
|
70
|
-
cli.propfind(name: '/a/dip.yml', depth: 0)
|
71
|
-
```
|
50
|
+
https://tech.yandex.ru/oauth/doc/dg/reference/refresh-client-docpage/
|
51
|
+
https://tech.yandex.ru/oauth/doc/dg/reference/auto-code-client-docpage/#auto-code-client__get-token
|
72
52
|
|
73
|
-
[list files in dir](https://yandex.ru/dev/disk/doc/dg/reference/property-request-docpage/)
|
74
53
|
```ruby
|
75
|
-
|
54
|
+
YandexClient.auth.create_token('9388894')
|
55
|
+
YandexClient.auth.refresh_token('refresh_token')
|
76
56
|
```
|
77
57
|
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
cli.propfind(name: '/', quota: true)
|
81
|
-
```
|
82
|
-
|
83
|
-
## Development
|
84
|
-
|
85
|
-
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.
|
86
|
-
|
87
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
58
|
+
## Passport
|
88
59
|
|
89
|
-
|
60
|
+
https://tech.yandex.ru/passport/doc/dg/reference/request-docpage/
|
90
61
|
|
91
|
-
|
92
|
-
|
93
|
-
```hash
|
94
|
-
gem install dip
|
95
|
-
```
|
96
|
-
* Prepare the the test environment
|
97
|
-
```bash
|
98
|
-
dip provision
|
99
|
-
```
|
100
|
-
* Run tests
|
101
|
-
```bash
|
102
|
-
dip rspec
|
62
|
+
```ruby
|
63
|
+
YandexClient::Passport::Client['access_token'].info
|
103
64
|
```
|
104
|
-
|
105
|
-
## TODO
|
106
|
-
* docs...
|
107
|
-
|
108
|
-
## Contributing
|
109
|
-
|
110
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/yamax2/yandex_client.
|
111
|
-
|
112
|
-
## License
|
113
|
-
|
114
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/dip.yml
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
version: '
|
1
|
+
version: '3.3'
|
2
2
|
|
3
3
|
environment:
|
4
|
-
DOCKER_RUBY_VERSION:
|
5
|
-
RUBY_IMAGE_TAG: 2.6.5
|
6
|
-
COMPOSE_FILE_EXT: development
|
4
|
+
DOCKER_RUBY_VERSION: 3.0
|
7
5
|
|
8
6
|
compose:
|
9
7
|
files:
|
10
8
|
- docker/docker-compose.yml
|
11
|
-
- docker/docker-compose.${COMPOSE_FILE_EXT}.yml
|
12
9
|
project_name: yandex_client
|
13
10
|
|
14
11
|
interaction:
|
@@ -17,7 +14,7 @@ interaction:
|
|
17
14
|
|
18
15
|
irb:
|
19
16
|
service: app
|
20
|
-
command:
|
17
|
+
command: bundle exec pry
|
21
18
|
|
22
19
|
bundle:
|
23
20
|
service: app
|
@@ -31,12 +28,16 @@ interaction:
|
|
31
28
|
service: app
|
32
29
|
command: bundle exec rspec
|
33
30
|
|
31
|
+
rubocop:
|
32
|
+
service: app
|
33
|
+
command: bundle exec ./rubocop --display-style-guide --extra-details
|
34
|
+
|
34
35
|
clean:
|
35
36
|
service: app
|
36
|
-
command: rm -
|
37
|
+
command: rm -rf Gemfile.lock
|
37
38
|
|
38
39
|
provision:
|
40
|
+
- ./docker/prepare_env.sh
|
39
41
|
- docker volume create --name bundler_data
|
40
42
|
- dip clean
|
41
43
|
- dip bundle install
|
42
|
-
- dip appraisal install
|
@@ -0,0 +1,8 @@
|
|
1
|
+
ARG DOCKER_RUBY_VERSION
|
2
|
+
FROM ruby:${DOCKER_RUBY_VERSION}-alpine
|
3
|
+
|
4
|
+
RUN gem update --system && \
|
5
|
+
apk add --update --no-cache tzdata less git build-base mc && \
|
6
|
+
cp /usr/share/zoneinfo/Asia/Yekaterinburg /etc/localtime && echo 'Asia/Yekaterinburg' > /etc/timezone
|
7
|
+
|
8
|
+
WORKDIR /app
|
data/docker/docker-compose.yml
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
-
version: '
|
1
|
+
version: '3.3'
|
2
2
|
|
3
3
|
services:
|
4
4
|
app:
|
5
5
|
build:
|
6
6
|
context: ../
|
7
|
-
dockerfile: ./docker/Dockerfile
|
7
|
+
dockerfile: ./docker/Dockerfile.dip
|
8
|
+
args:
|
9
|
+
DOCKER_RUBY_VERSION: $DOCKER_RUBY_VERSION
|
10
|
+
labels:
|
11
|
+
com.yandex-client.ruby.version: $DOCKER_RUBY_VERSION
|
8
12
|
environment:
|
9
|
-
- BUNDLE_PATH=/bundle/$DOCKER_RUBY_VERSION
|
10
|
-
|
11
|
-
-
|
12
|
-
-
|
13
|
-
|
14
|
-
|
13
|
+
- BUNDLE_PATH=/bundle/${DOCKER_RUBY_VERSION}
|
14
|
+
volumes:
|
15
|
+
- ..:/app
|
16
|
+
- bundler-data:/bundle
|
17
|
+
command: sh
|
18
|
+
|
19
|
+
volumes:
|
20
|
+
bundler-data:
|
21
|
+
external:
|
22
|
+
name: bundler_data
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
for line in $(docker images -f "label=com.yandex-client.ruby.version" -q | uniq); do
|
6
|
+
ver=$(docker inspect --format '{{ index .Config.Labels "com.yandex-client.ruby.version"}}' $line)
|
7
|
+
|
8
|
+
if ! [ $ver = $DOCKER_RUBY_VERSION ]; then
|
9
|
+
docker image rm --force $line
|
10
|
+
fi
|
11
|
+
done
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YandexClient
|
4
|
+
# https://tech.yandex.ru/oauth/doc/dg/reference/refresh-client-docpage/
|
5
|
+
# https://tech.yandex.ru/oauth/doc/dg/reference/auto-code-client-docpage/#auto-code-client__get-token
|
6
|
+
#
|
7
|
+
# https://oauth.yandex.ru/authorize?response_type=code&client_id=ede5c51271164a9e833ab9119b4d3c26&force_confirm=false
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# token = Token.first
|
11
|
+
#
|
12
|
+
# YandexClient.auth.create_token('9388894')
|
13
|
+
# YandexClient.auth.refresh_token(token.refresh_token)
|
14
|
+
class Auth
|
15
|
+
include Configurable
|
16
|
+
include ErrorHandler
|
17
|
+
|
18
|
+
ACTION_URL = 'https://oauth.yandex.ru/token'
|
19
|
+
|
20
|
+
def create_token(code)
|
21
|
+
process_response with_config.post(
|
22
|
+
ACTION_URL,
|
23
|
+
headers: common_headers,
|
24
|
+
body: URI.encode_www_form(
|
25
|
+
request_body_for('authorization_code').merge!(code: code)
|
26
|
+
)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def refresh_token(refresh_token)
|
31
|
+
process_response with_config.post(
|
32
|
+
ACTION_URL,
|
33
|
+
headers: common_headers,
|
34
|
+
body: URI.encode_www_form(
|
35
|
+
request_body_for('refresh_token').merge!(refresh_token: refresh_token)
|
36
|
+
)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def common_headers
|
43
|
+
{'Content-type' => 'application/x-www-form-urlencoded'}
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_body_for(grant_type)
|
47
|
+
{
|
48
|
+
grant_type: grant_type,
|
49
|
+
client_id: config.api_key,
|
50
|
+
client_secret: config.api_secret
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_response(response)
|
55
|
+
if response.status.success?
|
56
|
+
JSON.parse(response.body, symbolize_names: true)
|
57
|
+
else
|
58
|
+
error_for_response(response)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YandexClient
|
4
|
+
module Configurable
|
5
|
+
def self.included(base)
|
6
|
+
base.extend Forwardable
|
7
|
+
base.def_delegator :YandexClient, :config
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def with_config
|
13
|
+
req = HTTP.timeout(
|
14
|
+
connect: config.connect_timeout,
|
15
|
+
read: config.read_timeout,
|
16
|
+
write: config.write_timeout
|
17
|
+
)
|
18
|
+
|
19
|
+
if config.logger
|
20
|
+
req.use(logging: {logger: config.logger})
|
21
|
+
else
|
22
|
+
req
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ox'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module YandexClient
|
7
|
+
class Dav
|
8
|
+
class PropFindResponse
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
SUCCESS_STATUS = 'HTTP/1.1 200 OK'
|
12
|
+
|
13
|
+
class Item
|
14
|
+
attr_reader :name, :created_at, :last_modified, :content_type
|
15
|
+
|
16
|
+
def initialize(name, node)
|
17
|
+
@name = name
|
18
|
+
@folder = node[:'d:resourcetype'].is_a?(Hash)
|
19
|
+
|
20
|
+
load_node_data(node)
|
21
|
+
end
|
22
|
+
|
23
|
+
def folder?
|
24
|
+
@folder
|
25
|
+
end
|
26
|
+
|
27
|
+
def file?
|
28
|
+
!@folder
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def load_node_data(node)
|
34
|
+
@created_at = node.fetch(:'d:creationdate')
|
35
|
+
@last_modified = node.fetch(:'d:getlastmodified')
|
36
|
+
|
37
|
+
return if folder?
|
38
|
+
|
39
|
+
@etag = node.fetch(:'d:getetag')
|
40
|
+
@size = node.fetch(:'d:getcontentlength').to_i
|
41
|
+
@content_type = node.fetch(:'d:getcontenttype')
|
42
|
+
|
43
|
+
define_singleton_method(:etag) { @etag }
|
44
|
+
define_singleton_method(:size) { @size }
|
45
|
+
define_singleton_method(:content_type) { @content_type }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(xml)
|
50
|
+
@doc = Ox.load(
|
51
|
+
xml.dup.force_encoding('UTF-8'),
|
52
|
+
mode: :hash
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def each
|
57
|
+
@doc[:'d:multistatus'].each do |node|
|
58
|
+
next if (response = node[:'d:response']).nil?
|
59
|
+
|
60
|
+
name = CGI.unescape(response.fetch(:'d:href'))
|
61
|
+
node_data = response.fetch(:'d:propstat')
|
62
|
+
|
63
|
+
raise ParseError unless node_data.fetch(:'d:status') == SUCCESS_STATUS
|
64
|
+
|
65
|
+
yield Item.new(name, node_data.fetch(:'d:prop'))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'http'
|
5
|
+
require 'yandex_client/dav/prop_find_response'
|
6
|
+
|
7
|
+
module YandexClient
|
8
|
+
# https://tech.yandex.ru/disk/doc/dg/reference/put-docpage/
|
9
|
+
#
|
10
|
+
# Chainable client:
|
11
|
+
#
|
12
|
+
# YandexClient::Dav[access_token]
|
13
|
+
# .put('1.txt', '/a/b/c/1.txt')
|
14
|
+
# .put(File.open('1.txt', 'rb'), '/path/to/1.txt')
|
15
|
+
# .put(Tempfile.new.tap { |t| t.write('say ni'); t.rewind }, '/path/to/tmp.txt')
|
16
|
+
# .delete('/a/b/c/1.txt')
|
17
|
+
# .mkcol('/a/b/c')
|
18
|
+
# .propfind('/a/dip.yml', depth: 0)
|
19
|
+
# .propfind('/a', depth: 1)
|
20
|
+
# .propfind.to_a
|
21
|
+
class Dav
|
22
|
+
include Configurable
|
23
|
+
include ErrorHandler
|
24
|
+
|
25
|
+
ACTION_URL = 'https://webdav.yandex.ru'
|
26
|
+
PROPFIND_QUERY = '<?xml version="1.0" encoding="utf-8"?><propfind xmlns="DAV:"></propfind>'
|
27
|
+
|
28
|
+
attr_reader :token
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def with_token(token)
|
32
|
+
new(token)
|
33
|
+
end
|
34
|
+
|
35
|
+
alias [] with_token
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(token)
|
39
|
+
@token = token
|
40
|
+
end
|
41
|
+
|
42
|
+
def put(file, dest, etag: nil, sha256: nil, size: nil)
|
43
|
+
io = file.is_a?(String) ? File.open(file, 'rb') : file
|
44
|
+
|
45
|
+
headers = auth_headers.merge!(
|
46
|
+
'Etag' => etag || Digest::MD5.file(io.path),
|
47
|
+
'Sha256' => sha256 || Digest::SHA256.file(io.path),
|
48
|
+
'Expect' => '100-continue',
|
49
|
+
'Content-Length' => (size || File.size(io.path)).to_s
|
50
|
+
)
|
51
|
+
|
52
|
+
process_response with_config.put(url_for(dest), body: io, headers: headers)
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete(dest)
|
56
|
+
process_response with_config.delete(
|
57
|
+
url_for(dest),
|
58
|
+
headers: auth_headers
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def mkcol(dest)
|
63
|
+
process_response with_config.request(
|
64
|
+
:mkcol,
|
65
|
+
url_for(dest),
|
66
|
+
headers: auth_headers
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def propfind(dest = '', depth = 1)
|
71
|
+
headers = auth_headers.merge!(
|
72
|
+
Depth: depth.to_s,
|
73
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
74
|
+
'Content-Length' => PROPFIND_QUERY.length
|
75
|
+
)
|
76
|
+
|
77
|
+
response = with_config.request(:propfind, url_for(dest), headers: headers, body: PROPFIND_QUERY)
|
78
|
+
process_response(response)
|
79
|
+
|
80
|
+
PropFindResponse.new(response.body.to_s)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def auth_headers
|
86
|
+
{Authorization: "OAuth #{token}"}
|
87
|
+
end
|
88
|
+
|
89
|
+
def url_for(dest)
|
90
|
+
URI.parse(ACTION_URL).tap do |uri|
|
91
|
+
path = dest
|
92
|
+
path = "/#{path}" unless path.match?(%r{^/})
|
93
|
+
|
94
|
+
uri.path = path
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def process_response(response)
|
99
|
+
return self if response.status.success?
|
100
|
+
|
101
|
+
error_for_response(response)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module YandexClient
|
6
|
+
# https://yandex.ru/dev/disk/api/reference/capacity-docpage/
|
7
|
+
# https://yandex.ru/dev/disk/api/reference/content-docpage/
|
8
|
+
#
|
9
|
+
# YandexClient::Disk[access_token].info
|
10
|
+
# YandexClient::Disk[access_token].download_url('path/to/file')
|
11
|
+
# YandexClient::Disk[access_token].download_url('path/to/file', overwrite: false)
|
12
|
+
class Disk
|
13
|
+
include Configurable
|
14
|
+
include ErrorHandler
|
15
|
+
|
16
|
+
ACTION_URL = 'https://cloud-api.yandex.net'
|
17
|
+
|
18
|
+
attr_reader :token
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def with_token(token)
|
22
|
+
new(token)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias [] with_token
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(token)
|
29
|
+
@token = token
|
30
|
+
end
|
31
|
+
|
32
|
+
def info
|
33
|
+
process_response(
|
34
|
+
with_config.get("#{ACTION_URL}/v1/disk/", headers: auth_headers)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def download_url(path)
|
39
|
+
url = URI.parse(ACTION_URL).tap do |uri|
|
40
|
+
uri.path = '/v1/disk/resources/download'
|
41
|
+
uri.query = URI.encode_www_form(path: path)
|
42
|
+
end
|
43
|
+
|
44
|
+
process_response(
|
45
|
+
with_config.get(url, headers: auth_headers)
|
46
|
+
).fetch(:href)
|
47
|
+
end
|
48
|
+
|
49
|
+
def upload_url(path, overwrite: false)
|
50
|
+
url = URI.parse(ACTION_URL).tap do |uri|
|
51
|
+
uri.path = '/v1/disk/resources/upload'
|
52
|
+
uri.query = URI.encode_www_form(path: ::CGI.escape(path), overwrite: overwrite)
|
53
|
+
end
|
54
|
+
|
55
|
+
process_response(
|
56
|
+
with_config.get(url, headers: auth_headers)
|
57
|
+
).fetch(:href)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def auth_headers
|
63
|
+
{Authorization: "OAuth #{@token}"}
|
64
|
+
end
|
65
|
+
|
66
|
+
def process_response(response)
|
67
|
+
return JSON.parse(response.body, symbolize_names: true) if response.status.success?
|
68
|
+
|
69
|
+
error_for_response(response)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|