Merge branch 'nightly' of git.gnu.io:gnu/gnu-social into nightly

This commit is contained in:
abjectio 2016-02-27 20:37:03 +01:00
commit 12ad588a9b
205 changed files with 2600 additions and 792 deletions

View File

@ -120,8 +120,9 @@ db
-- --
This section is a reference to the configuration options for This section is a reference to the configuration options for
DB_DataObject (see <http://ur1.ca/7xp>). The ones that you may want to DB_DataObject (see
set are listed below for clarity. <http://pear.php.net/manual/en/package.database.db-dataobject.intro-configuration.php>).
The ones that you may want to set are listed below for clarity.
database: a DSN (Data Source Name) for your StatusNet database. This is database: a DSN (Data Source Name) for your StatusNet database. This is
in the format 'protocol://username:password@hostname/databasename', in the format 'protocol://username:password@hostname/databasename',
@ -322,8 +323,8 @@ server: If set, defines another server where avatars are stored in the
the client to speed up page loading, either with another the client to speed up page loading, either with another
virtual server or with an NFS or SAMBA share. Clients virtual server or with an NFS or SAMBA share. Clients
typically only make 2 connections to a single server at a typically only make 2 connections to a single server at a
time <http://ur1.ca/6ih>, so this can parallelize the job. time <https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4>,
Defaults to null. so this can parallelize the job. Defaults to null.
ssl: Whether to access avatars using HTTPS. Defaults to null, meaning ssl: Whether to access avatars using HTTPS. Defaults to null, meaning
to guess based on site-wide SSL settings. to guess based on site-wide SSL settings.
@ -673,7 +674,7 @@ Web crawlers. See http://www.robotstxt.org/ for more information
on the format of this file. on the format of this file.
crawldelay: if non-empty, this value is provided as the Crawl-Delay: crawldelay: if non-empty, this value is provided as the Crawl-Delay:
for the robots.txt file. see http://ur1.ca/l5a0 for the robots.txt file. see <https://en.wikipedia.org/wiki/Robots_exclusion_standard#Crawl-delay_directive>
for more information. Default is zero, no explicit delay. for more information. Default is zero, no explicit delay.
disallow: Array of (virtual) directories to disallow. Default is 'main', disallow: Array of (virtual) directories to disallow. Default is 'main',
'search', 'message', 'settings', 'admin'. Ignored when site 'search', 'message', 'settings', 'admin'. Ignored when site

View File

@ -155,6 +155,17 @@ class ShowstreamAction extends NoticestreamAction
sprintf(_('FOAF for %s'), $this->target->getNickname()))); sprintf(_('FOAF for %s'), $this->target->getNickname())));
} }
public function extraHeaders()
{
parent::extraHeaders();
// Publish all the rel="me" in the HTTP headers on our main profile page
if (get_class($this) == 'ShowstreamAction') {
foreach ($this->target->getRelMes() as $relMe) {
header('Link: <'.htmlspecialchars($relMe['href']).'>'.$type.'; rel="me"', false);
}
}
}
function extraHead() function extraHead()
{ {
if ($this->target->bio) { if ($this->target->bio) {

View File

@ -207,7 +207,7 @@ class Avatar extends Managed_DataObject
} }
} }
static function defaultImage($size) static function defaultImage($size=AVATAR_PROFILE_SIZE)
{ {
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile', static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream', AVATAR_STREAM_SIZE => 'stream',

View File

@ -106,6 +106,27 @@ class File extends Managed_DataObject
// We don't have the file's URL since before, so let's continue. // We don't have the file's URL since before, so let's continue.
} }
// if the given url is an local attachment url and the id already exists, don't
// save a new file record. This should never happen, but let's make it foolproof
// FIXME: how about attachments servers?
$u = parse_url($given_url);
if (isset($u['host']) && $u['host'] === common_config('site', 'server')) {
$r = Router::get();
// Skip the / in the beginning or $r->map won't match
$args = $r->map(mb_substr($u['path'], 1));
if ($args['action'] === 'attachment') {
try {
// $args['attachment'] should always be set if action===attachment, given our routing rules
$file = File::getByID($args['attachment']);
return $file;
} catch (EmptyIdException $e) {
// ...but $args['attachment'] can also be 0...
} catch (NoResultException $e) {
// apparently this link goes to us, but is _not_ an existing attachment (File) ID?
}
}
}
$file = new File; $file = new File;
$file->url = $given_url; $file->url = $given_url;
if (!empty($redir_data['protected'])) $file->protected = $redir_data['protected']; if (!empty($redir_data['protected'])) $file->protected = $redir_data['protected'];
@ -237,7 +258,7 @@ class File extends Managed_DataObject
static function filename(Profile $profile, $origname, $mimetype) static function filename(Profile $profile, $origname, $mimetype)
{ {
$ext = self::guessMimeExtension($mimetype); $ext = self::guessMimeExtension($mimetype, $origname);
// Normalize and make the original filename more URL friendly. // Normalize and make the original filename more URL friendly.
$origname = basename($origname, ".$ext"); $origname = basename($origname, ".$ext");
@ -258,19 +279,53 @@ class File extends Managed_DataObject
return $filename; return $filename;
} }
static function guessMimeExtension($mimetype) /**
* @param $mimetype The mimetype we've discovered for this file.
* @param $filename An optional filename which we can use on failure.
*/
static function guessMimeExtension($mimetype, $filename=null)
{ {
try { try {
// first see if we know the extension for our mimetype
$ext = common_supported_mime_to_ext($mimetype); $ext = common_supported_mime_to_ext($mimetype);
} catch (Exception $e) { // we do, so use it!
// We don't support this mimetype, but let's guess the extension return $ext;
$matches = array(); } catch (Exception $e) { // FIXME: Make this exception more specific to "unknown mime=>ext relation"
if (!preg_match('/\/([a-z0-9]+)/', mb_strtolower($mimetype), $matches)) { // We don't know the extension for this mimetype, but let's guess.
throw new Exception('Malformed mimetype: '.$mimetype);
// If we are very liberal with uploads ($config['attachments']['supported'] === true)
// then we try to do some guessing based on the filename, if it was supplied.
if (!is_null($filename) && common_config('attachments', 'supported')===true
&& preg_match('/^.+\.([A-Za-z0-9]+)$/', $filename, $matches)) {
// we matched on a file extension, so let's see if it means something.
$ext = mb_strtolower($matches[1]);
$blacklist = common_config('attachments', 'extblacklist');
// If we got an extension from $filename we want to check if it's in a blacklist
// so we avoid people uploading .php files etc.
if (array_key_exists($ext, $blacklist)) {
if (!is_string($blacklist[$ext])) {
// we don't have a safe replacement extension
throw new ClientException(_('Blacklisted file extension.'));
}
common_debug('Found replaced extension for filename '._ve($filename).': '._ve($ext));
// return a safe replacement extension ('php' => 'phps' for example)
return $blacklist[$ext];
}
// the attachment extension based on its filename was not blacklisted so it's ok to use it
return $ext;
} }
$ext = $matches[1];
} }
return mb_strtolower($ext);
// If nothing else has given us a result, try to extract it from
// the mimetype value (this turns .jpg to .jpeg for example...)
$matches = array();
// FIXME: try to build a regexp that will get jpeg from image/jpeg as well as json from application/jrd+json
if (!preg_match('/\/([a-z0-9]+)/', mb_strtolower($mimetype), $matches)) {
throw new Exception('Malformed mimetype: '.$mimetype);
}
return mb_strtolower($matches[1]);
} }
/** /**

View File

@ -172,56 +172,83 @@ class File_redirection extends Managed_DataObject
try { try {
$r = File_redirection::getByUrl($in_url); $r = File_redirection::getByUrl($in_url);
if($r instanceof File_redirection) {
try { $f = File::getKV('id',$r->file_id);
$f = File::getKV('id',$r->file_id);
$r->file = $f; if($file instanceof File) {
$r->redir_url = $f->url; $r->file = $f;
} catch (NoResultException $e) { $r->redir_url = $f->url;
// Invalid entry, delete and run again } else {
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and creating new File and File_redirection entries."); // Invalid entry, delete and run again
$r->delete(); common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and and trying again...");
return self::where($in_url); $r->delete();
} return self::where($in_url);
return $r;
} }
// File_redirecion and File record found, return both
return $r;
} catch (NoResultException $e) { } catch (NoResultException $e) {
// File_redirecion record not found, but this might be a direct link to a file
try { try {
$f = File::getByUrl($in_url); $f = File::getByUrl($in_url);
$redir->file_id = $f->id; $redir->file_id = $f->id;
$redir->file = $f; $redir->file = $f;
return $redir; return $redir;
} catch (NoResultException $e) { } catch (NoResultException $e) {
// Oh well, let's keep going // nope, this was not a direct link to a file either, let's keep going
} }
} }
if ($discover) { if ($discover) {
// try to follow redirects and get the final url
$redir_info = File_redirection::lookupWhere($in_url); $redir_info = File_redirection::lookupWhere($in_url);
if(is_string($redir_info)) { if(is_string($redir_info)) {
$redir_info = array('url' => $redir_info); $redir_info = array('url' => $redir_info);
} }
// Save the file if we don't have it already // the last url in the redirection chain can actually be a redirect!
$redir->file = File::saveNew($redir_info,$redir_info['url']); // this is the case with local /attachment/{file_id} links
// in that case we have the file id already
// If this is a redirection, save it try {
// (if it hasn't been saved yet by some other process while we we $r = File_redirection::getByUrl($redir_info['url']);
// were running lookupWhere())
if($redir_info['url'] != $in_url) { $f = File::getKV('id',$r->file_id);
try {
$file_redir = File_redirection::getByUrl($in_url); if($f instanceof File) {
} catch (NoResultException $e) { $redir->file = $f;
$file_redir = new File_redirection(); $redir->redir_url = $f->url;
$file_redir->urlhash = File::hashurl($in_url); } else {
$file_redir->url = $in_url; // Invalid entry in File_redirection, delete and run again
$file_redir->file_id = $redir->file->getID(); common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File_redirection entry and trying again...");
$file_redir->insert(); $r->delete();
$file_redir->redir_url = $redir->file->url; return self::where($in_url);
} }
} catch (NoResultException $e) {
// save the file now when we know that we don't have it in File_redirection
try {
$redir->file = File::saveNew($redir_info,$redir_info['url']);
} catch (ServerException $e) {
common_log(LOG_ERR, $e);
}
}
// If this is a redirection and we have a file to redirect to, save it
// (if it doesn't exist in File_redirection already)
if($redir->file instanceof File && $redir_info['url'] != $in_url) {
try {
$file_redir = File_redirection::getByUrl($in_url);
} catch (NoResultException $e) {
$file_redir = new File_redirection();
$file_redir->urlhash = File::hashurl($in_url);
$file_redir->url = $in_url;
$file_redir->file_id = $redir->file->getID();
$file_redir->insert();
$file_redir->redir_url = $redir->file->url;
}
$file_redir->file = $redir->file; $file_redir->file = $redir->file;
return $file_redir; return $file_redir;
} }
} }

View File

@ -88,7 +88,7 @@ class Notice extends Managed_DataObject
'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'), 'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'),
'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'), 'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'), 'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'), 'conversation' => array('type' => 'int', 'description' => 'the local numerical conversation id'),
'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => null), 'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => null),
'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'), 'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'),
@ -260,7 +260,8 @@ class Notice extends Managed_DataObject
public function getRendered() public function getRendered()
{ {
if (is_null($this->rendered) || $this->rendered === '') { // we test $this->id because if it's not inserted yet, we can't update the field
if (!empty($this->id) && (is_null($this->rendered) || $this->rendered === '')) {
// update to include rendered content on-the-fly, so we don't have to have a fix-up script in upgrade.php // update to include rendered content on-the-fly, so we don't have to have a fix-up script in upgrade.php
common_debug('Rendering notice '.$this->getID().' as it had no rendered HTML content.'); common_debug('Rendering notice '.$this->getID().' as it had no rendered HTML content.');
$orig = clone($this); $orig = clone($this);
@ -848,14 +849,14 @@ class Notice extends Managed_DataObject
$stored->url = $url; $stored->url = $url;
$stored->verb = $act->verb; $stored->verb = $act->verb;
$content = $act->content ?: $act->summary; // we use mb_strlen because it _might_ be that the content is just the string "0"...
if (is_null($content) && !is_null($actobj)) { $content = mb_strlen($act->content) ? $act->content : $act->summary;
$content = $actobj->content ?: $actobj->summary; if (mb_strlen($content)===0 && !is_null($actobj)) {
$content = mb_strlen($actobj->content) ? $actobj->content : $actobj->summary;
} }
// Strip out any bad HTML // Strip out any bad HTML from $content. URI.Base is used to sort out relative URLs.
$stored->rendered = common_purify($content); $stored->rendered = common_purify($content, ['URI.Base' => $stored->url ?: null]);
// yeah, just don't use getRendered() here since it's not inserted yet ;) $stored->content = common_strip_html($stored->getRendered(), true, true);
$stored->content = common_strip_html($stored->rendered);
if (trim($stored->content) === '') { if (trim($stored->content) === '') {
// TRANS: Error message when the plain text content of a notice has zero length. // TRANS: Error message when the plain text content of a notice has zero length.
throw new ClientException(_('Empty notice content, will not save this.')); throw new ClientException(_('Empty notice content, will not save this.'));
@ -996,7 +997,9 @@ class Notice extends Managed_DataObject
} }
} }
if (!$stored instanceof Notice) { if (!$stored instanceof Notice) {
throw new ServerException('StartNoticeSave did not give back a Notice'); throw new ServerException('StartNoticeSave did not give back a Notice.');
} elseif (empty($stored->id)) {
throw new ServerException('Supposedly saved Notice has no ID.');
} }
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if // Only save 'attention' and metadata stuff (URLs, tags...) stuff if

View File

@ -900,6 +900,31 @@ class Profile extends Managed_DataObject
return parent::update($dataObject); return parent::update($dataObject);
} }
public function getRelSelf()
{
return ['href' => $this->getUrl(),
'text' => common_config('site', 'name'),
'image' => Avatar::urlByProfile($this)];
}
// All the known rel="me", used for the IndieWeb audience
public function getRelMes()
{
$relMes = array();
try {
$relMes[] = $this->getRelSelf();
} catch (InvalidUrlException $e) {
// no valid profile URL available
}
if (common_valid_http_url($this->getHomepage())) {
$relMes[] = ['href' => $this->getHomepage(),
'text' => _('Homepage'),
'image' => null];
}
Event::handle('OtherAccountProfiles', array($this, &$relMes));
return $relMes;
}
function delete($useWhere=false) function delete($useWhere=false)
{ {
// just in case it hadn't been done before... (usually set before adding deluser to queue handling!) // just in case it hadn't been done before... (usually set before adding deluser to queue handling!)

View File

@ -105,6 +105,11 @@ class User_group extends Managed_DataObject
return $this->getProfile()->getNickname(); return $this->getProfile()->getNickname();
} }
public function getFullname()
{
return $this->getProfile()->getFullname();
}
public static function defaultLogo($size) public static function defaultLogo($size)
{ {
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile', static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,50 @@
<?php <?php
// /**
// +----------------------------------------------------------------------+ * Net_Socket
// | PHP Version 4 | *
// +----------------------------------------------------------------------+ * PHP Version 4
// | Copyright (c) 1997-2003 The PHP Group | *
// +----------------------------------------------------------------------+ * Copyright (c) 1997-2013 The PHP Group
// | This source file is subject to version 2.0 of the PHP license, | *
// | that is bundled with this package in the file LICENSE, and is | * This source file is subject to version 2.0 of the PHP license,
// | available at through the world-wide-web at | * that is bundled with this package in the file LICENSE, and is
// | http://www.php.net/license/2_02.txt. | * available at through the world-wide-web at
// | If you did not receive a copy of the PHP license and are unable to | * http://www.php.net/license/2_02.txt.
// | obtain it through the world-wide-web, please send a note to | * If you did not receive a copy of the PHP license and are unable to
// | license@php.net so we can mail you a copy immediately. | * obtain it through the world-wide-web, please send a note to
// +----------------------------------------------------------------------+ * license@php.net so we can mail you a copy immediately.
// | Authors: Stig Bakken <ssb@php.net> | *
// | Chuck Hagenbuch <chuck@horde.org> | * Authors: Stig Bakken <ssb@php.net>
// +----------------------------------------------------------------------+ * Chuck Hagenbuch <chuck@horde.org>
// *
// $Id: Socket.php,v 1.38 2008/02/15 18:24:17 chagenbu Exp $ * @category Net
* @package Net_Socket
* @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 1997-2003 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP 2.02
* @link http://pear.php.net/packages/Net_Socket
*/
require_once 'PEAR.php'; require_once 'PEAR.php';
define('NET_SOCKET_READ', 1); define('NET_SOCKET_READ', 1);
define('NET_SOCKET_WRITE', 2); define('NET_SOCKET_WRITE', 2);
define('NET_SOCKET_ERROR', 4); define('NET_SOCKET_ERROR', 4);
/** /**
* Generalized Socket class. * Generalized Socket class.
* *
* @version 1.1 * @category Net
* @author Stig Bakken <ssb@php.net> * @package Net_Socket
* @author Chuck Hagenbuch <chuck@horde.org> * @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 1997-2003 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP 2.02
* @link http://pear.php.net/packages/Net_Socket
*/ */
class Net_Socket extends PEAR { class Net_Socket extends PEAR
{
/** /**
* Socket file pointer. * Socket file pointer.
* @var resource $fp * @var resource $fp
@ -65,11 +76,11 @@ class Net_Socket extends PEAR {
var $port = 0; var $port = 0;
/** /**
* Number of seconds to wait on socket connections before assuming * Number of seconds to wait on socket operations before assuming
* there's no more data. Defaults to no timeout. * there's no more data. Defaults to no timeout.
* @var integer $timeout * @var integer|float $timeout
*/ */
var $timeout = false; var $timeout = null;
/** /**
* Number of bytes to read at a time in readLine() and * Number of bytes to read at a time in readLine() and
@ -78,23 +89,30 @@ class Net_Socket extends PEAR {
*/ */
var $lineLength = 2048; var $lineLength = 2048;
/**
* The string to use as a newline terminator. Usually "\r\n" or "\n".
* @var string $newline
*/
var $newline = "\r\n";
/** /**
* Connect to the specified port. If called when the socket is * Connect to the specified port. If called when the socket is
* already connected, it disconnects and connects again. * already connected, it disconnects and connects again.
* *
* @param string $addr IP address or host name. * @param string $addr IP address or host name (may be with protocol prefix).
* @param integer $port TCP port number. * @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is * @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests * persistent (kept open between requests
* by the web server). * by the web server).
* @param integer $timeout (optional) How long to wait for data. * @param integer $timeout (optional) Connection socket timeout.
* @param array $options See options for stream_context_create. * @param array $options See options for stream_context_create.
* *
* @access public * @access public
* *
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure. * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
*/ */
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) function connect($addr, $port = 0, $persistent = null,
$timeout = null, $options = null)
{ {
if (is_resource($this->fp)) { if (is_resource($this->fp)) {
@fclose($this->fp); @fclose($this->fp);
@ -103,11 +121,10 @@ class Net_Socket extends PEAR {
if (!$addr) { if (!$addr) {
return $this->raiseError('$addr cannot be empty'); return $this->raiseError('$addr cannot be empty');
} elseif (strspn($addr, '.0123456789') == strlen($addr) || } else if (strspn($addr, ':.0123456789') == strlen($addr)) {
strstr($addr, '/') !== false) { $this->addr = strpos($addr, ':') !== false ? '['.$addr.']' : $addr;
$this->addr = $addr;
} else { } else {
$this->addr = @gethostbyname($addr); $this->addr = $addr;
} }
$this->port = $port % 65536; $this->port = $port % 65536;
@ -116,40 +133,40 @@ class Net_Socket extends PEAR {
$this->persistent = $persistent; $this->persistent = $persistent;
} }
if ($timeout !== null) { $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$this->timeout = $timeout; $errno = 0;
$errstr = '';
$old_track_errors = @ini_set('track_errors', 1);
if ($timeout <= 0) {
$timeout = @ini_get('default_socket_timeout');
} }
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$errno = 0;
$errstr = '';
$old_track_errors = @ini_set('track_errors', 1);
if ($options && function_exists('stream_context_create')) { if ($options && function_exists('stream_context_create')) {
if ($this->timeout) {
$timeout = $this->timeout;
} else {
$timeout = 0;
}
$context = stream_context_create($options); $context = stream_context_create($options);
// Since PHP 5 fsockopen doesn't allow context specification // Since PHP 5 fsockopen doesn't allow context specification
if (function_exists('stream_socket_client')) { if (function_exists('stream_socket_client')) {
$flags = $this->persistent ? STREAM_CLIENT_PERSISTENT : STREAM_CLIENT_CONNECT; $flags = STREAM_CLIENT_CONNECT;
if ($this->persistent) {
$flags = STREAM_CLIENT_PERSISTENT;
}
$addr = $this->addr . ':' . $this->port; $addr = $this->addr . ':' . $this->port;
$fp = stream_socket_client($addr, $errno, $errstr, $timeout, $flags, $context); $fp = stream_socket_client($addr, $errno, $errstr,
$timeout, $flags, $context);
} else { } else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); $fp = @$openfunc($this->addr, $this->port, $errno,
$errstr, $timeout, $context);
} }
} else { } else {
if ($this->timeout) { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout);
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
} else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
}
} }
if (!$fp) { if (!$fp) {
if ($errno == 0 && isset($php_errormsg)) { if ($errno == 0 && !strlen($errstr) && isset($php_errormsg)) {
$errstr = $php_errormsg; $errstr = $php_errormsg;
} }
@ini_set('track_errors', $old_track_errors); @ini_set('track_errors', $old_track_errors);
@ -158,7 +175,7 @@ class Net_Socket extends PEAR {
@ini_set('track_errors', $old_track_errors); @ini_set('track_errors', $old_track_errors);
$this->fp = $fp; $this->fp = $fp;
$this->setTimeout();
return $this->setBlocking($this->blocking); return $this->setBlocking($this->blocking);
} }
@ -179,6 +196,18 @@ class Net_Socket extends PEAR {
return true; return true;
} }
/**
* Set the newline character/sequence to use.
*
* @param string $newline Newline character(s)
* @return boolean True
*/
function setNewline($newline)
{
$this->newline = $newline;
return true;
}
/** /**
* Find out if the socket is in blocking mode. * Find out if the socket is in blocking mode.
* *
@ -196,7 +225,8 @@ class Net_Socket extends PEAR {
* if there is no data available, whereas it will block until there * if there is no data available, whereas it will block until there
* is data for blocking sockets. * is data for blocking sockets.
* *
* @param boolean $mode True for blocking sockets, false for nonblocking. * @param boolean $mode True for blocking sockets, false for nonblocking.
*
* @access public * @access public
* @return mixed true on success or a PEAR_Error instance otherwise * @return mixed true on success or a PEAR_Error instance otherwise
*/ */
@ -207,7 +237,7 @@ class Net_Socket extends PEAR {
} }
$this->blocking = $mode; $this->blocking = $mode;
socket_set_blocking($this->fp, $this->blocking); stream_set_blocking($this->fp, (int)$this->blocking);
return true; return true;
} }
@ -215,25 +245,40 @@ class Net_Socket extends PEAR {
* Sets the timeout value on socket descriptor, * Sets the timeout value on socket descriptor,
* expressed in the sum of seconds and microseconds * expressed in the sum of seconds and microseconds
* *
* @param integer $seconds Seconds. * @param integer $seconds Seconds.
* @param integer $microseconds Microseconds. * @param integer $microseconds Microseconds, optional.
*
* @access public * @access public
* @return mixed true on success or a PEAR_Error instance otherwise * @return mixed True on success or false on failure or
* a PEAR_Error instance when not connected
*/ */
function setTimeout($seconds, $microseconds) function setTimeout($seconds = null, $microseconds = null)
{ {
if (!is_resource($this->fp)) { if (!is_resource($this->fp)) {
return $this->raiseError('not connected'); return $this->raiseError('not connected');
} }
return socket_set_timeout($this->fp, $seconds, $microseconds); if ($seconds === null && $microseconds === null) {
$seconds = (int) $this->timeout;
$microseconds = (int) (($this->timeout - $seconds) * 1000000);
} else {
$this->timeout = $seconds + $microseconds/1000000;
}
if ($this->timeout > 0) {
return stream_set_timeout($this->fp, (int) $seconds, (int) $microseconds);
}
else {
return false;
}
} }
/** /**
* Sets the file buffering size on the stream. * Sets the file buffering size on the stream.
* See php's stream_set_write_buffer for more information. * See php's stream_set_write_buffer for more information.
* *
* @param integer $size Write buffer size. * @param integer $size Write buffer size.
*
* @access public * @access public
* @return mixed on success or an PEAR_Error object otherwise * @return mixed on success or an PEAR_Error object otherwise
*/ */
@ -262,7 +307,8 @@ class Net_Socket extends PEAR {
* </p> * </p>
* *
* @access public * @access public
* @return mixed Array containing information about existing socket resource or a PEAR_Error instance otherwise * @return mixed Array containing information about existing socket
* resource or a PEAR_Error instance otherwise
*/ */
function getStatus() function getStatus()
{ {
@ -270,23 +316,32 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected'); return $this->raiseError('not connected');
} }
return socket_get_status($this->fp); return stream_get_meta_data($this->fp);
} }
/** /**
* Get a specified line of data * Get a specified line of data
* *
* @param int $size Reading ends when size - 1 bytes have been read,
* or a newline or an EOF (whichever comes first).
* If no size is specified, it will keep reading from
* the stream until it reaches the end of the line.
*
* @access public * @access public
* @return $size bytes of data from the socket, or a PEAR_Error if * @return mixed $size bytes of data from the socket, or a PEAR_Error if
* not connected. * not connected. If an error occurs, FALSE is returned.
*/ */
function gets($size) function gets($size = null)
{ {
if (!is_resource($this->fp)) { if (!is_resource($this->fp)) {
return $this->raiseError('not connected'); return $this->raiseError('not connected');
} }
return @fgets($this->fp, $size); if (is_null($size)) {
return @fgets($this->fp);
} else {
return @fgets($this->fp, $size);
}
} }
/** /**
@ -295,7 +350,8 @@ class Net_Socket extends PEAR {
* chunk; if you know the size of the data you're getting * chunk; if you know the size of the data you're getting
* beforehand, this is definitely the way to go. * beforehand, this is definitely the way to go.
* *
* @param integer $size The number of bytes to read from the socket. * @param integer $size The number of bytes to read from the socket.
*
* @access public * @access public
* @return $size bytes of data from the socket, or a PEAR_Error if * @return $size bytes of data from the socket, or a PEAR_Error if
* not connected. * not connected.
@ -312,14 +368,16 @@ class Net_Socket extends PEAR {
/** /**
* Write a specified amount of data. * Write a specified amount of data.
* *
* @param string $data Data to write. * @param string $data Data to write.
* @param integer $blocksize Amount of data to write at once. * @param integer $blocksize Amount of data to write at once.
* NULL means all at once. * NULL means all at once.
* *
* @access public * @access public
* @return mixed If the socket is not connected, returns an instance of PEAR_Error * @return mixed If the socket is not connected, returns an instance of
* If the write succeeds, returns the number of bytes written * PEAR_Error.
* If the write succeeds, returns the number of bytes written.
* If the write fails, returns false. * If the write fails, returns false.
* If the socket times out, returns an instance of PEAR_Error.
*/ */
function write($data, $blocksize = null) function write($data, $blocksize = null)
{ {
@ -328,19 +386,47 @@ class Net_Socket extends PEAR {
} }
if (is_null($blocksize) && !OS_WINDOWS) { if (is_null($blocksize) && !OS_WINDOWS) {
return @fwrite($this->fp, $data); $written = @fwrite($this->fp, $data);
// Check for timeout or lost connection
if (!$written) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
return $meta_data; // PEAR_Error
}
if (!empty($meta_data['timed_out'])) {
return $this->raiseError('timed out');
}
}
return $written;
} else { } else {
if (is_null($blocksize)) { if (is_null($blocksize)) {
$blocksize = 1024; $blocksize = 1024;
} }
$pos = 0; $pos = 0;
$size = strlen($data); $size = strlen($data);
while ($pos < $size) { while ($pos < $size) {
$written = @fwrite($this->fp, substr($data, $pos, $blocksize)); $written = @fwrite($this->fp, substr($data, $pos, $blocksize));
if ($written === false) {
return false; // Check for timeout or lost connection
if (!$written) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
return $meta_data; // PEAR_Error
}
if (!empty($meta_data['timed_out'])) {
return $this->raiseError('timed out');
}
return $written;
} }
$pos += $written; $pos += $written;
} }
@ -349,10 +435,12 @@ class Net_Socket extends PEAR {
} }
/** /**
* Write a line of data to the socket, followed by a trailing "\r\n". * Write a line of data to the socket, followed by a trailing newline.
*
* @param string $data Data to write
* *
* @access public * @access public
* @return mixed fputs result, or an error * @return mixed fwrite() result, or PEAR_Error when not connected
*/ */
function writeLine($data) function writeLine($data)
{ {
@ -360,7 +448,7 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected'); return $this->raiseError('not connected');
} }
return fwrite($this->fp, $data . "\r\n"); return fwrite($this->fp, $data . $this->newline);
} }
/** /**
@ -441,7 +529,7 @@ class Net_Socket extends PEAR {
} }
$string = ''; $string = '';
while (($char = @fread($this->fp, 1)) != "\x00") { while (($char = @fread($this->fp, 1)) != "\x00") {
$string .= $char; $string .= $char;
} }
return $string; return $string;
@ -481,11 +569,13 @@ class Net_Socket extends PEAR {
} }
$line = ''; $line = '';
$timeout = time() + $this->timeout; $timeout = time() + $this->timeout;
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
$line .= @fgets($this->fp, $this->lineLength); $line .= @fgets($this->fp, $this->lineLength);
if (substr($line, -1) == "\n") { if (substr($line, -1) == "\n") {
return rtrim($line, "\r\n"); return rtrim($line, $this->newline);
} }
} }
return $line; return $line;
@ -521,9 +611,9 @@ class Net_Socket extends PEAR {
* Runs the equivalent of the select() system call on the socket * Runs the equivalent of the select() system call on the socket
* with a timeout specified by tv_sec and tv_usec. * with a timeout specified by tv_sec and tv_usec.
* *
* @param integer $state Which of read/write/error to check for. * @param integer $state Which of read/write/error to check for.
* @param integer $tv_sec Number of seconds for timeout. * @param integer $tv_sec Number of seconds for timeout.
* @param integer $tv_usec Number of microseconds for timeout. * @param integer $tv_usec Number of microseconds for timeout.
* *
* @access public * @access public
* @return False if select fails, integer describing which of read/write/error * @return False if select fails, integer describing which of read/write/error
@ -535,8 +625,8 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected'); return $this->raiseError('not connected');
} }
$read = null; $read = null;
$write = null; $write = null;
$except = null; $except = null;
if ($state & NET_SOCKET_READ) { if ($state & NET_SOCKET_READ) {
$read[] = $this->fp; $read[] = $this->fp;
@ -547,7 +637,8 @@ class Net_Socket extends PEAR {
if ($state & NET_SOCKET_ERROR) { if ($state & NET_SOCKET_ERROR) {
$except[] = $this->fp; $except[] = $this->fp;
} }
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { if (false === ($sr = stream_select($read, $write, $except,
$tv_sec, $tv_usec))) {
return false; return false;
} }
@ -567,15 +658,17 @@ class Net_Socket extends PEAR {
/** /**
* Turns encryption on/off on a connected socket. * Turns encryption on/off on a connected socket.
* *
* @param bool $enabled Set this parameter to true to enable encryption * @param bool $enabled Set this parameter to true to enable encryption
* and false to disable encryption. * and false to disable encryption.
* @param integer $type Type of encryption. See * @param integer $type Type of encryption. See stream_socket_enable_crypto()
* http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values. * for values.
* *
* @see http://se.php.net/manual/en/function.stream-socket-enable-crypto.php
* @access public * @access public
* @return false on error, true on success and 0 if there isn't enough data and the * @return false on error, true on success and 0 if there isn't enough data
* user should try again (non-blocking sockets only). A PEAR_Error object * and the user should try again (non-blocking sockets only).
* is returned if the socket is not connected * A PEAR_Error object is returned if the socket is not
* connected
*/ */
function enableCrypto($enabled, $type) function enableCrypto($enabled, $type)
{ {
@ -585,7 +678,8 @@ class Net_Socket extends PEAR {
} }
return @stream_socket_enable_crypto($this->fp, $enabled, $type); return @stream_socket_enable_crypto($this->fp, $enabled, $type);
} else { } else {
return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0'); $msg = 'Net_Socket::enableCrypto() requires php version >= 5.1.0';
return $this->raiseError($msg);
} }
} }

View File

@ -93,9 +93,9 @@ function handleError($error)
return; return;
} }
$logmsg = "PEAR error: " . $error->getMessage(); $logmsg = "Exception thrown: " . _ve($error->getMessage());
if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) { if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) {
$logmsg .= " : ". $error->toText(); $logmsg .= " PEAR: ". $error->toText();
} }
// DB queries often end up with a lot of newlines; merge to a single line // DB queries often end up with a lot of newlines; merge to a single line
// for easier grepability... // for easier grepability...

View File

@ -241,6 +241,7 @@ $default =
'application/vnd.oasis.opendocument.text-web' => 'oth', 'application/vnd.oasis.opendocument.text-web' => 'oth',
'application/pdf' => 'pdf', 'application/pdf' => 'pdf',
'application/zip' => 'zip', 'application/zip' => 'zip',
'application/x-go-sgf' => 'sgf',
'application/xml' => 'xml', 'application/xml' => 'xml',
'image/png' => 'png', 'image/png' => 'png',
'image/jpeg' => 'jpg', 'image/jpeg' => 'jpg',
@ -266,6 +267,10 @@ $default =
'show_html' => false, // show (filtered) text/html attachments (and oEmbed HTML etc.). Doesn't affect AJAX calls. 'show_html' => false, // show (filtered) text/html attachments (and oEmbed HTML etc.). Doesn't affect AJAX calls.
'show_thumbs' => true, // show thumbnails in notice lists for uploaded images, and photos and videos linked remotely that provide oEmbed info 'show_thumbs' => true, // show thumbnails in notice lists for uploaded images, and photos and videos linked remotely that provide oEmbed info
'process_links' => true, // check linked resources for embeddable photos and videos; this will hit referenced external web sites when processing new messages. 'process_links' => true, // check linked resources for embeddable photos and videos; this will hit referenced external web sites when processing new messages.
'extblacklist' => [
'php' => 'phps',
'exe' => false, // this would deny any uploads to keep the "exe" file extension
],
), ),
'thumbnail' => 'thumbnail' =>
array('crop' => false, // overridden to true if thumb height === null array('crop' => false, // overridden to true if thumb height === null

View File

@ -62,6 +62,11 @@ class Feed
$this->title = $title; $this->title = $title;
} }
function getUrl()
{
return $this->url;
}
function mimeType() function mimeType()
{ {
switch ($this->type) { switch ($this->type) {

View File

@ -253,15 +253,15 @@ class MediaFile
File::respectsQuota($scoped, $_FILES[$param]['size']); File::respectsQuota($scoped, $_FILES[$param]['size']);
$mimetype = self::getUploadedMimeType($_FILES[$param]['tmp_name'], $_FILES[$param]['name']); $mimetype = self::getUploadedMimeType($_FILES[$param]['tmp_name'], $_FILES[$param]['name']);
$basename = basename($_FILES[$param]['name']);
switch (common_config('attachments', 'filename_base')) { switch (common_config('attachments', 'filename_base')) {
case 'upload': case 'upload':
$basename = basename($_FILES[$param]['name']);
$filename = File::filename($scoped, $basename, $mimetype); $filename = File::filename($scoped, $basename, $mimetype);
break; break;
case 'hash': case 'hash':
default: default:
$filename = strtolower($filehash) . '.' . File::guessMimeExtension($mimetype); $filename = strtolower($filehash) . '.' . File::guessMimeExtension($mimetype, $basename);
} }
$filepath = File::path($filename); $filepath = File::path($filename);

View File

@ -76,6 +76,16 @@ class Nickname
*/ */
const MAX_LEN = 64; const MAX_LEN = 64;
/**
* Regex with non-capturing group that matches whitespace and some
* characters which are allowed right before an @ or ! when mentioning
* other users. Like: 'This goes out to:@mmn (@chimo too) (!awwyiss).'
*
* FIXME: Make this so you can have multiple whitespace but not multiple
* parenthesis or something. '(((@n_n@)))' might as well be a smiley.
*/
const BEFORE_MENTIONS = '(?:^|[\s\.\,\:\;\[\(]+)';
/** /**
* Nice simple check of whether the given string is a valid input nickname, * Nice simple check of whether the given string is a valid input nickname,
* which can be normalized into an internally canonical form. * which can be normalized into an internally canonical form.

View File

@ -34,6 +34,18 @@ abstract class NoticestreamAction extends ProfileAction
// pass by default // pass by default
} }
public function extraHeaders()
{
parent::extraHeaders();
foreach ($this->getFeeds() as $feed) {
header('Link: <'.htmlspecialchars($feed->getUrl()).'>;' .
' rel="'.htmlspecialchars($feed->rel()).'";' .
' type="'.htmlspecialchars($feed->mimeType()).'"',
false // don't overwrite previous headers of this sort
);
}
}
// this fetches the NoticeStream // this fetches the NoticeStream
abstract public function getStream(); abstract public function getStream();
} }

View File

@ -580,7 +580,7 @@ function common_canonical_email($email)
return $email; return $email;
} }
function common_purify($html) function common_purify($html, array $args=array())
{ {
require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php'; require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php';
@ -588,6 +588,10 @@ function common_purify($html)
$cfg->set('Attr.AllowedRel', ['bookmark', 'directory', 'enclosure', 'home', 'license', 'nofollow', 'payment', 'tag']); // http://microformats.org/wiki/rel $cfg->set('Attr.AllowedRel', ['bookmark', 'directory', 'enclosure', 'home', 'license', 'nofollow', 'payment', 'tag']); // http://microformats.org/wiki/rel
$cfg->set('HTML.ForbiddenAttributes', array('style')); // id, on* etc. are already filtered by default $cfg->set('HTML.ForbiddenAttributes', array('style')); // id, on* etc. are already filtered by default
$cfg->set('URI.AllowedSchemes', array_fill_keys(common_url_schemes(), true)); $cfg->set('URI.AllowedSchemes', array_fill_keys(common_url_schemes(), true));
if (isset($args['URI.Base'])) {
$cfg->set('URI.Base', $args['URI.Base']); // if null this is like unsetting it I presume
$cfg->set('URI.MakeAbsolute', !is_null($args['URI.Base'])); // if we have a URI base, convert relative URLs to absolute ones.
}
// Remove more elements than what the default filter removes, default in GNU social are remotely // Remove more elements than what the default filter removes, default in GNU social are remotely
// linked resources such as img, video, audio // linked resources such as img, video, audio
@ -800,7 +804,7 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
// @#tag => mention of all subscriptions tagged 'tag' // @#tag => mention of all subscriptions tagged 'tag'
preg_match_all('/(?:^|[\s\.\,\:\;]+)@#([\pL\pN_\-\.]{1,64})/', preg_match_all('/'.Nickname::BEFORE_MENTIONS.'@#([\pL\pN_\-\.]{1,64})/',
$text, $hmatches, PREG_OFFSET_CAPTURE); $text, $hmatches, PREG_OFFSET_CAPTURE);
foreach ($hmatches[1] as $hmatch) { foreach ($hmatches[1] as $hmatch) {
$tag = common_canonical_tag($hmatch[0]); $tag = common_canonical_tag($hmatch[0]);
@ -822,7 +826,7 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
'url' => $url); 'url' => $url);
} }
preg_match_all('/(?:^|[\s\.\,\:\;]+)!(' . Nickname::DISPLAY_FMT . ')/', preg_match_all('/'.Nickname::BEFORE_MENTIONS.'!(' . Nickname::DISPLAY_FMT . ')/',
$text, $hmatches, PREG_OFFSET_CAPTURE); $text, $hmatches, PREG_OFFSET_CAPTURE);
foreach ($hmatches[1] as $hmatch) { foreach ($hmatches[1] as $hmatch) {
$nickname = Nickname::normalize($hmatch[0]); $nickname = Nickname::normalize($hmatch[0]);
@ -866,7 +870,7 @@ function common_find_mentions_raw($text)
$atmatches = array(); $atmatches = array();
// the regexp's "(?!\@)" makes sure it doesn't matches the single "@remote" in "@remote@server.com" // the regexp's "(?!\@)" makes sure it doesn't matches the single "@remote" in "@remote@server.com"
preg_match_all('/(?:^|\s+)@(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/', preg_match_all('/'.Nickname::BEFORE_MENTIONS.'@(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/',
$text, $text,
$atmatches, $atmatches,
PREG_OFFSET_CAPTURE); PREG_OFFSET_CAPTURE);

View File

@ -92,7 +92,7 @@ class AccountManagerPlugin extends Plugin
$versions[] = array('name' => 'AccountManager', $versions[] = array('name' => 'AccountManager',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:AccountManager', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AccountManager',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The Account Manager plugin implements the Account Manager specification.')); _m('The Account Manager plugin implements the Account Manager specification.'));

View File

@ -344,7 +344,7 @@ class ActivityPlugin extends Plugin
$versions[] = array('name' => 'Activity', $versions[] = array('name' => 'Activity',
'version' => self::VERSION, 'version' => self::VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Activity', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Activity',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Emits notices when social activities happen.')); _m('Emits notices when social activities happen.'));

View File

@ -220,7 +220,7 @@ class ActivitySpamPlugin extends Plugin
$versions[] = array('name' => 'ActivitySpam', $versions[] = array('name' => 'ActivitySpam',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:ActivitySpam', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ActivitySpam',
'description' => 'description' =>
_m('Test notices against the Activity Spam service.')); _m('Test notices against the Activity Spam service.'));
return true; return true;

23
plugins/ActivitySpam/README Executable file
View File

@ -0,0 +1,23 @@
The ActivitySpam plugin is a spam filter for GNU social.
It needs to connect to a activityspam server.
You can run one yourself: https://github.com/e14n/activityspam
Or use a public instance ( ex: https://spamicity.info/ )
Installation
============
add "addPlugin('ActivitySpam');"
to the bottom of your config.php
Settings
========
server: URL to the activityspam server
consumerkey: The "key" provided by the activityspam server after you've registered and configured an account.
secret: The "secret" provided by the activityspam server after you've registered and configured an account
Example
=======
$config['activityspam']['server'] = 'https://spamicity.info/';
$config['activityspam']['consumerkey'] = 'CONSUMER_KEY';
$config['activityspam']['secret'] = 'SECRET';
addPlugin('ActivitySpam');

View File

@ -273,7 +273,7 @@ class AnonymousFavePlugin extends Plugin
*/ */
function onPluginVersion(array &$versions) function onPluginVersion(array &$versions)
{ {
$url = 'http://status.net/wiki/Plugin:AnonymousFave'; $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AnonymousFave';
$versions[] = array('name' => 'AnonymousFave', $versions[] = array('name' => 'AnonymousFave',
'version' => ANONYMOUS_FAVE_PLUGIN_VERSION, 'version' => ANONYMOUS_FAVE_PLUGIN_VERSION,

14
plugins/AnonymousFave/README Executable file
View File

@ -0,0 +1,14 @@
The Anonymous Fave plugin allows anonymous (not logged in) users to favorite notices
Installation
============
add "addPlugin('AnonymousFave');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('AnonymousFave');

11
plugins/AntiBrute/README Executable file
View File

@ -0,0 +1,11 @@
The AntiBrute plugin implements a time delay between successive failed login
attempts to slow down brute force attacks ( https://en.wikipedia.org/wiki/Brute-force_attack#Countermeasures ).
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -80,7 +80,7 @@ class ApiLoggerPlugin extends Plugin
$versions[] = array('name' => 'ApiLogger', $versions[] = array('name' => 'ApiLogger',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber', 'author' => 'Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:ApiLogger', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ApiLogger',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Allows random sampling of API requests.')); _m('Allows random sampling of API requests.'));

18
plugins/ApiLogger/README Executable file
View File

@ -0,0 +1,18 @@
The ApiLogger plugin allows random sampling of API requests.
Installation
============
add "addPlugin('ApiLogger');"
to the bottom of your config.php
Settings
========
frequency: How often to sample (number between 0.0 and 1.0 representing
percentage -- e.g.: 0.1 will check about 10% of hits). Default 1.0
Example
=======
addPlugin('ApiLogger', array(
'frequency' => 1.0
));

View File

@ -155,7 +155,7 @@ class AuthCryptPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'AuthCrypt', $versions[] = array('name' => 'AuthCrypt',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Mikael Nordfeldth', 'author' => 'Mikael Nordfeldth',
'homepage' => 'http://status.net/wiki/Plugin:AuthCrypt', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AuthCrypt',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Authentication and password hashing with crypt()')); _m('Authentication and password hashing with crypt()'));

View File

@ -61,7 +61,7 @@ class AutoSandboxPlugin extends Plugin
$versions[] = array('name' => 'AutoSandbox', $versions[] = array('name' => 'AutoSandbox',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Sean Carmody', 'author' => 'Sean Carmody',
'homepage' => 'http://status.net/wiki/Plugin:AutoSandbox', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AutoSandbox',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Automatically sandboxes newly registered members.')); _m('Automatically sandboxes newly registered members.'));

View File

@ -57,7 +57,7 @@ class AutocompletePlugin extends Plugin
$versions[] = array('name' => 'Autocomplete', $versions[] = array('name' => 'Autocomplete',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:Autocomplete', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Autocomplete',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The autocomplete plugin adds autocompletion for @ replies.')); _m('The autocomplete plugin adds autocompletion for @ replies.'));

View File

@ -50,7 +50,7 @@ class AwesomenessPlugin extends Plugin
'name' => 'Awesomeness', 'name' => 'Awesomeness',
'version' => self::VERSION, 'version' => self::VERSION,
'author' => 'Jeroen De Dauw', 'author' => 'Jeroen De Dauw',
'homepage' => 'http://status.net/wiki/Plugin:Awesomeness', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Awesomeness',
// TRANS: Plugin description for a sample plugin. // TRANS: Plugin description for a sample plugin.
'rawdescription' => _m('The Awesomeness plugin adds additional awesomeness ' . 'rawdescription' => _m('The Awesomeness plugin adds additional awesomeness ' .
'to a StatusNet installation.' 'to a StatusNet installation.'

14
plugins/Awesomeness/README Executable file
View File

@ -0,0 +1,14 @@
Fun sample plugin: tweaks input data and adds a 'Cornify' ( http://www.cornify.com ) widget to sidebar.
Installation
============
add "addPlugin('Awesomeness');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Awesomeness');

View File

@ -150,7 +150,7 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
$versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName), $versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName),
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews, Brion Vibber', 'author' => 'Craig Andrews, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BitlyUrl',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly"). // TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly").
sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'), sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),

View File

@ -297,7 +297,7 @@ class BlacklistPlugin extends Plugin
'version' => self::VERSION, 'version' => self::VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'homepage' =>
'http://status.net/wiki/Plugin:Blacklist', 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Blacklist',
'description' => 'description' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Keeps a blacklist of forbidden nickname '. _m('Keeps a blacklist of forbidden nickname '.

17
plugins/Blacklist/README Executable file
View File

@ -0,0 +1,17 @@
Plugin to prevent use of nicknames or URLs on a blacklist
Installation
============
add "addPlugin('Blacklist');"
to the bottom of your config.php
Settings
========
nicknames: Array of nicknames to blacklist
urls: Array of URLs to blacklist
Example
=======
$config['blacklist']['nicknames'] = array('bad_nickname', 'worse_nickname');
$config['blacklist']['urls'] = array('http://example.org', 'http://example.net');
addPlugin('Blacklist');

View File

@ -122,7 +122,7 @@ class BlankAdPlugin extends UAPPlugin
$versions[] = array('name' => 'BlankAd', $versions[] = array('name' => 'BlankAd',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:BlankAdPlugin', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BlankAdPlugin',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Plugin for testing ad layout.')); _m('Plugin for testing ad layout.'));

14
plugins/BlankAd/README Executable file
View File

@ -0,0 +1,14 @@
Plugin for testing ad layout
This plugin uses the UAPPlugin framework to output ad content. However,
its ad content is just images with one red pixel stretched to the
right size. It's mostly useful for debugging theme layout.
To use this plugin, set the parameter for the ad size you want to use
to true (or anything non-null).
Example
=======
To make a leaderboard:
addPlugin('BlankAd', array('leaderboard' => true));

View File

@ -153,7 +153,7 @@ class BlogspamNetPlugin extends Plugin
$versions[] = array('name' => 'BlogspamNet', $versions[] = array('name' => 'BlogspamNet',
'version' => BLOGSPAMNETPLUGIN_VERSION, 'version' => BLOGSPAMNETPLUGIN_VERSION,
'author' => 'Evan Prodromou, Brion Vibber', 'author' => 'Evan Prodromou, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BlogspamNet',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Plugin to check submitted notices with blogspam.net.')); _m('Plugin to check submitted notices with blogspam.net.'));

22
plugins/BlogspamNet/README Executable file
View File

@ -0,0 +1,22 @@
Plugin to check submitted notices with blogspam.net
When new notices are saved, we check their text with blogspam.net (or
a compatible service).
Blogspam.net is supposed to catch blog comment spam. Some of its tests
(min/max size, bayesian match) gave a lot of false positives so those
tests are turned off by default.
Installation
============
add "addPlugin('BlogspamNet');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('BlogspamNet');

View File

@ -101,7 +101,7 @@ class CacheLogPlugin extends Plugin
$versions[] = array('name' => 'CacheLog', $versions[] = array('name' => 'CacheLog',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:CacheLog', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/CacheLog',
'description' => 'description' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Log reads and writes to the cache.')); _m('Log reads and writes to the cache.'));

23
plugins/CacheLog/README Executable file
View File

@ -0,0 +1,23 @@
Log cache access
Adds "Cache MISS, Cache HIT, set cache value, delete cache value" etc.
information to the log file.
Note: entries are logged at the LOG_INFO level.
Installation
============
add "addPlugin('CacheLog');"
to the bottom of your config.php
Settings
========
none
Example
=======
Note that since most caching plugins return false for StartCache*
methods, you should add this plugin before them, i.e.
addPlugin('CacheLog');
addPlugin('XCache');

View File

@ -152,7 +152,7 @@ class CasAuthenticationPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'CAS Authentication', $versions[] = array('name' => 'CAS Authentication',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:CasAuthentication', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/CasAuthentication',
// TRANS: Plugin description. CAS is Central Authentication Service. // TRANS: Plugin description. CAS is Central Authentication Service.
'rawdescription' => _m('The CAS Authentication plugin allows for StatusNet to handle authentication through CAS (Central Authentication Service).')); 'rawdescription' => _m('The CAS Authentication plugin allows for StatusNet to handle authentication through CAS (Central Authentication Service).'));
return true; return true;

View File

@ -59,7 +59,7 @@ class ClientSideShortenPlugin extends Plugin
$versions[] = array('name' => 'Shorten', $versions[] = array('name' => 'Shorten',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:ClientSideShorten', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ClientSideShorten',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('ClientSideShorten causes the web interface\'s notice form to automatically shorten URLs as they entered, and before the notice is submitted.')); _m('ClientSideShorten causes the web interface\'s notice form to automatically shorten URLs as they entered, and before the notice is submitted.'));

View File

@ -3,5 +3,5 @@ shorten URLs as they entered, and before the notice is submitted.
Installation Installation
============ ============
Add "addPlugin('ClientSideShorten');" to the bottom of your config.php This plugin is enabled by default
That's it!

View File

@ -109,7 +109,7 @@ class CometPlugin extends RealtimePlugin
$versions[] = array('name' => 'Comet', $versions[] = array('name' => 'Comet',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Comet', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Comet',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description message. Bayeux is a protocol for transporting asynchronous messages // TRANS: Plugin description message. Bayeux is a protocol for transporting asynchronous messages
// TRANS: and Comet is a web application model. // TRANS: and Comet is a web application model.

15
plugins/ConversationTree/README Executable file
View File

@ -0,0 +1,15 @@
The ConversationTree plugin displays conversation replies in a hierarchical
manner like StatusNet pre-v1.0 used to.
Installation
============
add "addPlugin('ConversationTree');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('ConversationTree');

12
plugins/Cronish/README Executable file
View File

@ -0,0 +1,12 @@
The Cronish plugin executes events on a near-minutely/hour/day/week basis.
Intervals are approximate and will vary depending on how busy
the instance is.
Installation
============
This plugin is enabled by default
Settings
========
none

17
plugins/Diaspora/README Executable file
View File

@ -0,0 +1,17 @@
The Diaspora plugin allows GNU social users to subscribe to Diaspora feeds
Note: The feeds are read-only at the moment. That is, replying to an entry
coming from Diaspora will not propagate to Diaspora.
Installation
============
add "addPlugin('Diaspora');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Diaspora');

10
plugins/DirectMessage/README Executable file
View File

@ -0,0 +1,10 @@
The DirectMessage plugin allows users to send Direct Message to other local users
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -246,7 +246,7 @@ class DirectionDetectorPlugin extends Plugin {
* plugin details * plugin details
*/ */
function onPluginVersion(array &$versions){ function onPluginVersion(array &$versions){
$url = 'http://status.net/wiki/Plugin:DirectionDetector'; $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DirectionDetector';
$versions[] = array( $versions[] = array(
'name' => 'Direction detector', 'name' => 'Direction detector',

View File

@ -0,0 +1,15 @@
The DirectionDetector plugin detects notices with RTL content and displays them
in the correct direction.
Installation
============
add "addPlugin('DirectionDetector');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('DirectionDetector');

View File

@ -257,7 +257,7 @@ class DirectoryPlugin extends Plugin
'name' => 'Directory', 'name' => 'Directory',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Zach Copley', 'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:Directory', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Directory',
// TRANS: Plugin description. // TRANS: Plugin description.
'rawdescription' => _m('Add a user directory.') 'rawdescription' => _m('Add a user directory.')
); );

15
plugins/Directory/README Executable file
View File

@ -0,0 +1,15 @@
The Directory plugin adds a user directory (list)
Installation
============
This plugin is enabled by default except on single-user instances, in which
case, it can be enabled by adding "addPlugin('Directory');" to the bottom of
your config.php
Settings
========
none
Example
=======
addPlugin('Directory');

View File

@ -166,7 +166,7 @@ class DiskCachePlugin extends Plugin
$versions[] = array('name' => 'DiskCache', $versions[] = array('name' => 'DiskCache',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DiskCache', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DiskCache',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Plugin to implement cache interface with disk files.')); _m('Plugin to implement cache interface with disk files.'));

17
plugins/DiskCache/README Executable file
View File

@ -0,0 +1,17 @@
The DiskCache plugin implements cache interface with disk files.
Installation
============
add "addPlugin('DiskCache');"
to the bottom of your config.php
Settings
========
root: Directory where to save cache data. Default /tmp
Example
=======
addPlugin('DiskCache', array(
'root' => '/tmp'
));

View File

@ -195,7 +195,7 @@ class DomainStatusNetworkPlugin extends Plugin
$versions[] = array('name' => 'DomainStatusNetwork', $versions[] = array('name' => 'DomainStatusNetwork',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DomainStatusNetwork', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DomainStatusNetwork',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('A plugin that maps a single status_network to an email domain.')); _m('A plugin that maps a single status_network to an email domain.'));

View File

@ -0,0 +1,24 @@
The DomainStatusNetwork plugin adds tools to map one status_network to one
email domain in a multi-site installation.
Relates to "status_network":
* /scripts/setup.cfg.sample
* /scripts/setup_status_network.sh
* /scripts/settag.php
* /scripts/delete_status_network.sh
* /scripts/move_status_network.sh
Installation
============
add "addPlugin('DomainStatusNetwork');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('DomainStatusNetwork');

View File

@ -272,7 +272,7 @@ class DomainWhitelistPlugin extends Plugin
$versions[] = array('name' => 'DomainWhitelist', $versions[] = array('name' => 'DomainWhitelist',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou, Zach Copley', 'author' => 'Evan Prodromou, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:DomainWhitelist', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DomainWhitelist',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Restrict domains for email users.')); _m('Restrict domains for email users.'));

16
plugins/DomainWhitelist/README Executable file
View File

@ -0,0 +1,16 @@
The DomainWhitelist plugin restricts the email addresses in a domain to a
select whitelist.
Installation
============
add "addPlugin('DomainWhitelist');"
to the bottom of your config.php
Settings
========
whitelist: An array of whitelisted domains
Example
=======
$config['email']['whitelist'] = array('example.org', 'example.net');
addPlugin('DomainWhitelist');

View File

@ -54,7 +54,7 @@ class EmailAuthenticationPlugin extends Plugin
$versions[] = array('name' => 'Email Authentication', $versions[] = array('name' => 'Email Authentication',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:EmailAuthentication', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailAuthentication',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The Email Authentication plugin allows users to login using their email address.')); _m('The Email Authentication plugin allows users to login using their email address.'));

View File

@ -5,4 +5,9 @@ nickname and the provided password is checked.
Installation Installation
============ ============
add "addPlugin('emailAuthentication');" to the bottom of your config.php. This plugin is enabled by default
Settings
========
none

View File

@ -177,7 +177,7 @@ class EmailRegistrationPlugin extends Plugin
$versions[] = array('name' => 'EmailRegistration', $versions[] = array('name' => 'EmailRegistration',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:EmailRegistration', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailRegistration',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Use email only for registration.')); _m('Use email only for registration.'));

View File

@ -0,0 +1,25 @@
The EmailRegistration plugin allows user registration with just an email
address.
When users register, the part before '@' in their email address will become
their nickname/username (normalized). In case of collisions, a auto-increment
number will be added to the username.
For example, if someone registers with "user@example.org", their username
will be "user". If someone else registers with "user@example.net", their
username will be user1, and so on.
Installation
============
add "addPlugin('EmailRegistration');"
to the bottom of your config.php
Note: This plugin is enabled by default on private instances.
Settings
========
none
Example
=======
addPlugin('EmailRegistration');

View File

@ -185,7 +185,7 @@ class EmailReminderPlugin extends Plugin
'name' => 'EmailReminder', 'name' => 'EmailReminder',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Zach Copley', 'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:EmailReminder', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailReminder',
// TRANS: Plugin description. // TRANS: Plugin description.
'rawdescription' => _m('Send email reminders for various things.') 'rawdescription' => _m('Send email reminders for various things.')
); );

21
plugins/EmailReminder/README Executable file
View File

@ -0,0 +1,21 @@
The EmailReminder plugin sends email reminders about various things
It will send reminder emails to email addresses that have been invited
but haven't registered yet.
It will also send reminders to email addresses that have registered but
haven't verified their email address yet.
Installation
============
add "addPlugin('EmailReminder');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('EmailReminder');

View File

@ -71,7 +71,7 @@ class EmailSummaryPlugin extends Plugin
$versions[] = array('name' => 'EmailSummary', $versions[] = array('name' => 'EmailSummary',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:EmailSummary', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailSummary',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Send an email summary of the inbox to users.')); _m('Send an email summary of the inbox to users.'));

22
plugins/EmailSummary/README Executable file
View File

@ -0,0 +1,22 @@
The EmailSummary plugin sends an email summary of the inbox to users in the
network.
After enabling the plugin, users will have an option to enable/disable the
feature in their "Email Settings" section.
You can run ./script/sendemailsummary.php to send emails (options are
documented in the file). You can run this script automatically via your OS's
cron mechanism to send emails regularly.
Installation
============
add "addPlugin('EmailSummary');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('EmailSummary');

View File

@ -102,7 +102,7 @@ class EventPlugin extends ActivityVerbHandlerPlugin
$versions[] = array('name' => 'Event', $versions[] = array('name' => 'Event',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Event', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Event',
'description' => 'description' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Event invitations and RSVPs.')); _m('Event invitations and RSVPs.'));

10
plugins/Event/README Normal file
View File

@ -0,0 +1,10 @@
The Event plugin adds event invitations and RSVPs types of notices.
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -35,7 +35,7 @@ class ExtendedProfilePlugin extends Plugin
'name' => 'ExtendedProfile', 'name' => 'ExtendedProfile',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber, Samantha Doherty, Zach Copley', 'author' => 'Brion Vibber, Samantha Doherty, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:ExtendedProfile', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ExtendedProfile',
// TRANS: Plugin description. // TRANS: Plugin description.
'rawdescription' => _m('UI extensions for additional profile fields.') 'rawdescription' => _m('UI extensions for additional profile fields.')
); );

View File

@ -0,0 +1,23 @@
The ExtendedProfile plugin adds additional profile fields such as:
* Phone
* IM
* Website
* Work experience
* Education
Installation
============
add "addPlugin('ExtendedProfile');"
to the bottom of your config.php
Note: This plugin is enabled by default on private instances.
Settings
========
none
Example
=======
addPlugin('ExtendedProfile');

View File

@ -594,7 +594,7 @@ ENDOFSCRIPT;
'name' => 'Facebook Bridge', 'name' => 'Facebook Bridge',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews, Zach Copley', 'author' => 'Craig Andrews, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:FacebookBridge', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/FacebookBridge',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('A plugin for integrating StatusNet with Facebook.') _m('A plugin for integrating StatusNet with Facebook.')

11
plugins/Favorite/README Normal file
View File

@ -0,0 +1,11 @@
The Favorite plugin adds the ability to mark a notice as a "favorite"
(i.e. "like").
Installation
============
This plugin is enabled by default
Settings
========
none

16
plugins/FeedPoller/README Normal file
View File

@ -0,0 +1,16 @@
The FeedPoller plugin allows users to subscribe to non-PuSH-enabled feeds
by regularly polling the source for new content.
Installation
============
add "addPlugin('FeedPoller');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('FeedPoller');

View File

@ -170,7 +170,7 @@ class FollowEveryonePlugin extends Plugin
$versions[] = array('name' => 'FollowEveryone', $versions[] = array('name' => 'FollowEveryone',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:FollowEveryone', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/FollowEveryone',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('New users follow everyone at registration and are followed in return.')); _m('New users follow everyone at registration and are followed in return.'));

View File

@ -0,0 +1,16 @@
The FollowEveryone plugin makes it so that when a new user registers, all
existing users follow them automatically.
Installation
============
add "addPlugin('FollowEveryone');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('FollowEveryone');

View File

@ -107,7 +107,7 @@ class ForceGroupPlugin extends Plugin
*/ */
function onPluginVersion(array &$versions) function onPluginVersion(array &$versions)
{ {
$url = 'http://status.net/wiki/Plugin:ForceGroup'; $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ForceGroup';
$versions[] = array('name' => 'ForceGroup', $versions[] = array('name' => 'ForceGroup',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,

16
plugins/ForceGroup/README Normal file
View File

@ -0,0 +1,16 @@
The ForceGroup plugin allows forced group memberships and forces all notices
to appear in groups that users were forced in.
Installation
============
add "addPlugin('ForceGroup');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('ForceGroup');

View File

View File

View File

View File

@ -121,7 +121,7 @@ class GeoURLPlugin extends Plugin
$versions[] = array('name' => 'GeoURL', $versions[] = array('name' => 'GeoURL',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:GeoURL', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GeoURL',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Ping <a href="http://geourl.org/">GeoURL</a> when '. _m('Ping <a href="http://geourl.org/">GeoURL</a> when '.

19
plugins/GeoURL/README Normal file
View File

@ -0,0 +1,19 @@
The GeoURL plugin add extra <meta> headers for certain pages that geourl.org
understands and pings geourl.org when those pages are created.
Note: The third-party service that this plugin depends on (geourl.org) seems to
be dead.
Installation
============
add "addPlugin('GeoURL');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GeoURL');

View File

@ -492,7 +492,7 @@ class GeonamesPlugin extends Plugin
$versions[] = array('name' => 'Geonames', $versions[] = array('name' => 'Geonames',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Geonames', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Geonames',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Uses <a href="http://geonames.org/">Geonames</a> service to get human-readable '. _m('Uses <a href="http://geonames.org/">Geonames</a> service to get human-readable '.

19
plugins/Geonames/README Normal file
View File

@ -0,0 +1,19 @@
The Geonames plugin uses geonames.org to get human-readable names for locations
based on user-provided lat/long pairs.
The human-readable names appear after notices that have a lat/long location
attached to them.
Installation
============
add "addPlugin('Geonames');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Geonames');

View File

@ -67,7 +67,7 @@ class GroupFavoritedPlugin extends Plugin
*/ */
function onPluginVersion(array &$versions) function onPluginVersion(array &$versions)
{ {
$url = 'http://status.net/wiki/Plugin:GroupFavorited'; $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GroupFavorited';
$versions[] = array('name' => 'GroupFavorited', $versions[] = array('name' => 'GroupFavorited',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,

View File

@ -0,0 +1,15 @@
The GroupFavorited plugin adds a menu item for popular notices in groups.
Installation
============
add "addPlugin('GroupFavorited');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GroupFavorited');

View File

@ -410,7 +410,7 @@ class GroupPrivateMessagePlugin extends Plugin
$versions[] = array('name' => 'GroupPrivateMessage', $versions[] = array('name' => 'GroupPrivateMessage',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:GroupPrivateMessage', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GroupPrivateMessage',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('Allow posting private messages to groups.')); _m('Allow posting private messages to groups.'));

View File

@ -0,0 +1,15 @@
The GroupPrivateMessage plugin allows users to send private messages to a group.
Installation
============
add "addPlugin('GroupPrivateMessage');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GroupPrivateMessage');

View File

@ -0,0 +1,21 @@
The ImageMagick plugin handles more kinds of image formats for thumbnails,
thanks to ImageMagick.
Note: This plugin depends on php5-imagick
Installation
============
add "addPlugin('ImageMagick');"
to the bottom of your config.php
Settings
========
animated: Whether to resize animated GIFs.
Note: We are not infinitely fast, so resizing animated GIFs is _not_ recommended.
Example
=======
$config['thumbnail']['animated'] = true;
addPlugin('ImageMagick');

View File

@ -81,7 +81,7 @@ class ImapPlugin extends Plugin
$versions[] = array('name' => 'IMAP', $versions[] = array('name' => 'IMAP',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:IMAP', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/IMAP',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The IMAP plugin allows for StatusNet to check a POP or IMAP mailbox for incoming mail containing user posts.')); _m('The IMAP plugin allows for StatusNet to check a POP or IMAP mailbox for incoming mail containing user posts.'));

View File

@ -172,7 +172,7 @@ class InProcessCachePlugin extends Plugin
*/ */
function onPluginVersion(array &$versions) function onPluginVersion(array &$versions)
{ {
$url = 'http://status.net/wiki/Plugin:InProcessCache'; $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/InProcessCache';
$versions[] = array('name' => 'InProcessCache', $versions[] = array('name' => 'InProcessCache',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,

View File

@ -0,0 +1,23 @@
The InProcessCache plugin adds an extra level of in-process caching to any
regular cache system like APC, XCache, or Memcache.
Installation
============
add "addPlugin('InProcessCache');"
to the bottom of your config.php
Settings
========
stats: Whether to dump statistics (cache size, etc) in the log file.
Note: entries are logged at the LOG_INFO level.
Example
=======
Note: since most caching plugins return false for StartCache* methods, you
should add this plugin before them, i.e.
$config['inprocess']['stats'] = true;
addPlugin('InProcessCache');
addPlugin('XCache');

View File

@ -46,7 +46,7 @@ class InfiniteScrollPlugin extends Plugin
$versions[] = array('name' => 'InfiniteScroll', $versions[] = array('name' => 'InfiniteScroll',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:InfiniteScroll', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/InfiniteScroll',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin dscription. // TRANS: Plugin dscription.
_m('Infinite Scroll adds the following functionality to your StatusNet installation: When a user scrolls towards the bottom of the page, the next page of notices is automatically retrieved and appended. This means they never need to click "Next Page", which dramatically increases stickiness.')); _m('Infinite Scroll adds the following functionality to your StatusNet installation: When a user scrolls towards the bottom of the page, the next page of notices is automatically retrieved and appended. This means they never need to click "Next Page", which dramatically increases stickiness.'));

14
plugins/LRDD/README Normal file
View File

@ -0,0 +1,14 @@
The LRDD plugin implements Link-based Resource Descriptor Discovery
based on RFC6415, Web Host Metadata, i.e. the predecessor to WebFinger resource
discovery.
See: http://tools.ietf.org/html/rfc6415
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -147,7 +147,7 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'LDAP Authentication', $versions[] = array('name' => 'LDAP Authentication',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LdapAuthentication', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LdapAuthentication',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The LDAP Authentication plugin allows for StatusNet to handle authentication through LDAP.')); _m('The LDAP Authentication plugin allows for StatusNet to handle authentication through LDAP.'));

View File

@ -123,7 +123,7 @@ class LdapAuthorizationPlugin extends AuthorizationPlugin
$versions[] = array('name' => 'LDAP Authorization', $versions[] = array('name' => 'LDAP Authorization',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LdapAuthorization', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LdapAuthorization',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('The LDAP Authorization plugin allows for StatusNet to handle authorization through LDAP.')); _m('The LDAP Authorization plugin allows for StatusNet to handle authorization through LDAP.'));

View File

@ -62,7 +62,7 @@ class LilUrlPlugin extends UrlShortenerPlugin
$versions[] = array('name' => sprintf('LilUrl (%s)', $this->shortenerName), $versions[] = array('name' => sprintf('LilUrl (%s)', $this->shortenerName),
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LilUrl', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LilUrl',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
// TRANS: %1$s is the service URL. // TRANS: %1$s is the service URL.

17
plugins/LilUrl/README Normal file
View File

@ -0,0 +1,17 @@
The LilUrl plugin shortens URLs via a lilURL instance.
See: http://lilurl.sourceforge.net/
Installation
============
add "addPlugin('LilUrl', array('serviceUrl' => 'http://example.org'));"
to the bottom of your config.php
Settings
========
serviceUrl: The URL to the LilUrl instance.
Example
=======
addPlugin('LilUrl', array('serviceUrl' => 'http://example.org'));

View File

@ -34,7 +34,7 @@ class LinkPreviewPlugin extends Plugin
$versions[] = array('name' => 'LinkPreview', $versions[] = array('name' => 'LinkPreview',
'version' => GNUSOCIAL_VERSION, 'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber', 'author' => 'Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:LinkPreview', 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LinkPreview',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description. // TRANS: Plugin description.
_m('UI extension for previewing thumbnails from links.')); _m('UI extension for previewing thumbnails from links.'));

View File

@ -1 +1,23 @@
Depends on the oEmbed plugin (Oembed) The LinkPreview plugin adds a UI for previewing thumbnails from links.
Note: This plugin depends on the "Oembed" plugin.
Installation
============
add "addPlugin('LinkPreview');"
to the bottom of your config.php
Settings
========
process_links: Whether to process links or not
thumbwidth: The width of the link preview
thumbheight: The height of the link preview
Example
=======
addPlugin('Oembed'); // Dependency
$config['attachments']['process_links'] = true;
$config['attachments']['thumbwidth'] = 42;
$config['attachments']['thumbheight'] = 42;
addPlugin('LinkPreview');

Some files were not shown because too many files have changed in this diff Show More