PageRenderTime 24ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/webapp/plugins/twitter/model/class.CrawlerTwitterAPIAccessorOAuth.php

https://github.com/suth/ThinkUp
PHP | 154 lines | 86 code | 6 blank | 62 comment | 21 complexity | e1deda95e5e3fc332d9725cd8928fb5a MD5 | raw file
  1. <?php
  2. /**
  3. *
  4. * ThinkUp/webapp/plugins/twitter/model/class.CrawlerTwitterAPIAccessorOAuth.php
  5. *
  6. * Copyright (c) 2009-2013 Gina Trapani
  7. *
  8. * LICENSE:
  9. *
  10. * This file is part of ThinkUp (http://thinkup.com).
  11. *
  12. * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
  13. * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
  14. * later version.
  15. *
  16. * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  17. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18. * details.
  19. *
  20. * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
  21. * <http://www.gnu.org/licenses/>.
  22. *
  23. *
  24. * Crawler TwitterAPI Accessor, via OAuth
  25. *
  26. * @license http://www.gnu.org/licenses/gpl.html
  27. * @copyright 2009-2013 Gina Trapani
  28. * @author Gina Trapani <ginatrapani[at]gmail[dot]com>
  29. */
  30. class CrawlerTwitterAPIAccessorOAuth extends TwitterAPIAccessorOAuth {
  31. /**
  32. * @var int
  33. */
  34. var $archive_limit;
  35. /**
  36. * @var int
  37. */
  38. var $num_retries = 2;
  39. /**
  40. * Maxiumum percent of available API calls that should be used for endpoint.
  41. * @var int
  42. */
  43. var $percent_use_ceiling = 90;
  44. /**
  45. * Constructor
  46. * @param str $oauth_token
  47. * @param str $oauth_token_secret
  48. * @param str $oauth_consumer_key
  49. * @param str $oauth_consumer_secret
  50. * @param Instance $instance
  51. * @param int $archive_limit
  52. * @param int $num_twitter_errors
  53. * @return CrawlerTwitterAPIAccessorOAuth
  54. */
  55. public function __construct($oauth_token, $oauth_token_secret, $oauth_consumer_key, $oauth_consumer_secret,
  56. $archive_limit, $num_twitter_errors) {
  57. parent::__construct($oauth_token, $oauth_token_secret, $oauth_consumer_key, $oauth_consumer_secret,
  58. $num_twitter_errors);
  59. $this->archive_limit = $archive_limit;
  60. self::initializeEndpointRateLimits();
  61. }
  62. /**
  63. * Set per-endpoint rate limits and next reset time.
  64. * @return void
  65. */
  66. public function initializeEndpointRateLimits() {
  67. $endpoint = $this->endpoints['rate_limits'];
  68. $args = array();
  69. $args["resources"] = 'account,statuses,users,followers,lists,friends,favorites,friendships,application';
  70. list($http_status, $payload) = $this->apiRequest($endpoint, $args);
  71. $rate_limit_data_array = JSONDecoder::decode($payload, true);
  72. $rate_limit_data_array = $rate_limit_data_array["resources"];
  73. $limits = array();
  74. foreach ($rate_limit_data_array as $resource) {
  75. foreach ($resource as $key=>$values) {
  76. $limits[$key] = $values;
  77. }
  78. }
  79. foreach ($this->endpoints as $endpoint) {
  80. $endpoint->setRemaining($limits[$endpoint->getShortPath()]['remaining']);
  81. $endpoint->setLimit($limits[$endpoint->getShortPath()]['limit']);
  82. $endpoint->setReset($limits[$endpoint->getShortPath()]['reset']);
  83. }
  84. }
  85. /**
  86. * Make a Twitter API request.
  87. * @param TwitterAPIEndpoint $endpoint
  88. * @param arr $args URL query string parameters
  89. * @param str $id ID for use in endpoint path
  90. * @param bool $suppress_404_error Defaults to false, don't log 404 errors from deleted tweets
  91. * @return arr HTTP status code, payload
  92. */
  93. public function apiRequest(TwitterAPIEndpoint $endpoint, $args=array(), $id=null, $suppress_404_error=false) {
  94. $logger = Logger::getInstance();
  95. $attempts = 0;
  96. $continue = true;
  97. $url = $endpoint->getPathWithID($id);
  98. $is_rate_limit_check = ($endpoint->getShortPath() == "/application/rate_limit_status");
  99. if ($is_rate_limit_check || $endpoint->isAvailable($this->percent_use_ceiling)) {
  100. while ($attempts <= $this->num_retries && $continue) {
  101. $content = $this->to->OAuthRequest($url, 'GET', $args);
  102. $status = $this->to->lastStatusCode();
  103. if (!$is_rate_limit_check) {
  104. $endpoint->decrementRemaining();
  105. $logger->logInfo($endpoint->getStatus(), __METHOD__.','.__LINE__);
  106. }
  107. $status_message = "";
  108. if ($status > 200) {
  109. $status_message = "Could not retrieve $url";
  110. if (sizeof($args) > 0) {
  111. $status_message .= "?";
  112. }
  113. foreach ($args as $key=>$value) {
  114. $status_message .= $key."=".$value."&";
  115. }
  116. $translated_status_code = $this->translateErrorCode($status);
  117. $status_message .= " | API ERROR: $translated_status_code";
  118. //we expect a 404 when checking a tweet deletion, so suppress log line if defined
  119. if ($status == 404) {
  120. if ($suppress_404_error === false ) {
  121. $logger->logUserError($status_message, __METHOD__.','.__LINE__);
  122. }
  123. } else { //do log any other kind of error
  124. $logger->logUserError($status_message, __METHOD__.','.__LINE__);
  125. }
  126. $status_message = "";
  127. if ($status != 404 && $status != 403) {
  128. $attempts++;
  129. if ($this->total_errors_so_far >= $this->total_errors_to_tolerate) {
  130. $continue = false;
  131. } else {
  132. $this->total_errors_so_far = $this->total_errors_so_far + 1;
  133. $logger->logUserInfo('Total API errors so far: ' . $this->total_errors_so_far .
  134. ' | Total errors to tolerate '. $this->total_errors_to_tolerate, __METHOD__.','.__LINE__);
  135. }
  136. } else {
  137. $continue = false;
  138. }
  139. } else {
  140. $continue = false;
  141. }
  142. }
  143. return array($status, $content);
  144. } else {
  145. throw new APICallLimitExceededException("API call allocation limit reached. ".$endpoint->getStatus());
  146. }
  147. }
  148. }