]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/apitimelinepublic.php
Merge commit 'refs/merge-requests/30' of https://gitorious.org/social/mainline into...
[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     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      * @param array $args $_REQUEST data (unused)
172      *
173      * @return void
174      */
175     function handle(array $args=array())
176     {
177         parent::handle($args);
178         $this->showTimeline();
179     }
180
181     /**
182      * Show the timeline of notices
183      *
184      * @return void
185      */
186     function showTimeline()
187     {
188         $sitename   = common_config('site', 'name');
189         $sitelogo   = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
190         // TRANS: Title for site timeline. %s is the StatusNet sitename.
191         $title      = sprintf(_("%s public timeline"), $sitename);
192         $taguribase = TagURI::base();
193         $id         = "tag:$taguribase:PublicTimeline";
194         $link       = common_local_url('public');
195         $self       = $this->getSelfUri();
196         // TRANS: Subtitle for site timeline. %s is the StatusNet sitename.
197         $subtitle   = sprintf(_("%s updates from everyone!"), $sitename);
198
199         switch($this->format) {
200         case 'xml':
201             $this->showXmlTimeline($this->notices);
202             break;
203         case 'rss':
204             $this->showRssTimeline(
205                 $this->notices,
206                 $title,
207                 $link,
208                 $subtitle,
209                 null,
210                 $sitelogo,
211                 $self
212             );
213             break;
214         case 'atom':
215
216             header('Content-Type: application/atom+xml; charset=utf-8');
217
218             $atom = new AtomNoticeFeed($this->auth_user);
219
220             $atom->setId($id);
221             $atom->setTitle($title);
222             $atom->setSubtitle($subtitle);
223             $atom->setLogo($sitelogo);
224             $atom->setUpdated('now');
225             $atom->addLink(common_local_url('public'));
226             $atom->setSelfLink($self);
227             $atom->addEntryFromNotices($this->notices);
228
229             $this->raw($atom->getString());
230
231             break;
232         case 'json':
233             $this->showJsonTimeline($this->notices);
234             break;
235         case 'as':
236             header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
237             $doc = new ActivityStreamJSONDocument($this->auth_user);
238             $doc->setTitle($title);
239             $doc->addLink($link, 'alternate', 'text/html');
240             $doc->addItemsFromNotices($this->notices);
241             $this->raw($doc->asString());
242             break;
243         default:
244             // TRANS: Client error displayed when coming across a non-supported API method.
245             $this->clientError(_('API method not found.'), $code = 404);
246             break;
247         }
248     }
249
250     /**
251      * Get notices
252      *
253      * @return array notices
254      */
255     function getNotices()
256     {
257         $notices = array();
258
259         $profile = ($this->auth_user) ? $this->auth_user->getProfile() : null;
260
261         $stream = new PublicNoticeStream($profile);
262
263         $notice = $stream->getNotices(($this->page - 1) * $this->count,
264                                       $this->count,
265                                       $this->since_id,
266                                       $this->max_id);
267
268         $notices = $notice->fetchAll();
269
270         NoticeList::prefill($notices);
271
272         return $notices;
273     }
274
275     /**
276      * Is this action read only?
277      *
278      * @param array $args other arguments
279      *
280      * @return boolean true
281      */
282     function isReadOnly(array $args=array())
283     {
284         return true;
285     }
286
287     /**
288      * When was this feed last modified?
289      *
290      * @return string datestamp of the latest notice in the stream
291      */
292     function lastModified()
293     {
294         if (!empty($this->notices) && (count($this->notices) > 0)) {
295             return strtotime($this->notices[0]->created);
296         }
297
298         return null;
299     }
300
301     /**
302      * An entity tag for this stream
303      *
304      * Returns an Etag based on the action name, language, and
305      * timestamps of the first and last notice in the timeline
306      *
307      * @return string etag
308      */
309     function etag()
310     {
311         if (!empty($this->notices) && (count($this->notices) > 0)) {
312
313             $last = count($this->notices) - 1;
314
315             return '"' . implode(
316                 ':',
317                 array($this->arg('action'),
318                       common_user_cache_hash($this->auth_user),
319                       common_language(),
320                       strtotime($this->notices[0]->created),
321                       strtotime($this->notices[$last]->created))
322             )
323             . '"';
324         }
325
326         return null;
327     }
328 }