//*****************************************************************************
// This file is part of CheckIn4Me. Copyright � 2010 David Ivins
//
// CheckIn4Me is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// CheckIn4Me is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with CheckIn4Me. If not, see <http://www.gnu.org/licenses/>.
//*****************************************************************************
package com.davidivins.checkin4me.foursquare;
import android.content.SharedPreferences;
import android.util.Log;
import com.davidivins.checkin4me.comparators.LocaleDistanceComparator;
import com.davidivins.checkin4me.core.Locale;
import com.davidivins.checkin4me.interfaces.APIInterface;
import com.davidivins.checkin4me.oauth.OAuth2Request;
import com.davidivins.checkin4me.oauth.OAuthResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.*;
/**
* FoursquareAPI
*
* @author david ivins
*/
public class FoursquareAPI implements APIInterface
{
private static final String TAG = FoursquareAPI.class.getSimpleName();
private int service_id;
private Properties config;
private List<Locale> latest_locations;
private boolean latest_checkin_status;
/**
* FoursquareAPI
*
* @param config
* @param service_id
*/
public FoursquareAPI(Properties config, int service_id)
{
this.config = config;
this.service_id = service_id;
latest_locations = new ArrayList<Locale>();
latest_checkin_status = false;
}
/**
* getLocationsThread
*
* @param query
* @param longitude
* @param latitude
* @param persistent_storage
* @return LocationThread
*/
public Runnable getLocationsThread(String query, String longitude, String latitude, SharedPreferences persistent_storage)
{
return new LocationsThread(query, longitude, latitude, persistent_storage);
}
/**
* getLatestLocations
*
* @return List<Locale>
*/
public List<Locale> getLatestLocations()
{
Collections.sort(latest_locations, new LocaleDistanceComparator());
return latest_locations;
}
/**
* getCheckInThread
*
* @param location
* @param persistent_storage
* @return CheckInThread
*/
public Runnable getCheckInThread(Locale location, String message, SharedPreferences persistent_storage)
{
latest_checkin_status = false;
return new CheckInThread(location, message, persistent_storage);
}
/**
* getLatestCheckInStatus
*
* @return boolean
*/
public boolean getLatestCheckInStatus()
{
return latest_checkin_status;
}
/**
* LocationsThread
*
* @author david
*/
class LocationsThread implements Runnable
{
private String query;
private String longitude;
private String latitude;
private SharedPreferences persistent_storage;
/**
* LocationsThread
*
* @param query
* @param longitude
* @param latitude
*/
LocationsThread(String query, String longitude, String latitude, SharedPreferences persistent_storage)
{
this.query = query;
this.longitude = longitude;
this.latitude = latitude;
this.persistent_storage = persistent_storage;
}
/**
* run
*/
public void run()
{
Log.i(TAG, "Retrieving Foursquare Locations");
// build new oauth request
OAuth2Request request = new OAuth2Request(
config.getProperty("api_http_method"), config.getProperty("api_host"),
config.getProperty("api_version") + config.getProperty("api_locations_endpoint"));
// set request headers
request.addHeader("User-Agent", "CheckIn4Me:2.0"); // TODO: set this from meta-data
// set query parameters
if (query != null)
{
request.addQueryParameterAndEncode("query", query);
request.addQueryParameter("limit", "10");
}
else
request.addQueryParameter("limit", "50");
request.addQueryParameter("ll", latitude + "," + longitude);
request.addQueryParameter("intent", "checkin");
request.addQueryParameter("oauth_token",
persistent_storage.getString("foursquare_oauth_token_secret", "FOURSQUARE_ACCESS_TOKEN_HERE"));
// execute http request
OAuthResponse response = (OAuthResponse)request.execute();
// save locations
if (response.getSuccessStatus())
setLocationsFromJson(response.getResponseString(), query);
}
/**
* setLocationsFromJson
*
* @param json_string
* @param query
*/
synchronized private void setLocationsFromJson(String json_string, String query)
{
Log.i(TAG, "json_string = " + json_string);
if (null != query) Log.i(TAG, "query = " + query);
// clear locations list
latest_locations.clear();
// get user's current location as doubles
double user_longitude = Double.valueOf(persistent_storage.getString("current_longitude", "0.0"));
double user_latitude = Double.valueOf(persistent_storage.getString("current_latitude", "0.0"));
// default to nearby places
String type = "nearby";
// if a query exists, look for the "places" group instead of "nearby"
if (query != null)
type = "places";
try
{
// get the json response string as a json object
JSONObject full_response = new JSONObject(json_string);
JSONObject response = full_response.getJSONObject("response");
JSONArray groups = response.getJSONArray("groups");
// loop through groups and find the group that is either the query results or the nearby places
for (int i = 0; i < groups.length(); i++)
{
JSONObject current_object = groups.getJSONObject(i);
// check the type of the current group
if (current_object.getString("type").equals(type))
{
// get this group's venues
JSONArray venues = current_object.getJSONArray("items");
// store each venue as a new locale
for (int j = 0; j < venues.length(); j++)
{
// get venue information
JSONObject venue = venues.getJSONObject(j);
String venue_id = venue.getString("id");
String name = venue.getString("name");
String description = "";
// get venue location information
JSONObject venue_location = venue.getJSONObject("location");
String latitude = venue_location.getString("lat");
String longitude = venue_location.getString("lng");
String address = (venue_location.has("address")) ? venue_location.getString("address") : "";
//String cross_street = (venue_location.has("crossStreet")) ? venue_location.getString("crossStreet") : "";
String city = (venue_location.has("city")) ? venue_location.getString("city") : "";
String state = (venue_location.has("state")) ? venue_location.getString("state") : "";
String zip = (venue_location.has("postalCode")) ? venue_location.getString("postalCode") : "";
//String distance = (venue_location.has("distance")) ? venue_location.getString("distance") : "";
//String country = (venue_location.has("country")) ? venue_location.getString("country") : "";
// create a new locale object with the venue's data
Locale location = new Locale(name, description, longitude, latitude,
address, city, state, zip);
location.calculateAndSetDistanceFromUser(user_longitude, user_latitude);
location.mapServiceIdToLocationId(service_id, venue_id);
// add the new locale to the latest locations list
latest_locations.add(location);
}
break;
}
}
}
catch (JSONException e)
{
Log.e(TAG, "JSON Exception: " + e.getMessage());
Log.e(TAG, "Could not parse json response: " + json_string);
}
}
}
/**
* CheckInThread
*
* @author david
*/
class CheckInThread implements Runnable
{
private Locale location;
private String message;
private SharedPreferences persistent_storage;
/**
* CheckInThread
*
* @param location
* @param persistent_storage
*/
CheckInThread(Locale location, String message, SharedPreferences persistent_storage)
{
this.location = location;
this.message = message;
this.persistent_storage = persistent_storage;
}
/**
* run
*/
public void run()
{
Log.i(TAG, "Checking in on Foursquare");
// build new oauth request
OAuth2Request request = new OAuth2Request(
config.getProperty("api_checkin_http_method"), config.getProperty("api_host"),
config.getProperty("api_version") + config.getProperty("api_checkin_endpoint"));
// set request headers
request.addHeader("User-Agent", "CheckIn4Me:1.0"); // TODO: get this from meta-data
// set query parameters
request.addQueryParameter("oauth_token",
persistent_storage.getString("foursquare_oauth_token_secret", "FOURSQUARE_ACCESS_TOKEN_HERE"));
Map<Integer, String> service_id_location_id_xref = location.getServiceIdToLocationIdMap();
String vid = service_id_location_id_xref.get(service_id);
request.addQueryParameter("venueId", vid);
request.addQueryParameter("ll", persistent_storage.getString("current_latitude", "CURRENT_LATITUDE_HERE") + "," +
persistent_storage.getString("current_longitude", "CURRENT_LONGITUDE_HERE"));
// initialize broadcast to public
String broadcast = "public";
// if post to facebook is enabled, post it
if (persistent_storage.getBoolean("foursquare_post_to_facebook_default", false))
broadcast += ",facebook";
// if post to twitter is enabled, add it to broadcast
if (persistent_storage.getBoolean("foursquare_post_to_twitter_default", false))
broadcast += ",twitter";
// add broadcast preferences to request
request.addQueryParameterAndEncode("broadcast", broadcast);
if (!message.equals(""))
request.addQueryParameterAndEncode("shout", message);
// execute http request
OAuthResponse response = (OAuthResponse)request.execute();
// save locations
if (response.getSuccessStatus())
setLocationsFromJson(response.getResponseString());
}
/**
* setLocationsFromJson
*
* @param json_string
*/
synchronized private void setLocationsFromJson(String json_string)
{
Log.i(TAG, "json_string = " + json_string);
latest_checkin_status = false;
try
{
// get the json response string as a json object
JSONObject full_response = new JSONObject(json_string);
JSONObject response = full_response.getJSONObject("response");
JSONObject checkin_info = response.getJSONObject("checkin");
// get checkin status from fields returned in json response
latest_checkin_status = checkin_info.has("id") && checkin_info.has("createdAt");
}
catch (JSONException e)
{
Log.i(TAG, "JSON Exception: " + e.getMessage());
Log.i(TAG, "Could not parse json response: " + json_string);
}
}
}
}