]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/apitimelinepublic.php
Merge remote-tracking branch 'upstream/master' into social-master
[quix0rs-gnu-social.git] / actions / apitimelinepublic.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Show the public timeline
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    mac65 <mac65@mac65.com>
28  * @author    Mike Cochrane <mikec@mikenz.geek.nz>
29  * @author    Robin Millette <robin@millette.info>
30  * @author    Zach Copley <zach@status.net>
31  * @copyright 2009 StatusNet, Inc.
32  * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
33  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
34  * @link      http://status.net/
35  */
36
37 if (!defined('STATUSNET')) {
38     exit(1);
39 }
40
41 /**
42  * Returns the most recent notices (default 20) posted by everybody
43  *
44  * @category API
45  * @package  StatusNet
46  * @author   Craig Andrews <candrews@integralblue.com>
47  * @author   Evan Prodromou <evan@status.net>
48  * @author   Jeffery To <jeffery.to@gmail.com>
49  * @author   mac65 <mac65@mac65.com>
50  * @author   Mike Cochrane <mikec@mikenz.geek.nz>
51  * @author   Robin Millette <robin@millette.info>
52  * @author   Zach Copley <zach@status.net>
53  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
54  * @link     http://status.net/
55  */
56
57 /* External API usage documentation. Please update when you change how this method works. */
58
59 /*! @page publictimeline statuses/public_timeline
60
61     @section Description
62     Returns the 20 most recent notices from users throughout the system who have
63     uploaded their own avatars. Depending on configuration, it may or may not
64     not include notices from automatic posting services.
65
66     @par URL patterns
67     @li /api/statuses/public_timeline.:format
68
69     @par Formats (:format)
70     xml, json, rss, atom
71
72     @par HTTP Method(s)
73     GET
74
75     @par Requires Authentication
76     No
77
78     @param since_id (Optional) Returns only statuses with an ID greater
79     than (that is, more recent than) the specified ID.
80     @param max_id (Optional) Returns only statuses with an ID less than
81     (that is, older than) or equal to the specified ID.
82     @param count (Optional) Specifies the number of statuses to retrieve.
83     @param page (Optional) Specifies the page of results to retrieve.
84
85     @sa @ref apiroot
86
87     @subsection usagenotes Usage notes
88     @li The URL pattern is relative to the @ref apiroot.
89     @li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
90     to encode the latitude and longitude (see example response below <georss:point>).
91
92     @subsection exampleusage Example usage
93
94     @verbatim
95     curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
96     @endverbatim
97
98     @subsection exampleresponse Example response
99
100     @verbatim
101     <?xml version="1.0" encoding="UTF-8"?>
102     <statuses type="array">
103      <status>
104       <text>@skwashd oh, commbank reenabled me super quick both times. but disconcerting when you don't expect it though</text>
105       <truncated>false</truncated>
106       <created_at>Sat Apr 17 00:49:12 +0000 2010</created_at>
107       <in_reply_to_status_id>28838393</in_reply_to_status_id>
108       <source>xmpp</source>
109       <id>28838456</id>
110       <in_reply_to_user_id>39303</in_reply_to_user_id>
111       <in_reply_to_screen_name>skwashd</in_reply_to_screen_name>
112       <geo></geo>
113       <favorited>false</favorited>
114       <user>
115        <id>44517</id>
116        <name>joshua may</name>
117        <screen_name>notjosh</screen_name>
118        <location></location>
119        <description></description>
120        <profile_image_url>http://avatar.identi.ca/44517-48-20090321004106.jpeg</profile_image_url>
121        <url></url>
122        <protected>false</protected>
123        <followers_count>17</followers_count>
124        <profile_background_color></profile_background_color>
125        <profile_text_color></profile_text_color>
126        <profile_link_color></profile_link_color>
127        <profile_sidebar_fill_color></profile_sidebar_fill_color>
128        <profile_sidebar_border_color></profile_sidebar_border_color>
129        <friends_count>20</friends_count>
130        <created_at>Sat Mar 21 00:40:25 +0000 2009</created_at>
131        <favourites_count>0</favourites_count>
132        <utc_offset>0</utc_offset>
133        <time_zone>UTC</time_zone>
134        <profile_background_image_url></profile_background_image_url>
135        <profile_background_tile>false</profile_background_tile>
136        <statuses_count>100</statuses_count>
137        <following>false</following>
138        <notifications>false</notifications>
139     </user>
140     </status>
141     [....]
142     </statuses>
143 @endverbatim
144 */
145 class ApiTimelinePublicAction extends ApiPrivateAuthAction
146 {
147     var $notices = null;
148
149     /**
150      * Take arguments for running
151      *
152      * @param array $args $_REQUEST args
153      *
154      * @return boolean success flag
155      *
156      */
157     protected function prepare(array $args=array())
158     {
159         parent::prepare($args);
160
161         $this->notices = $this->getNotices();
162
163         return true;
164     }
165
166     /**
167      * Handle the request
168      *
169      * Just show the notices
170      *
171      * @return void
172      */
173     protected function handle()
174     {
175         parent::handle();
176         $this->showTimeline();
177     }
178
179     function title()
180     {
181         // TRANS: Title for site timeline. %s is the GNU social sitename.
182         return sprintf(_("%s public timeline"), common_config('site', 'name'));
183     }
184
185     /**
186      * Show the timeline of notices
187      *
188      * @return void
189      */
190     function showTimeline()
191     {
192         $nonapi_action = substr($this->action, strlen('apitimeline'));  // Just so we don't need to set this explicitly
193
194         $sitelogo   = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
195         $title      = $this->title();
196         $taguribase = TagURI::base();
197         $id         = "tag:$taguribase:" . ucfirst($nonapi_action) . 'Timeline';    // Public or Networkpublic probably
198         $link       = common_local_url($nonapi_action);
199         $self       = $this->getSelfUri();
200         // TRANS: Subtitle for site timeline. %s is the GNU social sitename.
201         $subtitle   = sprintf(_("%s updates from everyone!"), common_config('site', 'name'));
202
203         switch($this->format) {
204         case 'xml':
205             $this->showXmlTimeline($this->notices);
206             break;
207         case 'rss':
208             $this->showRssTimeline(
209                 $this->notices,
210                 $title,
211                 $link,
212                 $subtitle,
213                 null,
214                 $sitelogo,
215                 $self
216             );
217             break;
218         case 'atom':
219
220             header('Content-Type: application/atom+xml; charset=utf-8');
221
222             $atom = new AtomNoticeFeed($this->auth_user);
223
224             $atom->setId($id);
225             $atom->setTitle($title);
226             $atom->setSubtitle($subtitle);
227             $atom->setLogo($sitelogo);
228             $atom->setUpdated('now');
229             $atom->addLink(common_local_url($nonapi_action));
230             $atom->setSelfLink($self);
231             $atom->addEntryFromNotices($this->notices);
232
233             $this->raw($atom->getString());
234
235             break;
236         case 'json':
237             $this->showJsonTimeline($this->notices);
238             break;
239         case 'as':
240             header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
241             $doc = new ActivityStreamJSONDocument($this->auth_user);
242             $doc->setTitle($title);
243             $doc->addLink($link, 'alternate', 'text/html');
244             $doc->addItemsFromNotices($this->notices);
245             $this->raw($doc->asString());
246             break;
247         default:
248             // TRANS: Client error displayed when coming across a non-supported API method.
249             $this->clientError(_('API method not found.'), $code = 404);
250             break;
251         }
252     }
253
254     /**
255      * Get notices
256      *
257      * @return array notices
258      */
259     function getNotices()
260     {
261         $notices = array();
262
263         $stream = $this->getStream();
264
265         $notice = $stream->getNotices(($this->page - 1) * $this->count,
266                                       $this->count,
267                                       $this->since_id,
268                                       $this->max_id);
269
270         $notices = $notice->fetchAll();
271
272         NoticeList::prefill($notices);
273
274         return $notices;
275     }
276
277     protected function getStream()
278     {
279         return new PublicNoticeStream($this->scoped);
280     }
281
282     /**
283      * Is this action read only?
284      *
285      * @param array $args other arguments
286      *
287      * @return boolean true
288      */
289     function isReadOnly(array $args=array())
290     {
291         return true;
292     }
293
294     /**
295      * When was this feed last modified?
296      *
297      * @return string datestamp of the latest notice in the stream
298      */
299     function lastModified()
300     {
301         if (!empty($this->notices) && (count($this->notices) > 0)) {
302             return strtotime($this->notices[0]->created);
303         }
304
305         return null;
306     }
307
308     /**
309      * An entity tag for this stream
310      *
311      * Returns an Etag based on the action name, language, and
312      * timestamps of the first and last notice in the timeline
313      *
314      * @return string etag
315      */
316     function etag()
317     {
318         if (!empty($this->notices) && (count($this->notices) > 0)) {
319
320             $last = count($this->notices) - 1;
321
322             return '"' . implode(
323                 ':',
324                 array($this->arg('action'),
325                       common_user_cache_hash($this->auth_user),
326                       common_language(),
327                       strtotime($this->notices[0]->created),
328                       strtotime($this->notices[$last]->created))
329             )
330             . '"';
331         }
332
333         return null;
334     }
335 }