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