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 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