Merge commit 'origin/testing' into 0.9.x

This commit is contained in:
Brion Vibber 2010-03-12 09:41:49 -08:00
commit f72eb17304
13 changed files with 199 additions and 177 deletions

View File

@ -23,7 +23,8 @@
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net> * @copyright 2009 StatusNet, Inc.
* @author Zach Copley <zach@status.net>
* @copyright 2009-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/
*/
@ -123,22 +124,26 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
? $avatar->displayUrl()
: Avatar::defaultImage(AVATAR_PROFILE_SIZE);
$link = common_local_url(
'showfavorites',
array('nickname' => $this->user->nickname)
);
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$link = common_local_url(
'showfavorites',
array('nickname' => $this->user->nickname)
);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo
$logo,
$self
);
break;
case 'atom':
@ -153,23 +158,8 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink(
common_local_url(
'showfavorites',
array('nickname' => $this->user->nickname)
)
);
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$atom->addLink(
$this->getSelfUri('ApiTimelineFavorites', $aargs),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);

View File

@ -117,9 +117,17 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
$subtitle = sprintf(
_('Updates from %1$s and friends on %2$s!'),
$this->user->nickname, $sitename
$this->user->nickname,
$sitename
);
$link = common_local_url(
'all',
array('nickname' => $this->user->nickname)
);
$self = $this->getSelfUri();
$logo = (!empty($avatar))
? $avatar->displayUrl()
: Avatar::defaultImage(AVATAR_PROFILE_SIZE);
@ -130,19 +138,14 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
break;
case 'rss':
$link = common_local_url(
'all', array(
'nickname' => $this->user->nickname
)
);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo
$logo,
$self
);
break;
case 'atom':
@ -156,24 +159,8 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
$atom->setSubtitle($subtitle);
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink(
common_local_url(
'all',
array('nickname' => $this->user->nickname)
)
);
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$atom->addLink(
$this->getSelfUri('ApiTimelineFriends', $aargs),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);

View File

@ -107,6 +107,8 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
// We'll pull common formatting out of this for other formats
$atom = new AtomGroupNoticeFeed($this->group);
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
@ -118,7 +120,8 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
$this->group->homeUrl(),
$atom->subtitle,
null,
$atom->logo
$atom->logo,
$self
);
break;
case 'atom':
@ -126,24 +129,12 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
try {
$atom->addAuthorRaw($this->group->asAtomAuthor());
$atom->setActivitySubject($this->group->asActivitySubject());
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$self = $this->getSelfUri('ApiTimelineGroup', $aargs);
$atom->setId($self);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
} catch (Atom10FeedException $e) {
$this->serverError(
'Could not generate feed for group - ' . $e->getMessage()

View File

@ -72,7 +72,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
function prepare($args)
{
parent::prepare($args);
common_debug("api home_timeline");
$this->user = $this->getTargetUser($this->arg('id'));
if (empty($this->user)) {
@ -121,6 +121,13 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
$this->user->nickname, $sitename
);
$link = common_local_url(
'all',
array('nickname' => $this->user->nickname)
);
$self = $this->getSelfUri();
$logo = (!empty($avatar))
? $avatar->displayUrl()
: Avatar::defaultImage(AVATAR_PROFILE_SIZE);
@ -130,17 +137,14 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$link = common_local_url(
'all',
array('nickname' => $this->user->nickname)
);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo
$logo,
$self
);
break;
case 'atom':
@ -155,23 +159,8 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink(
common_local_url(
'all',
array('nickname' => $this->user->nickname)
)
);
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$atom->addLink(
$this->getSelfUri('ApiTimelineHome', $aargs),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());

View File

@ -123,6 +123,9 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
'replies',
array('nickname' => $this->user->nickname)
);
$self = $this->getSelfUri();
$subtitle = sprintf(
_('%1$s updates that reply to updates from %2$s / %3$s.'),
$sitename, $this->user->nickname, $profile->getBestName()
@ -134,10 +137,20 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline($this->notices, $title, $link, $subtitle, null, $logo);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom->setId($id);
@ -146,23 +159,8 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink(
common_local_url(
'replies',
array('nickname' => $this->user->nickname)
)
);
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$atom->addLink(
$this->getSelfUri('ApiTimelineMentions', $aargs),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());

View File

@ -107,7 +107,8 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
$title = sprintf(_("%s public timeline"), $sitename);
$taguribase = TagURI::base();
$id = "tag:$taguribase:PublicTimeline";
$link = common_root_url();
$link = common_local_url('public');
$self = $this->getSelfUri();
$subtitle = sprintf(_("%s updates from everyone!"), $sitename);
switch($this->format) {
@ -115,10 +116,20 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline($this->notices, $title, $link, $subtitle, null, $sitelogo);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$sitelogo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom->setId($id);
@ -126,16 +137,8 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
$atom->setSubtitle($subtitle);
$atom->setLogo($sitelogo);
$atom->setUpdated('now');
$atom->addLink(common_local_url('public'));
$atom->addLink(
$this->getSelfUri(
'ApiTimelinePublic', array('format' => 'atom')
),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());

View File

@ -25,7 +25,7 @@
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-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/
*/
@ -67,6 +67,8 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
{
parent::prepare($args);
common_debug("apitimelinetag prepare()");
$this->tag = $this->arg('tag');
$this->notices = $this->getNotices();
@ -108,22 +110,28 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
$taguribase = TagURI::base();
$id = "tag:$taguribase:TagTimeline:".$tag;
$link = common_local_url(
'tag',
array('tag' => $this->tag)
);
$self = $this->getSelfUri();
common_debug("self link is: $self");
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$link = common_local_url(
'tag',
array('tag' => $this->tag)
);
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$sitelogo
$sitelogo,
$self
);
break;
case 'atom':
@ -138,22 +146,8 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink(
common_local_url(
'tag',
array('tag' => $this->tag)
)
);
$aargs = array('format' => 'atom');
if (!empty($this->tag)) {
$aargs['tag'] = $this->tag;
}
$atom->addLink(
$this->getSelfUri('ApiTimelineTag', $aargs),
array('rel' => 'self', 'type' => 'application/atom+xml')
);
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());

View File

@ -116,13 +116,13 @@ class ApiTimelineUserAction extends ApiBareAuthAction
// We'll use the shared params from the Atom stub
// for other feed types.
$atom = new AtomUserNoticeFeed($this->user);
$title = $atom->title;
$link = common_local_url(
'showstream',
array('nickname' => $this->user->nickname)
);
$subtitle = $atom->subtitle;
$logo = $atom->logo;
$self = $this->getSelfUri();
// FriendFeed's SUP protocol
// Also added RSS and Atom feeds
@ -136,25 +136,22 @@ class ApiTimelineUserAction extends ApiBareAuthAction
break;
case 'rss':
$this->showRssTimeline(
$this->notices, $title, $link,
$subtitle, $suplink, $logo
$this->notices,
$atom->title,
$link,
$atom->subtitle,
$suplink,
$atom->logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$id = $this->arg('id');
$aargs = array('format' => 'atom');
if (!empty($id)) {
$aargs['id'] = $id;
}
$self = $this->getSelfUri('ApiTimelineUser', $aargs);
$atom->setId($self);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;

View File

@ -1128,6 +1128,7 @@ class Notice extends Memcached_DataObject
if ($source) {
$xs->elementStart('source');
$xs->element('id', null, $profile->profileurl);
$xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
$xs->element('link', array('href' => $profile->profileurl));
$user = User::staticGet('id', $profile->id);
@ -1143,13 +1144,14 @@ class Notice extends Memcached_DataObject
}
$xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE));
$xs->element('updated', null, common_date_w3dtf($this->created));
}
if ($source) {
$xs->elementEnd('source');
}
$xs->element('title', null, $this->content);
$xs->element('title', null, common_xml_safe_str($this->content));
if ($author) {
$xs->raw($profile->asAtomAuthor());
@ -1225,7 +1227,11 @@ class Notice extends Memcached_DataObject
}
}
$xs->element('content', array('type' => 'html'), $this->rendered);
$xs->element(
'content',
array('type' => 'html'),
common_xml_safe_str($this->rendered)
);
$tag = new Notice_tag();
$tag->notice_id = $this->id;

View File

@ -371,16 +371,15 @@ class User_group extends Memcached_DataObject
if ($source) {
$xs->elementStart('source');
$xs->element('id', null, $this->permalink());
$xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
$xs->element('link', array('href' => $this->permalink()));
}
if ($source) {
$xs->element('updated', null, $this->modified);
$xs->elementEnd('source');
}
$xs->element('title', null, $this->nickname);
$xs->element('summary', null, $this->description);
$xs->element('summary', null, common_xml_safe_str($this->description));
$xs->element('link', array('rel' => 'alternate',
'href' => $this->permalink()));
@ -390,7 +389,11 @@ class User_group extends Memcached_DataObject
$xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->modified));
$xs->element('content', array('type' => 'html'), $this->description);
$xs->element(
'content',
array('type' => 'html'),
common_xml_safe_str($this->description)
);
$xs->elementEnd('entry');

View File

@ -78,7 +78,7 @@ class PoCoAddress
if (!empty($this->formatted)) {
$xs = new XMLStringer(true);
$xs->elementStart('poco:address');
$xs->element('poco:formatted', null, $this->formatted);
$xs->element('poco:formatted', null, common_xml_safe_str($this->formatted));
$xs->elementEnd('poco:address');
return $xs->getString();
}
@ -279,7 +279,7 @@ class PoCo
);
if (!empty($this->note)) {
$xs->element('poco:note', null, $this->note);
$xs->element('poco:note', null, common_xml_safe_str($this->note));
}
if (!empty($this->address)) {
@ -805,7 +805,6 @@ class ActivityObject
return $object;
}
function asString($tag='activity:object')
{
$xs = new XMLStringer(true);
@ -817,16 +816,28 @@ class ActivityObject
$xs->element(self::ID, null, $this->id);
if (!empty($this->title)) {
$xs->element(self::TITLE, null, $this->title);
$xs->element(
self::TITLE,
null,
common_xml_safe_str($this->title)
);
}
if (!empty($this->summary)) {
$xs->element(self::SUMMARY, null, $this->summary);
$xs->element(
self::SUMMARY,
null,
common_xml_safe_str($this->summary)
);
}
if (!empty($this->content)) {
// XXX: assuming HTML content here
$xs->element(ActivityUtils::CONTENT, array('type' => 'html'), $this->content);
$xs->element(
ActivityUtils::CONTENT,
array('type' => 'html'),
common_xml_safe_str($this->content)
);
}
if (!empty($this->link)) {

View File

@ -491,7 +491,7 @@ class ApiAction extends Action
$this->showXmlAttachments($twitter_status['attachments']);
break;
case 'geo':
$this->showGeoRSS($value);
$this->showGeoXML($value);
break;
case 'retweeted_status':
$this->showTwitterXmlStatus($value, 'retweeted_status');
@ -539,7 +539,7 @@ class ApiAction extends Action
}
}
function showGeoRSS($geo)
function showGeoXML($geo)
{
if (empty($geo)) {
// empty geo element
@ -551,6 +551,17 @@ class ApiAction extends Action
}
}
function showGeoRSS($geo)
{
if (!empty($geo)) {
$this->element(
'georss:point',
null,
$geo['coordinates'][0] . ' ' . $geo['coordinates'][1]
);
}
}
function showTwitterRssItem($entry)
{
$this->elementStart('item');
@ -619,13 +630,25 @@ class ApiAction extends Action
$this->endDocument('xml');
}
function showRssTimeline($notice, $title, $link, $subtitle, $suplink=null, $logo=null)
function showRssTimeline($notice, $title, $link, $subtitle, $suplink = null, $logo = null, $self = null)
{
$this->initDocument('rss');
$this->element('title', null, $title);
$this->element('link', null, $link);
if (!is_null($self)) {
$this->element(
'atom:link',
array(
'type' => 'application/rss+xml',
'href' => $self,
'rel' => 'self'
)
);
}
if (!is_null($suplink)) {
// For FriendFeed's SUP protocol
$this->element('link', array('xmlns' => 'http://www.w3.org/2005/Atom',
@ -732,8 +755,12 @@ class ApiAction extends Action
function showTwitterAtomEntry($entry)
{
$this->elementStart('entry');
$this->element('title', null, $entry['title']);
$this->element('content', array('type' => 'html'), $entry['content']);
$this->element('title', null, common_xml_safe_str($entry['title']));
$this->element(
'content',
array('type' => 'html'),
common_xml_safe_str($entry['content'])
);
$this->element('id', null, $entry['id']);
$this->element('published', null, $entry['published']);
$this->element('updated', null, $entry['updated']);
@ -848,7 +875,7 @@ class ApiAction extends Action
$this->initDocument('atom');
$this->element('title', null, $title);
$this->element('title', null, common_xml_safe_str($title));
$this->element('id', null, $id);
$this->element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), null);
@ -858,7 +885,7 @@ class ApiAction extends Action
}
$this->element('updated', null, common_date_iso8601('now'));
$this->element('subtitle', null, $subtitle);
$this->element('subtitle', null, common_xml_safe_str($subtitle));
if (is_array($group)) {
foreach ($group as $g) {
@ -1138,7 +1165,14 @@ class ApiAction extends Action
function initTwitterRss()
{
$this->startXML();
$this->elementStart('rss', array('version' => '2.0', 'xmlns:atom'=>'http://www.w3.org/2005/Atom'));
$this->elementStart(
'rss',
array(
'version' => '2.0',
'xmlns:atom' => 'http://www.w3.org/2005/Atom',
'xmlns:georss' => 'http://www.georss.org/georss'
)
);
$this->elementStart('channel');
Event::handle('StartApiRss', array($this));
}
@ -1336,8 +1370,27 @@ class ApiAction extends Action
}
}
function getSelfUri($action, $aargs)
/**
* Calculate the complete URI that called up this action. Used for
* Atom rel="self" links. Warning: this is funky.
*
* @return string URL a URL suitable for rel="self" Atom links
*/
function getSelfUri()
{
$action = mb_substr(get_class($this), 0, -6); // remove 'Action'
$id = $this->arg('id');
$aargs = array('format' => $this->format);
if (!empty($id)) {
$aargs['id'] = $id;
}
$tag = $this->arg('tag');
if (!empty($tag)) {
$aargs['tag'] = $tag;
}
parse_str($_SERVER['QUERY_STRING'], $params);
$pstring = '';
if (!empty($params)) {

View File

@ -178,7 +178,7 @@ class Atom10Feed extends XMLStringer
$this->element(
'generator', array(
'url' => 'http://status.net',
'uri' => 'http://status.net',
'version' => STATUSNET_VERSION
),
'StatusNet'