]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/OStatus/lib/hubdistribqueuehandler.php
a35b8874c5c572087ca6cff9be0b4aba974a07f9
[quix0rs-gnu-social.git] / plugins / OStatus / lib / hubdistribqueuehandler.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * Send a PuSH subscription verification from our internal hub.
22  * Queue up final distribution for 
23  * @package Hub
24  * @author Brion Vibber <brion@status.net>
25  */
26 class HubDistribQueueHandler extends QueueHandler
27 {
28     function transport()
29     {
30         return 'hubdistrib';
31     }
32
33     function handle($notice)
34     {
35         assert($notice instanceof Notice);
36
37         $this->pushUser($notice);
38         foreach ($notice->getGroups() as $group) {
39             $this->pushGroup($notice, $group->group_id);
40         }
41         return true;
42     }
43     
44     function pushUser($notice)
45     {
46         // See if there's any PuSH subscriptions, including OStatus clients.
47         // @fixme handle group subscriptions as well
48         // http://identi.ca/api/statuses/user_timeline/1.atom
49         $feed = common_local_url('ApiTimelineUser',
50                                  array('id' => $notice->profile_id,
51                                        'format' => 'atom'));
52         $sub = new HubSub();
53         $sub->topic = $feed;
54         if ($sub->find()) {
55             $atom = $this->userFeedForNotice($notice);
56             $this->pushFeeds($atom, $sub);
57         } else {
58             common_log(LOG_INFO, "No PuSH subscribers for $feed");
59         }
60         return true;
61     }
62
63     function pushGroup($notice, $group_id)
64     {
65         $feed = common_local_url('ApiTimelineGroup',
66                                  array('id' => $group_id,
67                                        'format' => 'atom'));
68         $sub = new HubSub();
69         $sub->topic = $feed;
70         if ($sub->find()) {
71             common_log(LOG_INFO, "Building PuSH feed for $feed");
72             $atom = $this->groupFeedForNotice($group_id, $notice);
73             $this->pushFeeds($atom, $sub);
74         } else {
75             common_log(LOG_INFO, "No PuSH subscribers for $feed");
76         }
77     }
78
79     
80     function pushFeeds($atom, $sub)
81     {
82         common_log(LOG_INFO, "Preparing $sub->N PuSH distribution(s) for $sub->topic");
83         $qm = QueueManager::get();
84         while ($sub->fetch()) {
85             common_log(LOG_INFO, "Prepping PuSH distribution to $sub->callback for $sub->topic");
86             $data = array('sub' => clone($sub),
87                           'atom' => $atom);
88             $qm->enqueue($data, 'hubout');
89         }
90     }
91
92     /**
93      * Build a single-item version of the sending user's Atom feed.
94      * @param Notice $notice
95      * @return string
96      */
97     function userFeedForNotice($notice)
98     {
99         // @fixme this feels VERY hacky...
100         // should probably be a cleaner way to do it
101
102         ob_start();
103         $api = new ApiTimelineUserAction();
104         $api->prepare(array('id' => $notice->profile_id,
105                             'format' => 'atom',
106                             'max_id' => $notice->id,
107                             'since_id' => $notice->id - 1));
108         $api->showTimeline();
109         $feed = ob_get_clean();
110         
111         // ...and override the content-type back to something normal... eww!
112         // hope there's no other headers that got set while we weren't looking.
113         header('Content-Type: text/html; charset=utf-8');
114
115         common_log(LOG_DEBUG, $feed);
116         return $feed;
117     }
118
119     function groupFeedForNotice($group_id, $notice)
120     {
121         // @fixme this feels VERY hacky...
122         // should probably be a cleaner way to do it
123
124         ob_start();
125         $api = new ApiTimelineGroupAction();
126         $args = array('id' => $group_id,
127                       'format' => 'atom',
128                       'max_id' => $notice->id,
129                       'since_id' => $notice->id - 1);
130         $api->prepare($args);
131         $api->handle($args);
132         $feed = ob_get_clean();
133         
134         // ...and override the content-type back to something normal... eww!
135         // hope there's no other headers that got set while we weren't looking.
136         header('Content-Type: text/html; charset=utf-8');
137
138         common_log(LOG_DEBUG, $feed);
139         return $feed;
140     }
141
142 }
143