ruby_instagram 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +2 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +93 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/Rakefile +6 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/faraday/mashify.rb +36 -0
- data/lib/faraday/raise_http_exception.rb +59 -0
- data/lib/ruby_instagram.rb +30 -0
- data/lib/ruby_instagram/api.rb +31 -0
- data/lib/ruby_instagram/client.rb +13 -0
- data/lib/ruby_instagram/client/users.rb +41 -0
- data/lib/ruby_instagram/configuration.rb +79 -0
- data/lib/ruby_instagram/connection.rb +24 -0
- data/lib/ruby_instagram/error.rb +33 -0
- data/lib/ruby_instagram/oauth.rb +38 -0
- data/lib/ruby_instagram/request.rb +39 -0
- data/lib/ruby_instagram/response.rb +11 -0
- data/lib/ruby_instagram/version.rb +5 -0
- data/ruby_instagram.gemspec +41 -0
- data/sample_app.rb +50 -0
- data/wercker.yml +10 -0
- metadata +233 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fe7275167fc3269ceacc12539eb7d4974ad11db3ff007f49ab8743d8bdc1601f
|
4
|
+
data.tar.gz: b2a9c0f6e058e85fdb950d80cc3f063e0c01662c992aa5d402052309dc4b9102
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6d26a1ce7f97161971ca25768411692240904c5182ff611b92726bee8fc1b2e05baa912334b1f53ac6f9306e50efa0f61b84a9bfcca9745ff32e738e5402020a
|
7
|
+
data.tar.gz: f880bcb78b4437227d8af5e3321e1266db3d91eb55198406ee6a0a6858bf8d9869b9b5bf81f9f4ff59553ccb81978dcb5db429b692667c8d7e230cde88942cd7
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: $COVERALLS_REPO_TOKEN
|
data/.gitignore
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at federico@prebo.com.ar. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ruby_instagram (0.1.0)
|
5
|
+
faraday (~> 0.17.0)
|
6
|
+
faraday_middleware (~> 0.13)
|
7
|
+
hashie (~> 4.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.7.0)
|
13
|
+
public_suffix (>= 2.0.2, < 5.0)
|
14
|
+
coderay (1.1.2)
|
15
|
+
coveralls (0.8.23)
|
16
|
+
json (>= 1.8, < 3)
|
17
|
+
simplecov (~> 0.16.1)
|
18
|
+
term-ansicolor (~> 1.3)
|
19
|
+
thor (>= 0.19.4, < 2.0)
|
20
|
+
tins (~> 1.6)
|
21
|
+
crack (0.4.3)
|
22
|
+
safe_yaml (~> 1.0.0)
|
23
|
+
diff-lcs (1.3)
|
24
|
+
docile (1.3.2)
|
25
|
+
faraday (0.17.1)
|
26
|
+
multipart-post (>= 1.2, < 3)
|
27
|
+
faraday_middleware (0.13.1)
|
28
|
+
faraday (>= 0.7.4, < 1.0)
|
29
|
+
hashdiff (0.4.0)
|
30
|
+
hashie (4.0.0)
|
31
|
+
json (2.2.0)
|
32
|
+
method_source (0.9.2)
|
33
|
+
multipart-post (2.1.1)
|
34
|
+
mustermann (1.0.3)
|
35
|
+
pry (0.12.2)
|
36
|
+
coderay (~> 1.1.0)
|
37
|
+
method_source (~> 0.9.0)
|
38
|
+
public_suffix (4.0.1)
|
39
|
+
rack (2.0.7)
|
40
|
+
rack-protection (2.0.7)
|
41
|
+
rack
|
42
|
+
rake (10.5.0)
|
43
|
+
rspec (3.8.0)
|
44
|
+
rspec-core (~> 3.8.0)
|
45
|
+
rspec-expectations (~> 3.8.0)
|
46
|
+
rspec-mocks (~> 3.8.0)
|
47
|
+
rspec-core (3.8.0)
|
48
|
+
rspec-support (~> 3.8.0)
|
49
|
+
rspec-expectations (3.8.3)
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
51
|
+
rspec-support (~> 3.8.0)
|
52
|
+
rspec-mocks (3.8.0)
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
54
|
+
rspec-support (~> 3.8.0)
|
55
|
+
rspec-support (3.8.0)
|
56
|
+
safe_yaml (1.0.5)
|
57
|
+
simplecov (0.16.1)
|
58
|
+
docile (~> 1.1)
|
59
|
+
json (>= 1.8, < 3)
|
60
|
+
simplecov-html (~> 0.10.0)
|
61
|
+
simplecov-html (0.10.2)
|
62
|
+
sinatra (2.0.7)
|
63
|
+
mustermann (~> 1.0)
|
64
|
+
rack (~> 2.0)
|
65
|
+
rack-protection (= 2.0.7)
|
66
|
+
tilt (~> 2.0)
|
67
|
+
term-ansicolor (1.7.1)
|
68
|
+
tins (~> 1.0)
|
69
|
+
thor (0.20.3)
|
70
|
+
tilt (2.0.10)
|
71
|
+
tins (1.22.2)
|
72
|
+
vcr (5.0.0)
|
73
|
+
webmock (3.6.0)
|
74
|
+
addressable (>= 2.3.6)
|
75
|
+
crack (>= 0.3.2)
|
76
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
77
|
+
|
78
|
+
PLATFORMS
|
79
|
+
ruby
|
80
|
+
|
81
|
+
DEPENDENCIES
|
82
|
+
bundler (~> 2.0)
|
83
|
+
coveralls
|
84
|
+
pry
|
85
|
+
rake (~> 10.0)
|
86
|
+
rspec (~> 3.0)
|
87
|
+
ruby_instagram!
|
88
|
+
sinatra (~> 2.0)
|
89
|
+
vcr
|
90
|
+
webmock
|
91
|
+
|
92
|
+
BUNDLED WITH
|
93
|
+
2.0.2
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 goprebo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Fede
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
[![wercker status](https://app.wercker.com/status/18ae5df682bec0bc60b9ed3174f9f98b/s/master "wercker status")](https://app.wercker.com/project/byKey/18ae5df682bec0bc60b9ed3174f9f98b)
|
2
|
+
[![Coverage Status](https://coveralls.io/repos/github/goprebo/ruby_instagram/badge.svg?branch=master)](https://coveralls.io/github/goprebo/ruby_instagram?branch=master)
|
3
|
+
|
4
|
+
# RubyInstagram
|
5
|
+
|
6
|
+
Ruby wrapper for the Instagram APIs
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'ruby_instagram'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install ruby_instagram
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
RubyInstagram.configure do |config|
|
28
|
+
config.client_id = "YOUR_CLIENT_ID"
|
29
|
+
config.client_secret = "YOUR_CLIENT_SECRET"
|
30
|
+
redirect_uri = "YOUR_REDIRECT_URI"
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
### Authentication
|
35
|
+
|
36
|
+
get "/oauth/connect" do
|
37
|
+
redirect Instagram.authorize_url(:redirect_uri => CALLBACK_URL)
|
38
|
+
end
|
39
|
+
|
40
|
+
get "/oauth/callback" do
|
41
|
+
response = Instagram.get_access_token(params[:code], :redirect_uri => CALLBACK_URL)
|
42
|
+
session[:access_token] = response.access_token
|
43
|
+
redirect "/nav"
|
44
|
+
end
|
45
|
+
|
46
|
+
## Development
|
47
|
+
|
48
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
49
|
+
|
50
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/goprebo/ruby_instagram. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
59
|
+
|
60
|
+
## Code of Conduct
|
61
|
+
|
62
|
+
Everyone interacting in the RubyInstagram project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/goprebo/ruby_instagram/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'ruby_instagram'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
require 'pry'
|
12
|
+
Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module FaradayMiddleware
|
6
|
+
# Public: Converts parsed response bodies to a Hashie::Mash if they were of
|
7
|
+
# Hash or Array type.
|
8
|
+
class Mashify < Faraday::Response::Middleware
|
9
|
+
attr_accessor :mash_class
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :mash_class
|
13
|
+
end
|
14
|
+
|
15
|
+
dependency do
|
16
|
+
require 'hashie/mash'
|
17
|
+
self.mash_class = ::Hashie::Mash
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(app = nil, options = {})
|
21
|
+
super(app)
|
22
|
+
self.mash_class = options[:mash_class] || self.class.mash_class
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(body)
|
26
|
+
case body
|
27
|
+
when Hash
|
28
|
+
mash_class.new(body)
|
29
|
+
when Array
|
30
|
+
body.map { |item| parse(item) }
|
31
|
+
else
|
32
|
+
body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
# @private
|
6
|
+
module FaradayMiddleware
|
7
|
+
# @private
|
8
|
+
class RaiseHttpException < Faraday::Middleware
|
9
|
+
def call(env)
|
10
|
+
@app.call(env).on_complete do |response|
|
11
|
+
case response[:status].to_i
|
12
|
+
when 400
|
13
|
+
raise RubyInstagram::BadRequest, error_message_400(response)
|
14
|
+
when 404
|
15
|
+
raise RubyInstagram::NotFound, error_message_400(response)
|
16
|
+
when 429
|
17
|
+
raise RubyInstagram::TooManyRequests, error_message_400(response)
|
18
|
+
when 500
|
19
|
+
raise RubyInstagram::InternalServerError, error_message_500(response, 'Something is technically wrong.')
|
20
|
+
when 502
|
21
|
+
raise RubyInstagram::BadGateway, error_message_500(response, 'The server returned an invalid or incomplete response.')
|
22
|
+
when 503
|
23
|
+
raise RubyInstagram::ServiceUnavailable, error_message_500(response, 'Instagram is rate limiting your requests.')
|
24
|
+
when 504
|
25
|
+
raise RubyInstagram::GatewayTimeout, error_message_500(response, '504 Gateway Time-out')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(app)
|
31
|
+
super app
|
32
|
+
@parser = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def content_type(response)
|
38
|
+
response[:response_headers][:content_type]
|
39
|
+
end
|
40
|
+
|
41
|
+
def text_response?(response)
|
42
|
+
content_type(response) == 'text/html; charset=utf-8'
|
43
|
+
end
|
44
|
+
|
45
|
+
def error_message_400(response)
|
46
|
+
"#{response[:method].to_s.upcase} #{response[:url]}: #{response[:status]} #{error_body(response)}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_message_500(response, body = nil)
|
50
|
+
"#{response[:method].to_s.upcase} #{response[:url]}: #{[response[:status].to_s + ':', body].compact.join(' ')}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def error_body(response)
|
54
|
+
return response[:body] if text_response?(response)
|
55
|
+
|
56
|
+
JSON.parse(response[:body])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('ruby_instagram/error', __dir__)
|
4
|
+
require File.expand_path('ruby_instagram/configuration', __dir__)
|
5
|
+
require File.expand_path('ruby_instagram/api', __dir__)
|
6
|
+
require File.expand_path('ruby_instagram/client', __dir__)
|
7
|
+
require File.expand_path('ruby_instagram/response', __dir__)
|
8
|
+
|
9
|
+
module RubyInstagram
|
10
|
+
extend Configuration
|
11
|
+
|
12
|
+
# Alias for Instagram::Client.new
|
13
|
+
#
|
14
|
+
# @return [Instagram::Client]
|
15
|
+
def self.client(options = {})
|
16
|
+
RubyInstagram::Client.new(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Delegate to Instagram::Client
|
20
|
+
def self.method_missing(method, *args, &block)
|
21
|
+
return super unless client.respond_to?(method)
|
22
|
+
|
23
|
+
client.send(method, *args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Delegate to Instagram::Client
|
27
|
+
def self.respond_to?(method, include_all = false)
|
28
|
+
client.respond_to?(method, include_all) || super
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('connection', __dir__)
|
4
|
+
require File.expand_path('request', __dir__)
|
5
|
+
require File.expand_path('oauth', __dir__)
|
6
|
+
|
7
|
+
module RubyInstagram
|
8
|
+
class API
|
9
|
+
attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
|
10
|
+
|
11
|
+
# Creates a new API
|
12
|
+
def initialize(options = {})
|
13
|
+
options = RubyInstagram.options.merge(options)
|
14
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
15
|
+
send("#{key}=", options[key])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
{}.tap do |conf|
|
21
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
22
|
+
conf[key] = send(key)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
include Connection
|
28
|
+
include Request
|
29
|
+
include OAuth
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyInstagram
|
4
|
+
# Wrapper for the Instagram REST API
|
5
|
+
#
|
6
|
+
# @note All methods have been separated into modules and follow the same grouping used in https://developers.facebook.com/docs/instagram-basic-display-api/reference
|
7
|
+
# @see http://instagram.com/developer/
|
8
|
+
class Client < API
|
9
|
+
Dir[File.expand_path('client/*.rb', __dir__)].each { |f| require f }
|
10
|
+
|
11
|
+
include RubyInstagram::Client::Users
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyInstagram
|
4
|
+
class Client
|
5
|
+
# Defines methods related to users
|
6
|
+
module Users
|
7
|
+
# Returns extended information of a given user
|
8
|
+
#
|
9
|
+
# @overload user(id=nil, options={})
|
10
|
+
# @param user [Integer] An Instagram user ID
|
11
|
+
# @return [Hashie::Mash] The requested user.
|
12
|
+
# @example Return extended information for @shayne
|
13
|
+
# RubyInstagram.user(20)
|
14
|
+
# @authenticated true
|
15
|
+
#
|
16
|
+
# If getting this data of a protected user, you must authenticate (and be allowed to see that user).
|
17
|
+
# @see https://developers.facebook.com/docs/instagram-basic-display-api/reference/user
|
18
|
+
def user(*args)
|
19
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
+
get(args.first || 'me', options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a list of recent media items for a given user
|
25
|
+
#
|
26
|
+
# @overload user_recent_media(options={})
|
27
|
+
# @param options [Hash] A customizable set of options.
|
28
|
+
# @return [Hashie::Mash]
|
29
|
+
# @example Returns a list of user media items for the currently authenticated user
|
30
|
+
# RubyInstagram.user_media
|
31
|
+
# @see https://developers.facebook.com/docs/instagram-basic-display-api/reference/user/media
|
32
|
+
# @authenticated true
|
33
|
+
#
|
34
|
+
# For getting this data, you must authenticate (and be allowed to see that user).
|
35
|
+
def user_media(*args)
|
36
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
37
|
+
id = args.first || 'me'
|
38
|
+
get("#{id}/media", options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require File.expand_path('version', __dir__)
|
5
|
+
|
6
|
+
module RubyInstagram
|
7
|
+
# Defines constants and methods related to configuration
|
8
|
+
module Configuration
|
9
|
+
# An array of valid keys in the options hash when configuring a {RubyInstagram::API}
|
10
|
+
VALID_OPTIONS_KEYS = %i[
|
11
|
+
access_token
|
12
|
+
app_id
|
13
|
+
app_secret
|
14
|
+
scope
|
15
|
+
connection_options
|
16
|
+
redirect_uri
|
17
|
+
endpoint
|
18
|
+
user_agent
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
# By default, don't set a user access token
|
22
|
+
DEFAULT_ACCESS_TOKEN = nil
|
23
|
+
|
24
|
+
# By default, don't set an application ID
|
25
|
+
DEFAULT_APP_ID = nil
|
26
|
+
|
27
|
+
# By default, don't set an application secret
|
28
|
+
DEFAULT_APP_SECRET = nil
|
29
|
+
|
30
|
+
# By default, don't set any connection options
|
31
|
+
DEFAULT_CONNECTION_OPTIONS = {}.freeze
|
32
|
+
|
33
|
+
# The endpoint that will be used to connect if none is set
|
34
|
+
#
|
35
|
+
# @note There is no reason to use any other endpoint at this time
|
36
|
+
DEFAULT_ENDPOINT = 'https://graph.instagram.com/'
|
37
|
+
|
38
|
+
# By default, don't set an application redirect uri
|
39
|
+
DEFAULT_REDIRECT_URI = nil
|
40
|
+
|
41
|
+
# By default, don't set a user scope
|
42
|
+
DEFAULT_SCOPE = 'user_profile'
|
43
|
+
|
44
|
+
# The user agent that will be sent to the API endpoint if none is set
|
45
|
+
DEFAULT_USER_AGENT = "Instagram Ruby Gem #{RubyInstagram::VERSION}"
|
46
|
+
|
47
|
+
# @private
|
48
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
49
|
+
|
50
|
+
# When this module is extended, set all configuration options to their default values
|
51
|
+
def self.extended(base)
|
52
|
+
base.reset
|
53
|
+
end
|
54
|
+
|
55
|
+
# Convenience method to allow configuration options to be set in a block
|
56
|
+
def configure
|
57
|
+
yield self
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create a hash of options and their values
|
61
|
+
def options
|
62
|
+
VALID_OPTIONS_KEYS.inject({}) do |option, key|
|
63
|
+
option.merge!(key => send(key))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Reset all configuration options to defaults
|
68
|
+
def reset
|
69
|
+
self.access_token = DEFAULT_ACCESS_TOKEN
|
70
|
+
self.app_id = DEFAULT_APP_ID
|
71
|
+
self.app_secret = DEFAULT_APP_SECRET
|
72
|
+
self.connection_options = DEFAULT_CONNECTION_OPTIONS
|
73
|
+
self.scope = DEFAULT_SCOPE
|
74
|
+
self.redirect_uri = DEFAULT_REDIRECT_URI
|
75
|
+
self.endpoint = DEFAULT_ENDPOINT
|
76
|
+
self.user_agent = DEFAULT_USER_AGENT
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday_middleware'
|
4
|
+
Dir[File.expand_path('../faraday/*.rb', __dir__)].each { |f| require f }
|
5
|
+
|
6
|
+
module RubyInstagram
|
7
|
+
module Connection
|
8
|
+
private
|
9
|
+
|
10
|
+
def connection(raw = false)
|
11
|
+
options = { headers: { 'Accept' => 'application/json; charset=utf-8', 'User-Agent' => user_agent },
|
12
|
+
url: endpoint }.merge(connection_options)
|
13
|
+
|
14
|
+
Faraday::Connection.new(options) do |builder|
|
15
|
+
builder.use(FaradayMiddleware::OAuth2, access_token, token_type: :param) if access_token
|
16
|
+
builder.use(Faraday::Request::UrlEncoded)
|
17
|
+
builder.use FaradayMiddleware::Mashify unless raw
|
18
|
+
builder.use(Faraday::Response::ParseJson) unless raw
|
19
|
+
builder.use(FaradayMiddleware::RaiseHttpException)
|
20
|
+
builder.adapter Faraday.default_adapter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyInstagram
|
4
|
+
# Custom error class for rescuing from all Instagram errors
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
# Raised when Instagram returns the HTTP status code 400
|
8
|
+
class BadRequest < Error; end
|
9
|
+
|
10
|
+
# Raised when Instagram returns the HTTP status code 404
|
11
|
+
class NotFound < Error; end
|
12
|
+
|
13
|
+
# Raised when Instagram returns the HTTP status code 429
|
14
|
+
class TooManyRequests < Error; end
|
15
|
+
|
16
|
+
# Raised when Instagram returns the HTTP status code 500
|
17
|
+
class InternalServerError < Error; end
|
18
|
+
|
19
|
+
# Raised when Instagram returns the HTTP status code 502
|
20
|
+
class BadGateway < Error; end
|
21
|
+
|
22
|
+
# Raised when Instagram returns the HTTP status code 503
|
23
|
+
class ServiceUnavailable < Error; end
|
24
|
+
|
25
|
+
# Raised when Instagram returns the HTTP status code 504
|
26
|
+
class GatewayTimeout < Error; end
|
27
|
+
|
28
|
+
# Raised when a subscription payload hash is invalid
|
29
|
+
class InvalidSignature < Error; end
|
30
|
+
|
31
|
+
# Raised when Instagram returns the HTTP status code 429
|
32
|
+
class RateLimitExceeded < Error; end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyInstagram
|
4
|
+
module OAuth
|
5
|
+
OAUTH_ENDPOINT = 'https://api.instagram.com/'
|
6
|
+
# Return URL for OAuth authorization
|
7
|
+
def authorize_url(options = {})
|
8
|
+
send('endpoint=', OAUTH_ENDPOINT)
|
9
|
+
options[:response_type] ||= 'code'
|
10
|
+
options[:redirect_uri] ||= options[:redirect_uri]
|
11
|
+
options[:scope] ||= scope
|
12
|
+
params = authorization_params.merge(options)
|
13
|
+
connection.build_url('/oauth/authorize/', params).to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return an access token from authorization
|
17
|
+
def get_access_token(code, options = {})
|
18
|
+
send('endpoint=', OAUTH_ENDPOINT)
|
19
|
+
options[:grant_type] ||= 'authorization_code'
|
20
|
+
options[:redirect_uri] ||= redirect_uri
|
21
|
+
params = access_token_params.merge(options)
|
22
|
+
post('/oauth/access_token/', params.merge(code: code))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def authorization_params
|
28
|
+
{ app_id: app_id }
|
29
|
+
end
|
30
|
+
|
31
|
+
def access_token_params
|
32
|
+
{
|
33
|
+
app_id: app_id,
|
34
|
+
app_secret: app_secret
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
module RubyInstagram
|
7
|
+
# Defines HTTP request methods
|
8
|
+
module Request
|
9
|
+
# Perform an HTTP GET request
|
10
|
+
def get(path, options = {}, raw = false)
|
11
|
+
request(:get, path, options, raw)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Perform an HTTP POST request
|
15
|
+
def post(path, options = {}, raw = false)
|
16
|
+
request(:post, path, options, raw)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Perform an HTTP request
|
22
|
+
def request(method, path, options, raw = false)
|
23
|
+
response = connection(raw).send(method) do |request|
|
24
|
+
options = options.compact
|
25
|
+
case method
|
26
|
+
when :get
|
27
|
+
request.url(path, options)
|
28
|
+
when :post
|
29
|
+
request.url(path)
|
30
|
+
request.body = options unless options.empty?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
return response if raw
|
35
|
+
|
36
|
+
Response.create(response.body)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'ruby_instagram/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'ruby_instagram'
|
9
|
+
spec.version = RubyInstagram::VERSION
|
10
|
+
spec.authors = ['Kickser', 'Federico Farina', 'Alejo Zárate', 'Nicolás Vázquez']
|
11
|
+
spec.email = ['support@goprebo.com', 'federico@goprebo.com', 'ale@goprebo.com', 'nico@goprebo.com']
|
12
|
+
|
13
|
+
spec.summary = 'Ruby wrapper for the Instagram API'
|
14
|
+
spec.homepage = 'https://github.com/goprebo/ruby_instagram'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
30
|
+
spec.add_development_dependency 'coveralls', '~> 0.8.23'
|
31
|
+
spec.add_development_dependency 'pry', '~> 0.12'
|
32
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
34
|
+
spec.add_development_dependency 'sinatra', '~> 2.0'
|
35
|
+
spec.add_development_dependency 'vcr', '~> 5.0'
|
36
|
+
spec.add_development_dependency 'webmock', '~> 3.6'
|
37
|
+
|
38
|
+
spec.add_runtime_dependency('faraday', '~> 0.17.0')
|
39
|
+
spec.add_runtime_dependency('faraday_middleware', '~> 0.13')
|
40
|
+
spec.add_runtime_dependency('hashie', '~> 4.0')
|
41
|
+
end
|
data/sample_app.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sinatra'
|
4
|
+
require 'pry'
|
5
|
+
require File.expand_path('lib/ruby_instagram', __dir__)
|
6
|
+
|
7
|
+
enable :sessions
|
8
|
+
|
9
|
+
CALLBACK_URL = 'localhost:4567/oauth/callback'
|
10
|
+
|
11
|
+
RubyInstagram.configure do |config|
|
12
|
+
config.app_id = 2_335_514_866_760_592
|
13
|
+
config.app_secret = 'f1b89d271654aba579f3c7eccfe7f7a9'
|
14
|
+
config.access_token = 'IGQVJVUlRMY2hiRWxKbG9SLUxaNXZAhYTUtUFgyS3hLd1daTGZAOSTlDN29wTFdERG10aW82OVcwTWZAZAOE0wa3FvMFFHRkFZAUThGZA1dlTmV5ZAWktOGdTQm8wUHhnMlBfcEpmaGcyaEN4MnFNN1RMbGcwaEl1U1BhdTBSZAUw4'
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/' do
|
18
|
+
html =
|
19
|
+
"\n <h1>Ruby Instagram Gem Sample Application</h1>
|
20
|
+
<ol>
|
21
|
+
<li><a href='/oauth/authorize'>Connect with Instagram</a></li>
|
22
|
+
<li><a href='/user_media'>User Media</a> Get a list of a user's media</li>
|
23
|
+
</ol>
|
24
|
+
"
|
25
|
+
html
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/oauth/authorize' do
|
29
|
+
redirect RubyInstagram.authorize_url(redirect_uri: CALLBACK_URL)
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/oauth/callback' do
|
33
|
+
response = RubyInstagram.get_access_token(params[:code], redirect_uri: CALLBACK_URL)
|
34
|
+
session[:access_token] = response.access_token
|
35
|
+
redirect '/nav'
|
36
|
+
end
|
37
|
+
|
38
|
+
get '/user_media' do
|
39
|
+
access_token = session[:access_token] || RubyInstagram.access_token
|
40
|
+
return '<h1>Not logged user</h1>' unless access_token
|
41
|
+
|
42
|
+
client = RubyInstagram.client(access_token: access_token)
|
43
|
+
user = client.user(fields: 'media_count,username,media,account_type')
|
44
|
+
html = "<h1>#{user.username}'s media, media_count:#{user.media_count}, account_type: #{user.account_type} </h1>"
|
45
|
+
items = client.user_media(fields: 'thumbnail_url,media_type,media_url,caption,username')
|
46
|
+
items.each do |media_item|
|
47
|
+
html += "<div style='float:left;'><img height='100' width='100' src='#{media_item.media_url}'><br/></div>"
|
48
|
+
end
|
49
|
+
html
|
50
|
+
end
|
data/wercker.yml
ADDED
metadata
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_instagram
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kickser
|
8
|
+
- Federico Farina
|
9
|
+
- Alejo Zárate
|
10
|
+
- Nicolás Vázquez
|
11
|
+
autorequire:
|
12
|
+
bindir: exe
|
13
|
+
cert_chain: []
|
14
|
+
date: 2019-12-04 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: bundler
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: coveralls
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - "~>"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.8.23
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.8.23
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: pry
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - "~>"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0.12'
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0.12'
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rake
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - "~>"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '10.0'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '10.0'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: rspec
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - "~>"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '3.0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '3.0'
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: sinatra
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - "~>"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '2.0'
|
93
|
+
type: :development
|
94
|
+
prerelease: false
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '2.0'
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: vcr
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '5.0'
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '5.0'
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: webmock
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '3.6'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - "~>"
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '3.6'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: faraday
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - "~>"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 0.17.0
|
135
|
+
type: :runtime
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "~>"
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 0.17.0
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: faraday_middleware
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - "~>"
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0.13'
|
149
|
+
type: :runtime
|
150
|
+
prerelease: false
|
151
|
+
version_requirements: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - "~>"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0.13'
|
156
|
+
- !ruby/object:Gem::Dependency
|
157
|
+
name: hashie
|
158
|
+
requirement: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - "~>"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '4.0'
|
163
|
+
type: :runtime
|
164
|
+
prerelease: false
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - "~>"
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '4.0'
|
170
|
+
description:
|
171
|
+
email:
|
172
|
+
- support@goprebo.com
|
173
|
+
- federico@goprebo.com
|
174
|
+
- ale@goprebo.com
|
175
|
+
- nico@goprebo.com
|
176
|
+
executables: []
|
177
|
+
extensions: []
|
178
|
+
extra_rdoc_files: []
|
179
|
+
files:
|
180
|
+
- ".coveralls.yml"
|
181
|
+
- ".gitignore"
|
182
|
+
- CODE_OF_CONDUCT.md
|
183
|
+
- Gemfile
|
184
|
+
- Gemfile.lock
|
185
|
+
- LICENSE
|
186
|
+
- LICENSE.txt
|
187
|
+
- README.md
|
188
|
+
- Rakefile
|
189
|
+
- bin/console
|
190
|
+
- bin/setup
|
191
|
+
- lib/faraday/mashify.rb
|
192
|
+
- lib/faraday/raise_http_exception.rb
|
193
|
+
- lib/ruby_instagram.rb
|
194
|
+
- lib/ruby_instagram/api.rb
|
195
|
+
- lib/ruby_instagram/client.rb
|
196
|
+
- lib/ruby_instagram/client/users.rb
|
197
|
+
- lib/ruby_instagram/configuration.rb
|
198
|
+
- lib/ruby_instagram/connection.rb
|
199
|
+
- lib/ruby_instagram/error.rb
|
200
|
+
- lib/ruby_instagram/oauth.rb
|
201
|
+
- lib/ruby_instagram/request.rb
|
202
|
+
- lib/ruby_instagram/response.rb
|
203
|
+
- lib/ruby_instagram/version.rb
|
204
|
+
- ruby_instagram.gemspec
|
205
|
+
- sample_app.rb
|
206
|
+
- wercker.yml
|
207
|
+
homepage: https://github.com/goprebo/ruby_instagram
|
208
|
+
licenses:
|
209
|
+
- MIT
|
210
|
+
metadata:
|
211
|
+
homepage_uri: https://github.com/goprebo/ruby_instagram
|
212
|
+
source_code_uri: https://github.com/goprebo/ruby_instagram
|
213
|
+
post_install_message:
|
214
|
+
rdoc_options: []
|
215
|
+
require_paths:
|
216
|
+
- lib
|
217
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ">="
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
requirements: []
|
228
|
+
rubyforge_project:
|
229
|
+
rubygems_version: 2.7.6.2
|
230
|
+
signing_key:
|
231
|
+
specification_version: 4
|
232
|
+
summary: Ruby wrapper for the Instagram API
|
233
|
+
test_files: []
|