Add OStatus PuSH hub and Salmon links back into user and group feeds

This commit is contained in:
Zach Copley 2010-02-12 19:00:35 -08:00
parent d6f1df8b76
commit f3a82e787c
8 changed files with 193 additions and 31 deletions

View File

@ -138,7 +138,19 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
try { try {
$atom = new AtomNoticeFeed(); // If this was called using an integer ID, i.e.: using the canonical
// URL for this group's feed, then pass the Group object into the feed,
// so the OStatus plugin, and possibly other plugins, can access it.
// Feels sorta hacky. -- Z
$atom = null;
$id = $this->arg('id');
if (strval(intval($id)) === strval($id)) {
$atom = new AtomGroupNoticeFeed($this->group);
} else {
$atom = new AtomGroupNoticeFeed();
}
$atom->setId($id); $atom->setId($id);
$atom->setTitle($title); $atom->setTitle($title);

View File

@ -148,7 +148,19 @@ class ApiTimelineUserAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8'); header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed(); // If this was called using an integer ID, i.e.: using the canonical
// URL for this user's feed, then pass the User object into the feed,
// so the OStatus plugin, and possibly other plugins, can access it.
// Feels sorta hacky. -- Z
$atom = null;
$id = $this->arg('id');
if (strval(intval($id)) === strval($id)) {
$atom = new AtomUserNoticeFeed($this->user);
} else {
$atom = new AtomUserNoticeFeed();
}
$atom->setId($id); $atom->setId($id);
$atom->setTitle($title); $atom->setTitle($title);

View File

@ -1154,7 +1154,6 @@ class ApiAction extends Action
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', $this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
'xml:lang' => 'en-US', 'xml:lang' => 'en-US',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0')); 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
Event::handle('StartApiAtom', array($this));
} }
function endTwitterAtom() function endTwitterAtom()

View File

@ -175,6 +175,8 @@ class Atom10Feed extends XMLStringer
$this->element('updated', null, $this->updated); $this->element('updated', null, $this->updated);
$this->renderAuthors();
$this->renderLinks(); $this->renderLinks();
} }
@ -221,18 +223,21 @@ class Atom10Feed extends XMLStringer
function getString() function getString()
{ {
$this->validate(); if (Event::handle('StartApiAtom', array($this))) {
$this->initFeed(); $this->validate();
$this->renderAuthors(); $this->initFeed();
if (!empty($this->subject)) { if (!empty($this->subject)) {
$this->raw($this->subject); $this->raw($this->subject);
}
$this->renderEntries();
$this->endFeed();
Event::handle('EndApiAtom', array($this));
} }
$this->renderEntries();
$this->endFeed();
return $this->xw->outputMemory(); return $this->xw->outputMemory();
} }

View File

@ -0,0 +1,67 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Class for building an in-memory Atom feed for a particular group's
* timeline.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Feed
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET'))
{
exit(1);
}
/**
* Class for group notice feeds. May contains a reference to the group.
*
* @category Feed
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AtomGroupNoticeFeed extends AtomNoticeFeed
{
private $group;
/**
* Constructor
*
* @param Group $group the group for the feed (optional)
* @param boolean $indent flag to turn indenting on or off
*
* @return void
*/
function __construct($group = null, $indent = true) {
parent::__construct($indent);
$this->group = $group;
}
function getGroup()
{
return $this->group;
}
}

View File

@ -2,7 +2,7 @@
/** /**
* StatusNet, the distributed open-source microblogging tool * StatusNet, the distributed open-source microblogging tool
* *
* Class for building and Atom feed from a collection of notices * Class for building an Atom feed from a collection of notices
* *
* PHP version 5 * PHP version 5
* *
@ -101,3 +101,5 @@ class AtomNoticeFeed extends Atom10Feed
} }
} }

View File

@ -0,0 +1,66 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Class for building an in-memory Atom feed for a particular user's
* timeline.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Feed
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET'))
{
exit(1);
}
/**
* Class for user notice feeds. May contain a reference to the user.
*
* @category Feed
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AtomUserNoticeFeed extends AtomNoticeFeed
{
private $user;
/**
* Constructor
*
* @param User $user the user for the feed (optional)
* @param boolean $indent flag to turn indenting on or off
*
* @return void
*/
function __construct($user = null, $indent = true) {
parent::__construct($indent);
$this->user = $user;
}
function getUser()
{
return $this->user;
}
}

View File

@ -63,9 +63,9 @@ class OStatusPlugin extends Plugin
$m->connect('main/ostatus?nickname=:nickname', $m->connect('main/ostatus?nickname=:nickname',
array('action' => 'ostatusinit'), array('nickname' => '[A-Za-z0-9_-]+')); array('action' => 'ostatusinit'), array('nickname' => '[A-Za-z0-9_-]+'));
$m->connect('main/ostatussub', $m->connect('main/ostatussub',
array('action' => 'ostatussub')); array('action' => 'ostatussub'));
$m->connect('main/ostatussub', $m->connect('main/ostatussub',
array('action' => 'ostatussub'), array('feed' => '[A-Za-z0-9\.\/\:]+')); array('action' => 'ostatussub'), array('feed' => '[A-Za-z0-9\.\/\:]+'));
// PuSH actions // PuSH actions
$m->connect('main/push/hub', array('action' => 'pushhub')); $m->connect('main/push/hub', array('action' => 'pushhub'));
@ -112,35 +112,34 @@ class OStatusPlugin extends Plugin
* Set up a PuSH hub link to our internal link for canonical timeline * Set up a PuSH hub link to our internal link for canonical timeline
* Atom feeds for users and groups. * Atom feeds for users and groups.
*/ */
function onStartApiAtom(Action $action) function onStartApiAtom(AtomNoticeFeed $feed)
{ {
if ($action instanceof ApiTimelineUserAction) { $id = null;
if ($feed instanceof AtomUserNoticeFeed) {
$salmonAction = 'salmon'; $salmonAction = 'salmon';
} else if ($action instanceof ApiTimelineGroupAction) { $id = $feed->getUser()->id;
} else if ($feed instanceof AtomGroupNoticeFeed) {
$salmonAction = 'salmongroup'; $salmonAction = 'salmongroup';
$id = $feed->getGroup()->id;
} else { } else {
return; return;
} }
$id = $action->arg('id'); if (!empty($id)) {
if (strval(intval($id)) === strval($id)) {
// Canonical form of id in URL? These are used for OStatus syndication.
$hub = common_config('ostatus', 'hub'); $hub = common_config('ostatus', 'hub');
if (empty($hub)) { if (empty($hub)) {
// Updates will be handled through our internal PuSH hub. // Updates will be handled through our internal PuSH hub.
$hub = common_local_url('pushhub'); $hub = common_local_url('pushhub');
} }
$action->element('link', array('rel' => 'hub', $feed->addLink($hub, array('rel' => 'hub'));
'href' => $hub));
// Also, we'll add in the salmon link // Also, we'll add in the salmon link
$salmon = common_local_url($salmonAction, array('id' => $id)); $salmon = common_local_url($salmonAction, array('id' => $id));
$action->element('link', array('rel' => 'salmon', $feed->addLink($salmon, array('rel' => 'salmon'));
'href' => $salmon));
} }
} }
/** /**
* Add the feed settings page to the Connect Settings menu * Add the feed settings page to the Connect Settings menu
* *
@ -201,7 +200,7 @@ class OStatusPlugin extends Plugin
$output->element('a', array('href' => $url, $output->element('a', array('href' => $url,
'class' => 'entity_remote_subscribe'), 'class' => 'entity_remote_subscribe'),
_m('OStatus')); _m('OStatus'));
$output->elementEnd('li'); $output->elementEnd('li');
} }
} }
@ -221,25 +220,25 @@ class OStatusPlugin extends Plugin
$w = new Webfinger; $w = new Webfinger;
$endpoint_uri = ''; $endpoint_uri = '';
$result = $w->lookup($webfinger); $result = $w->lookup($webfinger);
if (empty($result)) { if (empty($result)) {
continue; continue;
} }
foreach ($result->links as $link) { foreach ($result->links as $link) {
if ($link['rel'] == 'salmon') { if ($link['rel'] == 'salmon') {
$endpoint_uri = $link['href']; $endpoint_uri = $link['href'];
} }
} }
if (empty($endpoint_uri)) { if (empty($endpoint_uri)) {
continue; continue;
} }
$xml = '<?xml version="1.0" encoding="UTF-8" ?>'; $xml = '<?xml version="1.0" encoding="UTF-8" ?>';
$xml .= $notice->asAtomEntry(); $xml .= $notice->asAtomEntry();
$salmon = new Salmon(); $salmon = new Salmon();
$salmon->post($endpoint_uri, $xml); $salmon->post($endpoint_uri, $xml);
} }