vkontakte_api 0.2.1 → 1.0.rc
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.
- data/.rspec +1 -0
- data/.travis.yml +1 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +23 -0
- data/README.md +136 -61
- data/lib/generators/vkontakte_api/install/USAGE +2 -0
- data/lib/generators/vkontakte_api/install/install_generator.rb +9 -0
- data/lib/generators/vkontakte_api/install/templates/initializer.rb +22 -0
- data/lib/vkontakte_api/api.rb +27 -39
- data/lib/vkontakte_api/authorization.rb +66 -0
- data/lib/vkontakte_api/client.rb +14 -12
- data/lib/vkontakte_api/configuration.rb +22 -4
- data/lib/vkontakte_api/error.rb +15 -7
- data/lib/vkontakte_api/logger.rb +35 -0
- data/lib/vkontakte_api/method.rb +40 -0
- data/lib/vkontakte_api/namespace.rb +7 -0
- data/lib/vkontakte_api/resolvable.rb +20 -0
- data/lib/vkontakte_api/resolver.rb +18 -103
- data/lib/vkontakte_api/result.rb +48 -0
- data/lib/vkontakte_api/uploading.rb +29 -0
- data/lib/vkontakte_api/utils.rb +28 -0
- data/lib/vkontakte_api/version.rb +2 -1
- data/lib/vkontakte_api.rb +14 -3
- data/spec/integration_spec.rb +84 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/vkontakte_api/api_spec.rb +39 -58
- data/spec/vkontakte_api/authorization_spec.rb +111 -0
- data/spec/vkontakte_api/client_spec.rb +17 -24
- data/spec/vkontakte_api/configuration_spec.rb +5 -0
- data/spec/vkontakte_api/error_spec.rb +30 -10
- data/spec/vkontakte_api/logger_spec.rb +88 -0
- data/spec/vkontakte_api/method_spec.rb +59 -0
- data/spec/vkontakte_api/namespace_spec.rb +5 -0
- data/spec/vkontakte_api/resolvable_spec.rb +21 -0
- data/spec/vkontakte_api/resolver_spec.rb +58 -141
- data/spec/vkontakte_api/result_spec.rb +115 -0
- data/spec/vkontakte_api/uploading_spec.rb +46 -0
- data/spec/vkontakte_api/utils_spec.rb +47 -0
- data/spec/vkontakte_api_spec.rb +4 -0
- data/vkontakte_api.gemspec +6 -5
- metadata +119 -38
- data/README.ru.md +0 -115
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format=documentation
|
data/.travis.yml
CHANGED
data/.yardopts
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
## 1.0 (в разработке)
|
2
|
+
|
3
|
+
* rails-генератор конфиг-файла
|
4
|
+
* Загрузка файлов на сервера ВКонтакте
|
5
|
+
* Авторизация
|
6
|
+
* Переход на JSON-парсер `Oj`
|
7
|
+
* Результаты методов в виде `Hashie::Mash`
|
8
|
+
* Настраиваемый логгер
|
9
|
+
|
10
|
+
## 0.2.1 (31.03.2012)
|
11
|
+
|
12
|
+
* Пространство имен `stats`
|
13
|
+
|
14
|
+
## 0.2 (11.03.2012)
|
15
|
+
|
16
|
+
* Подчищенные неавторизованные запросы
|
17
|
+
* Документация кода (`YARD`)
|
18
|
+
* Поддержка аргументов-массивов
|
19
|
+
* Обновленный список пространств имен
|
20
|
+
|
21
|
+
## 0.1 (31.01.2012)
|
22
|
+
|
23
|
+
* Первая стабильная версия
|
data/README.md
CHANGED
@@ -1,115 +1,190 @@
|
|
1
|
-
|
1
|
+
## vkontakte_api [](http://travis-ci.org/7even/vkontakte_api) [](https://gemnasium.com/7even/vkontakte_api) [](https://codeclimate.com/github/7even/vkontakte_api)
|
2
2
|
|
3
|
-
`vkontakte_api`
|
3
|
+
`vkontakte_api` - ruby-адаптер для ВКонтакте API. Он позволяет вызывать методы API, загружать файлы на сервера ВКонтакте, а также поддерживает все 3 доступных способа авторизации (при этом позволяя использовать стороннее решение).
|
4
4
|
|
5
|
-
|
5
|
+
## Установка
|
6
6
|
|
7
|
-
|
7
|
+
``` ruby
|
8
|
+
# Gemfile
|
9
|
+
gem 'vkontakte_api', '~> 1.0.rc'
|
10
|
+
```
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
или просто
|
13
|
+
|
14
|
+
``` sh
|
15
|
+
$ gem install vkontakte_api
|
11
16
|
```
|
12
17
|
|
13
|
-
##
|
18
|
+
## Использование
|
14
19
|
|
15
|
-
|
20
|
+
### Вызов методов
|
16
21
|
|
17
22
|
``` ruby
|
18
|
-
|
19
|
-
|
23
|
+
# создаем клиент
|
24
|
+
@vk = VkontakteApi::Client.new
|
25
|
+
# и вызываем методы API
|
26
|
+
@vk.users.get(uid: 1)
|
27
|
+
|
28
|
+
# в ruby принято использовать snake_case в названиях методов,
|
29
|
+
# поэтому likes.getList становится likes.get_list
|
30
|
+
@vk.likes.get_list
|
31
|
+
# также названия методов, которые возвращают '1' или '0',
|
32
|
+
# заканчиваются на '?', а возвращаемые значения приводятся
|
33
|
+
# к true или false
|
34
|
+
@vk.is_app_user? # => false
|
35
|
+
|
36
|
+
# если ВКонтакте ожидает получить параметр в виде списка,
|
37
|
+
# разделенного запятыми, то его можно передать массивом
|
38
|
+
users = @vk.users.get(uids: [1, 2, 3])
|
39
|
+
|
40
|
+
# большинство методов возвращает структуры Hashie::Mash
|
41
|
+
# и массивы из них
|
42
|
+
users.first.uid # => 1
|
43
|
+
users.first.first_name # => "Павел"
|
44
|
+
users.first.last_name # => "Дуров"
|
45
|
+
users.first.online? # => true
|
46
|
+
|
47
|
+
# если метод, возвращающий массив, вызывается с блоком,
|
48
|
+
# то блок будет выполнен для каждого элемента,
|
49
|
+
# и метод вернет обработанный массив
|
50
|
+
fields = [:first_name, :last_name, :screen_name]
|
51
|
+
@vk.friends.get(fields: fields) do |friend|
|
52
|
+
"#{friend.first_name} '#{friend.screen_name}' #{friend.last_name}"
|
20
53
|
end
|
54
|
+
# => ["Павел 'durov' Дуров"]
|
21
55
|
```
|
22
56
|
|
23
|
-
|
57
|
+
### Загрузка файлов
|
58
|
+
|
59
|
+
Загрузка файлов на сервера ВКонтакте осуществляется в несколько этапов: сначала вызывается метод API, возвращающий URL для загрузки, затем происходит сама загрузка файлов, и после этого в некоторых случаях нужно вызвать другой метод API, передав в параметрах данные, возвращенные сервером после предыдущего запроса. Вызываемые методы API зависят от типа загружаемых файлов и описаны в [соответствующем разделе документации](http://vk.com/developers.php?oid=-1&p=%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81_%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_%D0%BD%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%D0%92%D0%9A%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B5).
|
60
|
+
|
61
|
+
Файлы передаются в формате хэша, где ключом является название параметра в запросе (указано в документации, например для загрузки фото на стену это будет `photo`), а значением - массив из 2 строк: полный путь к файлу и его MIME-тип:
|
24
62
|
|
25
63
|
``` ruby
|
26
|
-
|
64
|
+
url = 'http://cs303110.vkontakte.ru/upload.php?act=do_add'
|
65
|
+
VkontakteApi.upload(url: url, photo: ['/path/to/file.jpg', 'image/jpeg'])
|
27
66
|
```
|
28
67
|
|
29
|
-
|
68
|
+
Метод вернет ответ сервера ВКонтакте, преобразованный в `Hashie::Mash`; его можно использовать при вызове метода API на последнем этапе процесса загрузки.
|
69
|
+
|
70
|
+
### Авторизация
|
71
|
+
|
72
|
+
Для вызова большинства методов требуется токен доступа (access token). Чтобы получить его, можно использовать авторизацию, встроенную в `vkontakte_api`, либо положиться на какой-то другой механизм (например, [OmniAuth](https://github.com/intridea/omniauth)). В последнем случае в результате авторизации будет получен токен, который нужно будет передать в `VkontakteApi::Client.new`.
|
73
|
+
|
74
|
+
Для работы с ВКонтакте API предусмотрено 3 типа авторизации: для сайтов, для клиентских приложений (мобильных либо десктопных, имеющих доступ к управлению браузером) и специальный тип авторизации серверов приложений для вызова административных методов без авторизации самого пользователя. Более подробно они описаны [тут](http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F); рассмотрим, как работать с ними средствами `vkontakte_api`.
|
75
|
+
|
76
|
+
Для авторизации необходимо задать параметры `app_id` (ID приложения), `app_secret` (защищенный ключ) и `redirect_uri` (адрес, куда пользователь будет направлен после предоставления прав приложению) в настройках `VkontakteApi.configure`. Более подробно о конфигурировании `vkontakte_api` см. далее в соответствующем разделе.
|
77
|
+
|
78
|
+
##### Сайт
|
79
|
+
|
80
|
+
Авторизация сайтов проходит в 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`) пользователя.
|
30
81
|
|
31
82
|
``` ruby
|
32
|
-
|
83
|
+
redirect_to VkontakteApi.authorization_url(scope: [:friends, :photos])
|
33
84
|
```
|
34
85
|
|
35
|
-
|
36
|
-
|
37
|
-
Now you can call the API methods. All method names are underscore_cased as opposed to the [official documentation](http://vk.com/developers.php?oid=-17680044&p=API_Method_Description) where they are camelCased, so `getGroups` becomes `get_groups`. You can still call them in a camelCased manner, but that is not a Ruby-way practice.
|
86
|
+
После подтверждения пользователь перенаправляется на указанный в настройках `redirect_uri`, причем в параметрах будет передан код, по которому можно получить токен доступа. `vkontakte_api` предоставляет метод `VkontakteApi.authorize`, который делает запрос к ВКонтакте, получает токен и создает клиент; нужно лишь передать ему код:
|
38
87
|
|
39
88
|
``` ruby
|
40
|
-
@
|
41
|
-
|
89
|
+
@vk = VkontakteApi.authorize(code: params[:code])
|
90
|
+
# и теперь можно вызывать методы API на объекте @vk
|
91
|
+
@vk.is_app_user?
|
42
92
|
```
|
43
93
|
|
44
|
-
|
94
|
+
Также в этот момент полезно сохранить полученный токен в БД либо в сессии, чтобы использовать его повторно:
|
45
95
|
|
46
96
|
``` ruby
|
47
|
-
|
97
|
+
current_user.token = @vk.token
|
98
|
+
current_user.save
|
99
|
+
# позже
|
100
|
+
@vk = VkontakteApi::Client.new(current_user.token)
|
48
101
|
```
|
49
102
|
|
50
|
-
|
103
|
+
##### Клиентское приложение
|
51
104
|
|
52
|
-
|
105
|
+
Авторизация клиентского приложения несколько проще - не нужно получать токен отдельным запросом, он выдается сразу после редиректа пользователя.
|
53
106
|
|
54
107
|
``` ruby
|
55
|
-
|
56
|
-
|
57
|
-
# {
|
58
|
-
# :uid => "1",
|
59
|
-
# :first_name => "Павел",
|
60
|
-
# :last_name => "Дуров"
|
61
|
-
# },
|
62
|
-
# {
|
63
|
-
# :uid => "6492",
|
64
|
-
# :first_name => "Andrew",
|
65
|
-
# :last_name => "Rogozov"
|
66
|
-
# }
|
67
|
-
# ]
|
108
|
+
# пользователь направляется на следующий урл
|
109
|
+
VkontakteApi.authorization_url(type: :client, scope: [:friends, :photos])
|
68
110
|
```
|
69
111
|
|
70
|
-
|
112
|
+
Необходимо принимать во внимание, что `redirect_uri` нужно выставлять на `http://api.vkontakte.ru/blank.html`, иначе не получится вызывать методы, доступные клиентским приложениям.
|
113
|
+
|
114
|
+
Когда пользователь подтвердит права приложения, он будет перенаправлен на `redirect_uri`, при этом в параметре `access_token` будет токен, который нужно передать в `VkontakteApi::Client.new`.
|
115
|
+
|
116
|
+
##### Сервер приложения
|
117
|
+
|
118
|
+
Последний тип авторизации - самый простой, т.к. не предполагает участия пользователя.
|
71
119
|
|
72
120
|
``` ruby
|
73
|
-
|
74
|
-
@app.users.get(uids: users_ids) # => same output as above
|
121
|
+
@vk = VkontakteApi.authorize(type: :app_server)
|
75
122
|
```
|
76
123
|
|
77
|
-
|
124
|
+
### Обработка ошибок
|
78
125
|
|
79
|
-
|
126
|
+
Если ВКонтакте API возвращает ошибку, выбрасывается исключение класса `VkontakteApi::Error`.
|
80
127
|
|
81
128
|
``` ruby
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# => ["Павел Дуров", "Andrew Rogozov"]
|
129
|
+
vk = VK::Client.new
|
130
|
+
vk.friends.get(uid: 1, fields: [:first_name, :last_name, :photo])
|
131
|
+
# 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"}.
|
86
132
|
```
|
87
133
|
|
88
|
-
|
134
|
+
### Логгирование
|
135
|
+
|
136
|
+
`vkontakte_api` логгирует служебную информацию о запросах при вызове методов. По умолчанию все пишется в `STDOUT`, но в настройке можно указать любой другой совместимый логгер, например `Rails.logger`.
|
137
|
+
|
138
|
+
Есть возможность логгирования 3 типов информации, каждому соответствует ключ в глобальных настройках.
|
139
|
+
|
140
|
+
| | ключ настройки | по умолчанию | уровень логгирования |
|
141
|
+
| ---------------------- | --------------- | ------------ | -------------------- |
|
142
|
+
| URL запроса | `log_requests` | `true` | `debug` |
|
143
|
+
| JSON ответа при ошибке | `log_errors` | `true` | `warn` |
|
144
|
+
| JSON удачного ответа | `log_responses` | `false` | `debug` |
|
89
145
|
|
90
|
-
|
146
|
+
Таким образом, в rails-приложении с настройками по умолчанию в production записываются только ответы сервера при ошибках; в development также логгируются URL-ы запросов.
|
91
147
|
|
92
|
-
|
148
|
+
## Настройка
|
149
|
+
|
150
|
+
Глобальные параметры `vkontakte_api` задаются в блоке `VkontakteApi.configure` следующим образом:
|
93
151
|
|
94
152
|
``` ruby
|
95
|
-
|
96
|
-
#
|
153
|
+
VkontakteApi.configure do |config|
|
154
|
+
# параметры, необходимые для авторизации средствами vkontakte_api
|
155
|
+
# (не нужны при использовании сторонней авторизации)
|
156
|
+
config.app_id = '123'
|
157
|
+
config.app_secret = 'AbCdE654'
|
158
|
+
config.redirect_uri = 'http://example.com/oauth/callback'
|
159
|
+
|
160
|
+
# faraday-адаптер для сетевых запросов
|
161
|
+
config.adapter = :net_http
|
162
|
+
|
163
|
+
# логгер
|
164
|
+
config.logger = Rails.logger
|
165
|
+
config.log_requests = true # URL-ы запросов
|
166
|
+
config.log_errors = true # ошибки
|
167
|
+
config.log_responses = false # удачные ответы
|
168
|
+
end
|
97
169
|
```
|
98
170
|
|
99
|
-
|
171
|
+
По умолчанию для HTTP-запросов используется `Net::HTTP`; можно выбрать [любой другой адаптер](https://github.com/technoweenie/faraday/blob/master/lib/faraday/adapter.rb), поддерживаемый `faraday`.
|
172
|
+
|
173
|
+
Чтобы сгенерировать файл с настройками по умолчанию в rails-приложении, можно воспользоваться генератором `vkontakte_api:install`:
|
174
|
+
|
175
|
+
``` sh
|
176
|
+
$ cd /path/to/app
|
177
|
+
$ rails generate vkontakte_api:install
|
178
|
+
```
|
100
179
|
|
101
|
-
|
102
|
-
* 0.2 Array arguments support, cleaned up non-authorized requests, updated namespaces list, code documentation
|
103
|
-
* 0.2.1 `stats` namespace
|
180
|
+
## JSON-парсер
|
104
181
|
|
105
|
-
|
182
|
+
`vkontakte_api` использует парсер [Oj](https://github.com/ohler55/oj) - это единственный парсер, который не показал [ошибок](https://github.com/7even/vkontakte_api/issues/1) при парсинге JSON, генерируемого ВКонтакте.
|
106
183
|
|
107
|
-
|
108
|
-
* Authentication (getting the access_token from VK)
|
109
|
-
* Maybe Struct-like objects in result (instead of Hashes)
|
184
|
+
Также в библиотеке `multi_json` (обертка для различных JSON-парсеров, которая выбирает самый быстрый из установленных в системе и парсит им) `Oj` поддерживается и имеет наивысший приоритет; поэтому если он установлен в системе, `multi_json` будет использовать именно его.
|
110
185
|
|
111
|
-
##
|
186
|
+
## Участие в разработке
|
112
187
|
|
113
|
-
|
188
|
+
Если вы хотите поучаствовать в разработке проекта, форкните репозиторий, положите свои изменения в отдельную ветку и отправьте мне pull request.
|
114
189
|
|
115
|
-
`vkontakte_api`
|
190
|
+
`vkontakte_api` тестируется под MRI `1.8.7`, `1.9.2`, `1.9.3` и `2.0.0-dev`. Если в одной из этих сред что-то работает неправильно, либо вообще не работает, то это следует считать багом, и написать об этом в [issues на Github](https://github.com/7even/vkontakte_api/issues).
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# A rails generator `vkontakte:install`. It creates a config file in `config/initializers/vkontakte_api.rb`.
|
2
|
+
class VkontakteApi::InstallGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
|
5
|
+
# Creates the config file.
|
6
|
+
def create_initializer
|
7
|
+
copy_file 'initializer.rb', 'config/initializers/vkontakte_api.rb'
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
VkontakteApi.configure do |config|
|
2
|
+
# Authorization parameters (not needed when using an external authorization):
|
3
|
+
# config.app_id = '123'
|
4
|
+
# config.app_secret = 'AbCdE654'
|
5
|
+
# config.redirect_uri = 'http://example.com/oauth/callback'
|
6
|
+
|
7
|
+
# Faraday adapter to make requests with:
|
8
|
+
# config.adapter = :net_http
|
9
|
+
|
10
|
+
# Logging parameters:
|
11
|
+
# log everything through the rails logger
|
12
|
+
config.logger = Rails.logger
|
13
|
+
|
14
|
+
# log requests' URLs
|
15
|
+
# config.log_requests = true
|
16
|
+
|
17
|
+
# log response JSON after errors
|
18
|
+
# config.log_errors = true
|
19
|
+
|
20
|
+
# log response JSON after successful responses
|
21
|
+
# config.log_responses = false
|
22
|
+
end
|
data/lib/vkontakte_api/api.rb
CHANGED
@@ -1,50 +1,38 @@
|
|
1
1
|
module VkontakteApi
|
2
|
-
# A low-level module which handles the requests to VKontakte and returns their results as
|
2
|
+
# A low-level module which handles the requests to VKontakte API and returns their results as mashes.
|
3
3
|
#
|
4
|
-
# It uses Faraday underneath the hood.
|
4
|
+
# It uses Faraday with middleware underneath the hood.
|
5
5
|
module API
|
6
|
-
|
7
|
-
|
6
|
+
# URL prefix for calling API methods.
|
7
|
+
URL_PREFIX = 'https://api.vkontakte.ru/method'
|
8
8
|
|
9
9
|
class << self
|
10
|
-
#
|
10
|
+
# API method call.
|
11
11
|
# @param [String] method_name A full name of the method.
|
12
|
-
# @param [Hash] args Method arguments
|
13
|
-
# @
|
14
|
-
# @
|
15
|
-
def call(method_name, args = {},
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
url = url_for(method_name, args)
|
21
|
-
body = connection.get(url).body
|
22
|
-
response = Yajl::Parser.parse(body, :symbolize_keys => true)
|
23
|
-
|
24
|
-
if response.has_key?(:error)
|
25
|
-
raise VkontakteApi::Error.new(response[:error])
|
26
|
-
else
|
27
|
-
response[:response]
|
28
|
-
end
|
12
|
+
# @param [Hash] args Method arguments.
|
13
|
+
# @param [String] token The access token.
|
14
|
+
# @return [Hashie::Mash] Mashed server response.
|
15
|
+
def call(method_name, args = {}, token = nil)
|
16
|
+
flat_arguments = Utils.flatten_arguments(args)
|
17
|
+
connection(:url => URL_PREFIX, :token => token).get(method_name, flat_arguments).body
|
29
18
|
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
flat_args
|
20
|
+
# Faraday connection.
|
21
|
+
# @param [Hash] options Connection options.
|
22
|
+
# @option options [String] :url Connection URL (either full or just prefix).
|
23
|
+
# @option options [String] :token OAuth2 access token (not used if omitted).
|
24
|
+
# @return [Faraday::Connection] Created connection.
|
25
|
+
def connection(options = {})
|
26
|
+
url = options.delete(:url)
|
27
|
+
token = options.delete(:token)
|
28
|
+
|
29
|
+
Faraday.new(url) do |builder|
|
30
|
+
builder.request :oauth2, token unless token.nil?
|
31
|
+
builder.request :multipart
|
32
|
+
builder.response :vk_logger
|
33
|
+
builder.response :mashify
|
34
|
+
builder.response :oj, :preserve_raw => true
|
35
|
+
builder.adapter VkontakteApi.adapter
|
48
36
|
end
|
49
37
|
end
|
50
38
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module VkontakteApi
|
2
|
+
# A module containing the methods for authorization.
|
3
|
+
#
|
4
|
+
# @note `VkontakteApi::Authorization` extends `VkontakteApi` so these methods should be called from the latter.
|
5
|
+
module Authorization
|
6
|
+
# Authorization options.
|
7
|
+
OPTIONS = {
|
8
|
+
:client => {
|
9
|
+
:site => 'https://oauth.vk.com',
|
10
|
+
:authorize_url => '/authorize',
|
11
|
+
:token_url => '/access_token'
|
12
|
+
},
|
13
|
+
:client_credentials => {
|
14
|
+
'auth_scheme' => 'request_body'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
# URL for redirecting the user to VK where he gives the application all the requested access rights.
|
19
|
+
# @option options [Symbol] :type The type of authorization being used (`:site` and `:client` supported).
|
20
|
+
# @option options [String] :redirect_uri URL for redirecting the user back to the application (overrides the global configuration value).
|
21
|
+
# @option options [Array] :scope An array of requested access rights (each represented by a symbol or a string).
|
22
|
+
# @raise [ArgumentError] raises after receiving an unknown authorization type.
|
23
|
+
# @return [String] URL to redirect the user to.
|
24
|
+
def authorization_url(options = {})
|
25
|
+
type = options.delete(:type) || :site
|
26
|
+
# redirect_uri passed in options overrides the global setting
|
27
|
+
options[:redirect_uri] ||= VkontakteApi.redirect_uri
|
28
|
+
options[:scope] = VkontakteApi::Utils.flatten_argument(options[:scope]) if options[:scope]
|
29
|
+
|
30
|
+
case type
|
31
|
+
when :site
|
32
|
+
client.auth_code.authorize_url(options)
|
33
|
+
when :client
|
34
|
+
client.implicit.authorize_url(options)
|
35
|
+
else
|
36
|
+
raise ArgumentError, "Unknown authorization type #{type.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Authorization (getting the access token and building a `VkontakteApi::Client` with it).
|
41
|
+
# @option options [Symbol] :type The type of authorization being used (`:site` and `:app_server` supported).
|
42
|
+
# @option options [String] :code The code to exchange for an access token (for `:site` authorization type).
|
43
|
+
# @raise [ArgumentError] raises after receiving an unknown authorization type.
|
44
|
+
# @return [VkontakteApi::Client] An API client.
|
45
|
+
def authorize(options = {})
|
46
|
+
type = options.delete(:type) || :site
|
47
|
+
|
48
|
+
case type
|
49
|
+
when :site
|
50
|
+
code = options.delete(:code)
|
51
|
+
token = client.auth_code.get_token(code)
|
52
|
+
when :app_server
|
53
|
+
token = client.client_credentials.get_token({}, OPTIONS[:client_credentials])
|
54
|
+
else
|
55
|
+
raise ArgumentError, "Unknown authorization type #{type.inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
Client.new(token)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def client
|
63
|
+
@client ||= OAuth2::Client.new(VkontakteApi.app_id, VkontakteApi.app_secret, OPTIONS[:client])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/vkontakte_api/client.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
module VkontakteApi
|
2
|
-
# A class representing a connection to VK. It holds
|
2
|
+
# A class representing a connection to VK. It holds the access token.
|
3
3
|
class Client
|
4
|
+
include Resolver
|
5
|
+
|
4
6
|
# An access token needed by authorized requests.
|
5
|
-
attr_reader :
|
7
|
+
attr_reader :token
|
6
8
|
|
7
9
|
# A new API client.
|
8
|
-
# @param [String]
|
9
|
-
def initialize(
|
10
|
-
|
10
|
+
# @param [String, OAuth2::AccessToken] token An access token.
|
11
|
+
def initialize(token = nil)
|
12
|
+
if token.respond_to?(:token)
|
13
|
+
# token is an OAuth2::AccessToken
|
14
|
+
@token = token.token
|
15
|
+
else
|
16
|
+
# token is a String or nil
|
17
|
+
@token = token
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
# Is a `VkontakteApi::Client` instance authorized.
|
14
22
|
def authorized?
|
15
|
-
!@
|
16
|
-
end
|
17
|
-
|
18
|
-
# All unknown methods are delegated to a `VkontakteApi::Resolver` instance.
|
19
|
-
def method_missing(method_name, *args, &block)
|
20
|
-
args = args.first || {}
|
21
|
-
VkontakteApi::Resolver.new(:access_token => @access_token).send(method_name, args, &block)
|
23
|
+
!@token.nil?
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -1,20 +1,34 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
module VkontakteApi
|
2
4
|
# General configuration module.
|
3
5
|
#
|
4
|
-
#
|
6
|
+
# @note `VkontakteApi::Configuration` extends `VkontakteApi` so these methods should be called from the latter.
|
5
7
|
module Configuration
|
6
8
|
# Available options.
|
7
|
-
OPTION_NAMES = [:app_id, :app_secret, :adapter]
|
9
|
+
OPTION_NAMES = [:app_id, :app_secret, :redirect_uri, :adapter, :logger, :log_requests, :log_errors, :log_responses]
|
8
10
|
|
9
11
|
attr_accessor *OPTION_NAMES
|
10
12
|
|
13
|
+
alias_method :log_requests?, :log_requests
|
14
|
+
alias_method :log_errors?, :log_errors
|
15
|
+
alias_method :log_responses?, :log_responses
|
16
|
+
|
11
17
|
# Default HTTP adapter.
|
12
|
-
DEFAULT_ADAPTER =
|
18
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
19
|
+
|
20
|
+
# Logger default options.
|
21
|
+
DEFAULT_LOGGER_OPTIONS = {
|
22
|
+
:requests => true,
|
23
|
+
:errors => true,
|
24
|
+
:responses => false
|
25
|
+
}
|
13
26
|
|
14
27
|
# A global configuration set via the block.
|
15
28
|
# @example
|
16
29
|
# VkontakteApi.configure do |config|
|
17
30
|
# config.adapter = :net_http
|
31
|
+
# config.logger = Rails.logger
|
18
32
|
# end
|
19
33
|
def configure
|
20
34
|
yield self if block_given?
|
@@ -23,7 +37,11 @@ module VkontakteApi
|
|
23
37
|
|
24
38
|
# Reset all configuration options to defaults.
|
25
39
|
def reset
|
26
|
-
@adapter
|
40
|
+
@adapter = DEFAULT_ADAPTER
|
41
|
+
@logger = ::Logger.new(STDOUT)
|
42
|
+
@log_requests = DEFAULT_LOGGER_OPTIONS[:requests]
|
43
|
+
@log_errors = DEFAULT_LOGGER_OPTIONS[:errors]
|
44
|
+
@log_responses = DEFAULT_LOGGER_OPTIONS[:responses]
|
27
45
|
end
|
28
46
|
|
29
47
|
# When this module is extended, set all configuration options to their default values.
|
data/lib/vkontakte_api/error.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
module VkontakteApi
|
2
|
-
# An exception raised by `VkontakteApi::
|
2
|
+
# An exception raised by `VkontakteApi::Result` when given a response with an error.
|
3
3
|
class Error < StandardError
|
4
4
|
# An error code.
|
5
5
|
# @return [Fixnum]
|
6
6
|
attr_reader :error_code
|
7
7
|
|
8
|
-
# An exception is initialized by the data from response
|
8
|
+
# An exception is initialized by the data from response mash.
|
9
9
|
# @param [Hash] data Error data.
|
10
10
|
def initialize(data)
|
11
|
-
@error_code = data.
|
12
|
-
@error_msg = data.
|
13
|
-
@params = {}
|
11
|
+
@error_code = data.error_code
|
12
|
+
@error_msg = data.error_msg
|
14
13
|
|
15
|
-
request_params = parse_params(data.
|
14
|
+
request_params = parse_params(data.request_params)
|
16
15
|
|
17
16
|
@method_name = request_params.delete('method')
|
18
17
|
@access_token = request_params.delete('access_token')
|
@@ -23,7 +22,16 @@ module VkontakteApi
|
|
23
22
|
# A full description of the error.
|
24
23
|
# @return [String]
|
25
24
|
def message
|
26
|
-
"VKontakte returned an error #{@error_code}: '#{@error_msg}'
|
25
|
+
message = "VKontakte returned an error #{@error_code}: '#{@error_msg}'"
|
26
|
+
message << " after calling method '#{@method_name}'"
|
27
|
+
|
28
|
+
if @params.empty?
|
29
|
+
message << " without parameters."
|
30
|
+
else
|
31
|
+
message << " with parameters #{@params.inspect}."
|
32
|
+
end
|
33
|
+
|
34
|
+
message
|
27
35
|
end
|
28
36
|
|
29
37
|
private
|