Merge branch '0.7.x' of git@gitorious.org:laconica/dev into 0.7.x

This commit is contained in:
Sarven Capadisli 2009-02-11 16:53:01 +00:00
commit 012288bdf6
13 changed files with 277 additions and 329 deletions

View File

@ -69,13 +69,22 @@ class AllAction extends Action
} }
} }
function showFeeds() function getFeeds()
{ {
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1,
'href' => common_local_url('allrss', array('nickname' => common_local_url('allrss', array('nickname' =>
$this->user->nickname)), $this->user->nickname)),
'type' => 'application/rss+xml', sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
'title' => sprintf(_('Feed for friends of %s'), $this->user->nickname))); new Feed(Feed::RSS2,
common_local_url('api', array('apiaction' => 'statuses',
'method' => 'friends',
'argument' => $this->user->nickname.'.rss')),
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('api', array('apiaction' => 'statuses',
'method' => 'friends',
'argument' => $this->user->nickname.'.atom')),
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname)));
} }
function showLocalNav() function showLocalNav()
@ -84,15 +93,6 @@ class AllAction extends Action
$nav->show(); $nav->show();
} }
function showExportData()
{
$fl = new FeedList($this);
$fl->show(array(0=>array('href'=>common_local_url('allrss', array('nickname' => $this->user->nickname)),
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'allrss')));
}
function showContent() function showContent()
{ {
$notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); $notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);

View File

@ -145,6 +145,7 @@ class AvatarsettingsAction extends AccountSettingsAction
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
'alt' => $user->nickname)); 'alt' => $user->nickname));
$this->elementEnd('div'); $this->elementEnd('div');
$this->submit('delete', _('Delete'));
$this->elementEnd('li'); $this->elementEnd('li');
} }
@ -256,6 +257,8 @@ class AvatarsettingsAction extends AccountSettingsAction
$this->uploadAvatar(); $this->uploadAvatar();
} else if ($this->arg('crop')) { } else if ($this->arg('crop')) {
$this->cropAvatar(); $this->cropAvatar();
} else if ($this->arg('delete')) {
$this->deleteAvatar();
} else { } else {
$this->showForm(_('Unexpected form submission.')); $this->showForm(_('Unexpected form submission.'));
} }
@ -345,6 +348,29 @@ class AvatarsettingsAction extends AccountSettingsAction
} }
} }
/**
* Get rid of the current avatar.
*
* @return void
*/
function deleteAvatar()
{
$user = common_current_user();
$profile = $user->getProfile();
$avatar = $profile->getOriginalAvatar();
$avatar->delete();
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
$avatar->delete();
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$avatar->delete();
$avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
$avatar->delete();
$this->showForm(_('Avatar deleted.'), true);
}
/** /**
* Add the jCrop stylesheet * Add the jCrop stylesheet
* *

View File

@ -78,62 +78,20 @@ class NoticesearchAction extends SearchAction
return _('Text search'); return _('Text search');
} }
function getFeeds()
function showExportData()
{ {
$q = $this->trimmed('q'); $q = $this->trimmed('q');
if (!$q) { if (!$q) {
return; return null;
}
$fl = new FeedList($this);
$fl->show(array(0 => array('href' => common_local_url('noticesearchrss', array('q' => $q)),
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'noticesearchrss')));
} }
return array(new Feed(Feed::RSS1, common_local_url('noticesearchrss',
function showFeeds()
{
$q = $this->trimmed('q');
if (!$q) {
return;
}
$this->element('link', array('rel' => 'alternate',
'href' => common_local_url('noticesearchrss',
array('q' => $q)), array('q' => $q)),
'type' => 'application/rss+xml', sprintf(_('Search results for "%s" on %s'),
'title' => _('Search Stream Feed'))); $q, common_config('site', 'name'))));
} }
/**
* Show header
*
* @param array $arr array containing the query
*
* @return void
*/
function extraHead2()
{
$q = $this->trimmed('q');
if ($q) {
$this->element('link', array('rel' => 'alternate',
'href' => common_local_url('noticesearchrss',
array('q' => $q)),
'type' => 'application/rss+xml',
'title' => _('Search Stream Feed')));
}
}
/** /**
* Show results * Show results
* *

View File

@ -119,12 +119,20 @@ class PublicAction extends Action
* @return void * @return void
*/ */
function showFeeds() function getFeeds()
{ {
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1, common_local_url('publicrss'),
'href' => common_local_url('publicrss'), _('Public Stream Feed (RSS 1.0)')),
'type' => 'application/rss+xml', new Feed(Feed::RSS2,
'title' => _('Public Stream Feed'))); common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'public_timeline.rss')),
_('Public Stream Feed (RSS 2.0)')),
new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'public_timeline.atom')),
_('Public Stream Feed (Atom)')));
} }
/** /**
@ -185,27 +193,6 @@ class PublicAction extends Action
$this->page, 'public'); $this->page, 'public');
} }
/**
* Makes a list of exported feeds for this page
*
* @return void
*
* @todo I18N
*/
function showExportData()
{
$fl = new FeedList($this);
$fl->show(array(0 => array('href' => common_local_url('publicrss'),
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'publicrss'),
1 => array('href' => common_local_url('publicatom'),
'type' => 'atom',
'version' => 'Atom 1.0',
'item' => 'publicatom')));
}
function showSections() function showSections()
{ {
// $top = new TopPostersSection($this); // $top = new TopPostersSection($this);

View File

@ -129,16 +129,13 @@ class RepliesAction extends Action
* @return void * @return void
*/ */
function showFeeds() function getFeeds()
{ {
$rssurl = common_local_url('repliesrss', $rssurl = common_local_url('repliesrss',
array('nickname' => $this->user->nickname)); array('nickname' => $this->user->nickname));
$rsstitle = sprintf(_('Feed for replies to %s'), $this->user->nickname); $rsstitle = sprintf(_('Feed for replies to %s'), $this->user->nickname);
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1, $rssurl, $rsstitle));
'href' => $rssurl,
'type' => 'application/rss+xml',
'title' => $rsstitle));
} }
/** /**
@ -153,25 +150,6 @@ class RepliesAction extends Action
$nav->show(); $nav->show();
} }
/**
* Show the replies feed links
*
* @return void
*/
function showExportData()
{
$fl = new FeedList($this);
$rssurl = common_local_url('repliesrss',
array('nickname' => $this->user->nickname));
$fl->show(array(0=>array('href'=> $rssurl,
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'repliesrss')));
}
/** /**
* Show the content * Show the content
* *

View File

@ -136,10 +136,10 @@ class ShowfavoritesAction extends Action
/** /**
* Feeds for the <head> section * Feeds for the <head> section
* *
* @return void * @return array Feed objects to show
*/ */
function showFeeds() function getFeeds()
{ {
$feedurl = common_local_url('favoritesrss', $feedurl = common_local_url('favoritesrss',
array('nickname' => array('nickname' =>
@ -147,10 +147,7 @@ class ShowfavoritesAction extends Action
$feedtitle = sprintf(_('Feed for favorites of %s'), $feedtitle = sprintf(_('Feed for favorites of %s'),
$this->user->nickname); $this->user->nickname);
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1, $feedurl, $feedtitle));
'href' => $feedurl,
'type' => 'application/rss+xml',
'title' => $feedtitle));
} }
/** /**
@ -165,28 +162,6 @@ class ShowfavoritesAction extends Action
$nav->show(); $nav->show();
} }
/**
* Show the replies feed links
*
* @return void
*/
function showExportData()
{
$feedurl = common_local_url('favoritesrss',
array('nickname' =>
$this->user->nickname));
$fl = new FeedList($this);
// XXX: I18N
$fl->show(array(0=>array('href'=> $feedurl,
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'Favorites')));
}
/** /**
* Show the content * Show the content
* *

View File

@ -292,37 +292,18 @@ class ShowgroupAction extends Action
} }
/** /**
* Show a list of links to feeds this page produces * Get a list of the feeds for this page
* *
* @return void * @return void
*/ */
function showExportData() function getFeeds()
{
$fl = new FeedList($this);
$fl->show(array(0=>array('href'=>common_local_url('grouprss',
array('nickname' => $this->group->nickname)),
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'notices')));
}
/**
* Show a list of links to feeds this page produces
*
* @return void
*/
function showFeeds()
{ {
$url = $url =
common_local_url('grouprss', common_local_url('grouprss',
array('nickname' => $this->group->nickname)); array('nickname' => $this->group->nickname));
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1, $url, sprintf(_('Notice feed for %s group'),
'href' => $url,
'type' => 'application/rss+xml',
'title' => sprintf(_('Notice feed for %s group'),
$this->group->nickname))); $this->group->nickname)));
} }

View File

@ -155,54 +155,35 @@ class ShowstreamAction extends Action
return; return;
} }
function showExportData() function getFeeds()
{ {
$fl = new FeedList($this); return array(new Feed(Feed::RSS1,
$fl->show(array(0=>array('href'=>common_local_url('userrss', common_local_url('userrss',
array('nickname' => $this->user->nickname)), array('nickname' => $this->user->nickname)),
'type' => 'rss', sprintf(_('Notice feed for %s (RSS 1.0)'),
'version' => 'RSS 1.0', $this->user->nickname)),
'item' => 'notices'), new Feed(Feed::RSS2,
1=>array('href'=>common_local_url('usertimeline', common_local_url('api',
array('nickname' => $this->user->nickname)),
'type' => 'atom',
'version' => 'Atom 1.0',
'item' => 'usertimeline'),
2=>array('href'=>common_local_url('foaf',
array('nickname' => $this->user->nickname)),
'type' => 'rdf',
'version' => 'FOAF',
'item' => 'foaf')));
}
function showFeeds()
{
$this->element('link', array('rel' => 'alternate',
'type' => 'application/rss+xml',
'href' => common_local_url('userrss',
array('nickname' => $this->user->nickname)),
'title' => sprintf(_('Notice feed for %s (RSS)'),
$this->user->nickname)));
$this->element('link',
array('rel' => 'alternate',
'href' => common_local_url('api',
array('apiaction' => 'statuses', array('apiaction' => 'statuses',
'method' => 'user_timeline.atom', 'method' => 'user_timeline',
'argument' => $this->user->nickname)), 'argument' => $this->user->nickname.'.rss')),
'type' => 'application/atom+xml', sprintf(_('Notice feed for %s (RSS 2.0)'),
'title' => sprintf(_('Notice feed for %s (Atom)'), $this->user->nickname)),
$this->user->nickname))); new Feed(Feed::ATOM,
common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline',
'argument' => $this->user->nickname.'.atom')),
sprintf(_('Notice feed for %s (Atom)'),
$this->user->nickname)),
new Feed(Feed::FOAF,
common_local_url('foaf', array('nickname' =>
$this->user->nickname)),
sprintf(_('FOAF for %s'), $this->user->nickname)));
} }
function extraHead() function extraHead()
{ {
// FOAF
$this->element('link', array('rel' => 'meta',
'href' => common_local_url('foaf', array('nickname' =>
$this->user->nickname)),
'type' => 'application/rdf+xml',
'title' => 'FOAF'));
// for remote subscriptions etc. // for remote subscriptions etc.
$this->element('meta', array('http-equiv' => 'X-XRDS-Location', $this->element('meta', array('http-equiv' => 'X-XRDS-Location',
'content' => common_local_url('xrds', array('nickname' => 'content' => common_local_url('xrds', array('nickname' =>

View File

@ -61,12 +61,11 @@ class TagAction extends Action
$this->showPage(); $this->showPage();
} }
function showFeeds() function getFeeds()
{ {
$this->element('link', array('rel' => 'alternate', return array(new Feed(Feed::RSS1,
'href' => common_local_url('tagrss', array('tag' => $this->tag)), common_local_url('tagrss', array('tag' => $this->tag)),
'type' => 'application/rss+xml', sprintf(_('Feed for tag %s'), $this->tag)));
'title' => sprintf(_('Feed for tag %s'), $this->tag)));
} }
function showPageNotice() function showPageNotice()
@ -74,15 +73,6 @@ class TagAction extends Action
return sprintf(_('Messages tagged "%s", most recent first'), $this->tag); return sprintf(_('Messages tagged "%s", most recent first'), $this->tag);
} }
function showExportData()
{
$fl = new FeedList($this);
$fl->show(array(0=>array('href'=>common_local_url('tagrss', array('tag' => $this->tag)),
'type' => 'rss',
'version' => 'RSS 1.0',
'item' => 'tagrss')));
}
function showContent() function showContent()
{ {
$notice = Notice_tag::getStream($this->tag, (($this->page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1); $notice = Notice_tag::getStream($this->tag, (($this->page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);

View File

@ -225,9 +225,19 @@ class Action extends HTMLOutputter // lawsuit
* *
* @return nothing * @return nothing
*/ */
function showFeeds() function showFeeds()
{ {
// does nothing by default $feeds = $this->getFeeds();
if ($feeds) {
foreach ($feeds as $feed) {
$this->element('link', array('rel' => $feed->rel(),
'href' => $feed->url,
'type' => $feed->mimeType(),
'title' => $feed->title));
}
}
} }
/** /**
@ -540,15 +550,16 @@ class Action extends HTMLOutputter // lawsuit
/** /**
* Show export data feeds. * Show export data feeds.
* *
* MAY overload if there are feeds * @return void
*
* @return nothing
*/ */
function showExportData() function showExportData()
{ {
// is there structure to this? $feeds = $this->getFeeds();
// list of (visible!) feed links if ($feeds) {
// can we reuse list of feeds from showFeeds() ? $fl = new FeedList($this);
$fl->show($feeds);
}
} }
/** /**
@ -924,4 +935,17 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div'); $this->elementEnd('div');
} }
} }
/**
* An array of feeds for this action.
*
* Returns an array of potential feeds for this action.
*
* @return array Feed object to show in head and links
*/
function getFeeds()
{
return null;
}
} }

110
lib/feed.php Normal file
View File

@ -0,0 +1,110 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* Data structure for info about syndication feeds (RSS 1.0, RSS 2.0, Atom)
*
* 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 Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @copyright 2009 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
/**
* Data structure for feeds
*
* This structure is a helpful container for shipping around information about syndication feeds.
*
* @category Feed
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
class Feed
{
const RSS1 = 1;
const RSS2 = 2;
const ATOM = 3;
const FOAF = 4;
var $type = null;
var $url = null;
var $title = null;
function __construct($type, $url, $title)
{
$this->type = $type;
$this->url = $url;
$this->title = $title;
}
function mimeType()
{
switch ($this->type) {
case Feed::RSS1:
return 'application/rdf+xml';
case Feed::RSS2:
return 'application/rss+xml';
case Feed::ATOM:
return 'application/atom+xml';
case Feed::FOAF:
return 'application/rdf+xml';
default:
return null;
}
}
function typeName()
{
switch ($this->type) {
case Feed::RSS1:
return _('RSS 1.0');
case Feed::RSS2:
return _('RSS 2.0');
case Feed::ATOM:
return _('Atom');
case Feed::FOAF:
return _('FOAF');
default:
return null;
}
}
function rel()
{
switch ($this->type) {
case Feed::RSS1:
case Feed::RSS2:
case Feed::ATOM:
return 'alternate';
case Feed::FOAF:
return 'meta';
default:
return null;
}
}
}

View File

@ -64,8 +64,8 @@ class FeedList extends Widget
$this->out->element('h2', null, _('Export data')); $this->out->element('h2', null, _('Export data'));
$this->out->elementStart('ul', array('class' => 'xoxo')); $this->out->elementStart('ul', array('class' => 'xoxo'));
foreach ($feeds as $key => $value) { foreach ($feeds as $feed) {
$this->feedItem($feeds[$key]); $this->feedItem($feed);
} }
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@ -74,92 +74,27 @@ class FeedList extends Widget
function feedItem($feed) function feedItem($feed)
{ {
$nickname = $this->action->trimmed('nickname'); $classname = null;
switch($feed['item']) { switch ($feed->type) {
case 'notices': default: case Feed::RSS1:
$feed_classname = $feed['type']; case Feed::RSS2:
$feed_mimetype = "application/".$feed['type']."+xml"; $classname = 'rss';
$feed_title = "$nickname's ".$feed['version']." notice feed";
$feed['textContent'] = "RSS";
break; break;
case Feed::ATOM:
case 'allrss': $classname = 'atom';
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = $feed['version']." feed for $nickname and friends";
$feed['textContent'] = "RSS";
break; break;
case Feed::FOAF:
case 'repliesrss': $classname = 'foaf';
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = $feed['version']." feed for replies to $nickname";
$feed['textContent'] = "RSS";
break;
case 'publicrss':
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "Public timeline ".$feed['version']." feed";
$feed['textContent'] = "RSS";
break;
case 'publicatom':
$feed_classname = "atom";
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "Public timeline ".$feed['version']." feed";
$feed['textContent'] = "Atom";
break;
case 'noticesearchrss':
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = $feed['version']." feed for this notice search";
$feed['textContent'] = "RSS";
break;
case 'tagrss':
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = $feed['version']." feed for this tag";
$feed['textContent'] = "RSS";
break;
case 'favoritedrss':
$feed_classname = $feed['type'];
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "Favorited ".$feed['version']." feed";
$feed['textContent'] = "RSS";
break;
case 'foaf':
$feed_classname = "foaf";
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "$nickname's FOAF file";
$feed['textContent'] = "FOAF";
break;
case 'favoritesrss':
$feed_classname = "favorites";
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "Feed for favorites of $nickname";
$feed['textContent'] = "RSS";
break;
case 'usertimeline':
$feed_classname = "atom";
$feed_mimetype = "application/".$feed['type']."+xml";
$feed_title = "$nickname's ".$feed['version']." notice feed";
$feed['textContent'] = "Atom";
break; break;
} }
$this->out->elementStart('li'); $this->out->elementStart('li');
$this->out->element('a', array('href' => $feed['href'], $this->out->element('a', array('href' => $feed->url,
'class' => $feed_classname, 'class' => $classname,
'type' => $feed_mimetype, 'type' => $feed->mimeType(),
'title' => $feed_title), 'title' => $feed->title),
$feed['textContent']); $feed->typeName());
$this->out->elementEnd('li'); $this->out->elementEnd('li');
} }
} }

View File

@ -412,14 +412,14 @@ function common_replace_urls_callback($text, $callback) {
// Then clean up what the regex left behind // Then clean up what the regex left behind
$offset = 0; $offset = 0;
foreach($matches[0] as $url) { foreach($matches[0] as $orig_url) {
$url = htmlspecialchars_decode($url); $url = htmlspecialchars_decode($orig_url);
// Make sure we didn't pick up an email address // Make sure we didn't pick up an email address
if (preg_match('#^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$#i', $url)) continue; if (preg_match('#^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$#i', $url)) continue;
// Remove trailing punctuation // Remove surrounding punctuation
$url = rtrim($url, '.?!,;:\'"`'); $url = trim($url, '.?!,;:\'"`([<');
// Remove surrounding parens and the like // Remove surrounding parens and the like
preg_match('/[)\]>]+$/', $url, $trailing); preg_match('/[)\]>]+$/', $url, $trailing);
@ -446,7 +446,7 @@ function common_replace_urls_callback($text, $callback) {
// If the first part wasn't cap'd but the last part was, we captured too much // If the first part wasn't cap'd but the last part was, we captured too much
if ((!$prev_part && $last_part)) { if ((!$prev_part && $last_part)) {
$url = substr_replace($url, '', mb_strpos($url, '.'.$url_parts[2], 0)); $url = mb_substr($url, 0 , mb_strpos($url, '.'.$url_parts['2'], 0));
} }
// Capture the new TLD // Capture the new TLD
@ -456,6 +456,9 @@ function common_replace_urls_callback($text, $callback) {
if (!in_array($url_parts[2], $tlds)) continue; if (!in_array($url_parts[2], $tlds)) continue;
// Put the url back the way we found it.
$url = (mb_strpos($orig_url, htmlspecialchars($url)) === FALSE) ? $url:htmlspecialchars($url);
// Call user specified func // Call user specified func
$modified_url = $callback($url); $modified_url = $callback($url);