lib/gowalla/client.rb in gowalla-0.1.4 vs lib/gowalla/client.rb in gowalla-0.2.0

- old
+ new

@@ -1,158 +1,217 @@ +require 'forwardable' + module Gowalla - class Client - include HTTParty - format :json - base_uri "http://api.gowalla.com" - headers({'Accept' => 'application/json', "User-Agent" => 'Ruby gem'}) + extend Forwardable - attr_reader :username + attr_reader :username, :api_key, :api_secret + def_delegators :oauth_client, :web_server, :authorize_url, :access_token_url + def initialize(options={}) - api_key = options[:api_key] || Gowalla.api_key + @api_key = options[:api_key] || Gowalla.api_key + @api_secret = options[:api_secret] || Gowalla.api_secret @username = options[:username] || Gowalla.username + @access_token = options[:access_token] password = options[:password] || Gowalla.password - self.class.basic_auth(@username, password) unless @username.nil? - self.class.headers({'X-Gowalla-API-Key' => api_key }) unless api_key.nil? + connection.basic_auth(@username, password) unless @api_secret end - def user(user_id=self.username) - mashup(self.class.get("/users/#{user_id}")) + # Retrieve information about a specific user + # + # @param [String] user_id (authenticated basic auth user) User ID (screen name) + # @return [Hashie::Mash] User info + def user(user_id=nil) + user_id ||= username + handle_response(connection.get("/users/#{user_id}")) end - - def events(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/events")).activity - end - - def friends_events - mashup(self.class.get("/visits/recent")).activity - end - - def friend_requests(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/friend_requests")).friends_needing_approval - end - - def friends(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/friends")).friends - end - - def items(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/items")).items - end - - def missing_items(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/items/missing")).items - end - - def vaulted_items(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/items/vault")).items - end - + + # Retrieve information about a specific item + # + # @param [Integer] id Item ID + # @return [Hashie::Mash] item info def item(id) - mashup(self.class.get("/items/#{id}")) + handle_response(connection.get("/items/#{id}")) end - - def pins(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/pins")) - end - + + # Retrieve a list of the stamps the user has collected + # + # @param [String] user_id (authenticated basic auth user) User ID (screen name) + # @param [Integer] limit (20) limit per page + # @return [Hashie::Mash] stamps info def stamps(user_id=self.username, limit=20) - mashup(self.class.get("/users/#{user_id}/stamps", :query => {:limit => limit})).stamps + response = connection.get do |req| + req.url "/users/#{user_id}/stamps", :limit => limit + end + handle_response(response).stamps end - + + # Retrieve a list of spots the user has visited most often + # + # @param [String] user_id (authenticated basic auth user) User ID (screen name) + # @return [Hashie::Mash] item info def top_spots(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/top_spots")).top_spots + handle_response(connection.get("/users/#{user_id}/top_spots")).top_spots end - - def visited_spots(user_id=self.username) - mashup(self.class.get("/users/#{user_id}/visited_spots")) - end - + + # Retrieve information about a specific trip + # + # @param [Integer] trip_id Trip ID + # @return [Hashie::Mash] trip info def trip(trip_id) - mashup(self.class.get("/trips/#{trip_id}")) + handle_response(connection.get("/trips/#{trip_id}")) end + # Retrieve information about a specific spot + # + # @param [Integer] spot_id Spot ID + # @return [Hashie::Mash] Spot info def spot(spot_id) - mashup(self.class.get("/spots/#{spot_id}")) + handle_response(connection.get("/spots/#{spot_id}")) end + # Retrieve a list of check-ins at a particular spot. Shows only the activity that is visible to a given user. + # + # @param [Integer] spot_id Spot ID + # @return [Hashie::Mash] Spot info def spot_events(spot_id) - mashup(self.class.get("/spots/#{spot_id}/events")).activity + handle_response(connection.get("/spots/#{spot_id}/events")).activity end + # Retrieve a list of items available at a particular spot + # + # @param [Integer] spot_id Spot ID + # @return [Hashie::Mash] Spot info def spot_items(spot_id) - mashup(self.class.get("/spots/#{spot_id}/items")).items + handle_response(connection.get("/spots/#{spot_id}/items")).items end + # Retrieve a list of spots within a specified distance of a location + # + # @option options [Float] :latitude Latitude of search location + # @option options [Float] :longitude Longitude of search location + # @option options [Integer] :radius Search radius (in meters) + # @return [Hashie::Mash] spots info def list_spots(options={}) query = format_geo_options(options) - mashup(self.class.get("/spots", :query => query)).spots + response = connection.get do |req| + req.url "/spots", query + end + handle_response(response).spots end - def featured_spots(options={}) - list_spots(options.merge(:featured => 1)) - end - - def bookmarked_spots(options={}) - list_spots(options.merge(:bookmarked => 1)) - end - + # List of trips + # + # @return [<Hashie::Mash>] trip info def trips(options={}) if user_id = options.delete(:user_id) options[:user_url] = "/users/#{user_id}" end query = format_geo_options(options) - mashup(self.class.get("/trips", :query => query)).trips + response = connection.get do |req| + req.url "/trips", query + end + handle_response(response).trips end - - def featured_trips(options={}) - trips(options.merge(:context => 'featured')) - end - - def friends_trips(options={}) - trips(options.merge(:context => 'friends')) - end - + + # Lists all spot categories + # + # @return [<Hashie::Mash>] category info def categories - mashup(self.class.get("/categories")).spot_categories + handle_response(connection.get("/categories")).spot_categories end + # Retrieve information about a specific category + # + # @param [Integer] id Category ID + # @return [Hashie::Mash] category info def category(id) - mashup(self.class.get("/categories/#{id}")) + handle_response(connection.get("/categories/#{id}")) end - def checkin(spot_id, options = {}) - query = format_geo_options(options) + # Check for missing access token + # + # @return [Boolean] whether or not to redirect to get an access token + def needs_access? + @api_secret and @access_token.to_s == '' + end + + # Raw HTTP connection, either Faraday::Connection or OAuth2::AccessToken + # + # @return [OAuth2::Client] + def connection - mashup(self.class.post("/checkins", :body => options, :query => { :spot_id => spot_id })) + if api_secret + @connection ||= OAuth2::AccessToken.new(oauth_client, @access_token) + else + headers = default_headers + headers['X-Gowalla-API-Key'] = api_key if api_key + @connection ||= Faraday::Connection.new \ + :url => "http://api.gowalla.com", + :headers => headers + end end + # Provides raw access to the OAuth2 Client + # + # @return [OAuth2::Client] + def oauth_client + if @oauth_client + @oauth_client + else + conn ||= Faraday::Connection.new \ + :url => "https://api.gowalla.com", + :headers => default_headers + + oauth= OAuth2::Client.new(api_key, api_secret, oauth_options = { + :site => 'https://api.gowalla.com', + :authorize_url => 'https://gowalla.com/api/oauth/new', + :access_token_url => 'https://gowalla.com/api/oauth/token' + }) + oauth.connection = conn + oauth + end + end + private + # @private def format_geo_options(options={}) options[:lat] = "+#{options[:lat]}" if options[:lat].to_i > 0 options[:lng] = "+#{options[:lng]}" if options[:lng].to_i > 0 if options[:sw] && options[:ne] options[:order] ||= "checkins_count desc" end options end - - def mashup(response) - case response.code + + # @private + def default_headers + headers = { + :accept => 'application/json', + :user_agent => 'Ruby gem' + } + end + + # @private + def handle_response(response) + case response.status when 200 - if response.is_a?(Hash) - Hashie::Mash.new(response) + body = response.respond_to?(:body) ? response.body : response + data = MultiJson.decode(body) + if data.is_a?(Hash) + Hashie::Mash.new(data) else - if response.first.is_a?(Hash) - response.map{|item| Hashie::Mash.new(item)} + if data.first.is_a?(Hash) + data.map{|item| Hashie::Mash.new(item)} else - response + data end end end end + end end \ No newline at end of file