medium_sdk 0.0.1
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 +7 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +22 -0
- data/README.md +183 -0
- data/Rakefile +19 -0
- data/lib/medium_sdk.rb +12 -0
- data/lib/medium_sdk/client.rb +62 -0
- data/lib/medium_sdk/connection.rb +4 -0
- data/lib/medium_sdk/connection/auth_code.rb +118 -0
- data/lib/medium_sdk/connection/integration_token.rb +31 -0
- data/test/test_base.rb +6 -0
- data/test/test_setup_token.rb +15 -0
- metadata +214 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 27ae55e4729471ea5df5cb5ac7b6c1b9dcbbc3c9
|
4
|
+
data.tar.gz: c426a99fa02d096d53e09483fef7312874d3a769
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c977ab8bf32eeaea7b30094bec818aeee5280bfe20fe0e28a52ca2f696e15363dc844d2ce0ce89cef3d4bac27041f4bd22bfd4a01f3c0475903c8e2908f8504
|
7
|
+
data.tar.gz: 53ec090b9bc602ad79483a1dce0e516bdbc8b55fe8b0e6df5b5752826c6f8cc0c2676908ab4e9fee743c796885e8c8b0a54bb5c5f777398563b0b6387de4db8b
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
---------
|
3
|
+
- **2016-08-11**: 0.0.1
|
4
|
+
1. Initial release
|
5
|
+
1. Authorization via OAuth 2.0 and Integration Token
|
6
|
+
1. Token refresh
|
7
|
+
1. Methods for `me`, `user_publications`, `publication_contributors`, `post`
|
8
|
+
1. `post` supports user posts and publication posts
|
9
|
+
1. OAuth 2.0 sample app
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
medium_sdk (0.0.1)
|
5
|
+
faraday (~> 0.9, >= 0.9)
|
6
|
+
faraday_middleware (~> 0, >= 0)
|
7
|
+
faraday_middleware-oauth2_refresh (~> 0)
|
8
|
+
multi_json (~> 1.3)
|
9
|
+
oauth2 (~> 1.0, >= 1.0.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
coveralls (0.8.15)
|
15
|
+
json (>= 1.8, < 3)
|
16
|
+
simplecov (~> 0.12.0)
|
17
|
+
term-ansicolor (~> 1.3)
|
18
|
+
thor (~> 0.19.1)
|
19
|
+
tins (>= 1.6.0, < 2)
|
20
|
+
docile (1.1.5)
|
21
|
+
faraday (0.9.2)
|
22
|
+
multipart-post (>= 1.2, < 3)
|
23
|
+
faraday_middleware (0.10.0)
|
24
|
+
faraday (>= 0.7.4, < 0.10)
|
25
|
+
faraday_middleware-oauth2_refresh (0.0.2)
|
26
|
+
faraday (~> 0.9, >= 0.9)
|
27
|
+
faraday_middleware (~> 0, >= 0)
|
28
|
+
json (2.0.2)
|
29
|
+
jwt (1.5.4)
|
30
|
+
metaclass (0.0.4)
|
31
|
+
mocha (0.14.0)
|
32
|
+
metaclass (~> 0.0.1)
|
33
|
+
multi_json (1.12.1)
|
34
|
+
multi_xml (0.5.5)
|
35
|
+
multipart-post (2.0.0)
|
36
|
+
oauth2 (1.2.0)
|
37
|
+
faraday (>= 0.8, < 0.10)
|
38
|
+
jwt (~> 1.0)
|
39
|
+
multi_json (~> 1.3)
|
40
|
+
multi_xml (~> 0.5)
|
41
|
+
rack (>= 1.2, < 3)
|
42
|
+
power_assert (0.3.0)
|
43
|
+
rack (2.0.1)
|
44
|
+
rake (0.9.6)
|
45
|
+
simplecov (0.12.0)
|
46
|
+
docile (~> 1.1.0)
|
47
|
+
json (>= 1.8, < 3)
|
48
|
+
simplecov-html (~> 0.10.0)
|
49
|
+
simplecov-html (0.10.0)
|
50
|
+
term-ansicolor (1.3.2)
|
51
|
+
tins (~> 1.0)
|
52
|
+
test-unit (3.2.1)
|
53
|
+
power_assert
|
54
|
+
thor (0.19.1)
|
55
|
+
tins (1.12.0)
|
56
|
+
|
57
|
+
PLATFORMS
|
58
|
+
ruby
|
59
|
+
|
60
|
+
DEPENDENCIES
|
61
|
+
coveralls (~> 0)
|
62
|
+
medium_sdk!
|
63
|
+
mocha
|
64
|
+
rake (~> 0)
|
65
|
+
simplecov (~> 0)
|
66
|
+
test-unit
|
67
|
+
|
68
|
+
BUNDLED WITH
|
69
|
+
1.12.5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015-2016 John Wang
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
Medium SDK for Ruby
|
2
|
+
========================
|
3
|
+
|
4
|
+
[![Gem Version][gem-version-svg]][gem-version-link]
|
5
|
+
[![Build Status][build-status-svg]][build-status-link]
|
6
|
+
[![Coverage Status][coverage-status-svg]][coverage-status-link]
|
7
|
+
[![Dependency Status][dependency-status-svg]][dependency-status-link]
|
8
|
+
[![Code Climate][codeclimate-status-svg]][codeclimate-status-link]
|
9
|
+
[![Scrutinizer Code Quality][scrutinizer-status-svg]][scrutinizer-status-link]
|
10
|
+
[![Downloads][downloads-svg]][downloads-link]
|
11
|
+
[![Docs][docs-rubydoc-svg]][docs-rubydoc-link]
|
12
|
+
[![License][license-svg]][license-link]
|
13
|
+
|
14
|
+
## Description
|
15
|
+
|
16
|
+
A Ruby SDK for the [Medium.com API](https://github.com/Medium/medium-api-docs) including:
|
17
|
+
|
18
|
+
1. Auth via OAuth 2.0 with token refresh and demo app
|
19
|
+
1. Auth via integration token
|
20
|
+
1. Get and Post APIs
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
### Via Bundler
|
25
|
+
|
26
|
+
Add `medium_sdk` to Gemfile and then run `bundle`:
|
27
|
+
|
28
|
+
```sh
|
29
|
+
$ echo "gem 'medium_sdk'" >> Gemfile
|
30
|
+
$ bundle
|
31
|
+
```
|
32
|
+
|
33
|
+
### Via RubyGems
|
34
|
+
|
35
|
+
```sh
|
36
|
+
$ gem install medium_sdk
|
37
|
+
```
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
### Authorization
|
42
|
+
|
43
|
+
#### Authorization Code Grant
|
44
|
+
|
45
|
+
The OAuth 2.0 authorization code grant is designed for where authorization needs to be granted by a 3rd party resource owner.
|
46
|
+
|
47
|
+
Using the default authorization URL:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
require 'medium_sdk'
|
51
|
+
|
52
|
+
# Initialize SDK with OAuth redirect URI
|
53
|
+
client = MediumSdk.new(
|
54
|
+
client_id: 'my_client_id',
|
55
|
+
client_secret: 'my_client_secret',
|
56
|
+
redirect_uri: 'https://example.com/callback/medium'
|
57
|
+
)
|
58
|
+
|
59
|
+
# Retrieve OAuth authorize url using default redirect URL
|
60
|
+
auth_url = client.connection.authorize_uri(
|
61
|
+
scope: 'basicProfile,publishPost',
|
62
|
+
state: 'myState'
|
63
|
+
)
|
64
|
+
```
|
65
|
+
|
66
|
+
On your redirect page, you can exchange your authorization code for an access token using the following:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
code = params['code'] # e.g. using Sinatra to retrieve code param in Redirect URI
|
70
|
+
client.connection.authorize_code(code)
|
71
|
+
```
|
72
|
+
|
73
|
+
#### Integration Token
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
require 'medium_sdk'
|
77
|
+
|
78
|
+
client = MediumSdk.new integration_token: token
|
79
|
+
```
|
80
|
+
|
81
|
+
### API Requests
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# Getting the authenticated user’s details
|
85
|
+
data = client.me
|
86
|
+
|
87
|
+
# Listing the user’s publications
|
88
|
+
data = client.user_publications 'user_id'
|
89
|
+
|
90
|
+
# Fetching contributors for a publication
|
91
|
+
data = client.publication_contributors 'publication_id'
|
92
|
+
|
93
|
+
# Creating a user post
|
94
|
+
data = client.post, {
|
95
|
+
title: "Hard things in software development",
|
96
|
+
contentFormat: "html",
|
97
|
+
content: "<p>Cache invalidation</p><p>Naming things</p>",
|
98
|
+
tags: ["development", "design"],
|
99
|
+
publishStatus: "draft"
|
100
|
+
}
|
101
|
+
|
102
|
+
# Creating a publication post
|
103
|
+
data = client.post, {
|
104
|
+
title: "Hard things in software development",
|
105
|
+
contentFormat: "html",
|
106
|
+
content: "<p>Cache invalidation</p><p>Naming things</p>",
|
107
|
+
tags: ["development", "design"],
|
108
|
+
publishStatus: "draft",
|
109
|
+
publicationId: "deadbeef"
|
110
|
+
}
|
111
|
+
```
|
112
|
+
|
113
|
+
## Demos
|
114
|
+
|
115
|
+
Demos are in the `scripts` directory and use `.env` files for configuration.
|
116
|
+
|
117
|
+
### Integration Token Demo
|
118
|
+
|
119
|
+
```bash
|
120
|
+
$ cd scripts
|
121
|
+
$ cp example.env .env
|
122
|
+
$ vi .env
|
123
|
+
$ ruby me_token.rb
|
124
|
+
```
|
125
|
+
|
126
|
+
### OAuth 2.0 Demo
|
127
|
+
|
128
|
+
Execute the following and then go to the URL in your browser after launching the Sinatra app.
|
129
|
+
|
130
|
+
```bash
|
131
|
+
$ cd scripts/sinatra
|
132
|
+
$ bundle
|
133
|
+
$ cp example.env .env
|
134
|
+
$ vi .env
|
135
|
+
$ ruby app.rb
|
136
|
+
```
|
137
|
+
|
138
|
+
## Change Log
|
139
|
+
|
140
|
+
See [CHANGELOG.md](CHANGELOG.md)
|
141
|
+
|
142
|
+
## Links
|
143
|
+
|
144
|
+
Project Repo
|
145
|
+
|
146
|
+
* https://github.com/grokify/medium-sdk-ruby
|
147
|
+
|
148
|
+
Medium API Docs
|
149
|
+
|
150
|
+
* https://github.com/Medium/medium-api-docs
|
151
|
+
|
152
|
+
## Contributing
|
153
|
+
|
154
|
+
1. Fork it ( http://github.com/grokify/medium-sdk-ruby/fork )
|
155
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
156
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
157
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
158
|
+
5. Create new Pull Request
|
159
|
+
|
160
|
+
## License
|
161
|
+
|
162
|
+
Medium SDK for Ruby is available under an MIT-style license. See [LICENSE.txt](LICENSE.txt) for details.
|
163
|
+
|
164
|
+
Medium SDK for Ruby © 2016 by [John Wang](https://github.com/grokify)
|
165
|
+
|
166
|
+
[gem-version-svg]: https://badge.fury.io/rb/medium_sdk.svg
|
167
|
+
[gem-version-link]: http://badge.fury.io/rb/medium_sdk
|
168
|
+
[downloads-svg]: http://ruby-gem-downloads-badge.herokuapp.com/medium_sdk
|
169
|
+
[downloads-link]: https://rubygems.org/gems/medium_sdk
|
170
|
+
[build-status-svg]: https://api.travis-ci.org/grokify/medium-sdk-ruby.svg?branch=master
|
171
|
+
[build-status-link]: https://travis-ci.org/grokify/medium-sdk-ruby
|
172
|
+
[coverage-status-svg]: https://coveralls.io/repos/grokify/medium-sdk-ruby/badge.svg?branch=master
|
173
|
+
[coverage-status-link]: https://coveralls.io/r/grokify/medium-sdk-ruby?branch=master
|
174
|
+
[dependency-status-svg]: https://gemnasium.com/grokify/medium-sdk-ruby.svg
|
175
|
+
[dependency-status-link]: https://gemnasium.com/grokify/medium-sdk-ruby
|
176
|
+
[codeclimate-status-svg]: https://codeclimate.com/github/grokify/medium-sdk-ruby/badges/gpa.svg
|
177
|
+
[codeclimate-status-link]: https://codeclimate.com/github/grokify/medium-sdk-ruby
|
178
|
+
[scrutinizer-status-svg]: https://scrutinizer-ci.com/g/grokify/medium-sdk-ruby/badges/quality-score.png?b=master
|
179
|
+
[scrutinizer-status-link]: https://scrutinizer-ci.com/g/grokify/medium-sdk-ruby/?branch=master
|
180
|
+
[docs-rubydoc-svg]: https://img.shields.io/badge/docs-rubydoc-blue.svg
|
181
|
+
[docs-rubydoc-link]: http://www.rubydoc.info/gems/medium_sdk/
|
182
|
+
[license-svg]: https://img.shields.io/badge/license-MIT-blue.svg
|
183
|
+
[license-link]: https://github.com/grokify/medium-sdk-ruby/blob/master/LICENSE.txt
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
desc 'Default: run unit tests.'
|
5
|
+
task default: :test
|
6
|
+
|
7
|
+
desc 'Test the library.'
|
8
|
+
Rake::TestTask.new do |t|
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.pattern = 'test/**/test_*.rb'
|
11
|
+
t.verbose = false
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Generate YARD documentation.'
|
15
|
+
task :gendoc do
|
16
|
+
# puts 'yard doc generation disabled until JRuby build native extensions for redcarpet or yard removes the dependency.'
|
17
|
+
system 'yardoc'
|
18
|
+
system 'yard stats --list-undoc'
|
19
|
+
end
|
data/lib/medium_sdk.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module MediumSdk
|
2
|
+
class Client
|
3
|
+
attr_accessor :connection
|
4
|
+
|
5
|
+
attr_reader :me
|
6
|
+
|
7
|
+
def initialize(opts = {})
|
8
|
+
if opts.key? :integration_token
|
9
|
+
@connection = MediumSdk::Connection::IntegrationToken.new opts
|
10
|
+
elsif opts.key? :client_id
|
11
|
+
@connection = MediumSdk::Connection::AuthCode.new opts
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_url(url)
|
16
|
+
return @connection.http.get do |req|
|
17
|
+
req.url url
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def body_key(res, key)
|
22
|
+
return res.body.key?(key) ? res.body[key] : nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def me()
|
26
|
+
@me = body_key get_url('me'), 'data'
|
27
|
+
return @me
|
28
|
+
end
|
29
|
+
|
30
|
+
def user_publications(user_id)
|
31
|
+
res = get_url File.join 'users', user_id, 'publications'
|
32
|
+
return body_key(res, 'data')
|
33
|
+
end
|
34
|
+
|
35
|
+
def post(post)
|
36
|
+
url = ''
|
37
|
+
if post.key? :publicationId
|
38
|
+
publication_id = post[:publicationId].clone
|
39
|
+
post.delete :publicationId
|
40
|
+
url = File.join 'publications', publication_id, 'posts'
|
41
|
+
else
|
42
|
+
me unless @me
|
43
|
+
unless @me.is_a?(Hash) && @me.key?('id') && @me['id'].to_s.length>0
|
44
|
+
raise 'Authorized User Id is unknown'
|
45
|
+
end
|
46
|
+
id = @me['id']
|
47
|
+
url = File.join 'users', id, 'posts'
|
48
|
+
end
|
49
|
+
res = @connection.http.post do |req|
|
50
|
+
req.url url
|
51
|
+
req.body = post
|
52
|
+
end
|
53
|
+
return body_key(res, 'data')
|
54
|
+
end
|
55
|
+
|
56
|
+
def publication_contributors(publication_id)
|
57
|
+
res = get_url File.join 'publications', publication_id, 'contributors'
|
58
|
+
return body_key(res, 'data')
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'faraday_middleware/oauth2_refresh'
|
4
|
+
require 'oauth2'
|
5
|
+
|
6
|
+
module MediumSdk::Connection
|
7
|
+
class AuthCode
|
8
|
+
OAUTH_HOST = 'https://medium.com'
|
9
|
+
OAUTH_AUTHZ_ENDPOINT = '/m/oauth/authorize'
|
10
|
+
OAUTH_TOKEN_ENDPOINT = '/m/oauth/token'
|
11
|
+
API_HOST = 'https://api.medium.com'
|
12
|
+
API_VERSION = 'v1'
|
13
|
+
|
14
|
+
attr_reader :client_id
|
15
|
+
|
16
|
+
attr_accessor :oauth2client
|
17
|
+
attr_accessor :oauth_redirect_uri
|
18
|
+
attr_accessor :http
|
19
|
+
attr_accessor :token
|
20
|
+
|
21
|
+
def initialize(opts = {})
|
22
|
+
init_attributes
|
23
|
+
@client_id = opts[:client_id] if opts.key? :client_id
|
24
|
+
@client_secret = opts[:client_secret] if opts.key? :client_secret
|
25
|
+
@oauth_redirect_uri = opts[:redirect_uri] if opts.key? :redirect_uri
|
26
|
+
@scope = opts[:scope] if opts.key? :scope
|
27
|
+
@oauth2client = new_oauth2_client()
|
28
|
+
end
|
29
|
+
|
30
|
+
def init_attributes()
|
31
|
+
@token = nil
|
32
|
+
@http = nil
|
33
|
+
@instance_headers = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_token(token)
|
37
|
+
if token.is_a? Hash
|
38
|
+
token = OAuth2::AccessToken::from_hash(@oauth2client, token)
|
39
|
+
elsif token.is_a? String
|
40
|
+
if token =~ /^\s*{.+}\s*$/
|
41
|
+
token_hash = MultiJson.decode(token)
|
42
|
+
token = OAuth2::AccessToken::from_hash(@oauth2client, token_hash)
|
43
|
+
else
|
44
|
+
token = { 'access_token' => token }
|
45
|
+
token = OAuth2::AccessToken::from_hash(@oauth2client, token)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
unless token.is_a? OAuth2::AccessToken
|
50
|
+
raise "Token is not a OAuth2::AccessToken"
|
51
|
+
end
|
52
|
+
|
53
|
+
@token = token
|
54
|
+
|
55
|
+
@http = Faraday.new(url: api_version_url()) do |conn|
|
56
|
+
conn.request :oauth2_refresh, @token
|
57
|
+
conn.request :json
|
58
|
+
if @instance_headers.is_a? Hash
|
59
|
+
@instance_headers.each do |k,v|
|
60
|
+
conn.headers[k] = v
|
61
|
+
end
|
62
|
+
end
|
63
|
+
conn.response :json, content_type: /\bjson$/
|
64
|
+
conn.response :logger
|
65
|
+
conn.adapter Faraday.default_adapter
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def api_version_url()
|
70
|
+
return File.join API_HOST, API_VERSION
|
71
|
+
end
|
72
|
+
|
73
|
+
def authorize_uri(opts = {})
|
74
|
+
@oauth2client = new_oauth2_client() unless @oauth2client
|
75
|
+
opts.merge!({
|
76
|
+
'client_id' => @client_id,
|
77
|
+
'response_type' => 'code',
|
78
|
+
'scope' => @scope })
|
79
|
+
@oauth2client.auth_code.authorize_url _add_redirect_uri(opts)
|
80
|
+
end
|
81
|
+
|
82
|
+
def _add_redirect_uri(opts = {})
|
83
|
+
if !opts.key?(:redirect_uri) && @oauth_redirect_uri.to_s.length > 0
|
84
|
+
opts[:redirect_uri] = @oauth_redirect_uri.to_s
|
85
|
+
end
|
86
|
+
return opts
|
87
|
+
end
|
88
|
+
|
89
|
+
def authorize_code(code, opts = {})
|
90
|
+
#token = @oauth2client.auth_code.get_token(code, _add_redirect_uri(opts))
|
91
|
+
|
92
|
+
conn = Faraday.new(:url => API_HOST) do |faraday|
|
93
|
+
faraday.request :url_encoded # form-encode POST params
|
94
|
+
faraday.response :json, content_type: /\bjson$/
|
95
|
+
faraday.response :logger # log requests to STDOUT
|
96
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
97
|
+
end
|
98
|
+
params = {
|
99
|
+
code: code,
|
100
|
+
client_id: @client_id,
|
101
|
+
client_secret: @client_secret,
|
102
|
+
redirect_uri: @oauth_redirect_uri,
|
103
|
+
grant_type: 'authorization_code'
|
104
|
+
}
|
105
|
+
res = conn.post '/v1/tokens', params
|
106
|
+
set_token res.body
|
107
|
+
return @token
|
108
|
+
end
|
109
|
+
|
110
|
+
def new_oauth2_client()
|
111
|
+
return OAuth2::Client.new(@client_id, @client_secret,
|
112
|
+
site: OAUTH_HOST,
|
113
|
+
authorize_url: OAUTH_AUTHZ_ENDPOINT,
|
114
|
+
token_url: OAUTH_TOKEN_ENDPOINT)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
module MediumSdk::Connection
|
5
|
+
class IntegrationToken
|
6
|
+
attr_accessor :http
|
7
|
+
attr_accessor :token
|
8
|
+
|
9
|
+
def initialize(opts = {})
|
10
|
+
@endpoint = 'https://api.medium.com/v1/'
|
11
|
+
@token = opts[:integration_token] if opts.key? :integration_token
|
12
|
+
set_client
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_client()
|
16
|
+
headers = {
|
17
|
+
'Host' => 'api.medium.com',
|
18
|
+
'Authorization' => 'Bearer ' + @token,
|
19
|
+
'Content-Type' => 'application/json',
|
20
|
+
'Accept' => 'application/json',
|
21
|
+
'Accept-Charset' => 'utf-8'
|
22
|
+
}
|
23
|
+
@http = Faraday.new(url: @endpoint, headers: headers) do |conn|
|
24
|
+
conn.request :json
|
25
|
+
conn.response :json, content_type: 'application/json'
|
26
|
+
conn.adapter Faraday.default_adapter
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/test/test_base.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require './test/test_base.rb'
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'oauth2'
|
5
|
+
|
6
|
+
class MediumSdkSetupTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@token = 'deadbeef'
|
9
|
+
@sdk = MediumSdk.new integration_token: @token
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_main
|
13
|
+
assert_equal 'deadbeef', @sdk.connection.token
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: medium_sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Wang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.9'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.9'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.9'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: faraday_middleware
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: faraday_middleware-oauth2_refresh
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
type: :runtime
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: multi_json
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.3'
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.3'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: oauth2
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.0'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.0.0
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.0'
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.0.0
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: coveralls
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: mocha
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: rake
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: simplecov
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - "~>"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: test-unit
|
159
|
+
requirement: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
type: :development
|
165
|
+
prerelease: false
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
description: A Ruby SDK for the Medium.com API with OAuth 2 support
|
172
|
+
email: johncwang@gmail.com
|
173
|
+
executables: []
|
174
|
+
extensions: []
|
175
|
+
extra_rdoc_files: []
|
176
|
+
files:
|
177
|
+
- CHANGELOG.md
|
178
|
+
- Gemfile
|
179
|
+
- Gemfile.lock
|
180
|
+
- LICENSE.txt
|
181
|
+
- README.md
|
182
|
+
- Rakefile
|
183
|
+
- lib/medium_sdk.rb
|
184
|
+
- lib/medium_sdk/client.rb
|
185
|
+
- lib/medium_sdk/connection.rb
|
186
|
+
- lib/medium_sdk/connection/auth_code.rb
|
187
|
+
- lib/medium_sdk/connection/integration_token.rb
|
188
|
+
- test/test_base.rb
|
189
|
+
- test/test_setup_token.rb
|
190
|
+
homepage: https://github.com/grokify/
|
191
|
+
licenses:
|
192
|
+
- MIT
|
193
|
+
metadata: {}
|
194
|
+
post_install_message:
|
195
|
+
rdoc_options: []
|
196
|
+
require_paths:
|
197
|
+
- lib
|
198
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
requirements: []
|
209
|
+
rubyforge_project:
|
210
|
+
rubygems_version: 2.5.1
|
211
|
+
signing_key:
|
212
|
+
specification_version: 4
|
213
|
+
summary: Medium SDK - Ruby SDK for the Medium.com API
|
214
|
+
test_files: []
|