yandex_client 0.2.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bb3f0eb258b31efd0147df7db347df6d9bef47a24fcde9d84d44fdc4e033adb
4
- data.tar.gz: 6ec4eb7101152d430ba1dd1ba73863b48a8e5ecd727fd1a9d28f9bcc6dd5975a
3
+ metadata.gz: a211416fcc989ba097fb90416dd31415137ef6c0a20ad56b4df5ea3e5a3a83e9
4
+ data.tar.gz: d470d0894fafe9464b54ab8274d82c3a9272e8108b2189387525079a1b2698ae
5
5
  SHA512:
6
- metadata.gz: ed4e0e3bf4d35c0796421c8ecde6653446628a909bc2a688acdc1f75ceedaa2c47820bfa95ae9b22b40ae52709d722f1dfb44a923e10ec7b82904b2d24d3126a
7
- data.tar.gz: c2aa86695f8a5973d0ba86940ea7e916cfe65fe57934d4cdee4db3bb94d9083d2d1595ae8dded4021f253e6451909f308d845ef28fdfec2461c2ca86aab7e121
6
+ metadata.gz: 2c1d214066d1d32b0d636727b6fb648cfc054018ba3fe069fbd942452c52a35e6997de816f8d237597dafa80245bc6b6442bc9efe77293383539a535e52d97f1
7
+ data.tar.gz: fe3e3b361aef6101a150b00b9fb833bb72040d95c1598f89490c502aa3bb6ccf94c8797f7008928e3ad07239eff1fb91a3e6a6f53f649132955fe81f161d8fc1
@@ -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
@@ -14,3 +14,5 @@
14
14
  .byebug_history
15
15
 
16
16
  Gemfile.lock
17
+ .irb-save-history
18
+ coverage
data/.pryrc ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ Pry.config.history_file = "#{File.dirname(__FILE__)}/.irb-save-history"
4
+
5
+ require 'bundler/setup'
6
+ require 'yandex_client'
data/.rubocop.yml CHANGED
@@ -1,8 +1,11 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.4
2
+ TargetRubyVersion: 3.0
3
+ NewCops: enable
4
+ SuggestExtensions: false
3
5
  Exclude:
4
6
  - 'bin/**/*'
5
7
  - '.pryrc'
8
+ - 'vendor/**/*'
6
9
 
7
10
  Layout/LineLength:
8
11
  Max: 120
@@ -28,3 +31,6 @@ Layout/MultilineMethodCallIndentation:
28
31
  Metrics/BlockLength:
29
32
  Exclude:
30
33
  - spec/**/*
34
+
35
+ Gemspec/RequiredRubyVersion:
36
+ Enabled: false
data/Gemfile CHANGED
@@ -5,5 +5,7 @@ source 'https://rubygems.org'
5
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  gem 'pry-byebug'
8
+ gem 'rubocop', require: false
9
+ gem 'rubocop-rspec', require: false
8
10
 
9
11
  gemspec
data/README.md CHANGED
@@ -1,126 +1,63 @@
1
- [![Build Status](https://travis-ci.org/yamax2/yandex_client.svg?branch=master)](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
- $ bundle
11
+ ```bash
12
+ $ bundle install
13
+ ```
16
14
 
17
15
  Or install it yourself as:
18
-
19
- $ gem install yandex_client
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
- [create_token](https://tech.yandex.ru/oauth/doc/dg/reference/auto-code-client-docpage/#auto-code-client__get-token)
29
- ```ruby
30
- cli.create_token(code: 'your_code')
31
- ```
20
+ ## Disk webdav
32
21
 
33
- [refresh_token](https://yandex.ru/dev/oauth/doc/dg/reference/refresh-client-docpage/)
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
- ### [Passport](https://tech.yandex.ru/passport/doc/dg/reference/)
24
+ Chainable client:
39
25
  ```ruby
40
- cli = YandexClient::Passport::Client.new(access_token: 'your_access_token')
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
- [info](https://yandex.ru/dev/passport/doc/dg/reference/request-docpage/)
44
- ```ruby
45
- cli.info
46
- ```
37
+ ## Disk rest api
47
38
 
48
- ### [Yandex Disk WebDav](https://yandex.ru/dev/disk/doc/dg/concepts/quickstart-docpage/)
49
- ```ruby
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
- cli.put(file: '1.txt', name: '/a/b/c/1.txt')
43
+ YandexClient::Disk['access_token'].info
44
+ YandexClient::Disk['access_token'].download_url('path/to/file')
56
45
  ```
57
46
 
58
- [delete](https://yandex.ru/dev/disk/doc/dg/reference/delete-docpage/)
59
- ```ruby
60
- cli.delete(name: '/a/b/c/1.txt')
61
- ```
47
+ ## Auth
62
48
 
63
- [mkcol](https://yandex.ru/dev/disk/doc/dg/reference/mkcol-docpage/)
64
- ```ruby
65
- cli.mkcol(name: '/a/b/c')
66
- ```
49
+ https://tech.yandex.ru/oauth/doc/dg/reference/refresh-client-docpage/
50
+ https://tech.yandex.ru/oauth/doc/dg/reference/auto-code-client-docpage/#auto-code-client__get-token
67
51
 
68
- [file props](https://yandex.ru/dev/disk/doc/dg/reference/property-request-docpage/)
69
52
  ```ruby
70
- cli.propfind(name: '/a/dip.yml', depth: 0)
53
+ YandexClient.auth.create_token('9388894')
54
+ YandexClient.auth.refresh_token('refresh_token')
71
55
  ```
72
56
 
73
- [list files in dir](https://yandex.ru/dev/disk/doc/dg/reference/property-request-docpage/)
74
- ```ruby
75
- cli.propfind(name: '/a', depth: 1)
76
- ```
77
-
78
- [account free space and quota](https://yandex.ru/dev/disk/doc/dg/reference/property-request-docpage/)
79
- ```ruby
80
- cli.propfind(name: '/', quota: true)
81
- ```
57
+ ## Passport
82
58
 
83
- ### [Yandex Disk Rest](https://yandex.ru/dev/disk/api/concepts/about-docpage/)
84
- ```ruby
85
- cli = YandexClient::Disk::Client.new(access_token: 'your_token')
86
- ```
59
+ https://tech.yandex.ru/passport/doc/dg/reference/request-docpage/
87
60
 
88
- [info](https://yandex.ru/dev/disk/api/reference/capacity-docpage/)
89
61
  ```ruby
90
- cli.info
91
- ```
92
-
93
- [download_url](https://yandex.ru/dev/disk/api/reference/content-docpage/)
94
- ```ruby
95
- cli.download_url(path: '/test')
96
- ```
97
-
98
- ## Development
99
-
100
- 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.
101
-
102
- 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).
103
-
104
- ## Development with docker
105
-
106
- * Install docker and docker-compose
107
- * Install [dip](https://github.com/bibendi/dip)
108
- ```hash
109
- gem install dip
110
- ```
111
- * Prepare the the test environment
112
- ```bash
113
- dip provision
62
+ YandexClient::Passport::Client['access_token'].info
114
63
  ```
115
- * Run tests
116
- ```bash
117
- dip rspec
118
- ```
119
-
120
- ## Contributing
121
-
122
- Bug reports and pull requests are welcome on GitHub at https://github.com/yamax2/yandex_client.
123
-
124
- ## License
125
-
126
- 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'
1
+ version: '3.3'
2
2
 
3
3
  environment:
4
- DOCKER_RUBY_VERSION: 2.6
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: irb
17
+ command: bundle exec pry
21
18
 
22
19
  bundle:
23
20
  service: app
@@ -31,16 +28,16 @@ interaction:
31
28
  service: app
32
29
  command: bundle exec rspec
33
30
 
34
- clean:
31
+ rubocop:
35
32
  service: app
36
- command: rm -f Gemfile.lock
33
+ command: bundle exec ./rubocop --display-style-guide --extra-details
37
34
 
38
- rubocop:
35
+ clean:
39
36
  service: app
40
- command: rubocop
37
+ command: rm -rf Gemfile.lock
41
38
 
42
39
  provision:
40
+ - ./docker/prepare_env.sh
43
41
  - docker volume create --name bundler_data
44
42
  - dip clean
45
43
  - dip bundle install
46
- - 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
@@ -1,14 +1,22 @@
1
- version: '2'
1
+ version: '3.3'
2
2
 
3
3
  services:
4
4
  app:
5
5
  build:
6
6
  context: ../
7
- dockerfile: ./docker/Dockerfile.${DOCKER_RUBY_VERSION}
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
- - SSH_AUTH_SOCK=/ssh/auth/sock
11
- - TEST_DB_HOST=db
12
- - TEST_DB_NAME=docker
13
- - TEST_DB_USERNAME=postgres
14
- command: bash
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