]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/apitimelinefriends.php
Merge branch 'testing' of gitorious.org:statusnet/mainline into 0.9.x
[quix0rs-gnu-social.git] / actions / apitimelinefriends.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Show the friends 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-2010 StatusNet, Inc.
32  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
33  * @link      http://status.net/
34  */
35
36 /* External API usage documentation. Please update when you change how this method works. */
37
38 /*! @page friendstimeline statuses/friends_timeline
39
40     @section Description
41     Returns the 20 most recent statuses posted by the authenticating
42     user and that user's friends. This is the equivalent of "You and
43     friends" page in the web interface.
44
45     @par URL patterns
46     @li /api/statuses/friends_timeline.:format
47     @li /api/statuses/friends_timeline/:id.:format
48
49     @par Formats (:format)
50     xml, json, rss, atom
51
52     @par ID (:id)
53     username, user id
54
55     @par HTTP Method(s)
56     GET
57
58     @par Requires Authentication
59     Sometimes (see: @ref authentication)
60
61     @param user_id (Optional) Specifies a user by ID
62     @param screen_name (Optional) Specifies a user by screename (nickname)
63     @param since_id (Optional) Returns only statuses with an ID greater
64     than (that is, more recent than) the specified ID.
65     @param max_id (Optional) Returns only statuses with an ID less than
66     (that is, older than) or equal to the specified ID.
67     @param count (Optional) Specifies the number of statuses to retrieve.
68     @param page (Optional) Specifies the page of results to retrieve.
69
70     @sa @ref authentication
71     @sa @ref apiroot
72
73     @subsection usagenotes Usage notes
74     @li The URL pattern is relative to the @ref apiroot.
75     @li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
76     to encode the latitude and longitude (see example response below <georss:point>).
77
78     @subsection exampleusage Example usage
79
80     @verbatim
81     curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
82     @endverbatim
83
84     @subsection exampleresponse Example response
85
86     @verbatim
87     <?xml version="1.0"?>
88     <statuses type="array">
89       <status>
90         <text>back from the !yul !drupal meet with Evolving Web folk, @anarcat, @webchick and others, and an interesting refresher on SQL indexing</text>
91         <truncated>false</truncated>
92         <created_at>Wed Mar 31 01:33:02 +0000 2010</created_at>
93         <in_reply_to_status_id/>
94         <source>&lt;a href="http://code.google.com/p/microblog-purple/"&gt;mbpidgin&lt;/a&gt;</source>
95         <id>26674201</id>
96         <in_reply_to_user_id/>
97         <in_reply_to_screen_name/>
98         <geo/>
99         <favorited>false</favorited>
100         <user>
101           <id>246</id>
102           <name>Mark</name>
103           <screen_name>lambic</screen_name>
104           <location>Montreal, Canada</location>
105           <description>Geek</description>
106           <profile_image_url>http://avatar.identi.ca/246-48-20080702141545.png</profile_image_url>
107           <url>http://lambic.co.uk</url>
108           <protected>false</protected>
109           <followers_count>73</followers_count>
110           <profile_background_color>#F0F2F5</profile_background_color>
111           <profile_text_color/>
112           <profile_link_color>#002E6E</profile_link_color>
113           <profile_sidebar_fill_color>#CEE1E9</profile_sidebar_fill_color>
114           <profile_sidebar_border_color/>
115           <friends_count>58</friends_count>
116           <created_at>Wed Jul 02 14:12:15 +0000 2008</created_at>
117           <favourites_count>2</favourites_count>
118           <utc_offset>-14400</utc_offset>
119           <time_zone>US/Eastern</time_zone>
120           <profile_background_image_url/>
121           <profile_background_tile>false</profile_background_tile>
122           <statuses_count>933</statuses_count>
123           <following>false</following>
124           <notifications>false</notifications>
125         </user>
126       </status>
127     </statuses>
128     @endverbatim
129 */
130
131 if (!defined('STATUSNET')) {
132     exit(1);
133 }
134
135 require_once INSTALLDIR . '/lib/apibareauth.php';
136
137 /**
138  * Returns the most recent notices (default 20) posted by the target user.
139  * This is the equivalent of 'You and friends' page accessed via Web.
140  *
141  * @category API
142  * @package  StatusNet
143  * @author   Craig Andrews <candrews@integralblue.com>
144  * @author   Evan Prodromou <evan@status.net>
145  * @author   Jeffery To <jeffery.to@gmail.com>
146  * @author   mac65 <mac65@mac65.com>
147  * @author   Mike Cochrane <mikec@mikenz.geek.nz>
148  * @author   Robin Millette <robin@millette.info>
149  * @author   Zach Copley <zach@status.net>
150  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
151  * @link     http://status.net/
152  */
153
154 class ApiTimelineFriendsAction extends ApiBareAuthAction
155 {
156     var $notices  = null;
157
158     /**
159      * Take arguments for running
160      *
161      * @param array $args $_REQUEST args
162      *
163      * @return boolean success flag
164      *
165      */
166
167     function prepare($args)
168     {
169         parent::prepare($args);
170         $this->user = $this->getTargetUser($this->arg('id'));
171
172         if (empty($this->user)) {
173             $this->clientError(_('No such user.'), 404, $this->format);
174             return;
175         }
176
177         $this->notices = $this->getNotices();
178
179         return true;
180     }
181
182     /**
183      * Handle the request
184      *
185      * Just show the notices
186      *
187      * @param array $args $_REQUEST data (unused)
188      *
189      * @return void
190      */
191
192     function handle($args)
193     {
194         parent::handle($args);
195         $this->showTimeline();
196     }
197
198     /**
199      * Show the timeline of notices
200      *
201      * @return void
202      */
203
204     function showTimeline()
205     {
206         $profile    = $this->user->getProfile();
207         $avatar     = $profile->getAvatar(AVATAR_PROFILE_SIZE);
208         $sitename   = common_config('site', 'name');
209         $title      = sprintf(_("%s and friends"), $this->user->nickname);
210         $taguribase = TagURI::base();
211         $id         = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
212
213         $subtitle = sprintf(
214             // TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
215             _('Updates from %1$s and friends on %2$s!'),
216             $this->user->nickname,
217             $sitename
218         );
219
220         $link = common_local_url(
221             'all',
222              array('nickname' => $this->user->nickname)
223         );
224
225         $self = $this->getSelfUri();
226
227         $logo = (!empty($avatar))
228             ? $avatar->displayUrl()
229             : Avatar::defaultImage(AVATAR_PROFILE_SIZE);
230
231         switch($this->format) {
232         case 'xml':
233             $this->showXmlTimeline($this->notices);
234             break;
235         case 'rss':
236
237             $this->showRssTimeline(
238                 $this->notices,
239                 $title,
240                 $link,
241                 $subtitle,
242                 null,
243                 $logo,
244                 $self
245             );
246             break;
247         case 'atom':
248
249             header('Content-Type: application/atom+xml; charset=utf-8');
250
251             $atom = new AtomNoticeFeed($this->auth_user);
252
253             $atom->setId($id);
254             $atom->setTitle($title);
255             $atom->setSubtitle($subtitle);
256             $atom->setLogo($logo);
257             $atom->setUpdated('now');
258             $atom->addLink($link);
259             $atom->setSelfLink($self);
260
261             $atom->addEntryFromNotices($this->notices);
262
263             $this->raw($atom->getString());
264
265             break;
266         case 'json':
267             $this->showJsonTimeline($this->notices);
268             break;
269         default:
270             $this->clientError(_('API method not found.'), $code = 404);
271             break;
272         }
273     }
274
275     /**
276      * Get notices
277      *
278      * @return array notices
279      */
280
281     function getNotices()
282     {
283         $notices = array();
284
285         if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
286             $notice = $this->user->ownFriendsTimeline(($this->page-1) * $this->count,
287                                                       $this->count, $this->since_id,
288                                                       $this->max_id);
289         } else {
290             $notice = $this->user->friendsTimeline(($this->page-1) * $this->count,
291                                                    $this->count, $this->since_id,
292                                                    $this->max_id);
293         }
294
295         while ($notice->fetch()) {
296             $notices[] = clone($notice);
297         }
298
299         return $notices;
300     }
301
302     /**
303      * Is this action read only?
304      *
305      * @param array $args other arguments
306      *
307      * @return boolean true
308      */
309
310     function isReadOnly($args)
311     {
312         return true;
313     }
314
315     /**
316      * When was this feed last modified?
317      *
318      * @return string datestamp of the latest notice in the stream
319      */
320
321     function lastModified()
322     {
323         if (!empty($this->notices) && (count($this->notices) > 0)) {
324             return strtotime($this->notices[0]->created);
325         }
326
327         return null;
328     }
329
330     /**
331      * An entity tag for this stream
332      *
333      * Returns an Etag based on the action name, language, user ID, and
334      * timestamps of the first and last notice in the timeline
335      *
336      * @return string etag
337      */
338
339     function etag()
340     {
341         if (!empty($this->notices) && (count($this->notices) > 0)) {
342
343             $last = count($this->notices) - 1;
344
345             return '"' . implode(
346                                  ':',
347                                  array($this->arg('action'),
348                                        common_language(),
349                                        $this->user->id,
350                                        strtotime($this->notices[0]->created),
351                                        strtotime($this->notices[$last]->created))
352                                  )
353               . '"';
354         }
355
356         return null;
357     }
358
359 }