odnoklassniki 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa32a6ad3f01eeb19c56f001b06a75ba7564610d
4
- data.tar.gz: 888fdd5cacb10c743b680d5858df65a98d6830ff
3
+ metadata.gz: 2b3a824e8027e9e9d9ba740492920481a3310b1b
4
+ data.tar.gz: fe9adca08f39d5d97e7eab6b432ee0d41a98c5cf
5
5
  SHA512:
6
- metadata.gz: d3f1963e9c51d82be4760e9c7ac58795e40a5c39262b62755df9221216b2299d7d3aa07e88065f31640e6da82a987da2a475968744186dc4da0913debda505c7
7
- data.tar.gz: 18876b13cbc7e90b6038f78ad528ae100733555a870fb904d18c772b5d1e5c8d1a841d7f48c72efd517ba2cf7e640a5880b04ceaddf6170fa033a014450e817a
6
+ metadata.gz: 24f487fbb1cbacf25299394843fda7dba17555f0ca40ed46ff718d36d061226ec525e69cb17178eca4f730b35e6d4bdd9f779930a6929310c8ff01144ab77c21
7
+ data.tar.gz: 0294159377a0adf28f714b91f9c2eebee75799e4ef1c8a1ab0d874edc2c8a116dc8bfc6dbd3c63f355410bbafa2b9b7f4f55a5cb5fcbb06cb56c12e0a794fc1a
data/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  # Odnoklassniki
2
2
  [![Build Status](https://travis-ci.org/gazay/odnoklassniki.svg)](http://travis-ci.org/gazay/odnoklassniki) [![CodeClimate](https://d3s6mut3hikguw.cloudfront.net/github/gazay/odnoklassniki/badges/gpa.svg)](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
- Right now it is a simple wrapper on get and post requests to Odnoklassniki api.
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 in [Amplifr](https://amplifr.com) and currently being developed
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
- gem install odnoklassniki
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 odnoklassniki api methods you should have [VALUABLE ACCESS](http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=12878032) to odnoklassniki.
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
- You can create global configuration for your application. Create initializer `config/initializers/ok_api.rb`:
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 config object and feed it to `Odnoklassniki` module:
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 you create new `Odnoklassniki::Client` you can pass all needed (or missed on configuration step) options right there:
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 automaticaly just once
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 get requests above identical
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 handling
83
+ ### Error Handling
70
84
 
71
- Most of errors from Odnoklassniki API retruned in success response (with status code 200).
72
- So there is a wrapper for it in this gem:
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 are bunch of client/server error classes which structure was gratefully copied and adopted from
83
- @sferik's twitter gem. They can be useful when Odnoklassniki API wasn't reached or when some other issue occured.
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 @Strech, @igas.
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)
@@ -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
- MultiJson.load(response.body)
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,13 @@
1
+ module Odnoklassniki
2
+ module REST
3
+ class Mediatopic
4
+
5
+ attr_accessor :client
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Odnoklassniki
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  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.1
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: 2015-02-04 00:00:00.000000000 Z
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.2.2
256
+ rubygems_version: 2.5.1
252
257
  signing_key:
253
258
  specification_version: 4
254
259
  summary: Ruby wrapper for Odnoklassniki API