forked from GNUsocial/gnu-social
Merge branch 'master' into 0.9.x
This commit is contained in:
commit
e666433eb4
35
README
35
README
@ -2,8 +2,8 @@
|
|||||||
README
|
README
|
||||||
------
|
------
|
||||||
|
|
||||||
StatusNet 0.9.0 ("Stand") Release Candidate 2
|
StatusNet 0.9.0 ("Stand") Beta 3
|
||||||
22 Dec 2009
|
20 Jan 2010
|
||||||
|
|
||||||
This is the README file for StatusNet (formerly Laconica), the Open
|
This is the README file for StatusNet (formerly Laconica), the Open
|
||||||
Source microblogging platform. It includes installation instructions,
|
Source microblogging platform. It includes installation instructions,
|
||||||
@ -167,6 +167,37 @@ Notable changes this version:
|
|||||||
- Add support for "repeats" (similar to Twitter's "retweets").
|
- Add support for "repeats" (similar to Twitter's "retweets").
|
||||||
- Support for repeats in Twitter API.
|
- Support for repeats in Twitter API.
|
||||||
- Better notification of direct messages.
|
- Better notification of direct messages.
|
||||||
|
- New plugin to add "powered by StatusNet" to logo.
|
||||||
|
- Returnto works for private sites.
|
||||||
|
- Localisation updates, including new Persian translation.
|
||||||
|
- CAS authentication plugin
|
||||||
|
- Get rid of DB_DataObject native cache (big memory leaker)
|
||||||
|
- setconfig.php script to set configuration variables
|
||||||
|
- Blacklist plugin, to blacklist URLs and nicknames
|
||||||
|
- Users can set flag whether they want to share location
|
||||||
|
both in notice form (for one notice) and profile settings
|
||||||
|
(any notice)
|
||||||
|
- notice inboxes moved from normalized notice_inbox table to
|
||||||
|
denormalized inbox table
|
||||||
|
- Automatic compression of Memcache
|
||||||
|
- Memory caching pluginized
|
||||||
|
- Memcache, XCache, APC and Diskcache plugins
|
||||||
|
- A script to update user locations
|
||||||
|
- cache empty query results
|
||||||
|
- A sample plugin to show best plugin practices
|
||||||
|
- CacheLog plugin to debug cache accesses
|
||||||
|
- Require users to login to view attachments on private sites
|
||||||
|
- Plugin to use Mollom spam detection service
|
||||||
|
- Plugin for RSSCloud
|
||||||
|
- Add an array of default plugins
|
||||||
|
- A version action to give credit to contributors and plugin
|
||||||
|
developers
|
||||||
|
- Daemon to read IMAP mailbox instead of using a mailbox script
|
||||||
|
- Pass session information between SSL and non-SSL server
|
||||||
|
when SSL set to 'sometimes'
|
||||||
|
- Major refactoring of queue handlers to manage very
|
||||||
|
large hosting site (like status.net)
|
||||||
|
- SubscriptionThrottle plugin to prevent subscription spamming
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
|
@ -113,4 +113,19 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,58 +69,21 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
$cnt = $this->int('count', self::DEFAULTCOUNT, self::MAXCOUNT, 1);
|
$this->serverError('Unimplemented', 503);
|
||||||
|
|
||||||
$page = $this->int('page', 1, (self::MAXNOTICES/$this->cnt));
|
return false;
|
||||||
|
|
||||||
$since_id = $this->int('since_id');
|
|
||||||
|
|
||||||
$max_id = $this->int('max_id');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the request
|
* Return true if read only.
|
||||||
*
|
*
|
||||||
* show a timeline of the user's repeated notices
|
* @param array $args other arguments
|
||||||
*
|
*
|
||||||
* @param array $args $_REQUEST data (unused)
|
* @return boolean is read only action?
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function handle($args)
|
function isReadOnly($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
return true;
|
||||||
|
|
||||||
$offset = ($this->page-1) * $this->cnt;
|
|
||||||
$limit = $this->cnt;
|
|
||||||
|
|
||||||
$strm = $this->auth_user->repeatedByMe($offset, $limit, $this->since_id, $this->max_id);
|
|
||||||
|
|
||||||
switch ($this->format) {
|
|
||||||
case 'xml':
|
|
||||||
$this->showXmlTimeline($strm);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->showJsonTimeline($strm);
|
|
||||||
break;
|
|
||||||
case 'atom':
|
|
||||||
$profile = $this->auth_user->getProfile();
|
|
||||||
|
|
||||||
$title = sprintf(_("Repeated by %s"), $this->auth_user->nickname);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:RepeatedByMe:" . $this->auth_user->id;
|
|
||||||
$link = common_local_url('showstream',
|
|
||||||
array('nickname' => $this->auth_user->nickname));
|
|
||||||
|
|
||||||
$this->showAtomTimeline($strm, $title, $id, $link);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found.'), $code = 404);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,4 +122,19 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,4 +123,19 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||||
|
|
||||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
|
||||||
|
|
||||||
class Memcached_DataObject extends DB_DataObject
|
class Memcached_DataObject extends DB_DataObject
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -353,7 +351,7 @@ class Memcached_DataObject extends DB_DataObject
|
|||||||
unset($_DB_DATAOBJECT['CONNECTIONS'][$index]);
|
unset($_DB_DATAOBJECT['CONNECTIONS'][$index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = parent::_connect();
|
$result = parent::_connect();
|
||||||
|
|
||||||
if ($result && !$exists) {
|
if ($result && !$exists) {
|
||||||
|
@ -31,66 +31,152 @@ if (!defined('STATUSNET')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
define('DEFAULT_HUB','http://pubsubhubbub.appspot.com');
|
define('DEFAULT_HUB', 'http://pubsubhubbub.appspot.com');
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/plugins/PubSubHubBub/publisher.php');
|
require_once INSTALLDIR.'/plugins/PubSubHubBub/publisher.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin to provide publisher side of PubSubHubBub (PuSH)
|
||||||
|
* relationship.
|
||||||
|
*
|
||||||
|
* PuSH is a real-time or near-real-time protocol for Atom
|
||||||
|
* and RSS feeds. More information here:
|
||||||
|
*
|
||||||
|
* http://code.google.com/p/pubsubhubbub/
|
||||||
|
*
|
||||||
|
* To enable, add the following line to your config.php:
|
||||||
|
*
|
||||||
|
* addPlugin('PubSubHubBub');
|
||||||
|
*
|
||||||
|
* This will use the Google default hub. If you'd like to use
|
||||||
|
* another, try:
|
||||||
|
*
|
||||||
|
* addPlugin('PubSubHubBub',
|
||||||
|
* array('hub' => 'http://yourhub.example.net/'));
|
||||||
|
*
|
||||||
|
* @category Plugin
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @copyright 2009 Craig Andrews http://candrews.integralblue.com
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
class PubSubHubBubPlugin extends Plugin
|
class PubSubHubBubPlugin extends Plugin
|
||||||
{
|
{
|
||||||
private $hub;
|
/**
|
||||||
|
* URL of the hub to advertise and publish to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $hub = DEFAULT_HUB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
|
||||||
function __construct()
|
function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInitializePlugin(){
|
/**
|
||||||
$this->hub = common_config('PubSubHubBub', 'hub');
|
* Hooks the StartApiAtom event
|
||||||
if(empty($this->hub)){
|
*
|
||||||
$this->hub = DEFAULT_HUB;
|
* Adds the necessary bits to advertise PubSubHubBub
|
||||||
}
|
* for the Atom feed.
|
||||||
|
*
|
||||||
|
* @param Action $action The API action being shown.
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onStartApiAtom($action)
|
||||||
|
{
|
||||||
|
$action->element('link', array('rel' => 'hub', 'href' => $this->hub), null);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartApiAtom($action){
|
/**
|
||||||
$action->element('link',array('rel'=>'hub','href'=>$this->hub),null);
|
* Hooks the StartApiRss event
|
||||||
|
*
|
||||||
|
* Adds the necessary bits to advertise PubSubHubBub
|
||||||
|
* for the RSS 2.0 feeds.
|
||||||
|
*
|
||||||
|
* @param Action $action The API action being shown.
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onStartApiRss($action)
|
||||||
|
{
|
||||||
|
$action->element('atom:link', array('rel' => 'hub',
|
||||||
|
'href' => $this->hub),
|
||||||
|
null);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartApiRss($action){
|
/**
|
||||||
$action->element('atom:link',array('rel'=>'hub','href'=>$this->hub),null);
|
* Hook for a queued notice.
|
||||||
}
|
*
|
||||||
|
* When a notice has been queued, will ping the
|
||||||
|
* PuSH hub for each Atom and RSS feed in which
|
||||||
|
* the notice appears.
|
||||||
|
*
|
||||||
|
* @param Notice $notice The notice that's been queued
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
function onHandleQueuedNotice($notice){
|
function onHandleQueuedNotice($notice)
|
||||||
|
{
|
||||||
$publisher = new Publisher($this->hub);
|
$publisher = new Publisher($this->hub);
|
||||||
|
|
||||||
$feeds = array();
|
$feeds = array();
|
||||||
|
|
||||||
//public timeline feeds
|
//public timeline feeds
|
||||||
$feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'rss'));
|
$feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'rss'));
|
||||||
$feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'atom'));
|
$feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'atom'));
|
||||||
|
|
||||||
//author's own feeds
|
//author's own feeds
|
||||||
$user = User::staticGet('id',$notice->profile_id);
|
$user = User::staticGet('id', $notice->profile_id);
|
||||||
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
|
|
||||||
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
|
$feeds[] = common_local_url('ApiTimelineUser',
|
||||||
|
array('id' => $user->nickname,
|
||||||
|
'format' => 'rss'));
|
||||||
|
$feeds[] = common_local_url('ApiTimelineUser',
|
||||||
|
array('id' => $user->nickname,
|
||||||
|
'format' => 'atom'));
|
||||||
|
|
||||||
//tag feeds
|
//tag feeds
|
||||||
$tag = new Notice_tag();
|
$tag = new Notice_tag();
|
||||||
|
|
||||||
$tag->notice_id = $notice->id;
|
$tag->notice_id = $notice->id;
|
||||||
if ($tag->find()) {
|
if ($tag->find()) {
|
||||||
while ($tag->fetch()) {
|
while ($tag->fetch()) {
|
||||||
$feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'rss'));
|
$feeds[] = common_local_url('ApiTimelineTag',
|
||||||
$feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'atom'));
|
array('tag' => $tag->tag,
|
||||||
|
'format' => 'rss'));
|
||||||
|
$feeds[] = common_local_url('ApiTimelineTag',
|
||||||
|
array('tag' => $tag->tag,
|
||||||
|
'format' => 'atom'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//group feeds
|
//group feeds
|
||||||
$group_inbox = new Group_inbox();
|
$group_inbox = new Group_inbox();
|
||||||
|
|
||||||
$group_inbox->notice_id = $notice->id;
|
$group_inbox->notice_id = $notice->id;
|
||||||
if ($group_inbox->find()) {
|
if ($group_inbox->find()) {
|
||||||
while ($group_inbox->fetch()) {
|
while ($group_inbox->fetch()) {
|
||||||
$group = User_group::staticGet('id',$group_inbox->group_id);
|
$group = User_group::staticGet('id', $group_inbox->group_id);
|
||||||
$feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'rss'));
|
|
||||||
$feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'atom'));
|
$feeds[] = common_local_url('ApiTimelineGroup',
|
||||||
|
array('id' => $group->nickname,
|
||||||
|
'format' => 'rss'));
|
||||||
|
$feeds[] = common_local_url('ApiTimelineGroup',
|
||||||
|
array('id' => $group->nickname,
|
||||||
|
'format' => 'atom'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,32 +189,63 @@ class PubSubHubBubPlugin extends Plugin
|
|||||||
if (empty($user)) {
|
if (empty($user)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
|
$feeds[] = common_local_url('ApiTimelineFriends',
|
||||||
$feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
|
array('id' => $user->nickname,
|
||||||
|
'format' => 'rss'));
|
||||||
|
$feeds[] = common_local_url('ApiTimelineFriends',
|
||||||
|
array('id' => $user->nickname,
|
||||||
|
'format' => 'atom'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$replies = $notice->getReplies();
|
||||||
|
|
||||||
//feed of user replied to
|
//feed of user replied to
|
||||||
if($notice->reply_to){
|
foreach ($replies as $recipient) {
|
||||||
$user = User::staticGet('id',$notice->reply_to);
|
$user = User::staticGet('id', $recipient);
|
||||||
$feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'rss'));
|
if (!empty($user)) {
|
||||||
$feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'atom'));
|
$feeds[] = common_local_url('ApiTimelineMentions',
|
||||||
}
|
array('id' => $user->nickname,
|
||||||
|
'format' => 'rss'));
|
||||||
foreach(array_unique($feeds) as $feed){
|
$feeds[] = common_local_url('ApiTimelineMentions',
|
||||||
if(! $publisher->publish_update($feed)){
|
array('id' => $user->nickname,
|
||||||
common_log_line(LOG_WARNING,$feed.' was not published to hub at '.$this->hub.':'.$publisher->last_response());
|
'format' => 'atom'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (array_unique($feeds) as $feed) {
|
||||||
|
if (!$publisher->publish_update($feed)) {
|
||||||
|
common_log_line(LOG_WARNING,
|
||||||
|
$feed.' was not published to hub at '.
|
||||||
|
$this->hub.':'.$publisher->last_response());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide version information
|
||||||
|
*
|
||||||
|
* Adds this plugin's version data to the global
|
||||||
|
* version array, for e.g. displaying on the version page.
|
||||||
|
*
|
||||||
|
* @param array &$versions array of array of versions
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
function onPluginVersion(&$versions)
|
function onPluginVersion(&$versions)
|
||||||
{
|
{
|
||||||
$versions[] = array('name' => 'PubSubHubBub',
|
$versions[] = array('name' => 'PubSubHubBub',
|
||||||
'version' => STATUSNET_VERSION,
|
'version' => STATUSNET_VERSION,
|
||||||
'author' => 'Craig Andrews',
|
'author' => 'Craig Andrews',
|
||||||
'homepage' => 'http://status.net/wiki/Plugin:PubSubHubBub',
|
'homepage' =>
|
||||||
|
'http://status.net/wiki/Plugin:PubSubHubBub',
|
||||||
'rawdescription' =>
|
'rawdescription' =>
|
||||||
_m('The PubSubHubBub plugin pushes RSS/Atom updates to a <a href="http://pubsubhubbub.googlecode.com/">PubSubHubBub</a> hub.'));
|
_m('The PubSubHubBub plugin pushes RSS/Atom updates '.
|
||||||
|
'to a <a href = "'.
|
||||||
|
'http://pubsubhubbub.googlecode.com/'.
|
||||||
|
'">PubSubHubBub</a> hub.'));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,7 @@ class XMPPDaemon extends Daemon
|
|||||||
|
|
||||||
function handle_message(&$pl)
|
function handle_message(&$pl)
|
||||||
{
|
{
|
||||||
|
$this->log(LOG_DEBUG, "Received message: " . str_replace("\n", " ", var_export($pl, true)));
|
||||||
$from = jabber_normalize_jid($pl['from']);
|
$from = jabber_normalize_jid($pl['from']);
|
||||||
|
|
||||||
if ($pl['type'] != 'chat') {
|
if ($pl['type'] != 'chat') {
|
||||||
|
Loading…
Reference in New Issue
Block a user