git.gnu.io has moved to IP address 209.51.188.249 -- please double check where you are logging in.

Commit 20d6a7ca authored by Craig Andrews's avatar Craig Andrews

Merge branch '0.9.x' into 1.0.x

Conflicts:
	lib/queuemanager.php
	lib/xmppmanager.php
	plugins/Xmpp/Fake_XMPP.php
	scripts/imdaemon.php
parents 32084e33 d5cbfe80
InitializePlugin: a chance to initialize a plugin in a complete environment \InitializePlugin: a chance to initialize a plugin in a complete environment
CleanupPlugin: a chance to cleanup a plugin at the end of a program CleanupPlugin: a chance to cleanup a plugin at the end of a program
...@@ -355,6 +355,14 @@ EndShowHeadElements: Right before the </head> tag; put <script>s here if you nee ...@@ -355,6 +355,14 @@ EndShowHeadElements: Right before the </head> tag; put <script>s here if you nee
CheckSchema: chance to check the schema CheckSchema: chance to check the schema
StartProfileRemoteSubscribe: Before showing the link to remote subscription
- $userprofile: UserProfile widget
- &$profile: the profile being shown
EndProfileRemoteSubscribe: After showing the link to remote subscription
- $userprofile: UserProfile widget
- &$profile: the profile being shown
StartProfilePageProfileSection: Starting to show the section of the StartProfilePageProfileSection: Starting to show the section of the
profile page with the actual profile data; profile page with the actual profile data;
hook to prevent showing the profile (e.g.) hook to prevent showing the profile (e.g.)
......
...@@ -1192,6 +1192,8 @@ server: If set, defines another server where avatars are stored in the ...@@ -1192,6 +1192,8 @@ server: If set, defines another server where avatars are stored in the
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 <http://ur1.ca/6ih>, so this can parallelize the job.
Defaults to null. Defaults to null.
ssl: Whether to access avatars using HTTPS. Defaults to null, meaning
to guess based on site-wide SSL settings.
public public
------ ------
...@@ -1221,6 +1223,19 @@ path: Path part of theme URLs, before the theme name. Relative to the ...@@ -1221,6 +1223,19 @@ path: Path part of theme URLs, before the theme name. Relative to the
(using version numbers as the path) to make sure that all files are (using version numbers as the path) to make sure that all files are
reloaded by caching clients or proxies. Defaults to null, reloaded by caching clients or proxies. Defaults to null,
which means to use the site path + '/theme'. which means to use the site path + '/theme'.
ssl: Whether to use SSL for theme elements. Default is null, which means
guess based on site SSL settings.
javascript
----------
server: You can speed up page loading by pointing the
theme file lookup to another server (virtual or real).
Defaults to NULL, meaning to use the site server.
path: Path part of Javascript URLs. Defaults to null,
which means to use the site path + '/js/'.
ssl: Whether to use SSL for JavaScript files. Default is null, which means
guess based on site SSL settings.
xmpp xmpp
---- ----
...@@ -1447,6 +1462,8 @@ server: server name to use when creating URLs for uploaded files. ...@@ -1447,6 +1462,8 @@ server: server name to use when creating URLs for uploaded files.
a virtual server here can speed up Web performance. a virtual server here can speed up Web performance.
path: URL path, relative to the server, to find files. Defaults to path: URL path, relative to the server, to find files. Defaults to
main path + '/file/'. main path + '/file/'.
ssl: whether to use HTTPS for file URLs. Defaults to null, meaning to
guess based on other SSL settings.
filecommand: command to use for determining the type of a file. May be filecommand: command to use for determining the type of a file. May be
skipped if fileinfo extension is installed. Defaults to skipped if fileinfo extension is installed. Defaults to
'/usr/bin/file'. '/usr/bin/file'.
...@@ -1506,6 +1523,8 @@ dir: directory to write backgrounds too. Default is '/background/' ...@@ -1506,6 +1523,8 @@ dir: directory to write backgrounds too. Default is '/background/'
subdir of install dir. subdir of install dir.
path: path to backgrounds. Default is sub-path of install path; note path: path to backgrounds. Default is sub-path of install path; note
that you may need to change this if you change site-path too. that you may need to change this if you change site-path too.
ssl: Whether or not to use HTTPS for background files. Defaults to
null, meaning to guess from site-wide SSL settings.
ping ping
---- ----
......
...@@ -138,7 +138,19 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction ...@@ -138,7 +138,19 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
try { try {
$atom = new AtomNoticeFeed(); // If this was called using an integer ID, i.e.: using the canonical
// URL for this group's feed, then pass the Group object into the feed,
// so the OStatus plugin, and possibly other plugins, can access it.
// Feels sorta hacky. -- Z
$atom = null;
$id = $this->arg('id');
if (strval(intval($id)) === strval($id)) {
$atom = new AtomGroupNoticeFeed($this->group);
} else {
$atom = new AtomGroupNoticeFeed();
}
$atom->setId($id); $atom->setId($id);
$atom->setTitle($title); $atom->setTitle($title);
......
...@@ -148,7 +148,19 @@ class ApiTimelineUserAction extends ApiBareAuthAction ...@@ -148,7 +148,19 @@ class ApiTimelineUserAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8'); header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed(); // If this was called using an integer ID, i.e.: using the canonical
// URL for this user's feed, then pass the User object into the feed,
// so the OStatus plugin, and possibly other plugins, can access it.
// Feels sorta hacky. -- Z
$atom = null;
$id = $this->arg('id');
if (strval(intval($id)) === strval($id)) {
$atom = new AtomUserNoticeFeed($this->user);
} else {
$atom = new AtomUserNoticeFeed();
}
$atom->setId($id); $atom->setId($id);
$atom->setTitle($title); $atom->setTitle($title);
......
...@@ -82,9 +82,20 @@ class Avatar extends Memcached_DataObject ...@@ -82,9 +82,20 @@ class Avatar extends Memcached_DataObject
$server = common_config('site', 'server'); $server = common_config('site', 'server');
} }
// XXX: protocol $ssl = common_config('avatar', 'ssl');
if (is_null($ssl)) { // null -> guess
if (common_config('site', 'ssl') == 'always' &&
!common_config('avatar', 'server')) {
$ssl = true;
} else {
$ssl = false;
}
}
$protocol = ($ssl) ? 'https' : 'http';
return 'http://'.$server.$path.$filename; return $protocol.'://'.$server.$path.$filename;
} }
function displayUrl() function displayUrl()
......
...@@ -155,9 +155,20 @@ class Design extends Memcached_DataObject ...@@ -155,9 +155,20 @@ class Design extends Memcached_DataObject
$server = common_config('site', 'server'); $server = common_config('site', 'server');
} }
// XXX: protocol $ssl = common_config('background', 'ssl');
if (is_null($ssl)) { // null -> guess
if (common_config('site', 'ssl') == 'always' &&
!common_config('background', 'server')) {
$ssl = true;
} else {
$ssl = false;
}
}
$protocol = ($ssl) ? 'https' : 'http';
return 'http://'.$server.$path.$filename; return $protocol.'://'.$server.$path.$filename;
} }
function setDisposition($on, $off, $tile) function setDisposition($on, $off, $tile)
......
...@@ -228,9 +228,20 @@ class File extends Memcached_DataObject ...@@ -228,9 +228,20 @@ class File extends Memcached_DataObject
$server = common_config('site', 'server'); $server = common_config('site', 'server');
} }
// XXX: protocol $ssl = common_config('attachments', 'ssl');
return 'http://'.$server.$path.$filename; if (is_null($ssl)) { // null -> guess
if (common_config('site', 'ssl') == 'always' &&
!common_config('attachments', 'server')) {
$ssl = true;
} else {
$ssl = false;
}
}
$protocol = ($ssl) ? 'https' : 'http';
return $protocol.'://'.$server.$path.$filename;
} }
} }
......
...@@ -19,57 +19,8 @@ ...@@ -19,57 +19,8 @@
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
class Memcached_DataObject extends DB_DataObject class Memcached_DataObject extends Safe_DataObject
{ {
/**
* Destructor to free global memory resources associated with
* this data object when it's unset or goes out of scope.
* DB_DataObject doesn't do this yet by itself.
*/
function __destruct()
{
$this->free();
if (method_exists('DB_DataObject', '__destruct')) {
parent::__destruct();
}
}
/**
* Magic function called at serialize() time.
*
* We use this to drop a couple process-specific references
* from DB_DataObject which can cause trouble in future
* processes.
*
* @return array of variable names to include in serialization.
*/
function __sleep()
{
$vars = array_keys(get_object_vars($this));
$skip = array('_DB_resultid', '_link_loaded');
return array_diff($vars, $skip);
}
/**
* Magic function called at unserialize() time.
*
* Clean out some process-specific variables which might
* be floating around from a previous process's cached
* objects.
*
* Old cached objects may still have them.
*/
function __wakeup()
{
// Refers to global state info from a previous process.
// Clear this out so we don't accidentally break global
// state in *this* process.
$this->_DB_resultid = null;
// We don't have any local DBO refs, so clear these out.
$this->_link_loaded = false;
}
/** /**
* Wrapper for DB_DataObject's static lookup using memcached * Wrapper for DB_DataObject's static lookup using memcached
* as backing instead of an in-process cache array. * as backing instead of an in-process cache array.
...@@ -579,3 +530,4 @@ class Memcached_DataObject extends DB_DataObject ...@@ -579,3 +530,4 @@ class Memcached_DataObject extends DB_DataObject
return $c->set($cacheKey, $value); return $c->set($cacheKey, $value);
} }
} }
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2010, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
/**
* Extended DB_DataObject to improve a few things:
* - free global resources from destructor
* - remove bogus global references from serialized objects
* - don't leak memory when loading already-used .ini files
* (eg when using the same schema on thousands of databases)
*/
class Safe_DataObject extends DB_DataObject
{
/**
* Destructor to free global memory resources associated with
* this data object when it's unset or goes out of scope.
* DB_DataObject doesn't do this yet by itself.
*/
function __destruct()
{
$this->free();
if (method_exists('DB_DataObject', '__destruct')) {
parent::__destruct();
}
}
/**
* Magic function called at serialize() time.
*
* We use this to drop a couple process-specific references
* from DB_DataObject which can cause trouble in future
* processes.
*
* @return array of variable names to include in serialization.
*/
function __sleep()
{
$vars = array_keys(get_object_vars($this));
$skip = array('_DB_resultid', '_link_loaded');
return array_diff($vars, $skip);
}
/**
* Magic function called at unserialize() time.
*
* Clean out some process-specific variables which might
* be floating around from a previous process's cached
* objects.
*
* Old cached objects may still have them.
*/
function __wakeup()
{
// Refers to global state info from a previous process.
// Clear this out so we don't accidentally break global
// state in *this* process.
$this->_DB_resultid = null;
// We don't have any local DBO refs, so clear these out.
$this->_link_loaded = false;
}
/**
* Work around memory-leak bugs...
* Had to copy-paste the whole function in order to patch a couple lines of it.
* Would be nice if this code was better factored.
*
* @param optional string name of database to assign / read
* @param optional array structure of database, and keys
* @param optional array table links
*
* @access public
* @return true or PEAR:error on wrong paramenters.. or false if no file exists..
* or the array(tablename => array(column_name=>type)) if called with 1 argument.. (databasename)
*/
function databaseStructure()
{
global $_DB_DATAOBJECT;
// Assignment code
if ($args = func_get_args()) {
if (count($args) == 1) {
// this returns all the tables and their structure..
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loading Generator as databaseStructure called with args",1);
}
$x = new DB_DataObject;
$x->_database = $args[0];
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$tables = $DB->getListOf('tables');
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
foreach($tables as $table) {
$y = new DB_DataObject_Generator;
$y->fillTableSchema($x->_database,$table);
}
return $_DB_DATAOBJECT['INI'][$x->_database];
} else {
$_DB_DATAOBJECT['INI'][$args[0]] = isset($_DB_DATAOBJECT['INI'][$args[0]]) ?
$_DB_DATAOBJECT['INI'][$args[0]] + $args[1] : $args[1];
if (isset($args[1])) {
$_DB_DATAOBJECT['LINKS'][$args[0]] = isset($_DB_DATAOBJECT['LINKS'][$args[0]]) ?
$_DB_DATAOBJECT['LINKS'][$args[0]] + $args[2] : $args[2];
}
return true;
}
}
if (!$this->_database) {
$this->_connect();
}
// loaded already?
if (!empty($_DB_DATAOBJECT['INI'][$this->_database])) {
// database loaded - but this is table is not available..
if (
empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])
&& !empty($_DB_DATAOBJECT['CONFIG']['proxy'])
) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loading Generator to fetch Schema",1);
}
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
}
return true;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
// if you supply this with arguments, then it will take those
// as the database and links array...
$schemas = isset($_DB_DATAOBJECT['CONFIG']['schema_location']) ?
array("{$_DB_DATAOBJECT['CONFIG']['schema_location']}/{$this->_database}.ini") :
array() ;
if (isset($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"])) {
$schemas = is_array($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"] :
explode(PATH_SEPARATOR,$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]);
}
/* BEGIN CHANGED FROM UPSTREAM */
$_DB_DATAOBJECT['INI'][$this->_database] = $this->parseIniFiles($schemas);
/* END CHANGED FROM UPSTREAM */
// now have we loaded the structure..
if (!empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
return true;
}
// - if not try building it..
if (!empty($_DB_DATAOBJECT['CONFIG']['proxy'])) {
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
// should this fail!!!???
return true;
}
$this->debug("Cant find database schema: {$this->_database}/{$this->__table} \n".
"in links file data: " . print_r($_DB_DATAOBJECT['INI'],true),"databaseStructure",5);
// we have to die here!! - it causes chaos if we dont (including looping forever!)
$this->raiseError( "Unable to load schema for database and table (turn debugging up to 5 for full error message)", DB_DATAOBJECT_ERROR_INVALIDARGS, PEAR_ERROR_DIE);
return false;
}
/** For parseIniFiles */
protected static $iniCache = array();
/**
* When switching site configurations, DB_DataObject was loading its
* .ini files over and over, leaking gobs of memory.
* This refactored helper function uses a local cache of .ini files
* to minimize the leaks.
*
* @param array of .ini file names $schemas
* @return array
*/
protected function parseIniFiles($schemas)
{
$key = implode("|", $schemas);
if (!isset(Safe_DataObject::$iniCache[$key])) {
$data = array();
foreach ($schemas as $ini) {
if (file_exists($ini) && is_file($ini)) {
$data = array_merge($data, parse_ini_file($ini, true));
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
if (!is_readable ($ini)) {
$this->debug("ini file is not readable: $ini","databaseStructure",1);
} else {
$this->debug("Loaded ini file: $ini","databaseStructure",1);
}
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Missing ini file: $ini","databaseStructure",1);
}
}
}
Safe_DataObject::$iniCache[$key] = $data;
}
return Safe_DataObject::$iniCache[$key];
}
}
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
class Status_network extends DB_DataObject class Status_network extends Safe_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
...@@ -57,6 +57,7 @@ class Status_network extends DB_DataObject ...@@ -57,6 +57,7 @@ class Status_network extends DB_DataObject
###END_AUTOCODE ###END_AUTOCODE
static $cache = null; static $cache = null;
static $cacheInitialized = false;
static $base = null; static $base = null;
static $wildcard = null; static $wildcard = null;
...@@ -78,11 +79,15 @@ class Status_network extends DB_DataObject ...@@ -78,11 +79,15 @@ class Status_network extends DB_DataObject
if (class_exists('Memcache')) { if (class_exists('Memcache')) {
self::$cache = new Memcache(); self::$cache = new Memcache();
// Can't close persistent connections, making forking painful. // If we're a parent command-line process we need
// to be able to close out the connection after
// forking, so disable persistence.
// //
// @fixme only do this in *parent* CLI processes. // We'll turn it back on again the second time
// single-process and child-processes *should* use persistent. // through which will either be in a child process,
$persist = php_sapi_name() != 'cli'; // or a single-process script which is switching
// configurations.
$persist = php_sapi_name() != 'cli' || self::$cacheInitialized;
if (is_array($servers)) { if (is_array($servers)) {
foreach($servers as $server) { foreach($servers as $server) {
self::$cache->addServer($server, 11211, $persist); self::$cache->addServer($server, 11211, $persist);
...@@ -90,6 +95,7 @@ class Status_network extends DB_DataObject ...@@ -90,6 +95,7 @@ class Status_network extends DB_DataObject
} else { } else {
self::$cache->addServer($servers, 11211, $persist); self::$cache->addServer($servers, 11211, $persist);
} }
self::$cacheInitialized = true;
} }
self::$base = $dbname; self::$base = $dbname;
......
...@@ -285,6 +285,10 @@ class OMB_Service_Provider { ...@@ -285,6 +285,10 @@ class OMB_Service_Provider {
list($consumer, $token) = $this->getOAuthServer()->verify_request($req); list($consumer, $token) = $this->getOAuthServer()->verify_request($req);
} catch (OAuthException $e) { } catch (OAuthException $e) {
header('HTTP/1.1 403 Forbidden'); header('HTTP/1.1 403 Forbidden');
// @debug hack
throw OMB_RemoteServiceException::forRequest($uri,
'Revoked accesstoken for ' . $listenee . ': ' . $e->getMessage());
// @end debug
throw OMB_RemoteServiceException::forRequest($uri, throw OMB_RemoteServiceException::forRequest($uri,
'Revoked accesstoken for ' . $listenee); 'Revoked accesstoken for ' . $listenee);
} }
......
...@@ -404,12 +404,10 @@ var SN = { // StatusNet ...@@ -404,12 +404,10 @@ var SN = { // StatusNet
}, },
NoticeWithAttachment: function(notice) { NoticeWithAttachment: function(notice) {
if ($('.attachment', notice).length === 0) { if (notice.find('.attachment').length === 0) {
return; return;
} }
var notice_id = notice.attr('id');
$.fn.jOverlay.options = { $.fn.jOverlay.options = {
method : 'GET', method : 'GET',
data : '', data : '',
...@@ -429,35 +427,37 @@ var SN = { // StatusNet ...@@ -429,35 +427,37 @@ var SN = { // StatusNet
css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'} css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'}
}; };
$('#'+notice_id+' a.attachment').click(function() { notice.find('a.attachment').click(function() {
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); $().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
return false; return false;
}); });
var t; if ($('#shownotice').length == 0) {
$("body:not(#shownotice) #"+notice_id+" a.thumbnail").hover( var t;
function() { notice.find('a.thumbnail').hover(
var anchor = $(this); function() {
$("a.thumbnail").children('img').hide(); var anchor = $(this);
anchor.closest(".entry-title").addClass('ov'); $('a.thumbnail').children('img').hide();
anchor.closest(".entry-title").addClass('ov');
if (anchor.children('img').length === 0) {
t = setTimeout(function() { if (anchor.children('img').length === 0) {
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) { t = setTimeout(function() {
anchor.append(data); $.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
}); anchor.append(data);
}, 500); });
} }, 500);
else { }
anchor.children('img').show(); else {
anchor.children('img').show();
}
},
function() {
clearTimeout(t);
$('a.thumbnail').children('img').hide();
$(this).closest('.entry-title').removeClass('ov');
} }
}, );
function() { }
clearTimeout(t);
$("a.thumbnail").children('img').hide();
$(this).closest(".entry-title").removeClass('ov');
}
);
}, },
NoticeDataAttach: function() { NoticeDataAttach: function() {
......
...@@ -405,6 +405,7 @@ class Action extends HTMLOutputter // lawsuit ...@@ -405,6 +405,7 @@ class Action extends HTMLOutputter // lawsuit
'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png'),