odnoklassniki 0.0.1 → 0.0.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 +4 -4
- data/README.md +34 -19
- data/lib/odnoklassniki/client.rb +8 -6
- data/lib/odnoklassniki/request.rb +5 -1
- data/lib/odnoklassniki/rest/mediatopic.rb +13 -0
- data/lib/odnoklassniki/rest/mediatopic/content.rb +97 -0
- data/lib/odnoklassniki/rest/mediatopic/photoalbum.rb +117 -0
- data/lib/odnoklassniki/rest/user.rb +18 -0
- data/lib/odnoklassniki/utils.rb +18 -0
- data/lib/odnoklassniki/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b3a824e8027e9e9d9ba740492920481a3310b1b
|
4
|
+
data.tar.gz: fe9adca08f39d5d97e7eab6b432ee0d41a98c5cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24f487fbb1cbacf25299394843fda7dba17555f0ca40ed46ff718d36d061226ec525e69cb17178eca4f730b35e6d4bdd9f779930a6929310c8ff01144ab77c21
|
7
|
+
data.tar.gz: 0294159377a0adf28f714b91f9c2eebee75799e4ef1c8a1ab0d874edc2c8a116dc8bfc6dbd3c63f355410bbafa2b9b7f4f55a5cb5fcbb06cb56c12e0a794fc1a
|
data/README.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# Odnoklassniki
|
2
2
|
[](http://travis-ci.org/gazay/odnoklassniki) [](https://codeclimate.com/github/gazay/odnoklassniki)
|
3
3
|
|
4
|
-
Ruby wrapper for Odnoklassniki API
|
4
|
+
**Odnoklassniki** is a Ruby wrapper for the [Odnoklassniki social network API](http://apiok.ru/).
|
5
5
|
|
6
|
-
|
6
|
+
At the moment, it is just a simple wrapper for GET and POST requests for Odnoklassniki API.
|
7
7
|
|
8
|
-
This gem widely used
|
8
|
+
This gem is widely used by [Amplifr](https://amplifr.com/?utm_source=odnoklassniki-gem) social media management tool and is currently under development.
|
9
|
+
|
10
|
+
<a href="https://amplifr.com/?utm_source=odnoklassniki-gem">
|
11
|
+
<img src="https://amplifr.com/logo.png" alt="Amplifr" width="162" height="162">
|
12
|
+
</a>
|
9
13
|
|
10
14
|
<a href="https://evilmartians.com/?utm_source=odnoklassniki-gem">
|
11
15
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
@@ -13,17 +17,27 @@ This gem widely used in [Amplifr](https://amplifr.com) and currently being devel
|
|
13
17
|
|
14
18
|
## Installation
|
15
19
|
|
20
|
+
You can install the gem via RubyGems:
|
21
|
+
|
22
|
+
```
|
23
|
+
gem install odnoklassniki
|
16
24
|
```
|
17
|
-
|
25
|
+
|
26
|
+
Or by using Bundler: put
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem 'odnoklassniki'
|
18
30
|
```
|
19
31
|
|
32
|
+
in your `Gemfile`.
|
33
|
+
|
20
34
|
## Usage
|
21
35
|
|
22
|
-
To use
|
36
|
+
To use Odnoklassniki API methods you should have "[VALUABLE ACCESS](http://apiok.ru/wiki/display/api/Authorization+OAuth+2.0)" to Odnoklassniki.
|
23
37
|
|
24
38
|
### Configuration
|
25
39
|
|
26
|
-
|
40
|
+
When using the gem with a Ruby on Rails application, you can configure Odnoklassniki globally by creating an initializer: `config/initializers/ok_api.rb`
|
27
41
|
|
28
42
|
```ruby
|
29
43
|
Odnoklassniki.configure do |c|
|
@@ -33,17 +47,17 @@ Odnoklassniki.configure do |c|
|
|
33
47
|
end
|
34
48
|
```
|
35
49
|
|
36
|
-
Or you can create
|
50
|
+
Or you can create a `Config` object and feed it to the `Odnoklassniki` module:
|
37
51
|
|
38
52
|
```ruby
|
39
53
|
config = Odnoklassniki::Config.configure do |c|
|
40
|
-
...
|
54
|
+
# ...
|
41
55
|
end
|
42
56
|
|
43
57
|
Odnoklassniki.config = config
|
44
58
|
```
|
45
59
|
|
46
|
-
Also, when
|
60
|
+
Also, when creating a new `Odnoklassniki::Client`, you can pass along all required (or missing from the configuration step) options right there:
|
47
61
|
|
48
62
|
```ruby
|
49
63
|
Odnoklassniki::Client.new(access_token: 'your token', client_id: 'your client id')
|
@@ -54,22 +68,22 @@ Odnoklassniki::Client.new(access_token: 'your token', client_id: 'your client id
|
|
54
68
|
```ruby
|
55
69
|
client = Odnoklassniki::Client.new(access_token: token)
|
56
70
|
|
57
|
-
new_token = client.refresh_token! # This method will be called
|
58
|
-
# for each client before performing request
|
71
|
+
new_token = client.refresh_token! # This method will be called automatically just once
|
72
|
+
# for each client before performing the request
|
59
73
|
|
60
74
|
client.get('friends.get')
|
61
75
|
client.get('friends/get')
|
62
76
|
client.get('api/friends/get')
|
63
77
|
client.get('/api/friends/get')
|
64
|
-
# All
|
78
|
+
# NOTE: All GET requests above are identical!
|
65
79
|
|
66
80
|
client.post('mediatopic.post', type: 'USER_STATUS', attachment: attachment)
|
67
81
|
```
|
68
82
|
|
69
|
-
### Error
|
83
|
+
### Error Handling
|
70
84
|
|
71
|
-
|
72
|
-
So there is a wrapper for
|
85
|
+
Unfortunately, most errors from Odnoklassniki API are returned within a _success_ response (200 HTTP status code).
|
86
|
+
So, there is a wrapper just for that in this gem:
|
73
87
|
|
74
88
|
```ruby
|
75
89
|
begin
|
@@ -79,8 +93,9 @@ rescue Odnoklassniki::Error::ClientError => e
|
|
79
93
|
end
|
80
94
|
```
|
81
95
|
|
82
|
-
Also there
|
83
|
-
@sferik's twitter gem.
|
96
|
+
Also there is a bunch of client/server error classes whose structure was gratefully copied and adopted from
|
97
|
+
[@sferik](https://github.com/sferik)'s [twitter](https://github.com/sferik/twitter) gem.
|
98
|
+
They can be useful in case when Odnoklassniki API wasn't reached at all or when some other issue has occured.
|
84
99
|
|
85
100
|
## TODO
|
86
101
|
|
@@ -99,8 +114,8 @@ Also there are bunch of client/server error classes which structure was grateful
|
|
99
114
|
|
100
115
|
* @gazay
|
101
116
|
|
102
|
-
Special thanks to @
|
117
|
+
Special thanks to [@strech](https://github.com/strech), [@igas](https://github.com/igas).
|
103
118
|
|
104
119
|
## License
|
105
120
|
|
106
|
-
The MIT License
|
121
|
+
[The MIT License](https://github.com/gazay/odnoklassniki/blob/master/LICENSE)
|
data/lib/odnoklassniki/client.rb
CHANGED
@@ -11,12 +11,12 @@ module Odnoklassniki
|
|
11
11
|
@refreshed = false
|
12
12
|
end
|
13
13
|
|
14
|
-
def get(method, params={})
|
15
|
-
request_method(:get, method, params)
|
14
|
+
def get(method, params={}, &block)
|
15
|
+
request_method(:get, method, params, block)
|
16
16
|
end
|
17
17
|
|
18
|
-
def post(method, params={})
|
19
|
-
request_method(:post, method, params)
|
18
|
+
def post(method, params={}, &block)
|
19
|
+
request_method(:post, method, params, block)
|
20
20
|
end
|
21
21
|
|
22
22
|
def refresh_token!
|
@@ -53,9 +53,11 @@ module Odnoklassniki
|
|
53
53
|
}
|
54
54
|
end
|
55
55
|
|
56
|
-
def request_method(http_method, method, params)
|
56
|
+
def request_method(http_method, method, params, block)
|
57
57
|
method, params = fallback(method) if method.is_a?(Hash)
|
58
|
-
request.send(http_method, method_path(method), params)
|
58
|
+
response = request.send(http_method, method_path(method), params)
|
59
|
+
response = block.call response if block
|
60
|
+
response
|
59
61
|
end
|
60
62
|
|
61
63
|
def request
|
@@ -40,7 +40,11 @@ module Odnoklassniki
|
|
40
40
|
def respond(response)
|
41
41
|
parsed_body = \
|
42
42
|
begin
|
43
|
-
|
43
|
+
if response.body.nil? || response.body == ''
|
44
|
+
return response.body
|
45
|
+
else
|
46
|
+
MultiJson.load(response.body)
|
47
|
+
end
|
44
48
|
rescue MultiJson::DecodeError
|
45
49
|
#Есть случаи отдачи кривого JSON от одноклассников
|
46
50
|
gsubed = response.body.
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Odnoklassniki
|
2
|
+
module REST
|
3
|
+
class Mediatopic
|
4
|
+
class Content
|
5
|
+
VIDEO_LINK_PATTERN = /youtu\.?be|vimeo/.freeze
|
6
|
+
AUDIO_LINK_PATTERN = /soundcloud|snd\.cc/.freeze
|
7
|
+
EMBEDABLE_LINK_PATTERN = /#{VIDEO_LINK_PATTERN}|#{AUDIO_LINK_PATTERN}/.freeze
|
8
|
+
TEXT_TYPE = 'text'.freeze
|
9
|
+
LINK_TYPE = 'link'.freeze
|
10
|
+
PHOTO_TYPE = 'photo'.freeze
|
11
|
+
|
12
|
+
attr_accessor :options
|
13
|
+
|
14
|
+
# Options:
|
15
|
+
# text: string with message to OK (default: '')
|
16
|
+
# images: Array of File (default: [])
|
17
|
+
# account_type: :group/:personal (default: :personal)
|
18
|
+
def initialize(options={})
|
19
|
+
@options = Odnoklassniki::Utils._symbolize_kyes(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def message
|
23
|
+
@message ||= {
|
24
|
+
type: TEXT_TYPE,
|
25
|
+
text: (text || '')
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def link
|
30
|
+
@link ||= \
|
31
|
+
external_url.blank? ? nil : {type: LINK_TYPE, url: external_url}
|
32
|
+
end
|
33
|
+
|
34
|
+
def images
|
35
|
+
@images ||= [uploaded_images].compact
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def image_id_key
|
41
|
+
@image_id_key ||= options[:account_type] == :group ? :id : :photoId
|
42
|
+
end
|
43
|
+
|
44
|
+
def uploaded_images
|
45
|
+
return if options[:images].blank?
|
46
|
+
|
47
|
+
photos = options[:images].map do |photo|
|
48
|
+
{image_id_key => photoalbum.upload(photo)}
|
49
|
+
end
|
50
|
+
|
51
|
+
{type: PHOTO_TYPE, list: photos}
|
52
|
+
end
|
53
|
+
|
54
|
+
def photoalbum
|
55
|
+
@photoalbum ||= Photoalbum.new(account)
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_single_embedable_link?
|
59
|
+
has_single_link? && embedable_url?(urls[0])
|
60
|
+
end
|
61
|
+
|
62
|
+
def has_single_link?
|
63
|
+
urls.count == 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def text
|
67
|
+
@text ||= options[:text]
|
68
|
+
end
|
69
|
+
|
70
|
+
def urls
|
71
|
+
@urls ||= ::Twitter::Extractor.extract_urls(text)
|
72
|
+
end
|
73
|
+
|
74
|
+
def embedable_url?(url)
|
75
|
+
url =~ EMBEDABLE_LINK_PATTERN
|
76
|
+
end
|
77
|
+
|
78
|
+
def external_url
|
79
|
+
return unless resource.external_url?
|
80
|
+
return resource.external_url unless shorten_links?
|
81
|
+
|
82
|
+
@publication.links.where(original_url: resource.external_url)
|
83
|
+
.first_or_create.short_or_generate
|
84
|
+
end
|
85
|
+
|
86
|
+
def _symbalize_keys(hash)
|
87
|
+
symbolized = {}
|
88
|
+
hash.each do |k, v|
|
89
|
+
symbolized[k.to_sym] = v
|
90
|
+
end
|
91
|
+
hash
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/http/post/multipart'
|
3
|
+
require 'http_uploader'
|
4
|
+
|
5
|
+
require_relative '../odnoklassniki'
|
6
|
+
|
7
|
+
module Odnoklassniki
|
8
|
+
module REST
|
9
|
+
class Mediatopic
|
10
|
+
class Photoalbum
|
11
|
+
|
12
|
+
GET_ALBUMS_METHOD = 'photos.getAlbums'
|
13
|
+
CREATE_ALBUM_METHOD = 'photos.createAlbum'
|
14
|
+
GET_ALBUM_UPLOAD_URL_METHOD = 'photosV2.getUploadUrl'
|
15
|
+
COMMIT_PHOTO_METHOD = 'photosV2.commit'
|
16
|
+
|
17
|
+
ALBUM_NAME = 'apiok'
|
18
|
+
ALBUM_CREATION_OPTIONS = {
|
19
|
+
title: ALBUM_NAME,
|
20
|
+
description: 'Album for uploads from odnoklassniki api gem',
|
21
|
+
type: 'public'
|
22
|
+
}
|
23
|
+
|
24
|
+
attr_accessor :params
|
25
|
+
|
26
|
+
# Options:
|
27
|
+
# account: { id: Identifier for account in OK,
|
28
|
+
# type: :group/:personal }
|
29
|
+
# client: Client for specified account
|
30
|
+
def initialize(options)
|
31
|
+
@options = Odnoklassniki::Utils._symbolize_keys(options)
|
32
|
+
@account = @options[:account]
|
33
|
+
@api = @options[:client]
|
34
|
+
end
|
35
|
+
|
36
|
+
def upload(photo)
|
37
|
+
upload_photoalbum_photo(photo)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
Error = Class.new(StandardError)
|
43
|
+
FindingError = Class.new(Error)
|
44
|
+
CreationError = Class.new(Error)
|
45
|
+
UploadingError = Class.new(Error)
|
46
|
+
|
47
|
+
def upload_photoalbum_photo(photo)
|
48
|
+
upload_response = ::HttpUploader.new(photoalbum_upload_url)
|
49
|
+
.upload(photo.to_io,
|
50
|
+
photo.basename,
|
51
|
+
query_param: :pic1, content_type: photo.content_type)
|
52
|
+
|
53
|
+
unless Net::HTTPSuccess === upload_response
|
54
|
+
raise UploadingError, "Failed to upload file. Reason: #{upload_response.body}"
|
55
|
+
end
|
56
|
+
|
57
|
+
photo_id, photo_attributes = JSON.parse(upload_response.body)
|
58
|
+
.try(:[], 'photos').try(:flatten)
|
59
|
+
|
60
|
+
if photo_id.blank? || photo_attributes.blank?
|
61
|
+
raise UploadingError, "Broken upload response. Response: #{upload_response.body}"
|
62
|
+
end
|
63
|
+
|
64
|
+
if @account[:type] == :personal
|
65
|
+
commit_uploaded_photo(photo_id, photo_attributes['token'])
|
66
|
+
else
|
67
|
+
photo_attributes['token']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def photoalbum
|
72
|
+
@photoalbum ||= begin
|
73
|
+
params = {method: GET_ALBUMS_METHOD}
|
74
|
+
params.merge!(gid: @account[:id]) if @account[:type] == :group
|
75
|
+
|
76
|
+
@api.get(params).try(:[], 'albums').to_a
|
77
|
+
.find { |album| album['title'] == ALBUM_NAME }
|
78
|
+
rescue API::Error
|
79
|
+
raise FindingError
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_photoalbum
|
84
|
+
return photoalbum['aid'] if photoalbum.present?
|
85
|
+
|
86
|
+
params = {method: CREATE_ALBUM_METHOD}.merge!(ALBUM_CREATION_OPTIONS)
|
87
|
+
params.merge!(gid: @account[:id]) if @account[:type] == :group
|
88
|
+
|
89
|
+
@api.get(params)
|
90
|
+
rescue API::Error
|
91
|
+
raise CreationError
|
92
|
+
end
|
93
|
+
|
94
|
+
def photoalbum_upload_url
|
95
|
+
params = {method: GET_ALBUM_UPLOAD_URL_METHOD}
|
96
|
+
|
97
|
+
if @account[:type] == :group
|
98
|
+
params.merge!(gid: @account[:id])
|
99
|
+
else
|
100
|
+
params.merge!(aid: create_photoalbum)
|
101
|
+
end
|
102
|
+
|
103
|
+
@api.get(params) { |json| URI.parse json['upload_url'] }
|
104
|
+
end
|
105
|
+
|
106
|
+
def commit_uploaded_photo(photo_id, photo_token)
|
107
|
+
params = {method: COMMIT_PHOTO_METHOD, photo_id: photo_id, token: photo_token}
|
108
|
+
@api.get(params) do |commit_response|
|
109
|
+
commit_response['photos'][0]['assigned_photo_id']
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end # class Photoalbum
|
114
|
+
end # class Odnoklassniki
|
115
|
+
end # module Content
|
116
|
+
end # module Social
|
117
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Odnoklassniki
|
2
|
+
module REST
|
3
|
+
class User
|
4
|
+
|
5
|
+
attr_accessor :client
|
6
|
+
|
7
|
+
def initialize(client)
|
8
|
+
@client = client
|
9
|
+
end
|
10
|
+
|
11
|
+
def current_user(fields=[])
|
12
|
+
options = fields.empty? ? {} : fiels.join(',')
|
13
|
+
client.get('users.getCurrentUser', options)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Odnoklassniki
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def _symbolize_keys(hash)
|
7
|
+
symbolized = {}
|
8
|
+
hash.each do |k, v|
|
9
|
+
v = _symbolize_keys(v) if v.is_a?(Hash)
|
10
|
+
symbolized[k.to_sym] = v
|
11
|
+
end
|
12
|
+
symbolized
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: odnoklassniki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gazay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -215,6 +215,11 @@ files:
|
|
215
215
|
- lib/odnoklassniki/connection.rb
|
216
216
|
- lib/odnoklassniki/error.rb
|
217
217
|
- lib/odnoklassniki/request.rb
|
218
|
+
- lib/odnoklassniki/rest/mediatopic.rb
|
219
|
+
- lib/odnoklassniki/rest/mediatopic/content.rb
|
220
|
+
- lib/odnoklassniki/rest/mediatopic/photoalbum.rb
|
221
|
+
- lib/odnoklassniki/rest/user.rb
|
222
|
+
- lib/odnoklassniki/utils.rb
|
218
223
|
- lib/odnoklassniki/version.rb
|
219
224
|
- odnoklassniki.gemspec
|
220
225
|
- test/lib/odnoklassniki/client_test.rb
|
@@ -248,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
253
|
version: '0'
|
249
254
|
requirements: []
|
250
255
|
rubyforge_project: odnoklassniki
|
251
|
-
rubygems_version: 2.
|
256
|
+
rubygems_version: 2.5.1
|
252
257
|
signing_key:
|
253
258
|
specification_version: 4
|
254
259
|
summary: Ruby wrapper for Odnoklassniki API
|