Permalink
Browse files

oh hello

  • Loading branch information...
0 parents commit 4597f9ae2ef80964ee65230d4b48fd339251053a Shayne Sweeney committed Feb 2, 2011
Showing with 1,637 additions and 0 deletions.
  1. +12 −0 .gitignore
  2. +3 −0 .rspec
  3. +9 −0 .yardopts
  4. +3 −0 Gemfile
  5. +20 −0 LICENSE.md
  6. +143 −0 README.md
  7. +22 −0 Rakefile
  8. +40 −0 instagram.gemspec
  9. +37 −0 lib/faraday/raise_http_4xx.rb
  10. +29 −0 lib/faraday/raise_http_5xx.rb
  11. +26 −0 lib/instagram.rb
  12. +23 −0 lib/instagram/api.rb
  13. +16 −0 lib/instagram/client.rb
  14. +59 −0 lib/instagram/client/location.rb
  15. +62 −0 lib/instagram/client/media.rb
  16. +59 −0 lib/instagram/client/tag.rb
  17. +145 −0 lib/instagram/client/user.rb
  18. +15 −0 lib/instagram/client/utils.rb
  19. +90 −0 lib/instagram/configuration.rb
  20. +31 −0 lib/instagram/connection.rb
  21. +16 −0 lib/instagram/error.rb
  22. +28 −0 lib/instagram/oauth.rb
  23. +35 −0 lib/instagram/request.rb
  24. +3 −0 lib/instagram/version.rb
  25. +27 −0 spec/faraday/response_spec.rb
  26. +1 −0 spec/fixtures/followed_by.json
  27. +1 −0 spec/fixtures/follows.json
  28. +1 −0 spec/fixtures/location.json
  29. +1 −0 spec/fixtures/location_recent_media.json
  30. +1 −0 spec/fixtures/location_search.json
  31. +1 −0 spec/fixtures/media.json
  32. +1 −0 spec/fixtures/media_popular.json
  33. +1 −0 spec/fixtures/media_search.json
  34. +1 −0 spec/fixtures/mikeyk.json
  35. +1 −0 spec/fixtures/recent_media.json
  36. +1 −0 spec/fixtures/shayne.json
  37. +1 −0 spec/fixtures/tag.json
  38. +1 −0 spec/fixtures/tag_recent_media.json
  39. +1 −0 spec/fixtures/tag_search.json
  40. +1 −0 spec/fixtures/user_media_feed.json
  41. +1 −0 spec/fixtures/user_search.json
  42. +67 −0 spec/instagram/api_spec.rb
  43. +78 −0 spec/instagram/client/locations_spec.rb
  44. +78 −0 spec/instagram/client/media_spec.rb
  45. +78 −0 spec/instagram/client/tags_spec.rb
  46. +217 −0 spec/instagram/client/users_spec.rb
  47. +23 −0 spec/instagram/client_spec.rb
  48. +97 −0 spec/instagram_spec.rb
  49. +30 −0 spec/spec_helper.rb
@@ -0,0 +1,12 @@
+*.gem
+*.rbc
+.DS_Store
+.bundle
+.rvmrc
+.yardoc
+.rake_tasks~
+Gemfile.lock
+coverage/*
+doc/*
+log/*
+pkg/*
3 .rspec
@@ -0,0 +1,3 @@
+--color
+--format=nested
+--backtrace
@@ -0,0 +1,9 @@
+--no-private
+--protected
+--tag format:"Supported formats"
+--tag authenticated:"Requires Authentication"
+--tag rate_limited:"Rate Limited"
+--markup markdown
+-
+HISTORY.mkd
+LICENSE.mkd
@@ -0,0 +1,3 @@
+source "http://rubygems.org"
+
+gemspec
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Instagram (Burbn, Inc.)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
143 README.md
@@ -0,0 +1,143 @@
+The Instagram Ruby Gem
+====================
+A Ruby wrapper for the Instagram REST and Search APIs
+
+
+Installation
+------------
+ gem install instagram
+
+
+Follow @instagramapi on Twitter
+----------------------------
+You should [follow @instagramapi on Twitter](http://twitter.com/#!/instagramapi) for announcements,
+updates, and news about the Instagram gem.
+
+
+Join the mailing list!
+----------------------
+<https://groups.google.com/group/instagram-ruby-gem>
+
+
+Does your project or organization use this gem?
+-----------------------------------------------
+Add it to the [apps](http://github.com/Instagram/instagram-ruby-gem/wiki/apps) wiki!
+
+
+Sample Application
+------------------
+ require "sinatra"
+ require "instagram"
+
+ enable :sessions
+
+ CALLBACK_URL = "http://localhost:4567/oauth/callback"
+
+ Instagram.configure do |config|
+ config.client_id = "YOUR_CLIENT_ID"
+ config.client_secret = "YOUR_CLIENT_SECRET"
+ end
+
+ get "/" do
+ '<a href="/oauth/connect">Connect with Instagram</a>'
+ end
+
+ get "/oauth/connect" do
+ redirect Instagram.authorize_url(:redirect_uri => CALLBACK_URL)
+ end
+
+ get "/oauth/callback" do
+ session[:access_token] = Instagram.get_access_token(params[:code], :redirect_uri => CALLBACK_URL)
+ redirect "/feed"
+ end
+
+ get "/feed" do
+ client = Instagram.client(:access_token => session[:access_token])
+ user = client.user
+
+ html = "<h1>#{user.username}'s recent photos</h1>"
+ for media_item in client.user_recent_media
+ html << "<img src='#{media_item.images.thumbnail.url}'>"
+ end
+ html
+ end
+
+
+API Usage Examples
+------------------
+ require "rubygems"
+ require "instagram"
+
+ # Get a list of a user's most recent media
+ puts Instagram.user_recent_media(1234)
+
+ # Get the currently authenticated user's media feed
+ puts Instagram.user_media_feed
+
+ # Get a list of recent media at a given location, in this case, the Instagram office
+ puts Instagram.location_recent_media(514276)
+
+ # All methods require authentication (either by client ID or access token).
+ # To get your Instagram OAuth credentials, register an app at http://instagr.am/oauth/client/register/
+ Instagram.configure do |config|
+ config.client_id = YOUR_CLIENT_KEY
+ config.access_token = YOUR_ACCESS_TOKEN
+ end
+
+ # Get a list of all the users you're following
+ puts Instagram.follows
+
+ # Get a list of media close to a given latitude and longitude
+ puts Instagram.media_search("37.7808851,-122.3948632")
+
+ # Get a list of the overall most popular media items
+ puts Instagram.media_popular
+
+ # Search for users on instagram, by name or username
+ puts Instagram.user_search("shayne sweeney")
+
+
+Contributing
+------------
+In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
+
+Here are some ways *you* can contribute:
+
+* by using alpha, beta, and prerelease versions
+* by reporting bugs
+* by suggesting new features
+* by writing or editing documentation
+* by writing specifications
+* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
+* by refactoring code
+* by closing [issues](http://github.com/Instagram/instagram-ruby-gem/issues)
+* by reviewing patches
+
+
+Submitting an Issue
+-------------------
+We use the [GitHub issue tracker](http://github.com/Instagram/instagram-ruby-gem/issues) to track bugs and
+features. Before submitting a bug report or feature request, check to make sure it hasn't already
+been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
+bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any
+details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
+operating system. Ideally, a bug report should include a pull request with failing specs.
+
+
+Submitting a Pull Request
+-------------------------
+1. Fork the project.
+2. Create a topic branch.
+3. Implement your feature or bug fix.
+4. Add documentation for your feature or bug fix.
+5. Run <tt>bundle exec rake doc:yard</tt>. If your changes are not 100% documented, go back to step 4.
+6. Add specs for your feature or bug fix.
+7. Run <tt>bundle exec rake spec</tt>. If your changes are not 100% covered, go back to step 6.
+8. Commit and push your changes.
+9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
+
+
+Copyright
+---------
+Copyright (c) 2010 Instagram (Burbn, Inc).
+See [LICENSE](https://github.com/Instagram/instagram-ruby-gem/blob/master/LICENSE.md) for details.
@@ -0,0 +1,22 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec)
+
+task :default => :spec
+
+namespace :doc do
+ require 'yard'
+ YARD::Rake::YardocTask.new do |task|
+ task.files = ['HISTORY.mkd', 'LICENSE.mkd', 'lib/**/*.rb']
+ task.options = [
+ '--protected',
+ '--output-dir', 'doc/yard',
+ '--tag', 'format:Supported formats',
+ '--tag', 'authenticated:Requires Authentication',
+ '--tag', 'rate_limited:Rate Limited',
+ '--markup', 'markdown',
+ ]
+ end
+end
@@ -0,0 +1,40 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/instagram/version', __FILE__)
+
+Gem::Specification.new do |s|
+ s.add_development_dependency('bundler', '~> 1.0')
+ s.add_development_dependency('rspec', '~> 2.4')
+ s.add_development_dependency('yard', '~> 0.6')
+ s.add_development_dependency('simplecov', '~> 0.3')
+ s.add_development_dependency('webmock', '~> 1.6')
+ s.add_development_dependency('ZenTest', '~> 4.4')
+ s.add_runtime_dependency('faraday', '~> 0.5.4')
+ s.add_runtime_dependency('faraday_middleware', '~> 0.3.1')
+ s.add_runtime_dependency('multi_json', '~> 0.0.5')
+ s.add_runtime_dependency('hashie', '~> 1.0.0')
+ s.authors = ["Shayne Sweeney"]
+ s.description = %q{A Ruby wrapper for the Instagram REST and Search APIs}
+ s.post_install_message =<<eos
+********************************************************************************
+
+ Follow @instagram on Twitter for announcements, updates, and news.
+ https://twitter.com/instagram
+
+ Join the mailing list!
+ https://groups.google.com/group/instagram-ruby-gem
+
+********************************************************************************
+eos
+ s.email = ['shayne@instagr.am']
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.files = `git ls-files`.split("\n")
+ s.homepage = 'https://github.com/Instagram/instagramrb'
+ s.name = 'instagram'
+ s.platform = Gem::Platform::RUBY
+ s.require_paths = ['lib']
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
+ s.rubyforge_project = s.name
+ s.summary = %q{Ruby wrapper for the Instagram API}
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.version = Instagram::VERSION.dup
+end
@@ -0,0 +1,37 @@
+require 'faraday'
+
+# @private
+module Faraday
+ # @private
+ class Response::RaiseHttp4xx < Response::Middleware
+ def self.register_on_complete(env)
+ env[:response].on_complete do |response|
+ case response[:status].to_i
+ when 400
+ raise Instagram::BadRequest, error_message(response)
+ when 404
+ raise Instagram::NotFound, error_message(response)
+ end
+ end
+ end
+
+ def initialize(app)
+ super
+ @parser = nil
+ end
+
+ private
+
+ def self.error_message(response)
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:status]}#{error_body(response[:body])}"
+ end
+
+ def self.error_body(body)
+ if body.nil?
+ nil
+ elsif body['meta']
+ ": #{body['error_message']}"
+ end
+ end
+ end
+end
@@ -0,0 +1,29 @@
+require 'faraday'
+
+# @private
+module Faraday
+ # @private
+ class Response::RaiseHttp5xx < Response::Middleware
+ def self.register_on_complete(env)
+ env[:response].on_complete do |response|
+ case response[:status].to_i
+ when 500
+ raise Instagram::InternalServerError, error_message(response, "Something is technically wrong.")
+ when 503
+ raise Instagram::ServiceUnavailable, error_message(response, "Instagram is rate limiting your requests.")
+ end
+ end
+ end
+
+ def initialize(app)
+ super
+ @parser = nil
+ end
+
+ private
+
+ def self.error_message(response, body=nil)
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{[response[:status].to_s + ':', body].compact.join(' ')}"
+ end
+ end
+end
@@ -0,0 +1,26 @@
+require File.expand_path('../instagram/error', __FILE__)
+require File.expand_path('../instagram/configuration', __FILE__)
+require File.expand_path('../instagram/api', __FILE__)
+require File.expand_path('../instagram/client', __FILE__)
+
+module Instagram
+ extend Configuration
+
+ # Alias for Instagram::Client.new
+ #
+ # @return [Instagram::Client]
+ def self.client(options={})
+ Instagram::Client.new(options)
+ end
+
+ # Delegate to Instagram::Client
+ def self.method_missing(method, *args, &block)
+ return super unless client.respond_to?(method)
+ client.send(method, *args, &block)
+ end
+
+ # Delegate to Instagram::Client
+ def self.respond_to?(method)
+ return client.respond_to?(method) || super
+ end
+end
@@ -0,0 +1,23 @@
+require File.expand_path('../connection', __FILE__)
+require File.expand_path('../request', __FILE__)
+require File.expand_path('../oauth', __FILE__)
+
+module Instagram
+ # @private
+ class API
+ # @private
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
+
+ # Creates a new API
+ def initialize(options={})
+ options = Instagram.options.merge(options)
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
+ send("#{key}=", options[key])
+ end
+ end
+
+ include Connection
+ include Request
+ include OAuth
+ end
+end
@@ -0,0 +1,16 @@
+module Instagram
+ # Wrapper for the Instagram REST API
+ #
+ # @note All methods have been separated into modules and follow the same grouping used in {TODO:doc_URL the Instagram API Documentation}.
+ # @see TODO:doc_url
+ class Client < API
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each{|f| require f}
+
+ include Instagram::Client::Utils
+
+ include Instagram::Client::User
+ include Instagram::Client::Media
+ include Instagram::Client::Location
+ include Instagram::Client::Tag
+ end
+end
Oops, something went wrong.

0 comments on commit 4597f9a

Please sign in to comment.