apitimelinelist.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * Show a list's notices
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category API
  23. * @package StatusNet
  24. * @author Craig Andrews <candrews@integralblue.com>
  25. * @author Evan Prodromou <evan@status.net>
  26. * @author Jeffery To <jeffery.to@gmail.com>
  27. * @author Zach Copley <zach@status.net>
  28. * @copyright 2009 StatusNet, Inc.
  29. * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
  30. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  31. * @link http://status.net/
  32. */
  33. if (!defined('STATUSNET')) {
  34. exit(1);
  35. }
  36. require_once INSTALLDIR . '/lib/atomlistnoticefeed.php';
  37. /**
  38. * Returns the most recent notices (default 20) posted to the list specified by ID
  39. *
  40. * @category API
  41. * @package StatusNet
  42. * @author Craig Andrews <candrews@integralblue.com>
  43. * @author Evan Prodromou <evan@status.net>
  44. * @author Jeffery To <jeffery.to@gmail.com>
  45. * @author Zach Copley <zach@status.net>
  46. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  47. * @link http://status.net/
  48. */
  49. class ApiTimelineListAction extends ApiPrivateAuthAction
  50. {
  51. var $list = null;
  52. var $notices = array();
  53. var $next_cursor = 0;
  54. var $prev_cursor = 0;
  55. var $cursor = -1;
  56. /**
  57. * Take arguments for running
  58. *
  59. * @param array $args $_REQUEST args
  60. *
  61. * @return boolean success flag
  62. *
  63. */
  64. protected function prepare(array $args=array())
  65. {
  66. parent::prepare($args);
  67. $this->cursor = (int) $this->arg('cursor', -1);
  68. $this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
  69. return true;
  70. }
  71. /**
  72. * Handle the request
  73. *
  74. * Just show the notices
  75. *
  76. * @return void
  77. */
  78. protected function handle()
  79. {
  80. parent::handle();
  81. if (empty($this->list)) {
  82. // TRANS: Client error displayed trying to perform an action related to a non-existing list.
  83. $this->clientError(_('List not found.'), 404);
  84. }
  85. $this->getNotices();
  86. $this->showTimeline();
  87. }
  88. /**
  89. * Show the timeline of notices
  90. *
  91. * @return void
  92. */
  93. function showTimeline()
  94. {
  95. // We'll pull common formatting out of this for other formats
  96. $atom = new AtomListNoticeFeed($this->list, $this->auth_user);
  97. $self = $this->getSelfUri();
  98. switch($this->format) {
  99. case 'xml':
  100. $this->initDocument('xml');
  101. $this->elementStart('statuses_list',
  102. array('xmlns:statusnet' => 'http://status.net/schema/api/1/'));
  103. $this->elementStart('statuses', array('type' => 'array'));
  104. foreach ($this->notices as $n) {
  105. $twitter_status = $this->twitterStatusArray($n);
  106. $this->showTwitterXmlStatus($twitter_status);
  107. }
  108. $this->elementEnd('statuses');
  109. $this->element('next_cursor', null, $this->next_cursor);
  110. $this->element('previous_cursor', null, $this->prev_cursor);
  111. $this->elementEnd('statuses_list');
  112. $this->endDocument('xml');
  113. break;
  114. case 'rss':
  115. $this->showRssTimeline(
  116. $this->notices,
  117. $atom->title,
  118. $this->list->getUri(),
  119. $atom->subtitle,
  120. null,
  121. $atom->logo,
  122. $self
  123. );
  124. break;
  125. case 'atom':
  126. header('Content-Type: application/atom+xml; charset=utf-8');
  127. try {
  128. $atom->setId($self);
  129. $atom->setSelfLink($self);
  130. $atom->addEntryFromNotices($this->notices);
  131. $this->raw($atom->getString());
  132. } catch (Atom10FeedException $e) {
  133. // TRANS: Server error displayed whe trying to get a timeline fails.
  134. // TRANS: %s is the error message.
  135. $this->serverError(sprintf(_('Could not generate feed for list - %s'), $e->getMessage()));
  136. }
  137. break;
  138. case 'json':
  139. $this->initDocument('json');
  140. $statuses = array();
  141. foreach ($this->notices as $n) {
  142. $twitter_status = $this->twitterStatusArray($n);
  143. array_push($statuses, $twitter_status);
  144. }
  145. $statuses_list = array('statuses' => $statuses,
  146. 'next_cursor' => $this->next_cusror,
  147. 'next_cursor_str' => strval($this->next_cusror),
  148. 'previous_cursor' => $this->prev_cusror,
  149. 'previous_cursor_str' => strval($this->prev_cusror)
  150. );
  151. $this->showJsonObjects($statuses_list);
  152. $this->initDocument('json');
  153. break;
  154. default:
  155. // TRANS: Client error displayed when coming across a non-supported API method.
  156. $this->clientError(_('API method not found.'), 404);
  157. }
  158. }
  159. /**
  160. * Get notices
  161. *
  162. * @return array notices
  163. */
  164. function getNotices()
  165. {
  166. $fn = array($this->list, 'getNotices');
  167. list($this->notices, $this->next_cursor, $this->prev_cursor) =
  168. Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
  169. if (!$this->notices) {
  170. $this->notices = array();
  171. }
  172. }
  173. /**
  174. * Is this action read only?
  175. *
  176. * @param array $args other arguments
  177. *
  178. * @return boolean true
  179. */
  180. function isReadOnly($args)
  181. {
  182. return true;
  183. }
  184. /**
  185. * When was this feed last modified?
  186. *
  187. * @return string datestamp of the latest notice in the stream
  188. */
  189. function lastModified()
  190. {
  191. if (!empty($this->notices) && (count($this->notices) > 0)) {
  192. return strtotime($this->notices[0]->created);
  193. }
  194. return null;
  195. }
  196. /**
  197. * An entity tag for this stream
  198. *
  199. * Returns an Etag based on the action name, language, list ID and
  200. * timestamps of the first and last notice in the timeline
  201. *
  202. * @return string etag
  203. */
  204. function etag()
  205. {
  206. if (!empty($this->notices) && (count($this->notices) > 0)) {
  207. $last = count($this->notices) - 1;
  208. return '"' . implode(
  209. ':',
  210. array($this->arg('action'),
  211. common_language(),
  212. $this->list->id,
  213. strtotime($this->notices[0]->created),
  214. strtotime($this->notices[$last]->created))
  215. )
  216. . '"';
  217. }
  218. return null;
  219. }
  220. }