Merge branch '1.1.x' of gitorious.org:statusnet/mainline into 1.1.x

This commit is contained in:
Evan Prodromou 2013-06-25 22:27:23 -04:00
commit 660b8f0c9c
12 changed files with 881 additions and 60 deletions

View File

@ -231,32 +231,12 @@ class ApiStatusesUpdateAction extends ApiAuthAction
return;
}
$status_shortened = $this->auth_user->shortenlinks($this->status);
if (Notice::contentTooLong($status_shortened)) {
// Note: Twitter truncates anything over 140, flags the status
// as "truncated."
$this->clientError(
sprintf(
// TRANS: Client error displayed exceeding the maximum notice length.
// TRANS: %d is the maximum length for a notice.
_m('That\'s too long. Maximum notice size is %d character.',
'That\'s too long. Maximum notice size is %d characters.',
Notice::maxContent()),
Notice::maxContent()
),
406,
$this->format
);
return;
}
/* Do not call shortenlinks until the whole notice has been build */
// Check for commands
$inter = new CommandInterpreter();
$cmd = $inter->handle_command($this->auth_user, $status_shortened);
$cmd = $inter->handle_command($this->auth_user, $this->status);
if ($cmd) {
if ($this->supported($cmd)) {
@ -299,23 +279,32 @@ class ApiStatusesUpdateAction extends ApiAuthAction
}
if (isset($upload)) {
$status_shortened .= ' ' . $upload->shortUrl();
$this->status .= ' ' . $upload->shortUrl();
if (Notice::contentTooLong($status_shortened)) {
$upload->delete();
// TRANS: Client error displayed exceeding the maximum notice length.
// TRANS: %d is the maximum lenth for a notice.
$msg = _m('Maximum notice size is %d character, including attachment URL.',
'Maximum notice size is %d characters, including attachment URL.',
Notice::maxContent());
$this->clientError(
sprintf($msg, Notice::maxContent()),
400,
$this->format
);
}
/* Do not call shortenlinks until the whole notice has been build */
}
/* Do call shortenlinks here & check notice length since notice is about to be saved & sent */
$status_shortened = $this->auth_user->shortenlinks($this->status);
if (Notice::contentTooLong($status_shortened)) {
if (isset($upload)) {
$upload->delete();
}
// TRANS: Client error displayed exceeding the maximum notice length.
// TRANS: %d is the maximum lenth for a notice.
$msg = _m('Maximum notice size is %d character, including attachment URL.',
'Maximum notice size is %d characters, including attachment URL.',
Notice::maxContent());
/* Use HTTP 413 error code (Request Entity Too Large)
* instead of basic 400 for better understanding
*/
$this->clientError(sprintf($msg, Notice::maxContent()),
413,
$this->format);
}
$content = html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8');
$options = array('reply_to' => $reply_to);

View File

@ -216,6 +216,10 @@ class oEmbedHelper
{
$params['url'] = $url;
$params['format'] = 'json';
$key=common_config('oembed','apikey');
if(isset($key)) {
$params['key'] = common_config('oembed','apikey');
}
$data = self::json($api, $params);
return self::normalize($data);
}

View File

@ -148,6 +148,9 @@ class BookmarkPlugin extends MicroAppPlugin
switch ($cls)
{
case 'BookmarksAction':
case 'BookmarksrssAction':
case 'ApiTimelineBookmarksAction':
case 'ShowbookmarkAction':
case 'NewbookmarkAction':
case 'BookmarkpopupAction':
@ -180,6 +183,26 @@ class BookmarkPlugin extends MicroAppPlugin
*/
function onRouterInitialized($m)
{
if (common_config('singleuser', 'enabled')) {
$nickname = User::singleUserNickname();
$m->connect('bookmarks',
array('action' => 'bookmarks', 'nickname' => $nickname));
$m->connect('bookmarks/rss',
array('action' => 'bookmarksrss', 'nickname' => $nickname));
} else {
$m->connect(':nickname/bookmarks',
array('action' => 'bookmarks'),
array('nickname' => Nickname::DISPLAY_FMT));
$m->connect(':nickname/bookmarks/rss',
array('action' => 'bookmarksrss'),
array('nickname' => Nickname::DISPLAY_FMT));
}
$m->connect('api/bookmarks/:id.:format',
array('action' => 'ApiTimelineBookmarks',
'id' => Nickname::INPUT_FMT,
'format' => '(xml|json|rss|atom|as)'));
$m->connect('main/bookmark/new',
array('action' => 'newbookmark'),
array('id' => '[0-9]+'));
@ -230,11 +253,13 @@ class BookmarkPlugin extends MicroAppPlugin
{
$versions[] = array('name' => 'Bookmark',
'version' => self::VERSION,
'author' => 'Evan Prodromou',
'author' => 'Evan Prodromou, Stephane Berube, Jean Baptiste Favre',
'homepage' => 'http://status.net/wiki/Plugin:Bookmark',
'description' =>
// TRANS: Plugin description.
_m('Simple extension for supporting bookmarks.'));
_m('Simple extension for supporting bookmarks. ') .
'BookmarkList feature has been developped by Stephane Berube. ' .
'Integration has been done by Jean Baptiste Favre.');
return true;
}
@ -315,6 +340,41 @@ class BookmarkPlugin extends MicroAppPlugin
return false;
}
/**
* Modify the default menu to link to our custom action
*
* Using event handlers, it's possible to modify the default UI for pages
* almost without limit. In this method, we add a menu item to the default
* primary menu for the interface to link to our action.
*
* The Action class provides a rich set of events to hook, as well as output
* methods.
*
* @param Action $action The current action handler. Use this to
* do any output.
*
* @return boolean hook value; true means continue processing, false means stop.
*
* @see Action
*/
function onEndPersonalGroupNav($action)
{
$this->user = common_current_user();
if (!$this->user) {
// TRANS: Client error displayed when trying to display bookmarks for a non-existing user.
$this->clientError(_('No such user.'));
return false;
}
$action->menuItem(common_local_url('bookmarks', array('nickname' => $this->user->nickname)),
// TRANS: Menu item in sample plugin.
_m('Bookmarks'),
// TRANS: Menu item title in sample plugin.
_m('A list of your bookmarks'), false, 'nav_timeline_bookmarks');
return true;
}
/**
* Save a remote bookmark (from Salmon or PuSH)
*

View File

@ -0,0 +1,268 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a user's favorite notices
*
* 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 API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @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);
}
require_once INSTALLDIR.'/lib/apibareauth.php';
require_once 'bookmarksnoticestream.php';
/**
* Returns the 20 most recent favorite notices for the authenticating user or user
* specified by the ID parameter in the requested format.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @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 ApiTimelineBookmarksAction extends ApiBareAuthAction
{
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
$this->user = $this->getTargetUser($this->arg('id'));
if (empty($this->user)) {
// TRANS: Client error displayed when requesting most recent favourite notices by a user for a non-existing user.
$this->clientError(_('No such user.'), 404, $this->format);
return;
}
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
function handle($args)
{
parent::handle($args);
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$profile = $this->user->getProfile();
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
$sitename = common_config('site', 'name');
$title = sprintf(
// TRANS: Title for timeline of most recent favourite notices by a user.
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname.
_('%1$s / Bookmarks from %2$s'),
$sitename,
$this->user->nickname
);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Bookmarks:" . $this->user->id;
$subtitle = sprintf(
// TRANS: Subtitle for timeline of most recent favourite notices by a user.
// TRANS: %1$s is the StatusNet sitename, %2$s is a user's full name,
// TRANS: %3$s is a user nickname.
_('%1$s updates bookmarked by %2$s / %3$s.'),
$sitename,
$profile->getBestName(),
$this->user->nickname
);
$logo = !empty($avatar)
? $avatar->displayUrl()
: Avatar::defaultImage(AVATAR_PROFILE_SIZE);
$link = common_local_url(
'bookmarks',
array('nickname' => $this->user->nickname)
);
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$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($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link,'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
break;
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
common_debug("since id = " . $this->since_id . " max id = " . $this->max_id);
$notice = new BookmarksNoticeStream($this->user->id, true);
$notice = $notice->getNotices(
($this->page-1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->user->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@ -0,0 +1,233 @@
<?php
/**
* Give a warm greeting to our friendly user
*
* PHP version 5
*
* @category Bookmark
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2009, StatusNet, Inc.
*
* 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/>.
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once 'bookmarksnoticestream.php';
/**
* List currently logged-in user's bookmakrs
*
* @category Bookmark
* @package StatusNet
* @author Stephane Berube <chimo@chromic.org>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link https://github.com/chimo/BookmarkList
*/
class BookmarksAction extends Action
{
var $user = null;
var $gc = null;
/**
* Take arguments for running
*
* This method is called first, and it lets the action class get
* all its arguments and validate them. It's also the time
* to fetch any relevant data from the database.
*
* Action classes should run parent::prepare($args) as the first
* line of this method to make sure the default argument-processing
* happens.
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
if (common_config('singleuser', 'enabled')) {
$nickname = User::singleUserNickname();
} else {
// PHP 5.4
// $nickname = $this->returnToArgs()[1]['nickname'];
// PHP < 5.4
$nickname = $this->returnToArgs();
$nickname = $nickname[1]['nickname'];
}
$this->user = User::staticGet('nickname', $nickname);
if (!$this->user) {
// TRANS: Client error displayed when trying to display bookmarks for a non-existing user.
$this->clientError(_('No such user.'));
return false;
}
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
$stream = new BookmarksNoticeStream($this->user->id, true);
$this->notices = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
if($this->page > 1 && $this->notices->N == 0) {
throw new ClientException(_('No such page.'), 404);
}
return true;
}
/**
* Handle request
*
* This is the main method for handling a request. Note that
* most preparation should be done in the prepare() method;
* by the time handle() is called the action should be
* more or less ready to go.
*
* @param array $args $_REQUEST args; handled in prepare()
*
* @return void
*/
function handle($args)
{
parent::handle($args);
$this->showPage();
}
/**
* Title of this page
*
* Override this method to show a custom title.
*
* @return string Title of the page
*/
function title()
{
if (empty($this->user)) {
// TRANS: Page title for sample plugin.
return _m('Log in');
} else {
// TRANS: Page title for sample plugin. %s is a user nickname.
return sprintf(_m('%s\'s bookmarks'), $this->user->nickname);
}
}
/**
* Feeds for the <head> section
*
* @return array Feed objects to show
*/
function getFeeds()
{
return array(new Feed(Feed::JSON,
common_local_url('ApiTimelineBookmarks',
array(
'id' => $this->user->nickname,
'format' => 'as')),
// TRANS: Feed link text. %s is a username.
sprintf(_('Feed for favorites of %s (Activity Streams JSON)'),
$this->user->nickname)),
new Feed(Feed::RSS1,
common_local_url('bookmarksrss',
array('nickname' => $this->user->nickname)),
// TRANS: Feed link text. %s is a username.
sprintf(_('Feed for favorites of %s (RSS 1.0)'),
$this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url('ApiTimelineBookmarks',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
// TRANS: Feed link text. %s is a username.
sprintf(_('Feed for favorites of %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('ApiTimelineBookmarks',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
// TRANS: Feed link text. %s is a username.
sprintf(_('Feed for favorites of %s (Atom)'),
$this->user->nickname)));
}
/**
* Show content in the content area
*
* The default StatusNet page has a lot of decorations: menus,
* logos, tabs, all that jazz. This method is used to show
* content in the content area of the page; it's the main
* thing you want to overload.
*
* This method also demonstrates use of a plural localized string.
*
* @return void
*/
function showContent()
{
$nl = new NoticeList($this->notices, $this);
$cnt = $nl->show();
if ($cnt == 0) {
$this->showEmptyList();
}
$this->pagination($this->page > 1,
$cnt > NOTICES_PER_PAGE,
$this->page, 'bookmarks',
array('nickname' => $this->user->nickname));
}
function showEmptyList() {
$message = sprintf(_('This is %1$s\'s bookmark stream, but %1$s hasn\'t bookmarked anything yet.'), $this->user->nickname) . ' ';
$this->elementStart('div', 'guide');
$this->raw(common_markup_to_html($message));
$this->elementEnd('div');
}
/**
* Return true if read only.
*
* Some actions only read from the database; others read and write.
* The simple database load-balancer built into StatusNet will
* direct read-only actions to database mirrors (if they are configured),
* and read-write actions to the master database.
*
* This defaults to false to avoid data integrity issues, but you
* should make sure to overload it for performance gains.
*
* @param array $args other arguments, if RO/RW status depends on them.
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@ -0,0 +1,80 @@
<?php
class RawBookmarksNoticeStream extends NoticeStream
{
protected $user_id;
protected $own;
function __construct($user_id, $own)
{
$this->user_id = $user_id;
$this->own = $own;
}
function getNoticeIds($offset, $limit, $since_id, $max_id)
{
$notice = new Notice();
$qry = null;
$qry = 'SELECT notice.* FROM notice ';
$qry .= 'INNER JOIN bookmark ON bookmark.uri = notice.uri ';
$qry .= 'WHERE bookmark.profile_id = ' . $this->user_id . ' ';
$qry .= 'AND notice.is_local != ' . Notice::GATEWAY . ' ';
if ($since_id != 0) {
$qry .= 'AND notice.id > ' . $since_id . ' ';
}
if ($max_id != 0) {
$qry .= 'AND notice.id <= ' . $max_id . ' ';
}
// NOTE: we sort by bookmark time, not by notice time!
$qry .= 'ORDER BY created DESC ';
if (!is_null($offset)) {
$qry .= "LIMIT $limit OFFSET $offset";
}
$notice->query($qry);
$ids = array();
while ($notice->fetch()) {
$ids[] = $notice->id;
}
$notice->free();
unset($notice);
return $ids;
}
}
/**
* Notice stream for bookmarks
*
* @category Stream
* @package StatusNet
* @author Stephane Berube <chimo@chromic.org>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class BookmarksNoticeStream extends ScopingNoticeStream
{
function __construct($user_id, $own, $profile = -1)
{
$stream = new RawBookmarksNoticeStream($user_id, $own);
if ($own) {
$key = 'bookmark:ids_by_user_own:'.$user_id;
} else {
$key = 'bookmark:ids_by_user:'.$user_id;
}
if (is_int($profile) && $profile == -1) {
$profile = Profile::current();
}
parent::__construct(new CachingNoticeStream($stream, $key),
$profile);
}
}

View File

@ -0,0 +1,137 @@
<?php
/**
* RSS feed for user bookmarks action class.
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* 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/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/rssaction.php';
require_once 'bookmarksnoticestream.php';
/**
* RSS feed for user bookmarks action class.
*
* Formatting of RSS handled by Rss10Action
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @author Zach Copley <zach@status.net>
* @author Stephane Berube <chimo@chromic.org> (modified 'favoritesrss.php' to show bookmarks instead)
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/
class BookmarksrssAction extends Rss10Action
{
/** The user whose bookmarks to display */
var $user = null;
/**
* Find the user to display by supplied nickname
*
* @param array $args Arguments from $_REQUEST
*
* @return boolean success
*/
function prepare($args)
{
parent::prepare($args);
$nickname = $this->trimmed('nickname');
$this->user = User::staticGet('nickname', $nickname);
if (!$this->user) {
// TRANS: Client error displayed when trying to get the RSS feed with bookmarks of a user that does not exist.
$this->clientError(_('No such user.'));
return false;
} else {
$this->notices = $this->getNotices($this->limit);
return true;
}
}
/**
* Get notices
*
* @param integer $limit max number of notices to return
*
* @return array notices
*/
function getNotices($limit=0)
{
$user = $this->user;
$notice = new BookmarksNoticeStream($this->user->id, true);
$notice = $notice->getNotices(0, NOTICES_PER_PAGE);
$notices = array();
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Get channel.
*
* @return array associative array on channel information
*/
function getChannel()
{
$user = $this->user;
$c = array('url' => common_local_url('bookmarksrss',
array('nickname' =>
$user->nickname)),
// TRANS: Title of RSS feed with bookmarks of a user.
// TRANS: %s is a user's nickname.
'title' => sprintf(_("%s's bookmarks"), $user->nickname),
'link' => common_local_url('bookmarks',
array('nickname' =>
$user->nickname)),
// TRANS: Desciption of RSS feed with bookmarks of a user.
// TRANS: %1$s is a user's nickname, %2$s is the name of the StatusNet site.
'description' => sprintf(_('Bookmarks posted by %1$s on %2$s!'),
$user->nickname, common_config('site', 'name')));
return $c;
}
/**
* Get image.
*
* @return void
*/
function getImage()
{
return null;
}
}

View File

@ -31,6 +31,15 @@ class RemoteProfileAction extends ShowstreamAction
$this->tag = $this->trimmed('tag');
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
$p = Profile::current();
if (empty($this->tag)) {
$stream = new ProfileNoticeStream($this->profile, $p);
} else {
$stream = new TaggedProfileNoticeStream($this->profile, $this->tag, $p);
}
$this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
return true;
}
@ -71,6 +80,25 @@ class RemoteProfileAction extends ShowstreamAction
// TRANS: Message on blocked remote profile page.
$markdown = _m('Site moderators have silenced this profile, which prevents delivery of new messages to any users on this site.');
$this->raw(common_markup_to_html($markdown));
}else{
$pnl = null;
if (Event::handle('ShowStreamNoticeList', array($this->notice, $this, &$pnl))) {
$pnl = new ProfileNoticeList($this->notice, $this);
}
$cnt = $pnl->show();
if (0 == $cnt) {
$this->showEmptyListMessage();
}
$args = array('id' => $this->profile->id);
if (!empty($this->tag))
{
$args['tag'] = $this->tag;
}
$this->pagination($this->page>1, $cnt>NOTICES_PER_PAGE, $this->page,
'remoteprofile', $args);
}
}
@ -90,14 +118,12 @@ class RemoteProfileAction extends ShowstreamAction
function showLocalNav()
{
$nav = new PublicGroupNav($this);
$nav->show();
// skip
}
function showSections()
{
ProfileAction::showSections();
// skip tag cloud
// skip
}
function showStatistics()

View File

@ -339,10 +339,7 @@ class TwitterImport
{
global $config;
$path_parts = pathinfo($twitter_user->profile_image_url);
$newname = 'Twitter_' . $twitter_user->id . '_' .
$path_parts['basename'];
$newname = 'Twitter_' . $twitter_user->id . '_' . basename($twitter_user->profile_image_url);
$oldname = $profile->getAvatar(48)->filename;
@ -370,15 +367,15 @@ class TwitterImport
$path_parts = pathinfo($twitter_user->profile_image_url);
$img_root = substr($path_parts['basename'], 0, -11);
$ext = $path_parts['extension'];
$mediatype = $this->getMediatype($ext);
$ext = (isset($path_parts['extension']) ? '.'.$path_parts['extension'] : ''); // some lack extension
$img_root = basename($path_parts['basename'], '_normal'.$ext); // cut off extension
$mediatype = $this->getMediatype(substr($ext, 1));
foreach (array('mini', 'normal', 'bigger') as $size) {
$url = $path_parts['dirname'] . '/' .
$img_root . '_' . $size . ".$ext";
$img_root . '_' . $size . $ext;
$filename = 'Twitter_' . $twitter_user->id . '_' .
$img_root . "_$size.$ext";
$img_root . '_' . $size . $ext;
$this->updateAvatar($profile->id, $size, $mediatype, $filename);
$this->fetchAvatar($url, $filename);
@ -401,8 +398,9 @@ class TwitterImport
$mediatype = null;
switch (strtolower($ext)) {
case 'jpeg':
case 'jpg':
$mediatype = 'image/jpg';
$mediatype = 'image/jpeg';
break;
case 'gif':
$mediatype = 'image/gif';
@ -419,16 +417,15 @@ class TwitterImport
global $config;
$path_parts = pathinfo($user->profile_image_url);
$ext = $path_parts['extension'];
$end = strlen('_normal' . $ext);
$img_root = substr($path_parts['basename'], 0, -($end+1));
$mediatype = $this->getMediatype($ext);
$ext = (isset($path_parts['extension']) ? '.'.$path_parts['extension'] : '');
$img_root = basename($path_parts['basename'], '_normal'.$ext);
$mediatype = $this->getMediatype(substr($ext, 1));
foreach (array('mini', 'normal', 'bigger') as $size) {
$url = $path_parts['dirname'] . '/' .
$img_root . '_' . $size . ".$ext";
$img_root . '_' . $size . $ext;
$filename = 'Twitter_' . $user->id . '_' .
$img_root . "_$size.$ext";
$img_root . '_' . $size . $ext;
if ($this->fetchAvatar($url, $filename)) {
$this->newAvatar($id, $size, $mediatype, $filename);

View File

@ -433,6 +433,31 @@ class XmppPlugin extends ImPlugin
);
}
/**
* Add XMPP plugin daemon to the list of daemon to start
*
* @param array $daemons the list of daemons to run
*
* @return boolean hook return
*/
function onGetValidDaemons($daemons)
{
if( isset($this->server) &&
isset($this->port) &&
isset($this->user) &&
isset($this->password) ){
array_push(
$daemons,
INSTALLDIR
. '/scripts/imdaemon.php'
);
}
return true;
}
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'XMPP',

View File

@ -39,8 +39,6 @@ $daemons = array();
$daemons[] = INSTALLDIR.'/scripts/queuedaemon.php';
$daemons[] = INSTALLDIR.'/scripts/imdaemon.php';
if (Event::handle('GetValidDaemons', array(&$daemons))) {
foreach ($daemons as $daemon) {
print $daemon . ' ';

View File

@ -688,18 +688,22 @@ font-style:italic;
display:none;
}
#remoteprofile .notice .entry-title, #remoteprofile .notice div.entry-content,
#showstream .notice .entry-title, #showstream .notice div.entry-content {
margin-left: 0;
}
#remoteprofile .notice .entry-title,
#showstream .notice .entry-title {
min-height: 1px;
}
#remoteprofile #content .notice .author,
#showstream #content .notice .author {
display: none;
}
#remoteprofile .notice,
#showstream .notice {
min-height: 1em;
}