vkontakte 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +25 -0
- data/lib/vkontakte.rb +29 -0
- data/lib/vkontakte/api/base.rb +13 -0
- data/lib/vkontakte/api/friends.rb +42 -0
- data/lib/vkontakte/api/groups.rb +41 -0
- data/lib/vkontakte/api/photos.rb +218 -0
- data/lib/vkontakte/api/secure.rb +77 -0
- data/lib/vkontakte/app/base.rb +112 -0
- data/lib/vkontakte/app/iframe.rb +71 -0
- data/lib/vkontakte/app/secure.rb +15 -0
- data/lib/vkontakte/config.rb +38 -0
- data/lib/vkontakte/utils.rb +24 -0
- data/lib/vkontakte/version.rb +3 -0
- data/spec/api/friends_spec.rb +56 -0
- data/spec/api/groups_spec.rb +64 -0
- data/spec/api/photos_spec.rb +27 -0
- data/spec/api/secure_spec.rb +88 -0
- data/spec/apps/base_spec.rb +5 -0
- data/spec/apps/iframe_spec.rb +32 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/vkontakte_spec.rb +31 -0
- metadata +125 -0
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem "activesupport"
|
6
|
+
gem "i18n"
|
7
|
+
|
8
|
+
gem "rspec", "~> 2.6.0", :require => "spec"
|
9
|
+
gem "fakeweb"
|
10
|
+
|
11
|
+
# To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
|
12
|
+
# gem 'ruby-debug'
|
13
|
+
# gem 'ruby-debug19'
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 Aimbulance
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
= Vkontakte
|
2
|
+
|
3
|
+
The easiest way to access Vkontakte API and some other utils.
|
4
|
+
More info about API:
|
5
|
+
|
6
|
+
1. http://vkontakte.ru/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
|
7
|
+
|
8
|
+
2. http://vkontakte.ru/developers.php?oid=-1&p=%D0%92%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2_%D0%BA_API
|
9
|
+
|
10
|
+
== Install
|
11
|
+
|
12
|
+
gem 'vkontakte'
|
13
|
+
|
14
|
+
== Configure
|
15
|
+
|
16
|
+
Vkontakte.setup do |config|
|
17
|
+
config.app_id = "YOUR Vkontakte API ID"
|
18
|
+
config.app_secret = "YOUR Vkontakte APP SECRET"
|
19
|
+
config.format = :json
|
20
|
+
config.debug = false
|
21
|
+
config.logger = File.open(Rails.root.join('log', 'vkontakte.log'), "a")
|
22
|
+
end
|
23
|
+
|
24
|
+
== Usage
|
25
|
+
|
26
|
+
=== Secure API
|
27
|
+
|
28
|
+
@app = Vkontakte::App::Secure.new
|
29
|
+
@app.secure.getAppBalance # {"response"=>2000}
|
30
|
+
@app.auth # {"expires_in"=>0, "access_token"=>"d173f5...319f"}
|
31
|
+
|
32
|
+
=== IFrame application
|
33
|
+
|
34
|
+
Check if auth_key is valid:
|
35
|
+
|
36
|
+
def index
|
37
|
+
@app = Vkontakte::App::Iframe.new
|
38
|
+
@app.params = params
|
39
|
+
|
40
|
+
if @app.valid_auth_key?
|
41
|
+
session[:viewer_id] = params[:viewer_id]
|
42
|
+
else
|
43
|
+
render :action => "failure"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
== Test
|
48
|
+
|
49
|
+
rake spec
|
50
|
+
|
51
|
+
Copyright (c) 2011 Aimbulance, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rake'
|
10
|
+
require 'rdoc/task'
|
11
|
+
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'ShareChecker'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
data/lib/vkontakte.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
require 'active_support/core_ext/object'
|
3
|
+
require 'active_support/core_ext/string'
|
4
|
+
|
5
|
+
module Vkontakte
|
6
|
+
autoload :Config, 'vkontakte/config'
|
7
|
+
autoload :Utils, 'vkontakte/utils'
|
8
|
+
|
9
|
+
module App
|
10
|
+
autoload :Base, 'vkontakte/app/base'
|
11
|
+
autoload :Iframe, 'vkontakte/app/iframe'
|
12
|
+
autoload :Secure, 'vkontakte/app/secure'
|
13
|
+
end
|
14
|
+
|
15
|
+
module Api
|
16
|
+
autoload :Base, 'vkontakte/api/base'
|
17
|
+
autoload :Photos, 'vkontakte/api/photos'
|
18
|
+
autoload :Friends, 'vkontakte/api/friends'
|
19
|
+
autoload :Groups, 'vkontakte/api/groups'
|
20
|
+
autoload :Secure, 'vkontakte/api/secure'
|
21
|
+
end
|
22
|
+
|
23
|
+
mattr_accessor :config
|
24
|
+
@@config = Config.new
|
25
|
+
|
26
|
+
def self.setup(&block)
|
27
|
+
yield config
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module Api
|
3
|
+
module Friends
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
define_method :friends do
|
8
|
+
@friends ||= Standart.new(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Standart < Api::Base
|
14
|
+
# Возвращает список идентификаторов друзей пользователя или
|
15
|
+
# расширенную информацию о друзьях пользователя (при использовании параметра fields).
|
16
|
+
# http://vkontakte.ru/developers.php?oid=-1&p=friends.get
|
17
|
+
#
|
18
|
+
def get(options = {})
|
19
|
+
call('friends.get', options)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Возвращает список идентификаторов друзей текущего пользователя, которые установили данное приложение.
|
23
|
+
#
|
24
|
+
def getAppUsers(options = {})
|
25
|
+
call('friends.getAppUsers', options)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Возвращает список идентификаторов, находящихся на сайте друзей, текущего пользователя.
|
29
|
+
#
|
30
|
+
def getOnline(options = {})
|
31
|
+
call('friends.getOnline', options)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Возвращает список идентификаторов общих друзей между парой пользователей.
|
35
|
+
#
|
36
|
+
def getMutual(options = {})
|
37
|
+
call('friends.getMutual', options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module Api
|
3
|
+
module Groups
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
define_method :groups do
|
8
|
+
@groups ||= Standart.new(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Standart < Api::Base
|
14
|
+
# Возвращает список групп указанного пользователя.
|
15
|
+
# http://vkontakte.ru/developers.php?oid=-1&p=groups.get
|
16
|
+
#
|
17
|
+
def get(options = {})
|
18
|
+
call('groups.get', options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Возвращает информацию о заданной группе или о нескольких группах.
|
22
|
+
#
|
23
|
+
def getById(options = {})
|
24
|
+
call('groups.getById', options)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Возвращает информацию о том является ли пользователь участником заданной группы.
|
28
|
+
#
|
29
|
+
def isMember(options = {})
|
30
|
+
call('groups.isMember', options)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Возвращает список участников группы.
|
34
|
+
#
|
35
|
+
def getMembers(options = {})
|
36
|
+
call('groups.getMembers', options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module Api
|
3
|
+
module Photos
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
define_method :photos do
|
8
|
+
@photos ||= Standart.new(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Extended
|
14
|
+
def self.included(base)
|
15
|
+
base.define_method :photos do
|
16
|
+
@photos ||= Extend.new(self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Standart < Api::Base
|
22
|
+
|
23
|
+
# возвращает список альбомов пользователя.
|
24
|
+
#
|
25
|
+
def getAlbums(options={})
|
26
|
+
call('photos.getAlbums', options)
|
27
|
+
end
|
28
|
+
|
29
|
+
# возвращает количество альбомов пользователя.
|
30
|
+
#
|
31
|
+
def getAlbumsCount(options={})
|
32
|
+
call('photos.getAlbumsCount', options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# возвращает список фотографий в альбоме.
|
36
|
+
#
|
37
|
+
def get(options={})
|
38
|
+
call('photos.get', options)
|
39
|
+
end
|
40
|
+
|
41
|
+
# возвращает все фотографии пользователя в антихронологическом порядке.
|
42
|
+
#
|
43
|
+
def getAll(options={})
|
44
|
+
call('photos.getAll', options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# возвращает информацию о фотографиях.
|
48
|
+
#
|
49
|
+
def getById(options={})
|
50
|
+
call('photos.getById', options)
|
51
|
+
end
|
52
|
+
|
53
|
+
# создает пустой альбом для фотографий.
|
54
|
+
#
|
55
|
+
def createAlbum(options={})
|
56
|
+
call('photos.createAlbum', options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# обновляет данные альбома для фотографий.
|
60
|
+
#
|
61
|
+
def editAlbum(options={})
|
62
|
+
call('photos.editAlbum', options)
|
63
|
+
end
|
64
|
+
|
65
|
+
# переносит фотографию из одного альбома в другой.
|
66
|
+
#
|
67
|
+
def move(options={})
|
68
|
+
call('photos.move', options)
|
69
|
+
end
|
70
|
+
|
71
|
+
# делает фотографию обложкой альбома.
|
72
|
+
#
|
73
|
+
def makeCover(options={})
|
74
|
+
call('photos.makeCover', options)
|
75
|
+
end
|
76
|
+
|
77
|
+
# меняет порядок альбома в списке альбомов пользователя.
|
78
|
+
#
|
79
|
+
def reorderAlbums(options={})
|
80
|
+
call('photos.reorderAlbums', options)
|
81
|
+
end
|
82
|
+
|
83
|
+
# меняет порядок фотографий в списке фотографий альбома.
|
84
|
+
#
|
85
|
+
def reorderPhotos(options={})
|
86
|
+
call('photos.reorderPhotos', options)
|
87
|
+
end
|
88
|
+
|
89
|
+
# возвращает адрес сервера для загрузки фотографий.
|
90
|
+
#
|
91
|
+
def getUploadServer(options={})
|
92
|
+
call('photos.getUploadServer', options)
|
93
|
+
end
|
94
|
+
|
95
|
+
# сохраняет фотографии после успешной загрузки.
|
96
|
+
#
|
97
|
+
def save(options={})
|
98
|
+
call('photos.save', options)
|
99
|
+
end
|
100
|
+
|
101
|
+
# возвращает адрес сервера для загрузки фотографии на страницу пользователя.
|
102
|
+
#
|
103
|
+
def getProfileUploadServer(options={})
|
104
|
+
call('photos.getProfileUploadServer', options)
|
105
|
+
end
|
106
|
+
|
107
|
+
# сохраняет фотографию страницы пользователя после успешной загрузки.
|
108
|
+
#
|
109
|
+
def saveProfilePhoto(options={})
|
110
|
+
call('photos.saveProfilePhoto', options)
|
111
|
+
end
|
112
|
+
|
113
|
+
# возвращает адрес сервера для загрузки фотографии в специальный альбом, предназначенный для фотографий со стены.
|
114
|
+
#
|
115
|
+
def getWallUploadServer(options={})
|
116
|
+
call('photos.getWallUploadServer', options)
|
117
|
+
end
|
118
|
+
|
119
|
+
# сохраняет фотографию после успешной загрузки.
|
120
|
+
#
|
121
|
+
def saveWallPhoto(options={})
|
122
|
+
call('photos.saveWallPhoto', options)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
class Extend < Standart
|
130
|
+
# возвращает список комментариев к фотографии.
|
131
|
+
#
|
132
|
+
def getComments(options={})
|
133
|
+
call('photos.getComments', options)
|
134
|
+
end
|
135
|
+
|
136
|
+
# возвращает список комментариев к альбому или ко всем альбомам.
|
137
|
+
#
|
138
|
+
def getAllComments(options={})
|
139
|
+
call('photos.getAllComments', options)
|
140
|
+
end
|
141
|
+
|
142
|
+
# создает новый комментарий к фотографии.
|
143
|
+
#
|
144
|
+
def createComment(options={})
|
145
|
+
call('photos.createComment', options)
|
146
|
+
end
|
147
|
+
|
148
|
+
# изменяет текст комментария к фотографии.
|
149
|
+
#
|
150
|
+
def editComment(options={})
|
151
|
+
call('photos.editComment', options)
|
152
|
+
end
|
153
|
+
|
154
|
+
# удаляет комментарий к фотографии.
|
155
|
+
#
|
156
|
+
def deleteComment(options={})
|
157
|
+
call('photos.deleteComment', options)
|
158
|
+
end
|
159
|
+
|
160
|
+
# восстанавливает комментарий к фотографии.
|
161
|
+
#
|
162
|
+
def restoreComment(options={})
|
163
|
+
call('photos.restoreComment', options)
|
164
|
+
end
|
165
|
+
|
166
|
+
# возвращает список фотографий, на которых отмечен пользователь.
|
167
|
+
#
|
168
|
+
def getUserPhotos(options={})
|
169
|
+
call('photos.getUserPhotos', options)
|
170
|
+
end
|
171
|
+
|
172
|
+
# возвращает список отметок на фотографии.
|
173
|
+
#
|
174
|
+
def getTags(options={})
|
175
|
+
call('photos.getTags', options)
|
176
|
+
end
|
177
|
+
|
178
|
+
# добавляет отметку на фотографию.
|
179
|
+
#
|
180
|
+
def putTag(options={})
|
181
|
+
call('photos.putTag', options)
|
182
|
+
end
|
183
|
+
|
184
|
+
# удаляет отметку с фотографии.
|
185
|
+
#
|
186
|
+
def removeTag(options={})
|
187
|
+
call('photos.removeTag', options)
|
188
|
+
end
|
189
|
+
|
190
|
+
# удаляет фотоальбом пользователя.
|
191
|
+
#
|
192
|
+
def deleteAlbumnew(options={})
|
193
|
+
call('photos.deleteAlbumnew', options)
|
194
|
+
end
|
195
|
+
|
196
|
+
# возвращает адрес сервера для загрузки фотографии в качестве прикрепления к личному сообщению.
|
197
|
+
#
|
198
|
+
def getMessagesUploadServer(options={})
|
199
|
+
call('photos.getMessagesUploadServer', options)
|
200
|
+
end
|
201
|
+
|
202
|
+
# сохраняет фотографию после загрузки.
|
203
|
+
#
|
204
|
+
def saveMessagesPhoto(options={})
|
205
|
+
call('photos.saveMessagesPhoto', options)
|
206
|
+
end
|
207
|
+
|
208
|
+
# удаляет фотографию.
|
209
|
+
#
|
210
|
+
def delete(options={})
|
211
|
+
call('photos.delete', options)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module Api
|
3
|
+
module Secure
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
define_method :secure do
|
8
|
+
@secure ||= Standart.new(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Standart < Api::Base
|
14
|
+
|
15
|
+
def default_options
|
16
|
+
{
|
17
|
+
:timestamp => Time.now.utc.to_i,
|
18
|
+
:random => Kernel.rand(10000),
|
19
|
+
:client_secret => Vkontakte.config.app_secret
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Отправляет уведомление пользователю.
|
24
|
+
# http://vkontakte.ru/developers.php?oid=-1&p=secure.sendNotification
|
25
|
+
#
|
26
|
+
def sendNotification(options = {})
|
27
|
+
options = default_options.merge(options)
|
28
|
+
call('secure.sendNotification', options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Возвращает платежный баланс (счет) приложения в сотых долях голоса.
|
32
|
+
#
|
33
|
+
def getAppBalance(options = {})
|
34
|
+
options = default_options.merge(options)
|
35
|
+
call("secure.getAppBalance", options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Возвращает баланс пользователя на счету приложения в сотых долях голоса.
|
39
|
+
#
|
40
|
+
def getBalance(options = {})
|
41
|
+
options = default_options.merge(options)
|
42
|
+
call("secure.getBalance", options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Списывает голоса со счета пользователя на счет приложения (в сотых долях).
|
46
|
+
#
|
47
|
+
def withdrawVotes(options = {})
|
48
|
+
options = default_options.merge(options)
|
49
|
+
call("secure.withdrawVotes", options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Выводит историю транзакций по переводу голосов между пользователями и приложением.
|
53
|
+
#
|
54
|
+
def getTransactionsHistory(options = {})
|
55
|
+
options = default_options.merge(options)
|
56
|
+
call("secure.getTransactionsHistory", options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Поднимает пользователю рейтинг от имени приложения.
|
60
|
+
#
|
61
|
+
def addRating(options = {})
|
62
|
+
options = default_options.merge(options)
|
63
|
+
call("secure.addRating", options)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Устанавливает счетчик, который выводится пользователю жирным шрифтом в левом меню.
|
67
|
+
# Это происходит только в том случае, если пользователь добавил приложение в левое меню со страницы приложения,
|
68
|
+
# списка приложений или настроек.
|
69
|
+
#
|
70
|
+
def setCounter(options = {})
|
71
|
+
options = default_options.merge(options)
|
72
|
+
call("secure.setCounter", options)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Vkontakte
|
4
|
+
module App
|
5
|
+
class Base
|
6
|
+
include ::HTTParty
|
7
|
+
|
8
|
+
base_uri "https://api.vkontakte.ru"
|
9
|
+
format Vkontakte.config.format
|
10
|
+
debug_output Vkontakte.config.logger
|
11
|
+
|
12
|
+
attr_accessor :auth
|
13
|
+
|
14
|
+
def initialize(app_id = nil, app_secret = nil)
|
15
|
+
@config = {
|
16
|
+
:app_id => (app_id || Vkontakte.config.app_id),
|
17
|
+
:app_secret => (app_secret || Vkontakte.config.app_secret)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# http://vkontakte.ru/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
|
22
|
+
# Site auth:
|
23
|
+
# https://api.vkontakte.ru/oauth/access_token?
|
24
|
+
# client_id=APP_ID&
|
25
|
+
# client_secret=APP_SECRET&
|
26
|
+
# code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a
|
27
|
+
#
|
28
|
+
# Server auth:
|
29
|
+
# https://api.vkontakte.ru/oauth/access_token?
|
30
|
+
# client_id=' + APP_ID + '&client_secret=' + APP_SECRET + '&grant_type=client_credentials'
|
31
|
+
#
|
32
|
+
# Response:
|
33
|
+
# {"access_token":"533bacf01e11f55b536a565b57531ac114461ae8736d6506a3", "expires_in":43200, "user_id":6492}
|
34
|
+
#
|
35
|
+
def authorize(code = nil, options = {})
|
36
|
+
options = {
|
37
|
+
:client_id => @config[:app_id],
|
38
|
+
:client_secret => @config[:app_secret],
|
39
|
+
:code => code
|
40
|
+
}.merge(options)
|
41
|
+
|
42
|
+
# Server auth
|
43
|
+
if options[:code].blank?
|
44
|
+
options.delete(:code)
|
45
|
+
options[:grant_type] = 'client_credentials'
|
46
|
+
end
|
47
|
+
|
48
|
+
@auth = get("/oauth/access_token", options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Check if app is authorized
|
52
|
+
#
|
53
|
+
def authorized?
|
54
|
+
auth && auth['access_token']
|
55
|
+
end
|
56
|
+
|
57
|
+
# Выполнение запросов к API
|
58
|
+
# https://api.vkontakte.ru/method/METHOD_NAME?PARAMETERS&access_token=ACCESS_TOKEN
|
59
|
+
# METHOD_NAME – название метода из списка функций API,
|
60
|
+
# PARAMETERS – параметры соответствующего метода API,
|
61
|
+
# ACCESS_TOKEN – ключ доступа, полученный в результате успешной авторизации приложения.
|
62
|
+
# Example:
|
63
|
+
# https://api.vkontakte.ru/method/getProfiles?uid=66748&access_token=533bacf01e11f55b536a565b57531ac114461ae8736d6506a3
|
64
|
+
#
|
65
|
+
# More info: http://vkontakte.ru/developers.php?oid=-1&p=%D0%92%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2_%D0%BA_API
|
66
|
+
#
|
67
|
+
def call(method_name, params = {})
|
68
|
+
params[:access_token] ||= @auth['access_token'] if authorized?
|
69
|
+
|
70
|
+
unless params[:access_token].blank?
|
71
|
+
get("/method/#{method_name}", params)
|
72
|
+
else
|
73
|
+
raise VkException.new(method_name, {
|
74
|
+
:error => 'access_token is blank',
|
75
|
+
:error_description => 'You need first authorize app before call API methods.'
|
76
|
+
})
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
|
82
|
+
def get(method_name, options = {})
|
83
|
+
response = self.class.get(method_name, :query => options)
|
84
|
+
|
85
|
+
if response['error']
|
86
|
+
raise VkException.new(method_name, response)
|
87
|
+
else
|
88
|
+
return response
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Errors
|
94
|
+
# {"error":"invalid_grant","error_description":"Code is expired."}
|
95
|
+
# {"error":{"error_code":5,"error_msg":"User authorization failed: invalid application type","request_params":[{"key":"oauth","value":"1"},{"key":"method","value":"getProfiles"},{"key":"uid","value":"66748"},{"key":"access_token","value":"533bacf01e11f55b536a565b57531ac114461ae8736d6506a3"}]}}
|
96
|
+
#
|
97
|
+
class VkException < Exception
|
98
|
+
def initialize(method_name, options)
|
99
|
+
error_hash = options.symbolize_keys
|
100
|
+
@message = "Error in #{method_name}: "
|
101
|
+
|
102
|
+
if error_hash[:error].is_a?(Hash)
|
103
|
+
@message += error_hash[:error].inspect
|
104
|
+
else
|
105
|
+
@message += [error_hash[:error], error_hash[:error_description]].join('-')
|
106
|
+
end
|
107
|
+
|
108
|
+
super @message
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module App
|
3
|
+
# IFrame приложения
|
4
|
+
# More info at http://vkontakte.ru/developers.php?id=-1_27971896&s=1
|
5
|
+
#
|
6
|
+
class Iframe < Base
|
7
|
+
include Api::Photos
|
8
|
+
include Api::Friends
|
9
|
+
include Api::Groups
|
10
|
+
|
11
|
+
attr_accessor :params
|
12
|
+
|
13
|
+
# Основные параметры запуска приложения
|
14
|
+
# При отображении приложения посредством flashVars или строки запроса (для IFrame приложений)
|
15
|
+
# в него передаются следующие параметры: api_url, api_id, user_id, sid, secret, group_id ...
|
16
|
+
# http://vkontakte.ru/developers.php?id=-1_27971896&s=1
|
17
|
+
#
|
18
|
+
def params=(value)
|
19
|
+
@params = value.symbolize_keys
|
20
|
+
|
21
|
+
if @params[:access_token] && auth.nil?
|
22
|
+
self.auth = { 'access_token' => @params[:access_token] }
|
23
|
+
end
|
24
|
+
|
25
|
+
@params
|
26
|
+
end
|
27
|
+
|
28
|
+
# Этот параметр приходит, если в приложении включена система платежей (во вкладке Платежи при редактировании приложения).
|
29
|
+
# auth_key вычисляется на сервере ВКонтакте следующим образом:
|
30
|
+
# auth_key = md5(api_id + '_' + viewer_id + '_' + api_secret)
|
31
|
+
#
|
32
|
+
def valid_auth_key?
|
33
|
+
!params[:auth_key].blank? && params[:auth_key] == auth_key
|
34
|
+
end
|
35
|
+
|
36
|
+
# Переменная language может принимать следующие значения:
|
37
|
+
#
|
38
|
+
# 0 – русский язык.
|
39
|
+
# 1 – украинский язык.
|
40
|
+
# 2 – белорусский язык.
|
41
|
+
# 3 – английский язык.
|
42
|
+
#
|
43
|
+
def language
|
44
|
+
return :ru if params[:language].blank?
|
45
|
+
case params[:language].to_s
|
46
|
+
when '0' then :ru
|
47
|
+
when '1' then :uk
|
48
|
+
when '2' then :be
|
49
|
+
when '3' then :en
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# результат выполнения API-запроса, формирующийся при просмотре приложения.
|
54
|
+
# Параметры этого запроса можно ввести в разделе редактирования приложения.
|
55
|
+
# Например, для получения информации об указанных пользователях, можно использовать следующий запрос:
|
56
|
+
# method=getProfiles&uids={user_id},{viewer_id},1,6492&format=json&v=2.0
|
57
|
+
#
|
58
|
+
def api_result
|
59
|
+
@api_result ||= MultiJson.decode(params[:api_result])
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
# это ключ, необходимый для авторизации пользователя на стороннем сервере
|
65
|
+
#
|
66
|
+
def auth_key
|
67
|
+
Utils.md5( [@config[:app_id], params[:viewer_id], @config[:app_secret]].join('_') )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
module App
|
3
|
+
# Данный метод доступен только с серверной стороны.
|
4
|
+
# More info at http://vkontakte.ru/developers.php?id=-1_27971896&s=1
|
5
|
+
#
|
6
|
+
class Secure < Base
|
7
|
+
include Api::Secure
|
8
|
+
|
9
|
+
def initialize(app_id = nil, app_secret = nil)
|
10
|
+
super
|
11
|
+
authorize
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Vkontakte
|
2
|
+
class Config < Hash
|
3
|
+
# Creates an accessor that simply sets and reads a key in the hash:
|
4
|
+
#
|
5
|
+
# class Config < Hash
|
6
|
+
# hash_accessor :routes, :secret_key, :service_number, :project_name
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# config = Config.new
|
10
|
+
# config.routes = '/posts/message'
|
11
|
+
# config[:routes] #=> '/posts/message'
|
12
|
+
#
|
13
|
+
def self.hash_accessor(*names) #:nodoc:
|
14
|
+
names.each do |name|
|
15
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
16
|
+
def #{name}
|
17
|
+
self[:#{name}]
|
18
|
+
end
|
19
|
+
|
20
|
+
def #{name}=(value)
|
21
|
+
self[:#{name}] = value
|
22
|
+
end
|
23
|
+
METHOD
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
hash_accessor :app_id, :app_secret, :debug, :logger, :format
|
28
|
+
|
29
|
+
def initialize(other={})
|
30
|
+
merge!(other)
|
31
|
+
self[:app_id] ||= "Vkontakte API ID"
|
32
|
+
self[:app_secret] ||= "Vkontakte APP SECRET"
|
33
|
+
self[:format] ||= :json
|
34
|
+
self[:debug] ||= false
|
35
|
+
self[:logger] ||= nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Vkontakte
|
4
|
+
module Utils
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def generate_cookie_sign(data, app_secret)
|
8
|
+
md5(collect_params(data) + app_secret)
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_api_sign(cookies, data)
|
12
|
+
cookies['secret'] ||= Vkontakte.config.app_secret
|
13
|
+
md5(cookies['mid'], collect_params(data), cookies['secret'])
|
14
|
+
end
|
15
|
+
|
16
|
+
def collect_params(data)
|
17
|
+
data.sort{|a, b| a.first.to_s <=> b.first.to_s}.collect{|key, value| "#{key}=#{value}"}.join
|
18
|
+
end
|
19
|
+
|
20
|
+
def md5(*args)
|
21
|
+
Digest::MD5.hexdigest(args.join)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Vkontakte::Api::Friends do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte::Api::Friends.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "iframe" do
|
9
|
+
before(:each) do
|
10
|
+
@token = '3a3d250e705051b03ed479343c3ec2833783eea3eea29860182716ed1d40319'
|
11
|
+
@iframe = Vkontakte::App::Iframe.new
|
12
|
+
@iframe.auth = {'access_token' => @token}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get friends list by uid param" do
|
16
|
+
FakeWeb.register_uri(:get,
|
17
|
+
"https://api.vkontakte.ru/method/friends.get?access_token=#{@token}&uid=81202312",
|
18
|
+
:body => '{"response":[2592709,3859793,4663468]}')
|
19
|
+
|
20
|
+
@iframe.friends.get(:uid => 81202312).should == {"response"=>[2592709, 3859793, 4663468]}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should get friends list by fields" do
|
24
|
+
FakeWeb.register_uri(:get,
|
25
|
+
"https://api.vkontakte.ru/method/friends.get?access_token=#{@token}&fields=81202312",
|
26
|
+
:body => '{"response":[{"uid":2592709,"first_name":"Павел","last_name":"Галета","online":0},{"uid":3859793,"first_name":"Мария","last_name":"Семёнова","online":0},{"uid":4663468,"first_name":"Ekaterina","last_name":"Koronotova","online":0}]}')
|
27
|
+
|
28
|
+
@iframe.friends.get(:fields => 81202312).should == {"response"=>[{"uid"=>2592709, "last_name"=>"\320\223\320\260\320\273\320\265\321\202\320\260", "online"=>0, "first_name"=>"\320\237\320\260\320\262\320\265\320\273"}, {"uid"=>3859793, "last_name"=>"\320\241\320\265\320\274\321\221\320\275\320\276\320\262\320\260", "online"=>0, "first_name"=>"\320\234\320\260\321\200\320\270\321\217"}, {"uid"=>4663468, "last_name"=>"Koronotova", "online"=>0, "first_name"=>"Ekaterina"}]}
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should get getAppUsers" do
|
32
|
+
FakeWeb.register_uri(:get,
|
33
|
+
"https://api.vkontakte.ru/method/friends.getAppUsers?access_token=#{@token}",
|
34
|
+
:body => '{"response":[2592709]}')
|
35
|
+
|
36
|
+
@iframe.friends.getAppUsers.should == {"response" => [2592709]}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should get getOnline" do
|
40
|
+
FakeWeb.register_uri(:get,
|
41
|
+
"https://api.vkontakte.ru/method/friends.getOnline?access_token=#{@token}&uid=2592709",
|
42
|
+
:body => '{"response":[2450999,2488708,2649518,4440077]}')
|
43
|
+
|
44
|
+
@iframe.friends.getOnline(:uid => 2592709).should == {"response"=>[2450999, 2488708, 2649518, 4440077]}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should get getMutual" do
|
48
|
+
FakeWeb.register_uri(:get,
|
49
|
+
"https://api.vkontakte.ru/method/friends.getMutual?target_uid=2450999&access_token=#{@token}&source_uid=2592709",
|
50
|
+
:body => '{"response":[2301578,2619312,5818827,6391852,6411298,6422462]}')
|
51
|
+
|
52
|
+
response = @iframe.friends.getMutual(:target_uid => 2450999, :source_uid => 2592709)
|
53
|
+
response.should == {"response" => [2301578,2619312,5818827,6391852,6411298,6422462]}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Vkontakte::Api::Groups do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte::Api::Groups.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "iframe" do
|
9
|
+
before(:each) do
|
10
|
+
@token = '3a3d250e705051b03ed479343c3ec2833783eea3eea29860182716ed1d40319'
|
11
|
+
@iframe = Vkontakte::App::Iframe.new
|
12
|
+
@iframe.auth = {'access_token' => @token}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get groups list by uid param" do
|
16
|
+
FakeWeb.register_uri(:get,
|
17
|
+
"https://api.vkontakte.ru/method/groups.get?access_token=#{@token}&uid=81202312",
|
18
|
+
:body => '{"response":[16527885]}')
|
19
|
+
|
20
|
+
@iframe.groups.get(:uid => 81202312).should == {"response" => [16527885]}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise permission error on access friend groups" do
|
24
|
+
FakeWeb.register_uri(:get,
|
25
|
+
"https://api.vkontakte.ru/method/groups.get?access_token=#{@token}&uid=2592709",
|
26
|
+
:body => '{"error":{"error_code":7,"error_msg":"Permission to perform this action is denied by user","request_params":[{"key":"oauth","value":"1"},{"key":"method","value":"groups.get"},{"key":"uid","value":"2592709"},{"key":"access_token","value":"74aee6063ec4aea07047ba3cb47079607f870797079ea90fef75c6361570a5f"}]}}')
|
27
|
+
|
28
|
+
lambda {
|
29
|
+
@iframe.groups.get(:uid => 2592709)
|
30
|
+
}.should raise_error Vkontakte::App::VkException
|
31
|
+
end
|
32
|
+
|
33
|
+
context "exists group" do
|
34
|
+
before(:each) do
|
35
|
+
@group_id = 16527885
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return group info" do
|
39
|
+
FakeWeb.register_uri(:get,
|
40
|
+
"https://api.vkontakte.ru/method/groups.getById?access_token=#{@token}&gid=#{@group_id}",
|
41
|
+
:body => '{"response":[{"gid":16527885,"name":"Club Music Group of Kiev","screen_name":"club16527885","is_closed":0,"type":"group","photo":"http:\/\/cs884.vkontakte.ru\/g16527885\/c_08b73308.jpg","photo_medium":"http:\/\/cs884.vkontakte.ru\/g16527885\/b_6e68053d.jpg","photo_big":"http:\/\/cs884.vkontakte.ru\/g16527885\/a_ba67625c.jpg"}]}')
|
42
|
+
|
43
|
+
@iframe.groups.getById(:gid => @group_id).should == {"response"=>[{"photo"=>"http://cs884.vkontakte.ru/g16527885/c_08b73308.jpg", "name"=>"Club Music Group of Kiev", "gid"=>16527885, "is_closed"=>0, "photo_medium"=>"http://cs884.vkontakte.ru/g16527885/b_6e68053d.jpg", "type"=>"group", "photo_big"=>"http://cs884.vkontakte.ru/g16527885/a_ba67625c.jpg", "screen_name"=>"club16527885"}]}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return group member" do
|
47
|
+
FakeWeb.register_uri(:get,
|
48
|
+
"https://api.vkontakte.ru/method/groups.isMember?access_token=#{@token}&gid=#{@group_id}&uid=81202312",
|
49
|
+
:body => '{"response":1}')
|
50
|
+
|
51
|
+
@iframe.groups.isMember(:uid => 81202312, :gid => @group_id).should == {"response" => 1}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return all groups members" do
|
55
|
+
FakeWeb.register_uri(:get,
|
56
|
+
"https://api.vkontakte.ru/method/groups.getMembers?access_token=#{@token}&gid=#{@group_id}&count=5",
|
57
|
+
:body => '{"response":{"count":29364,"users":[107765962,66506999,145557591,72256631,28639402]}}')
|
58
|
+
|
59
|
+
response = @iframe.groups.getMembers(:gid => @group_id, :count => 5)
|
60
|
+
response.should == {"response"=>{"count"=>29364, "users"=>[107765962, 66506999, 145557591, 72256631, 28639402]}}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Vkontakte::Api::Photos do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte::Api::Photos.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "params" do
|
9
|
+
before(:each) do
|
10
|
+
@token = '3a3d250e705051b03ed479343c3ec2833783eea3eea29860182716ed1d40319'
|
11
|
+
@iframe = Vkontakte::App::Iframe.new
|
12
|
+
@iframe.auth = {'access_token' => @token}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be call getAlbums method" do
|
16
|
+
response = '{"response":[{"aid":"17071606","thumb_id":"98054577","owner_id":"6492","title":"",
|
17
|
+
"description":"","created":"1204576880","updated":"1229532461", "size":"3","privacy":"0"}]}'
|
18
|
+
|
19
|
+
FakeWeb.register_uri(:get,
|
20
|
+
"https://api.vkontakte.ru/method/photos.getAlbums?access_token=#{@token}",
|
21
|
+
:body => response)
|
22
|
+
|
23
|
+
@iframe.photos.getAlbums.should == {"response" => [{"aid" => "17071606","thumb_id" => "98054577","owner_id" => "6492","title" => "", "description" => "","created" => "1204576880","updated" => "1229532461", "size" => "3","privacy" => "0"}]}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Vkontakte::Api::Secure do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte::Api::Secure.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "secure" do
|
9
|
+
before(:all) do
|
10
|
+
@token = '3a3d250e705051b03ed479343c3ec2833783eea3eea29860182716ed1d40319'
|
11
|
+
|
12
|
+
FakeWeb.register_uri(:get,
|
13
|
+
"https://api.vkontakte.ru/oauth/access_token?grant_type=client_credentials&client_id=#{Vkontakte.config.app_id}&client_secret=#{Vkontakte.config.app_secret}",
|
14
|
+
:body => '{"access_token":"#{@token}"}')
|
15
|
+
|
16
|
+
@app = Vkontakte::App::Secure.new
|
17
|
+
@options = @app.secure.default_options.merge(:access_token => @token)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should call sendNotification" do
|
21
|
+
p = @options.merge(:uids => 81202312, :message => "test")
|
22
|
+
|
23
|
+
FakeWeb.register_uri(:get,
|
24
|
+
"https://api.vkontakte.ru/method/secure.sendNotification?" + HTTParty::HashConversions.to_params(p),
|
25
|
+
:body => '{"response":"81202312"}')
|
26
|
+
|
27
|
+
@app.secure.sendNotification(p).should == {"response"=>"81202312"}
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should call getAppBalance" do
|
31
|
+
FakeWeb.register_uri(:get,
|
32
|
+
"https://api.vkontakte.ru/method/secure.getAppBalance?" + HTTParty::HashConversions.to_params(@options),
|
33
|
+
:body => '{"response":5000}')
|
34
|
+
|
35
|
+
@app.secure.getAppBalance(@options).should == {"response"=>5000}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should call getBalance" do
|
39
|
+
p = @options.merge(:uid => 81202312)
|
40
|
+
|
41
|
+
FakeWeb.register_uri(:get,
|
42
|
+
"https://api.vkontakte.ru/method/secure.getBalance?" + HTTParty::HashConversions.to_params(p),
|
43
|
+
:body => '{"response":350}')
|
44
|
+
|
45
|
+
@app.secure.getBalance(p).should == {"response"=>350}
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should call withdrawVotes" do
|
49
|
+
p = @options.merge(:uid => 81202312, :votes => 2)
|
50
|
+
|
51
|
+
FakeWeb.register_uri(:get,
|
52
|
+
"https://api.vkontakte.ru/method/secure.withdrawVotes?" + HTTParty::HashConversions.to_params(p),
|
53
|
+
:body => '{"response":2}')
|
54
|
+
|
55
|
+
@app.secure.withdrawVotes(p).should == {"response"=>2}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should call getTransactionsHistory" do
|
59
|
+
p = @options.merge(:uid => 81202312, :type => 0, :limit => 2)
|
60
|
+
|
61
|
+
FakeWeb.register_uri(:get,
|
62
|
+
"https://api.vkontakte.ru/method/secure.getTransactionsHistory?" + HTTParty::HashConversions.to_params(p),
|
63
|
+
:body => '{"response":[{"id":"65968","uid_from":"34804733","uid_to":"33239732","votes":"1000","date":"1243421339"},{"id":"65956","uid_from":"35003049","uid_to":"33239732","votes":"300","date":"1243421213"}]}')
|
64
|
+
|
65
|
+
@app.secure.getTransactionsHistory(p).should == {"response"=>[{"votes"=>"1000", "uid_to"=>"33239732", "date"=>"1243421339", "id"=>"65968", "uid_from"=>"34804733"}, {"votes"=>"300", "uid_to"=>"33239732", "date"=>"1243421213", "id"=>"65956", "uid_from"=>"35003049"}]}
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should call addRating" do
|
69
|
+
p = @options.merge(:uid => 81202312, :rate => 200)
|
70
|
+
|
71
|
+
FakeWeb.register_uri(:get,
|
72
|
+
"https://api.vkontakte.ru/method/secure.addRating?" + HTTParty::HashConversions.to_params(p),
|
73
|
+
:body => '{"response":{"rating_added":200}}')
|
74
|
+
|
75
|
+
@app.secure.addRating(p).should == {"response" => {"rating_added" => 200}}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should call setCounter" do
|
79
|
+
p = @options.merge(:uid => 81202312, :counter => 4)
|
80
|
+
|
81
|
+
FakeWeb.register_uri(:get,
|
82
|
+
"https://api.vkontakte.ru/method/secure.setCounter?" + HTTParty::HashConversions.to_params(p),
|
83
|
+
:body => '{"response":1}')
|
84
|
+
|
85
|
+
@app.secure.setCounter(p).should == {"response" => 1}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Vkontakte::App::Iframe do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte::App::Iframe.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "params" do
|
9
|
+
before(:each) do
|
10
|
+
@params = {"referrer"=>"profile", "is_app_user"=>"0", "api_settings"=>"0", "parent_language"=>"0", "hash"=>"", "sid"=>"db5aa091133cb1971817421f3cf14a1b78605ad2ab67218e8066c2bd57e736", "language"=>"0", "group_id"=>"0", "user_id"=>"2592709", "viewer_type"=>"1", "secret"=>"492aeb00af", "lc_name"=>"5941f805", "access_token"=>"3a3d250e705051b03ed479343c3ec2833783eea3eea29860182716ed1d40319", "viewer_id"=>"81202312", "api_url"=>"http://api.vkontakte.ru/api.php"}
|
11
|
+
@params["auth_key"] = Vkontakte::Utils.md5([Vkontakte.config.app_id, @params['viewer_id'], Vkontakte.config.app_secret].join('_'))
|
12
|
+
@params["api_result"] = '{"response":[{"uid":81202312,"first_name":"Tester","last_name":"Tester"}]}'
|
13
|
+
@params["app_id"] = Vkontakte.config.app_id
|
14
|
+
|
15
|
+
@iframe = Vkontakte::App::Iframe.new
|
16
|
+
@iframe.params = @params
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should parse request params" do
|
20
|
+
@iframe.language.should == :ru
|
21
|
+
@iframe.auth.should_not be_nil
|
22
|
+
@iframe.auth['access_token'].should == @params["access_token"]
|
23
|
+
@iframe.valid_auth_key?.should be_true
|
24
|
+
@iframe.api_result.should == {"response"=>[{"uid"=>81202312, "last_name"=>"Tester", "first_name"=>"Tester"}]}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not be valid auth_key" do
|
28
|
+
@iframe.params = @params.merge("auth_key" => 'wrong')
|
29
|
+
@iframe.valid_auth_key?.should_not be_true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
$:.push File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require "vkontakte"
|
6
|
+
require "fakeweb"
|
7
|
+
|
8
|
+
# Load support files
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
10
|
+
|
11
|
+
Vkontakte.setup do |config|
|
12
|
+
config.app_id = 10000
|
13
|
+
config.app_secret = "supersecret"
|
14
|
+
config.format = :json
|
15
|
+
config.debug = false
|
16
|
+
config.logger = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
# Remove this line if you don't want RSpec's should and should_not
|
21
|
+
# methods or matchers
|
22
|
+
require 'rspec/expectations'
|
23
|
+
config.include RSpec::Matchers
|
24
|
+
|
25
|
+
# == Mock Framework
|
26
|
+
config.mock_with :rspec
|
27
|
+
|
28
|
+
config.before(:suite) do
|
29
|
+
FakeWeb.allow_net_connect = false
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:suite) do
|
33
|
+
FakeWeb.allow_net_connect = true
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vkontakte do
|
4
|
+
it "should be valid" do
|
5
|
+
Vkontakte.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "setup" do
|
9
|
+
before(:each) do
|
10
|
+
Vkontakte.setup do |config|
|
11
|
+
config.app_id = 1234567
|
12
|
+
config.app_secret = "supersecretkey"
|
13
|
+
config.format = :xml
|
14
|
+
config.debug = false
|
15
|
+
config.logger = nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set config options" do
|
20
|
+
Vkontakte.config.app_id.should == 1234567
|
21
|
+
Vkontakte.config.app_secret.should == 'supersecretkey'
|
22
|
+
Vkontakte.config.format.should == :xml
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise error on not exists option" do
|
26
|
+
lambda {
|
27
|
+
Vkontakte.config.some_param
|
28
|
+
}.should raise_error(StandardError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vkontakte
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Igor Galeta
|
14
|
+
- Pavlo Galeta
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-11-11 00:00:00 +02:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: activesupport
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: httparty
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: "The easiest way to access Vkontakte API and some other utils. "
|
51
|
+
email: galeta.igor@gmail.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files:
|
57
|
+
- README.rdoc
|
58
|
+
files:
|
59
|
+
- lib/vkontakte/app/secure.rb
|
60
|
+
- lib/vkontakte/app/iframe.rb
|
61
|
+
- lib/vkontakte/app/base.rb
|
62
|
+
- lib/vkontakte/utils.rb
|
63
|
+
- lib/vkontakte/api/secure.rb
|
64
|
+
- lib/vkontakte/api/friends.rb
|
65
|
+
- lib/vkontakte/api/groups.rb
|
66
|
+
- lib/vkontakte/api/base.rb
|
67
|
+
- lib/vkontakte/api/photos.rb
|
68
|
+
- lib/vkontakte/config.rb
|
69
|
+
- lib/vkontakte/version.rb
|
70
|
+
- lib/vkontakte.rb
|
71
|
+
- MIT-LICENSE
|
72
|
+
- Rakefile
|
73
|
+
- Gemfile
|
74
|
+
- README.rdoc
|
75
|
+
- spec/api/secure_spec.rb
|
76
|
+
- spec/api/friends_spec.rb
|
77
|
+
- spec/api/photos_spec.rb
|
78
|
+
- spec/api/groups_spec.rb
|
79
|
+
- spec/vkontakte_spec.rb
|
80
|
+
- spec/apps/base_spec.rb
|
81
|
+
- spec/apps/iframe_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
has_rdoc: true
|
84
|
+
homepage: https://github.com/galetahub/vkontakte
|
85
|
+
licenses: []
|
86
|
+
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
hash: 3
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 3
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
requirements: []
|
111
|
+
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.6.2
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Vkontakte API
|
117
|
+
test_files:
|
118
|
+
- spec/api/secure_spec.rb
|
119
|
+
- spec/api/friends_spec.rb
|
120
|
+
- spec/api/photos_spec.rb
|
121
|
+
- spec/api/groups_spec.rb
|
122
|
+
- spec/vkontakte_spec.rb
|
123
|
+
- spec/apps/base_spec.rb
|
124
|
+
- spec/apps/iframe_spec.rb
|
125
|
+
- spec/spec_helper.rb
|