vkontakte_api 1.1 → 1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d37878c023a9ef41c525a2e80d94a1116bf7cdf4
4
+ data.tar.gz: d6bee0ae8a1dfa7a74d74e26327f5cf880214e9b
5
+ SHA512:
6
+ metadata.gz: 100e3698409e4c1c76ac1adbbb75609675b92c965905e5218b32cc5f1dae49d0f69783db01bb7ca5729e724bae8e4718e0f3ffc7cb8ec8cc86a87a7e0d399301
7
+ data.tar.gz: 43b9a423fd114d904b395f34fdf510eb72a48657722b2a88c2e15f82bdb8544b6aa2180fe8eb225a3e28aec20b12bbf3bc31cabb788f1f34739f62457d7ada19
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  .yardoc/*
6
+ spec/support/credentials.yml
data/.travis.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  rvm:
2
- - 1.8.7
3
2
  - 1.9.2
4
3
  - 1.9.3
5
- # - ruby-head
4
+ - 2.0.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.2 (14.07.2013)
2
+
3
+ * Повтор запроса при определенных ошибках
4
+ * Корректная работа метода `messages.send`
5
+ * Поддержка параметров `captcha_sid` и `captcha_img` при ошибке 14
6
+
1
7
  ## 1.1 (18.12.2012)
2
8
 
3
9
  * Передача `redirect_uri` при получении токена
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in vkontakte_api.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ## vkontakte_api [![Build Status](https://secure.travis-ci.org/7even/vkontakte_api.png)](http://travis-ci.org/7even/vkontakte_api) [![Dependency Status](https://gemnasium.com/7even/vkontakte_api.png)](https://gemnasium.com/7even/vkontakte_api) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/7even/vkontakte_api)
1
+ ## vkontakte_api [![Build Status](https://secure.travis-ci.org/7even/vkontakte_api.png)](http://travis-ci.org/7even/vkontakte_api) [![Gem Version](https://badge.fury.io/rb/vkontakte_api.png)](http://badge.fury.io/rb/vkontakte_api) [![Dependency Status](https://gemnasium.com/7even/vkontakte_api.png)](https://gemnasium.com/7even/vkontakte_api) [![Code Climate](https://codeclimate.com/github/7even/vkontakte_api.png)](https://codeclimate.com/github/7even/vkontakte_api)
2
2
 
3
3
  `vkontakte_api` - ruby-адаптер для ВКонтакте API. Он позволяет вызывать методы API, загружать файлы на сервера ВКонтакте, а также поддерживает все 3 доступных способа авторизации (при этом позволяя использовать стороннее решение).
4
4
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ``` ruby
8
8
  # Gemfile
9
- gem 'vkontakte_api', '~> 1.0'
9
+ gem 'vkontakte_api', '~> 1.2'
10
10
  ```
11
11
 
12
12
  или просто
@@ -78,7 +78,7 @@ VkontakteApi.upload(url: url, photo: ['/path/to/file.jpg', 'image/jpeg'])
78
78
 
79
79
  Авторизация сайтов проходит в 2 шага. Сначала пользователь перенаправляется на страницу ВКонтакте для подтверждения запрошенных у него прав сайта на доступ к его данным. Со списком возможных прав можно ознакомиться [здесь](http://vk.com/developers.php?oid=-1&p=%D0%9F%D1%80%D0%B0%D0%B2%D0%B0_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9). Допустим, нужно получить доступ к друзьям (`friends`) и фотографиям (`photos`) пользователя.
80
80
 
81
- В соответствии с [рекомендациями](http://tools.ietf.org/html/draft-ietf-oauth-v2-30#section-10.12) в протоколе OAuth2 для защиты от [CSRF](http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D0%BB%D0%BA%D0%B0_%D0%BC%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D1%85_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2), нужно передать параметр `state`, содержащий случайное значение. На данный момент по непонятным причинам ВКонтакте игнорирует этот параметр, если в `scope` не указан `notify`.
81
+ В соответствии с [рекомендациями](http://tools.ietf.org/html/draft-ietf-oauth-v2-30#section-10.12) в протоколе OAuth2 для защиты от [CSRF](http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D0%BB%D0%BA%D0%B0_%D0%BC%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D1%85_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2), нужно передать параметр `state`, содержащий случайное значение.
82
82
 
83
83
  ``` ruby
84
84
  session[:state] = Digest::MD5.hexdigest(rand.to_s)
@@ -181,6 +181,8 @@ vk.friends.get(uid: 1, fields: [:first_name, :last_name, :photo])
181
181
  # VkontakteApi::Error: VKontakte returned an error 7: 'Permission to perform this action is denied' after calling method 'friends.get' with parameters {"uid"=>"1", "fields"=>"first_name,last_name,photo"}.
182
182
  ```
183
183
 
184
+ Особый случай ошибки - 14: необходимо ввести код с captcha. В этом случае можно получить параметры капчи методами `VkontakteApi::Error#captcha_sid` и `VkontakteApi::Error#captcha_img` - например, [так](https://github.com/7even/vkontakte_api/issues/10#issuecomment-11666091).
185
+
184
186
  ### Логгирование
185
187
 
186
188
  `vkontakte_api` логгирует служебную информацию о запросах при вызове методов. По умолчанию все пишется в `STDOUT`, но в настройке можно указать любой другой совместимый логгер, например `Rails.logger`.
@@ -197,7 +199,9 @@ vk.friends.get(uid: 1, fields: [:first_name, :last_name, :photo])
197
199
 
198
200
  ### Пример использования
199
201
 
200
- [Здесь](http://vkontakte-on-rails.herokuapp.com/) можно посмотреть пример использования `vkontakte_api` в rails-приложении (используются только читающие методы *.get - приложение ничего не пишет на ВКонтакте, только читает). Исходный код можно посмотреть [тут](https://github.com/7even/vkontakte_on_rails).
202
+ Пример использования `vkontakte_api` совместно с `eventmachine` можно посмотреть [здесь](https://github.com/7even/vkontakte_on_em).
203
+
204
+ Также был написан [пример использования с rails](https://github.com/7even/vkontakte_on_rails), но он больше не работает из-за отсутствия прав на вызов метода `newsfeed.get`.
201
205
 
202
206
  ## Настройка
203
207
 
@@ -226,6 +230,8 @@ VkontakteApi.configure do |config|
226
230
  password: 'bar'
227
231
  }
228
232
  }
233
+ # максимальное количество повторов запроса при ошибках
234
+ config.max_retries = 2
229
235
 
230
236
  # логгер
231
237
  config.logger = Rails.logger
@@ -256,14 +262,11 @@ $ rails generate vkontakte_api:install
256
262
 
257
263
  ## Roadmap
258
264
 
259
- * метод, возвращающий права текущего токена в читабельной форме (используя `getUserSettings` и кэшируя результат)
260
- * сохранение параметра `expires_at` токена в объекте `VkontakteApi::Client` после авторизации через `VkontakteApi.authorize`
261
- * метод `VkontakteApi::Client#offline?`, проверяющий, является ли токен бесконечным, используя значение `VkontakteApi::Client#expires_at`
262
- * `POST`-запросы по умолчанию
263
- * логгирование тела `POST`-запроса
265
+ * настраиваемый retry запроса при стандартных исключениях
266
+ * CLI-интерфейс с автоматической авторизацией
264
267
 
265
268
  ## Участие в разработке
266
269
 
267
270
  Если вы хотите поучаствовать в разработке проекта, форкните репозиторий, положите свои изменения в отдельную ветку, покройте их спеками и отправьте мне pull request.
268
271
 
269
- `vkontakte_api` тестируется под MRI `1.8.7`, `1.9.2` и `1.9.3`. Если в одной из этих сред что-то работает неправильно, либо вообще не работает, то это следует считать багом, и написать об этом в [issues на Github](https://github.com/7even/vkontakte_api/issues).
272
+ `vkontakte_api` тестируется под MRI `1.9.2`, `1.9.3` и `2.0.0`. Если в одной из этих сред что-то работает неправильно, либо вообще не работает, то это следует считать багом, и написать об этом в [issues на Github](https://github.com/7even/vkontakte_api/issues).
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'bundler/gem_tasks'
2
2
 
3
3
  desc 'Fires up the console with preloaded vkontakte_api'
4
4
  task :console do
5
- sh 'pry -I ./lib/ -r ./lib/vkontakte_api.rb'
5
+ sh 'pry -I ./lib -r ./lib/vkontakte_api'
6
6
  end
7
7
 
8
8
  require 'rspec/core/rake_task'
@@ -10,4 +10,4 @@ RSpec::Core::RakeTask.new do |t|
10
10
  t.rspec_opts = '--color --format doc'
11
11
  end
12
12
 
13
- task :default => :spec
13
+ task default: :spec
@@ -14,7 +14,7 @@ module VkontakteApi
14
14
  # @return [Hashie::Mash] Mashed server response.
15
15
  def call(method_name, args = {}, token = nil)
16
16
  flat_arguments = Utils.flatten_arguments(args)
17
- connection(:url => URL_PREFIX, :token => token).send(VkontakteApi.http_verb, method_name, flat_arguments).body
17
+ connection(url: URL_PREFIX, token: token).send(VkontakteApi.http_verb, method_name, flat_arguments).body
18
18
  end
19
19
 
20
20
  # Faraday connection.
@@ -30,9 +30,10 @@ module VkontakteApi
30
30
  builder.request :oauth2, token unless token.nil?
31
31
  builder.request :multipart
32
32
  builder.request :url_encoded
33
+ builder.request :retry, VkontakteApi.max_retries
33
34
  builder.response :vk_logger
34
35
  builder.response :mashify
35
- builder.response :oj, :preserve_raw => true
36
+ builder.response :oj, preserve_raw: true
36
37
  builder.adapter VkontakteApi.adapter
37
38
  end
38
39
  end
@@ -5,12 +5,12 @@ module VkontakteApi
5
5
  module Authorization
6
6
  # Authorization options.
7
7
  OPTIONS = {
8
- :client => {
9
- :site => 'https://oauth.vk.com',
10
- :authorize_url => '/authorize',
11
- :token_url => '/access_token'
8
+ client: {
9
+ site: 'https://oauth.vk.com',
10
+ authorize_url: '/authorize',
11
+ token_url: '/access_token'
12
12
  },
13
- :client_credentials => {
13
+ client_credentials: {
14
14
  'auth_scheme' => 'request_body'
15
15
  }
16
16
  }
@@ -5,23 +5,23 @@ module VkontakteApi
5
5
 
6
6
  # Access rights and their respective number representation.
7
7
  SCOPE = {
8
- :notify => 1,
9
- :friends => 2,
10
- :photos => 4,
11
- :audio => 8,
12
- :video => 16,
13
- :offers => 32,
14
- :questions => 64,
15
- :pages => 128,
16
- :status => 1024,
17
- :notes => 2048,
18
- :messages => 4096,
19
- :wall => 8192,
20
- :ads => 32768,
21
- :docs => 131072,
22
- :groups => 262144,
23
- :notifications => 524288,
24
- :stats => 1048576
8
+ notify: 1,
9
+ friends: 2,
10
+ photos: 4,
11
+ audio: 8,
12
+ video: 16,
13
+ offers: 32,
14
+ questions: 64,
15
+ pages: 128,
16
+ status: 1024,
17
+ notes: 2048,
18
+ messages: 4096,
19
+ wall: 8192,
20
+ ads: 32768,
21
+ docs: 131072,
22
+ groups: 262144,
23
+ notifications: 524288,
24
+ stats: 1048576
25
25
  }
26
26
 
27
27
  # An access token needed by authorized requests.
@@ -13,6 +13,7 @@ module VkontakteApi
13
13
  :adapter,
14
14
  :http_verb,
15
15
  :faraday_options,
16
+ :max_retries,
16
17
  :logger,
17
18
  :log_requests,
18
19
  :log_errors,
@@ -31,11 +32,14 @@ module VkontakteApi
31
32
  # Default HTTP verb for API methods.
32
33
  DEFAULT_HTTP_VERB = :post
33
34
 
35
+ # Default max retries count.
36
+ DEFAULT_MAX_RETRIES = 2
37
+
34
38
  # Logger default options.
35
39
  DEFAULT_LOGGER_OPTIONS = {
36
- :requests => true,
37
- :errors => true,
38
- :responses => false
40
+ requests: true,
41
+ errors: true,
42
+ responses: false
39
43
  }
40
44
 
41
45
  # A global configuration set via the block.
@@ -54,6 +58,7 @@ module VkontakteApi
54
58
  @adapter = DEFAULT_ADAPTER
55
59
  @http_verb = DEFAULT_HTTP_VERB
56
60
  @faraday_options = {}
61
+ @max_retries = DEFAULT_MAX_RETRIES
57
62
  @logger = ::Logger.new(STDOUT)
58
63
  @log_requests = DEFAULT_LOGGER_OPTIONS[:requests]
59
64
  @log_errors = DEFAULT_LOGGER_OPTIONS[:errors]
@@ -4,6 +4,12 @@ module VkontakteApi
4
4
  # An error code.
5
5
  # @return [Fixnum]
6
6
  attr_reader :error_code
7
+ # Captcha identifier (only for "Captcha needed" errors).
8
+ # @return [String]
9
+ attr_reader :captcha_sid
10
+ # Captcha image URL (only for "Captcha needed" errors).
11
+ # @return [String]
12
+ attr_reader :captcha_img
7
13
 
8
14
  # An exception is initialized by the data from response mash.
9
15
  # @param [Hash] data Error data.
@@ -17,6 +23,9 @@ module VkontakteApi
17
23
  @access_token = request_params.delete('access_token')
18
24
  @oauth = request_params.delete('oauth')
19
25
  @params = request_params
26
+
27
+ @captcha_sid = data.captcha_sid
28
+ @captcha_img = data.captcha_img
20
29
  end
21
30
 
22
31
  # A full description of the error.
@@ -33,4 +33,4 @@ module VkontakteApi
33
33
  end
34
34
  end
35
35
 
36
- Faraday.register_middleware :response, :vk_logger => VkontakteApi::Logger
36
+ Faraday.register_middleware :response, vk_logger: VkontakteApi::Logger
@@ -27,3 +27,6 @@
27
27
  - auth
28
28
  - ads
29
29
  - orders
30
+ - search
31
+ - apps
32
+ - utils
@@ -10,17 +10,17 @@ module VkontakteApi
10
10
 
11
11
  if Resolver.namespaces.include?(method_name)
12
12
  # called from Client
13
- Namespace.new(method_name, :resolver => resolver)
13
+ Namespace.new(method_name, resolver: resolver)
14
14
  else
15
15
  # called from Namespace or one-level method
16
- Method.new(method_name, :resolver => resolver).call(args.first || {}, &block)
16
+ Method.new(method_name, resolver: resolver).call(args.first || {}, &block)
17
17
  end
18
18
  end
19
19
 
20
20
  # A `Hashie::Mash` structure holding the name and token of current instance.
21
21
  # @return [Hashie::Mash]
22
22
  def resolver
23
- @resolver ||= Hashie::Mash.new(:name => @name, :token => token)
23
+ @resolver ||= Hashie::Mash.new(name: @name, token: token)
24
24
  end
25
25
 
26
26
  class << self
@@ -35,6 +35,14 @@ module VkontakteApi
35
35
 
36
36
  @namespaces
37
37
  end
38
+
39
+ # When this module is included, it undefines the `:send` instance method in the `base_class`
40
+ # so it can be resolved via `method_missing`.
41
+ def included(base_class)
42
+ base_class.class_eval do
43
+ undef_method :send
44
+ end
45
+ end
38
46
  end
39
47
  end
40
48
  end
@@ -1,4 +1,4 @@
1
1
  module VkontakteApi
2
2
  # Library version.
3
- VERSION = '1.1'
3
+ VERSION = '1.2'
4
4
  end
@@ -18,33 +18,35 @@ describe "Integration" do
18
18
  end
19
19
 
20
20
  it "get users" do
21
- user = @vk.users.get(:uid => 1).first
22
- user.uid.should == 1
23
- user.last_name.should_not be_empty
21
+ user = @vk.users.get(uid: 1).first
22
+ user.uid.should == 1
23
+ user.last_name.should_not be_empty
24
24
  user.first_name.should_not be_empty
25
25
  end
26
26
  end
27
27
 
28
- describe "authorized requests" do
29
- before(:each) do
30
- @vk = VK::Client.new(ENV['TOKEN'])
31
- end
32
-
33
- it "get groups" do
34
- groups = @vk.groups.get
35
- groups.should include(1)
36
- end
37
- end if ENV['TOKEN']
38
-
39
- describe "requests with camelCase and predicate methods" do
40
- before(:each) do
41
- @vk = VK::Client.new(ENV['TOKEN'])
28
+ if MechanizedAuthorization.on?
29
+ describe "authorized requests" do
30
+ before(:each) do
31
+ @vk = MechanizedAuthorization.client
32
+ end
33
+
34
+ it "get groups" do
35
+ groups = @vk.groups.get
36
+ groups.should include(1)
37
+ end
42
38
  end
43
39
 
44
- it "convert method names to vk.com format" do
45
- @vk.is_app_user?.should be_true
40
+ describe "requests with camelCase and predicate methods" do
41
+ before(:each) do
42
+ @vk = MechanizedAuthorization.client
43
+ end
44
+
45
+ it "convert method names to vk.com format" do
46
+ @vk.is_app_user?.should be_true
47
+ end
46
48
  end
47
- end if ENV['TOKEN']
49
+ end
48
50
 
49
51
  describe "requests with array arguments" do
50
52
  before(:each) do
@@ -52,7 +54,7 @@ describe "Integration" do
52
54
  end
53
55
 
54
56
  it "join arrays with a comma" do
55
- users = @vk.users.get(:uids => [1, 2, 3], :fields => %w[first_name last_name screen_name])
57
+ users = @vk.users.get(uids: [1, 2, 3], fields: %w[first_name last_name screen_name])
56
58
  users.first.screen_name.should_not be_empty
57
59
  end
58
60
  end
@@ -63,7 +65,7 @@ describe "Integration" do
63
65
  end
64
66
 
65
67
  it "map the result with a block" do
66
- users = @vk.users.get(:uid => 1) do |user|
68
+ users = @vk.users.get(uid: 1) do |user|
67
69
  "#{user.last_name} #{user.first_name}"
68
70
  end
69
71
 
@@ -74,7 +76,7 @@ describe "Integration" do
74
76
  describe "authorization" do
75
77
  context "with a scope" do
76
78
  it "returns a correct url" do
77
- VK.authorization_url(:scope => %w[friends groups]).should include('scope=friends%2Cgroups')
79
+ VK.authorization_url(scope: %w[friends groups]).should include('scope=friends%2Cgroups')
78
80
  end
79
81
  end
80
82
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'vkontakte_api'
2
2
  require 'pry'
3
+ require 'awesome_print'
4
+ require_relative './support/mechanized_authorization'
3
5
 
4
6
  RSpec::Matchers.define :log_requests do
5
7
  match do |logger|
@@ -0,0 +1,57 @@
1
+ require 'mechanize'
2
+
3
+ module MechanizedAuthorization
4
+ class << self
5
+ def client
6
+ @client ||= begin
7
+ agent = Mechanize.new
8
+
9
+ configure
10
+ agent.get VkontakteApi.authorization_url(scope: [:friends, :groups], type: :client)
11
+
12
+ agent.page.form_with(action: /login.vk.com/) do |form|
13
+ form.email = settings.email
14
+ form.pass = settings.password
15
+ end.submit
16
+
17
+ # uri.fragment: access_token=ee6b952fa432c70&expires_in=86400&user_id=123456
18
+ params = agent.page.uri.fragment.split('&').inject({}) do |hash, pair|
19
+ key, value = pair.split('=')
20
+ hash[key] = value
21
+ hash
22
+ end
23
+ token = params['access_token']
24
+
25
+ VkontakteApi::Client.new(token)
26
+ end
27
+ end
28
+
29
+ def on?
30
+ !off?
31
+ end
32
+
33
+ private
34
+ def off?
35
+ ENV['NO_AUTH'] || !File.exists?(credentials_path)
36
+ end
37
+
38
+ def configure
39
+ VkontakteApi.configure do |config|
40
+ config.app_id = settings.app_id
41
+ config.app_secret = settings.app_secret
42
+ end
43
+ end
44
+
45
+ def settings
46
+ @settings ||= Hashie::Mash.new(settings_hash)
47
+ end
48
+
49
+ def settings_hash
50
+ YAML.load_file(credentials_path)
51
+ end
52
+
53
+ def credentials_path
54
+ File.expand_path('../credentials.yml', __FILE__)
55
+ end
56
+ end
57
+ end