<commit_before><?php

/**
 * FireEagle OAuth+API PHP bindings
 *
 * Copyright (C) 2007-08 Yahoo! Inc
 *
 * See http://fireeagle.yahoo.net/developer/documentation/walkthru_php
 * for usage instructions.
 *
 */

/*

NOTES:

- You'll probably need PHP 5.2.3+.  If you find you don't have the
  hash_hmac() function, see here for a pure PHP version:

    http://laughingmeme.org/code/hmacsha1.php.txt

- To get HTTPS working on Windows, download curl-ca-bundle.crt from
  here:

    http://curl.haxx.se/latest.cgi?curl=win32-ssl

  Then add this line after the curl_init() call in the
  Fireeagle::http() function, replacing c:/web with the path of the
  folder containing curl-ca-bundle.crt:

    curl_setopt($ch, CURLOPT_CAINFO, 'c:/web/curl-ca-bundle.crt');

*/

// Requires OAuth.php from http://oauth.googlecode.com/svn/code/php/OAuth.php
require_once(dirname(__FILE__)."/OAuth.php");

// Various things that can go wrong
class FireEagleException extends Exception {
  const TOKEN_REQUIRED = 1; // call missing an oauth request/access token
  const LOCATION_REQUIRED = 2; // call to update() without a location
  const REMOTE_ERROR = 3; // FE sent an error
  const REQUEST_FAILED = 4; // empty or malformed response from FE
  const CONNECT_FAILED = 5; // totally failed to make an HTTP request

  public $response; // for REMOTE_ERROR codes, this is the response from FireEagle (useful: $response->code and $response->message)

  // Values of $this->response->code:
  const UPDATE_NOT_PERMITTED = 1;

  function __construct($msg, $code, $response=null) {
    parent::__construct($msg, $code);
    $this->response = $response;
  }
}

/**
 * FireEagle API access helper class.
 */
class FireEagle {

  public static $FE_ROOT = "http://fireeagle.yahoo.net";
  public static $FE_API_ROOT = "https://fireeagle.yahooapis.com";

  public static $FE_DEBUG = false; // set to true to print out debugging info
  public static $FE_DUMP_REQUESTS = false; // set to a pathname to dump out http requests to a log

  // OAuth URLs
  function requestTokenURL() { return self::$FE_API_ROOT.'/oauth/request_token'; }
  function authorizeURL() { return self::$FE_ROOT.'/oauth/authorize'; }
  function accessTokenURL() { return self::$FE_API_ROOT.'/oauth/access_token'; }
  // API URLs
  function methodURL($method) { return self::$FE_API_ROOT.'/api/0.1/'.$method.'.json'; }

  function __construct($consumerKey,
		       $consumerSecret, 
		       $oAuthToken = null, 
		       $oAuthTokenSecret = null)  {
    $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
    $this->consumer = new OAuthConsumer($consumerKey, $consumerSecret, NULL);
    if (!empty($oAuthToken) && !empty($oAuthTokenSecret)) {
      $this->token = new OAuthConsumer($oAuthToken, $oAuthTokenSecret);
    } else {
      $this->token = NULL;
    }
  }

  /**
   * Get a request token for authenticating your application with FE.
   *
   * @returns a key/value pair array containing: oauth_token and
   * oauth_token_secret.
   */
  public function getRequestToken() {
    $r = $this->oAuthRequest($this->requestTokenURL());
    $token = $this->oAuthParseResponse($r);
    if (self::$FE_DUMP_REQUESTS) self::dump("Now the user is redirected to ".$this->getAuthorizeURL($token['oauth_token'])."\nOnce the user returns, via the callback URL for web authentication or manually for desktop authentication, we can get their access token and secret by calling /oauth/access_token.\n\n");
    return $token;
  }

  /**
   * Get the URL to redirect to to authorize the user and validate a
   * request token.
   *
   * @returns a string containing the URL  to redirect to.
   */
  public function getAuthorizeURL($token) {
    return $this->authorizeURL() . '?oauth_token=' . $token;
  }
  
  /**
   * Exchange the request token and secret for an access token and
   * secret, to sign API calls.
   *
   *
   * @returns array("oauth_token" => the access token,
   *                "oauth_token_secret" => the access secret)
   */
  public function getAccessToken() {
    $this->requireToken();
    $r = $this->oAuthRequest($this->accessTokenURL());
    return $this->oAuthParseResponse($r);
  }

  /**
   * Generic method call function.  You can use this to get the raw
   * output from an API method, or to call future API methods.
   *
   * e.g.
   *   Get a user's location: $fe->call("user")
   *     or $fe->user()
   *   Set a user's location: $fe->call("update", array("q" => "new york, new york"))
   *     or $fe->update(array("q" => "new york, new york"))
   */

  public function call($method, $params=array()) {
    $this->requireToken();
    $r = $this->oAuthRequest($this->methodURL($method), $params);
    return $this->parseJSON($r);
  }

  // --- Wrappers for individual methods ---
  
  /**
   * Wrapper for 'user' API method, which fetches the current location
   * for a user.
   */
  public function user() {
    $r = $this->call("user");
    // add latitudes and longitudes, and extract best guess
    if (isset($r->user->location_hierarchy)) {
      $r->user->best_guess = NULL;
      foreach ($r->user->location_hierarchy as &$loc) {
	$c = $loc->geometry->coordinates;
	switch ($loc->geometry->type) {
	case 'Box': // DEPRECATED
	  $loc->bbox = $c;
	  $loc->latitude = ($c[0][0] + $c[1][0]) / 2;
	  $loc->longitude = ($c[0][1] + $c[1][1]) / 2;
	  $loc->geotype = 'box';
	  break;
	case 'Polygon':
	  $loc->bbox = $bbox = $loc->geometry->bbox;
	  $loc->latitude = ($bbox[0][0] + $bbox[1][0]) / 2;
	  $loc->longitude = ($bbox[0][1] + $bbox[1][1]) / 2;
	  $loc->geotype = 'box';
	  break;
	case 'Point':
	  list($loc->longitude, $loc->latitude) = $c;
	  $loc->geotype = 'point';
	  break;
	}
	if ($loc->best_guess) $r->user->best_guess = $loc; // add shortcut to get 'best guess' loc
	unset($loc);
      }
    }
    
    return $r;
  }

  /**
   * Wrapper for 'update' API method, to set a user's location.
   */
  public function update($args=array()) {
    if (empty($args)) throw new FireEagleException("FireEagle::update() needs a location", FireEagleException::LOCATION_REQUIRED);
    return $this->call("update", $args);
  }<commit_msg>fixed centroid latitude/longitude calculation for Box/Polygon type locations<commit_after><?php

/**
 * FireEagle OAuth+API PHP bindings
 *
 * Copyright (C) 2007-08 Yahoo! Inc
 *
 * See http://fireeagle.yahoo.net/developer/documentation/walkthru_php
 * for usage instructions.
 *
 */

/*

NOTES:

- You'll probably need PHP 5.2.3+.  If you find you don't have the
  hash_hmac() function, see here for a pure PHP version:

    http://laughingmeme.org/code/hmacsha1.php.txt

- To get HTTPS working on Windows, download curl-ca-bundle.crt from
  here:

    http://curl.haxx.se/latest.cgi?curl=win32-ssl

  Then add this line after the curl_init() call in the
  Fireeagle::http() function, replacing c:/web with the path of the
  folder containing curl-ca-bundle.crt:

    curl_setopt($ch, CURLOPT_CAINFO, 'c:/web/curl-ca-bundle.crt');

*/

// Requires OAuth.php from http://oauth.googlecode.com/svn/code/php/OAuth.php
require_once(dirname(__FILE__)."/OAuth.php");

// Various things that can go wrong
class FireEagleException extends Exception {
  const TOKEN_REQUIRED = 1; // call missing an oauth request/access token
  const LOCATION_REQUIRED = 2; // call to update() without a location
  const REMOTE_ERROR = 3; // FE sent an error
  const REQUEST_FAILED = 4; // empty or malformed response from FE
  const CONNECT_FAILED = 5; // totally failed to make an HTTP request

  public $response; // for REMOTE_ERROR codes, this is the response from FireEagle (useful: $response->code and $response->message)

  // Values of $this->response->code:
  const UPDATE_NOT_PERMITTED = 1;

  function __construct($msg, $code, $response=null) {
    parent::__construct($msg, $code);
    $this->response = $response;
  }
}

/**
 * FireEagle API access helper class.
 */
class FireEagle {

  public static $FE_ROOT = "http://fireeagle.yahoo.net";
  public static $FE_API_ROOT = "https://fireeagle.yahooapis.com";

  public static $FE_DEBUG = false; // set to true to print out debugging info
  public static $FE_DUMP_REQUESTS = false; // set to a pathname to dump out http requests to a log

  // OAuth URLs
  function requestTokenURL() { return self::$FE_API_ROOT.'/oauth/request_token'; }
  function authorizeURL() { return self::$FE_ROOT.'/oauth/authorize'; }
  function accessTokenURL() { return self::$FE_API_ROOT.'/oauth/access_token'; }
  // API URLs
  function methodURL($method) { return self::$FE_API_ROOT.'/api/0.1/'.$method.'.json'; }

  function __construct($consumerKey,
		       $consumerSecret, 
		       $oAuthToken = null, 
		       $oAuthTokenSecret = null)  {
    $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
    $this->consumer = new OAuthConsumer($consumerKey, $consumerSecret, NULL);
    if (!empty($oAuthToken) && !empty($oAuthTokenSecret)) {
      $this->token = new OAuthConsumer($oAuthToken, $oAuthTokenSecret);
    } else {
      $this->token = NULL;
    }
  }

  /**
   * Get a request token for authenticating your application with FE.
   *
   * @returns a key/value pair array containing: oauth_token and
   * oauth_token_secret.
   */
  public function getRequestToken() {
    $r = $this->oAuthRequest($this->requestTokenURL());
    $token = $this->oAuthParseResponse($r);
    if (self::$FE_DUMP_REQUESTS) self::dump("Now the user is redirected to ".$this->getAuthorizeURL($token['oauth_token'])."\nOnce the user returns, via the callback URL for web authentication or manually for desktop authentication, we can get their access token and secret by calling /oauth/access_token.\n\n");
    return $token;
  }

  /**
   * Get the URL to redirect to to authorize the user and validate a
   * request token.
   *
   * @returns a string containing the URL  to redirect to.
   */
  public function getAuthorizeURL($token) {
    return $this->authorizeURL() . '?oauth_token=' . $token;
  }
  
  /**
   * Exchange the request token and secret for an access token and
   * secret, to sign API calls.
   *
   *
   * @returns array("oauth_token" => the access token,
   *                "oauth_token_secret" => the access secret)
   */
  public function getAccessToken() {
    $this->requireToken();
    $r = $this->oAuthRequest($this->accessTokenURL());
    return $this->oAuthParseResponse($r);
  }

  /**
   * Generic method call function.  You can use this to get the raw
   * output from an API method, or to call future API methods.
   *
   * e.g.
   *   Get a user's location: $fe->call("user")
   *     or $fe->user()
   *   Set a user's location: $fe->call("update", array("q" => "new york, new york"))
   *     or $fe->update(array("q" => "new york, new york"))
   */

  public function call($method, $params=array()) {
    $this->requireToken();
    $r = $this->oAuthRequest($this->methodURL($method), $params);
    return $this->parseJSON($r);
  }

  // --- Wrappers for individual methods ---
  
  /**
   * Wrapper for 'user' API method, which fetches the current location
   * for a user.
   */
  public function user() {
    $r = $this->call("user");
    // add latitudes and longitudes, and extract best guess
    if (isset($r->user->location_hierarchy)) {
      $r->user->best_guess = NULL;
      foreach ($r->user->location_hierarchy as &$loc) {
	$c = $loc->geometry->coordinates;
	switch ($loc->geometry->type) {
	case 'Box': // DEPRECATED
	  $loc->bbox = $c;
	  $loc->longitude = ($c[0][0] + $c[1][0]) / 2;
	  $loc->latitude = ($c[0][1] + $c[1][1]) / 2;
	  $loc->geotype = 'box';
	  break;
	case 'Polygon':
	  $loc->bbox = $bbox = $loc->geometry->bbox;
	  $loc->longitude = ($bbox[0][0] + $bbox[1][0]) / 2;
	  $loc->latitude = ($bbox[0][1] + $bbox[1][1]) / 2;
	  $loc->geotype = 'box';
	  break;
	case 'Point':
	  list($loc->longitude, $loc->latitude) = $c;
	  $loc->geotype = 'point';
	  break;
	}
	if ($loc->best_guess) $r->user->best_guess = $loc; // add shortcut to get 'best guess' loc
	unset($loc);
      }
    }
    
    return $r;
  }

  /**
   * Wrapper for 'update' API method, to set a user's location.
   */
  public function update($args=array()) {
    if (empty($args)) throw new FireEagleException("FireEagle::update() needs a location", FireEagleException::LOCATION_REQUIRED);
    return $this->call("update", $args);
  }
{'fraction_non_alphanumeric': 0.14954031405093157, 'fraction_numerical': 0.006834268977300464, 'mean_word_length': 3.3342736248236955, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 119, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6391221', 'n_tokens_mistral': 4234, 'n_tokens_neox': 4053, 'n_words': 1117}