Merge branch '0.9.x' of git://gitorious.org/statusnet/mainline into 0.9.x
This commit is contained in:
commit
f7f8ac87a7
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -15,9 +15,25 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Actions
|
||||||
|
* @package Actions
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Meitar Moscovitz <meitarm@gmail.com>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@controlyourself.ca>
|
||||||
|
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||||
|
* @link http://status.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/personalgroupnav.php';
|
require_once INSTALLDIR.'/lib/personalgroupnav.php';
|
||||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
require_once INSTALLDIR.'/lib/noticelist.php';
|
||||||
@ -43,8 +59,8 @@ class AllAction extends ProfileAction
|
|||||||
$this->notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
$this->notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->page > 1 && $this->notice->N == 0){
|
if ($this->page > 1 && $this->notice->N == 0) {
|
||||||
$this->serverError(_('No such page'),$code=404);
|
$this->serverError(_('No such page'), $code = 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -73,20 +89,33 @@ class AllAction extends ProfileAction
|
|||||||
|
|
||||||
function getFeeds()
|
function getFeeds()
|
||||||
{
|
{
|
||||||
return array(new Feed(Feed::RSS1,
|
return array(
|
||||||
common_local_url('allrss', array('nickname' =>
|
new Feed(Feed::RSS1,
|
||||||
$this->user->nickname)),
|
common_local_url(
|
||||||
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
|
'allrss', array(
|
||||||
new Feed(Feed::RSS2,
|
'nickname' =>
|
||||||
common_local_url('api', array('apiaction' => 'statuses',
|
$this->user->nickname)
|
||||||
'method' => 'friends_timeline',
|
),
|
||||||
'argument' => $this->user->nickname.'.rss')),
|
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
|
||||||
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
|
new Feed(Feed::RSS2,
|
||||||
new Feed(Feed::ATOM,
|
common_local_url(
|
||||||
common_local_url('api', array('apiaction' => 'statuses',
|
'api', array(
|
||||||
'method' => 'friends_timeline',
|
'apiaction' => 'statuses',
|
||||||
'argument' => $this->user->nickname.'.atom')),
|
'method' => 'friends_timeline',
|
||||||
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname)));
|
'argument' => $this->user->nickname.'.rss'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
|
||||||
|
new Feed(Feed::ATOM,
|
||||||
|
common_local_url(
|
||||||
|
'api', array(
|
||||||
|
'apiaction' => 'statuses',
|
||||||
|
'method' => 'friends_timeline',
|
||||||
|
'argument' => $this->user->nickname.'.atom'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLocalNav()
|
function showLocalNav()
|
||||||
@ -106,8 +135,7 @@ class AllAction extends ProfileAction
|
|||||||
} else {
|
} else {
|
||||||
$message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
|
$message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
|
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,17 +154,19 @@ class AllAction extends ProfileAction
|
|||||||
$this->showEmptyListMessage();
|
$this->showEmptyListMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
|
$this->pagination(
|
||||||
$this->page, 'all', array('nickname' => $this->user->nickname));
|
$this->page > 1, $cnt > NOTICES_PER_PAGE,
|
||||||
|
$this->page, 'all', array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPageTitle()
|
function showPageTitle()
|
||||||
{
|
{
|
||||||
$user =& common_current_user();
|
$user =& common_current_user();
|
||||||
if ($user && ($user->id == $this->user->id)) {
|
if ($user && ($user->id == $this->user->id)) {
|
||||||
$this->element('h1', NULL, _("You and friends"));
|
$this->element('h1', null, _("You and friends"));
|
||||||
} else {
|
} else {
|
||||||
$this->element('h1', NULL, sprintf(_('%s and friends'), $this->user->nickname));
|
$this->element('h1', null, sprintf(_('%s and friends'), $this->user->nickname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -15,9 +15,27 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Actions
|
||||||
|
* @package Actions
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @author Tom Adams <tom@holizz.com>
|
||||||
|
* @author Christopher Vollick <psycotica0@gmail.com>
|
||||||
|
* @author CiaranG <ciaran@ciarang.com>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Gina Haeussge <osd@foosel.net>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||||
|
* @link http://status.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
class ApiAction extends Action
|
class ApiAction extends Action
|
||||||
{
|
{
|
||||||
@ -37,7 +55,7 @@ class ApiAction extends Action
|
|||||||
$this->api_action = $this->arg('apiaction');
|
$this->api_action = $this->arg('apiaction');
|
||||||
$method = $this->arg('method');
|
$method = $this->arg('method');
|
||||||
$argument = $this->arg('argument');
|
$argument = $this->arg('argument');
|
||||||
$this->basic_auth_process_header();
|
$this->basic_auth_process_header();
|
||||||
|
|
||||||
if (isset($argument)) {
|
if (isset($argument)) {
|
||||||
$cmdext = explode('.', $argument);
|
$cmdext = explode('.', $argument);
|
||||||
@ -46,7 +64,7 @@ class ApiAction extends Action
|
|||||||
$this->content_type = strtolower($cmdext[1]);
|
$this->content_type = strtolower($cmdext[1]);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
# Requested format / content-type will be an extension on the method
|
//Requested format / content-type will be an extension on the method
|
||||||
$cmdext = explode('.', $method);
|
$cmdext = explode('.', $method);
|
||||||
$this->api_method = $cmdext[0];
|
$this->api_method = $cmdext[0];
|
||||||
$this->content_type = strtolower($cmdext[1]);
|
$this->content_type = strtolower($cmdext[1]);
|
||||||
@ -55,10 +73,10 @@ class ApiAction extends Action
|
|||||||
if ($this->requires_auth()) {
|
if ($this->requires_auth()) {
|
||||||
if (!isset($this->auth_user)) {
|
if (!isset($this->auth_user)) {
|
||||||
|
|
||||||
# This header makes basic auth go
|
//This header makes basic auth go
|
||||||
header('WWW-Authenticate: Basic realm="StatusNet API"');
|
header('WWW-Authenticate: Basic realm="StatusNet API"');
|
||||||
|
|
||||||
# If the user hits cancel -- bam!
|
//If the user hits cancel -- bam!
|
||||||
$this->show_basic_auth_error();
|
$this->show_basic_auth_error();
|
||||||
} else {
|
} else {
|
||||||
$nickname = $this->auth_user;
|
$nickname = $this->auth_user;
|
||||||
@ -69,7 +87,7 @@ class ApiAction extends Action
|
|||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->process_command();
|
$this->process_command();
|
||||||
} else {
|
} else {
|
||||||
# basic authentication failed
|
//basic authentication failed
|
||||||
list($proxy, $ip) = common_client_ip();
|
list($proxy, $ip) = common_client_ip();
|
||||||
|
|
||||||
common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
||||||
@ -84,7 +102,7 @@ class ApiAction extends Action
|
|||||||
if ($user) {
|
if ($user) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
# Twitter doesn't throw an error if the user isn't found
|
//Twitter doesn't throw an error if the user isn't found
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->process_command();
|
$this->process_command();
|
||||||
@ -97,7 +115,7 @@ class ApiAction extends Action
|
|||||||
$actionfile = INSTALLDIR."/actions/$action.php";
|
$actionfile = INSTALLDIR."/actions/$action.php";
|
||||||
|
|
||||||
if (file_exists($actionfile)) {
|
if (file_exists($actionfile)) {
|
||||||
require_once($actionfile);
|
include_once $actionfile;
|
||||||
$action_class = ucfirst($action)."Action";
|
$action_class = ucfirst($action)."Action";
|
||||||
$action_obj = new $action_class();
|
$action_obj = new $action_class();
|
||||||
|
|
||||||
@ -113,10 +131,10 @@ class ApiAction extends Action
|
|||||||
|
|
||||||
call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
|
call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
|
||||||
} else {
|
} else {
|
||||||
$this->clientError("API method not found!", $code=404);
|
$this->clientError("API method not found!", $code = 404);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->clientError("API method not found!", $code=404);
|
$this->clientError("API method not found!", $code = 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +202,11 @@ class ApiAction extends Action
|
|||||||
$user_id = $this->arg('user_id');
|
$user_id = $this->arg('user_id');
|
||||||
$screen_name = $this->arg('screen_name');
|
$screen_name = $this->arg('screen_name');
|
||||||
|
|
||||||
if (empty($this->api_arg) &&
|
if (empty($this->api_arg)
|
||||||
empty($id) &&
|
&& empty($id)
|
||||||
empty($user_id) &&
|
&& empty($user_id)
|
||||||
empty($screen_name)) {
|
&& empty($screen_name)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -208,35 +227,29 @@ class ApiAction extends Action
|
|||||||
|
|
||||||
function basic_auth_process_header()
|
function basic_auth_process_header()
|
||||||
{
|
{
|
||||||
if(isset($_SERVER['AUTHORIZATION']) || isset($_SERVER['HTTP_AUTHORIZATION']))
|
if (isset($_SERVER['AUTHORIZATION']) || isset($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
{
|
$authorization_header = isset($_SERVER['HTTP_AUTHORIZATION'])? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['AUTHORIZATION'];
|
||||||
$authorization_header = isset($_SERVER['HTTP_AUTHORIZATION'])?$_SERVER['HTTP_AUTHORIZATION']:$_SERVER['AUTHORIZATION'];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($_SERVER['PHP_AUTH_USER']))
|
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
{
|
$this->auth_user = $_SERVER['PHP_AUTH_USER'];
|
||||||
$this->auth_user = $_SERVER['PHP_AUTH_USER'];
|
$this->auth_pw = $_SERVER['PHP_AUTH_PW'];
|
||||||
$this->auth_pw = $_SERVER['PHP_AUTH_PW'];
|
} elseif (isset($authorization_header) && strstr(substr($authorization_header, 0, 5), 'Basic')) {
|
||||||
}
|
// decode the HTTP_AUTHORIZATION header on php-cgi server self
|
||||||
elseif ( isset($authorization_header) && strstr(substr($authorization_header, 0,5),'Basic') )
|
// on fcgid server the header name is AUTHORIZATION
|
||||||
{
|
|
||||||
// decode the HTTP_AUTHORIZATION header on php-cgi server self
|
|
||||||
// on fcgid server the header name is AUTHORIZATION
|
|
||||||
|
|
||||||
$auth_hash = base64_decode( substr($authorization_header, 6) );
|
$auth_hash = base64_decode(substr($authorization_header, 6));
|
||||||
list($this->auth_user, $this->auth_pw) = explode(':', $auth_hash);
|
list($this->auth_user, $this->auth_pw) = explode(':', $auth_hash);
|
||||||
|
|
||||||
// set all to NULL on a empty basic auth request
|
// set all to null on a empty basic auth request
|
||||||
if($this->auth_user == "") {
|
if ($this->auth_user == "") {
|
||||||
$this->auth_user = NULL;
|
$this->auth_user = null;
|
||||||
$this->auth_pw = NULL;
|
$this->auth_pw = null;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
$this->auth_user = null;
|
||||||
{
|
$this->auth_pw = null;
|
||||||
$this->auth_user = NULL;
|
}
|
||||||
$this->auth_pw = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_basic_auth_error()
|
function show_basic_auth_error()
|
||||||
@ -252,7 +265,7 @@ class ApiAction extends Action
|
|||||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
||||||
$this->elementEnd('hash');
|
$this->elementEnd('hash');
|
||||||
$this->endXML();
|
$this->endXML();
|
||||||
} else if ($this->content_type == 'json') {
|
} else if ($this->content_type == 'json') {
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
||||||
print(json_encode($error_array));
|
print(json_encode($error_array));
|
||||||
|
@ -41,7 +41,7 @@ require_once INSTALLDIR.'/lib/omb.php';
|
|||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package Laconica
|
* @package Laconica
|
||||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @author Robin Millette <millette@controlyourself.ca>
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
@ -143,67 +143,4 @@ class FinishremotesubscribeAction extends Action
|
|||||||
$user->nickname)),
|
$user->nickname)),
|
||||||
303);
|
303);
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_avatar($profile, $url)
|
|
||||||
{
|
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
|
||||||
copy($url, $temp_filename);
|
|
||||||
$imagefile = new ImageFile($profile->id, $temp_filename);
|
|
||||||
$filename = Avatar::filename($profile->id,
|
|
||||||
image_type_to_extension($imagefile->type),
|
|
||||||
null,
|
|
||||||
common_timestamp());
|
|
||||||
rename($temp_filename, Avatar::path($filename));
|
|
||||||
return $profile->setOriginal($filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
function access_token($omb)
|
|
||||||
{
|
|
||||||
|
|
||||||
common_debug('starting request for access token', __FILE__);
|
|
||||||
|
|
||||||
$con = omb_oauth_consumer();
|
|
||||||
$tok = new OAuthToken($omb['token'], $omb['secret']);
|
|
||||||
|
|
||||||
common_debug('using request token "'.$tok.'"', __FILE__);
|
|
||||||
|
|
||||||
$url = $omb['access_token_url'];
|
|
||||||
|
|
||||||
common_debug('using access token url "'.$url.'"', __FILE__);
|
|
||||||
|
|
||||||
# XXX: Is this the right thing to do? Strip off GET params and make them
|
|
||||||
# POST params? Seems wrong to me.
|
|
||||||
|
|
||||||
$parsed = parse_url($url);
|
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
|
||||||
|
|
||||||
$req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params);
|
|
||||||
|
|
||||||
$req->set_parameter('omb_version', OMB_VERSION_01);
|
|
||||||
|
|
||||||
# XXX: test to see if endpoint accepts this signature method
|
|
||||||
|
|
||||||
$req->sign_request(omb_hmac_sha1(), $con, $tok);
|
|
||||||
|
|
||||||
# We re-use this tool's fetcher, since it's pretty good
|
|
||||||
|
|
||||||
common_debug('posting to access token url "'.$req->get_normalized_http_url().'"', __FILE__);
|
|
||||||
common_debug('posting request data "'.$req->to_postdata().'"', __FILE__);
|
|
||||||
|
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
|
||||||
$result = $fetcher->post($req->get_normalized_http_url(),
|
|
||||||
$req->to_postdata(),
|
|
||||||
array('User-Agent: StatusNet/' . STATUSNET_VERSION));
|
|
||||||
|
|
||||||
common_debug('got result: "'.print_r($result,true).'"', __FILE__);
|
|
||||||
|
|
||||||
if ($result->status != 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_str($result->body, $return);
|
|
||||||
|
|
||||||
return array($return['oauth_token'], $return['oauth_token_secret']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,12 @@ class TwitapifriendshipsAction extends TwitterapiAction
|
|||||||
$other = $this->get_profile($id);
|
$other = $this->get_profile($id);
|
||||||
$user = $apidata['user']; // Alwyas the auth user
|
$user = $apidata['user']; // Alwyas the auth user
|
||||||
|
|
||||||
|
if ($user->id == $other->id) {
|
||||||
|
$this->clientError(_("You cannot unfollow yourself!"),
|
||||||
|
403, $apidata['content-type']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$sub = new Subscription();
|
$sub = new Subscription();
|
||||||
$sub->subscriber = $user->id;
|
$sub->subscriber = $user->id;
|
||||||
$sub->subscribed = $other->id;
|
$sub->subscribed = $other->id;
|
||||||
|
@ -136,6 +136,11 @@ class TwitapistatusesAction extends TwitterapiAction
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function home_timeline($args, $apidata)
|
||||||
|
{
|
||||||
|
call_user_func(array($this, 'friends_timeline'), $args, $apidata);
|
||||||
|
}
|
||||||
|
|
||||||
function user_timeline($args, $apidata)
|
function user_timeline($args, $apidata)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
@ -38,7 +38,7 @@ require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
|
|||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package Laconica
|
* @package Laconica
|
||||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @author Robin Millette <millette@controlyourself.ca>
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
@ -55,46 +55,13 @@ class UpdateprofileAction extends Action
|
|||||||
*/
|
*/
|
||||||
function prepare($argarray)
|
function prepare($argarray)
|
||||||
{
|
{
|
||||||
$version = $req->get_parameter('omb_version');
|
parent::prepare($argarray);
|
||||||
if ($version != OMB_VERSION_01) {
|
$license = $_POST['omb_listenee_license'];
|
||||||
$this->clientError(_('Unsupported OMB version'), 400);
|
$site_license = common_config('license', 'url');
|
||||||
return false;
|
if (!common_compatible_license($license, $site_license)) {
|
||||||
}
|
$this->clientError(sprintf(_('Listenee stream license ‘%s’ is not '.
|
||||||
# First, check to see if listenee exists
|
'compatible with site license ‘%s’.'),
|
||||||
$listenee = $req->get_parameter('omb_listenee');
|
$license, $site_license));
|
||||||
$remote = Remote_profile::staticGet('uri', $listenee);
|
|
||||||
if (!$remote) {
|
|
||||||
$this->clientError(_('Profile unknown'), 404);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
# Second, check to see if they should be able to post updates!
|
|
||||||
# We see if there are any subscriptions to that remote user with
|
|
||||||
# the given token.
|
|
||||||
|
|
||||||
$sub = new Subscription();
|
|
||||||
$sub->subscribed = $remote->id;
|
|
||||||
$sub->token = $token->key;
|
|
||||||
if (!$sub->find(true)) {
|
|
||||||
$this->clientError(_('You did not send us that profile'), 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = Profile::staticGet('id', $remote->id);
|
|
||||||
if (!$profile) {
|
|
||||||
# This one is our fault
|
|
||||||
$this->serverError(_('Remote profile with no matching profile'), 500);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$nickname = $req->get_parameter('omb_listenee_nickname');
|
|
||||||
if ($nickname && !Validate::string($nickname, array('min_length' => 1,
|
|
||||||
'max_length' => 64,
|
|
||||||
'format' => NICKNAME_FMT))) {
|
|
||||||
$this->clientError(_('Nickname must have only lowercase letters and numbers and no spaces.'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$license = $req->get_parameter('omb_listenee_license');
|
|
||||||
if ($license && !common_valid_http_url($license)) {
|
|
||||||
$this->clientError(sprintf(_("Invalid license URL '%s'"), $license));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
4
classes/Config.php
Executable file → Normal file
4
classes/Config.php
Executable file → Normal file
@ -17,7 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table Definition for config
|
* Table Definition for config
|
||||||
|
4
classes/Deleted_notice.php
Executable file → Normal file
4
classes/Deleted_notice.php
Executable file → Normal file
@ -17,7 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table Definition for notice
|
* Table Definition for notice
|
||||||
|
0
classes/statusnet.ini
Executable file → Normal file
0
classes/statusnet.ini
Executable file → Normal file
@ -21,6 +21,7 @@ VALUES
|
|||||||
('identichat','identichat','http://identichat.prosody.im/', now()),
|
('identichat','identichat','http://identichat.prosody.im/', now()),
|
||||||
('IdentiFox','IdentiFox','http://www.bitbucket.org/uncryptic/identifox/', now()),
|
('IdentiFox','IdentiFox','http://www.bitbucket.org/uncryptic/identifox/', now()),
|
||||||
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
|
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
|
||||||
|
('Jiminy','Jiminy','http://code.google.com/p/jiminy/', now()),
|
||||||
('LaTwit','LaTwit','http://latwit.mac65.com/', now()),
|
('LaTwit','LaTwit','http://latwit.mac65.com/', now()),
|
||||||
('LiveTweeter', 'LiveTweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
|
('LiveTweeter', 'LiveTweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
|
||||||
('livetweeter', 'livetweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
|
('livetweeter', 'livetweeter', 'http://addons.songbirdnest.com/addon/1204', now()),
|
||||||
|
74
index.php
74
index.php
@ -15,6 +15,22 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category StatusNet
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Christopher Vollick <psycotica0@gmail.com>
|
||||||
|
* @author CiaranG <ciaran@ciarang.com>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@controlezvous.ca>
|
||||||
|
* @author Gina Haeussge <osd@foosel.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||||
|
* @author Tom Adams <tom@holizz.com>
|
||||||
|
*
|
||||||
|
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('INSTALLDIR', dirname(__FILE__));
|
define('INSTALLDIR', dirname(__FILE__));
|
||||||
@ -29,7 +45,8 @@ $action = null;
|
|||||||
function getPath($req)
|
function getPath($req)
|
||||||
{
|
{
|
||||||
if ((common_config('site', 'fancy') || !array_key_exists('PATH_INFO', $_SERVER))
|
if ((common_config('site', 'fancy') || !array_key_exists('PATH_INFO', $_SERVER))
|
||||||
&& array_key_exists('p', $req)) {
|
&& array_key_exists('p', $req)
|
||||||
|
) {
|
||||||
return $req['p'];
|
return $req['p'];
|
||||||
} else if (array_key_exists('PATH_INFO', $_SERVER)) {
|
} else if (array_key_exists('PATH_INFO', $_SERVER)) {
|
||||||
return $_SERVER['PATH_INFO'];
|
return $_SERVER['PATH_INFO'];
|
||||||
@ -45,28 +62,35 @@ function handleError($error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
$logmsg = "PEAR error: " . $error->getMessage();
|
$logmsg = "PEAR error: " . $error->getMessage();
|
||||||
if(common_config('site', 'logdebug')) {
|
if (common_config('site', 'logdebug')) {
|
||||||
$logmsg .= " : ". $error->getDebugInfo();
|
$logmsg .= " : ". $error->getDebugInfo();
|
||||||
}
|
}
|
||||||
common_log(LOG_ERR, $logmsg);
|
common_log(LOG_ERR, $logmsg);
|
||||||
if(common_config('site', 'logdebug')) {
|
if (common_config('site', 'logdebug')) {
|
||||||
$bt = $error->getBacktrace();
|
$bt = $error->getBacktrace();
|
||||||
foreach ($bt as $line) {
|
foreach ($bt as $line) {
|
||||||
common_log(LOG_ERR, $line);
|
common_log(LOG_ERR, $line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($error instanceof DB_DataObject_Error ||
|
if ($error instanceof DB_DataObject_Error
|
||||||
$error instanceof DB_Error) {
|
|| $error instanceof DB_Error
|
||||||
$msg = sprintf(_('The database for %s isn\'t responding correctly, '.
|
) {
|
||||||
'so the site won\'t work properly. '.
|
$msg = sprintf(
|
||||||
'The site admins probably know about the problem, '.
|
_(
|
||||||
'but you can contact them at %s to make sure. '.
|
'The database for %s isn\'t responding correctly, '.
|
||||||
'Otherwise, wait a few minutes and try again.'),
|
'so the site won\'t work properly. '.
|
||||||
common_config('site', 'name'),
|
'The site admins probably know about the problem, '.
|
||||||
common_config('site', 'email'));
|
'but you can contact them at %s to make sure. '.
|
||||||
|
'Otherwise, wait a few minutes and try again.'
|
||||||
|
),
|
||||||
|
common_config('site', 'name'),
|
||||||
|
common_config('site', 'email')
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$msg = _('An important error occured, probably related to email setup. '.
|
$msg = _(
|
||||||
'Check logfiles for more info..');
|
'An important error occured, probably related to email setup. '.
|
||||||
|
'Check logfiles for more info..'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dac = new DBErrorAction($msg, 500);
|
$dac = new DBErrorAction($msg, 500);
|
||||||
@ -127,10 +151,11 @@ function main()
|
|||||||
$_lighty_url = @parse_url($_lighty_url);
|
$_lighty_url = @parse_url($_lighty_url);
|
||||||
|
|
||||||
if ($_lighty_url['path'] != '/index.php' && $_lighty_url['path'] != '/') {
|
if ($_lighty_url['path'] != '/index.php' && $_lighty_url['path'] != '/') {
|
||||||
$_lighty_path = preg_replace('/^'.preg_quote(common_config('site','path')).'\//', '', substr($_lighty_url['path'], 1));
|
$_lighty_path = preg_replace('/^'.preg_quote(common_config('site', 'path')).'\//', '', substr($_lighty_url['path'], 1));
|
||||||
$_SERVER['QUERY_STRING'] = 'p='.$_lighty_path;
|
$_SERVER['QUERY_STRING'] = 'p='.$_lighty_path;
|
||||||
if ($_lighty_url['query'])
|
if ($_lighty_url['query']) {
|
||||||
$_SERVER['QUERY_STRING'] .= '&'.$_lighty_url['query'];
|
$_SERVER['QUERY_STRING'] .= '&'.$_lighty_url['query'];
|
||||||
|
}
|
||||||
parse_str($_lighty_url['query'], $_lighty_query);
|
parse_str($_lighty_url['query'], $_lighty_query);
|
||||||
foreach ($_lighty_query as $key => $val) {
|
foreach ($_lighty_query as $key => $val) {
|
||||||
$_GET[$key] = $_REQUEST[$key] = $val;
|
$_GET[$key] = $_REQUEST[$key] = $val;
|
||||||
@ -141,7 +166,7 @@ function main()
|
|||||||
$_SERVER['REDIRECT_URL'] = preg_replace("/\?.+$/", "", $_SERVER['REQUEST_URI']);
|
$_SERVER['REDIRECT_URL'] = preg_replace("/\?.+$/", "", $_SERVER['REQUEST_URI']);
|
||||||
|
|
||||||
// quick check for fancy URL auto-detection support in installer.
|
// quick check for fancy URL auto-detection support in installer.
|
||||||
if (isset($_SERVER['REDIRECT_URL']) && (preg_replace("/^\/$/","",(dirname($_SERVER['REQUEST_URI']))) . '/check-fancy') === $_SERVER['REDIRECT_URL']) {
|
if (isset($_SERVER['REDIRECT_URL']) && (preg_replace("/^\/$/", "", (dirname($_SERVER['REQUEST_URI']))) . '/check-fancy') === $_SERVER['REDIRECT_URL']) {
|
||||||
die("Fancy URL support detection succeeded. We suggest you enable this to get fancy (pretty) URLs.");
|
die("Fancy URL support detection succeeded. We suggest you enable this to get fancy (pretty) URLs.");
|
||||||
}
|
}
|
||||||
global $user, $action;
|
global $user, $action;
|
||||||
@ -149,8 +174,12 @@ function main()
|
|||||||
Snapshot::check();
|
Snapshot::check();
|
||||||
|
|
||||||
if (!_have_config()) {
|
if (!_have_config()) {
|
||||||
$msg = sprintf(_("No configuration file found. Try running ".
|
$msg = sprintf(
|
||||||
"the installation program first."));
|
_(
|
||||||
|
"No configuration file found. Try running ".
|
||||||
|
"the installation program first."
|
||||||
|
)
|
||||||
|
);
|
||||||
$sac = new ServerErrorAction($msg);
|
$sac = new ServerErrorAction($msg);
|
||||||
$sac->showPage();
|
$sac->showPage();
|
||||||
return;
|
return;
|
||||||
@ -196,9 +225,10 @@ function main()
|
|||||||
// If the site is private, and they're not on one of the "public"
|
// If the site is private, and they're not on one of the "public"
|
||||||
// parts of the site, redirect to login
|
// parts of the site, redirect to login
|
||||||
|
|
||||||
if (!$user && common_config('site', 'private') &&
|
if (!$user && common_config('site', 'private')
|
||||||
!isLoginAction($action) &&
|
&& !isLoginAction($action)
|
||||||
!preg_match('/rss$/', $action)) {
|
&& !preg_match('/rss$/', $action)
|
||||||
|
) {
|
||||||
common_redirect(common_local_url('login'));
|
common_redirect(common_local_url('login'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
401
install.php
401
install.php
@ -15,6 +15,24 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Installation
|
||||||
|
* @package Installation
|
||||||
|
*
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Brett Taylor <brett@webfroot.co.nz>
|
||||||
|
* @author Brion Vibber <brion@pobox.com>
|
||||||
|
* @author CiaranG <ciaran@ciarang.com>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Eric Helgeson <helfire@Erics-MBP.local>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @author Tom Adams <tom@holizz.com>
|
||||||
|
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||||
|
* @version 0.9
|
||||||
|
* @link http://status.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('INSTALLDIR', dirname(__FILE__));
|
define('INSTALLDIR', dirname(__FILE__));
|
||||||
@ -181,17 +199,34 @@ $external_libraries=array(
|
|||||||
'check_class'=>'Validate'
|
'check_class'=>'Validate'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
$dbModules = array(
|
||||||
|
'mysql' => array(
|
||||||
|
'name' => 'MySQL',
|
||||||
|
'check_module' => 'mysql', // mysqli?
|
||||||
|
'installer' => 'mysql_db_installer',
|
||||||
|
),
|
||||||
|
'pgsql' => array(
|
||||||
|
'name' => 'PostgreSQL',
|
||||||
|
'check_module' => 'pgsql',
|
||||||
|
'installer' => 'pgsql_db_installer',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the actual installation.
|
||||||
|
* If call libraries are present, then install
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
if (!checkPrereqs())
|
if (!checkPrereqs()) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( $_GET['checklibs'] ){
|
if (!empty($_GET['checklibs'])) {
|
||||||
showLibs();
|
showLibs();
|
||||||
}else{
|
} else {
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
handlePost();
|
handlePost();
|
||||||
} else {
|
} else {
|
||||||
@ -200,33 +235,44 @@ function main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if an external libary is present
|
||||||
|
*
|
||||||
|
* @param string $external_library Name of library
|
||||||
|
*
|
||||||
|
* @return boolean indicates if library present
|
||||||
|
*/
|
||||||
function haveExternalLibrary($external_library)
|
function haveExternalLibrary($external_library)
|
||||||
{
|
{
|
||||||
if(isset($external_library['include']) && ! include_once($external_library['include'])){
|
if (isset($external_library['include']) && ! @include_once $external_library['include'] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(isset($external_library['check_function']) && ! function_exists($external_library['check_function'])){
|
if (isset($external_library['check_function']) && ! function_exists($external_library['check_function'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(isset($external_library['check_class']) && ! class_exists($external_library['check_class'])){
|
if (isset($external_library['check_class']) && ! class_exists($external_library['check_class'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all is ready for installation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
function checkPrereqs()
|
function checkPrereqs()
|
||||||
{
|
{
|
||||||
$pass = true;
|
$pass = true;
|
||||||
|
|
||||||
if (file_exists(INSTALLDIR.'/config.php')) {
|
if (file_exists(INSTALLDIR.'/config.php')) {
|
||||||
?><p class="error">Config file "config.php" already exists.</p>
|
printf('<p class="error">Config file "config.php" already exists.</p>');
|
||||||
<?php
|
|
||||||
$pass = false;
|
$pass = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.2.3', '<')) {
|
if (version_compare(PHP_VERSION, '5.2.3', '<')) {
|
||||||
?><p class="error">Require PHP version 5.2.3 or greater.</p><?php
|
printf('<p class="error">Require PHP version 5.2.3 or greater.</p>');
|
||||||
$pass = false;
|
$pass = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$reqs = array('gd', 'curl',
|
$reqs = array('gd', 'curl',
|
||||||
@ -234,37 +280,52 @@ function checkPrereqs()
|
|||||||
|
|
||||||
foreach ($reqs as $req) {
|
foreach ($reqs as $req) {
|
||||||
if (!checkExtension($req)) {
|
if (!checkExtension($req)) {
|
||||||
?><p class="error">Cannot load required extension: <code><?php echo $req; ?></code></p><?php
|
printf('<p class="error">Cannot load required extension: <code>%s</code></p>', $req);
|
||||||
$pass = false;
|
$pass = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!checkExtension('pgsql') && !checkExtension('mysql')) {
|
// Make sure we have at least one database module available
|
||||||
?><p class="error">Cannot find mysql or pgsql extension. You need one or the other: <code><?php echo $req; ?></code></p><?php
|
global $dbModules;
|
||||||
$pass = false;
|
$missingExtensions = array();
|
||||||
|
foreach ($dbModules as $type => $info) {
|
||||||
|
if (!checkExtension($info['check_module'])) {
|
||||||
|
$missingExtensions[] = $info['check_module'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_writable(INSTALLDIR)) {
|
if (count($missingExtensions) == count($dbModules)) {
|
||||||
?><p class="error">Cannot write config file to: <code><?php echo INSTALLDIR; ?></code></p>
|
$req = implode(', ', $missingExtensions);
|
||||||
<p>On your server, try this command: <code>chmod a+w <?php echo INSTALLDIR; ?></code>
|
printf('<p class="error">Cannot find mysql or pgsql extension. You need one or the other.');
|
||||||
<?php
|
$pass = false;
|
||||||
$pass = false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check the subdirs used for file uploads
|
if (!is_writable(INSTALLDIR)) {
|
||||||
$fileSubdirs = array('avatar', 'background', 'file');
|
printf('<p class="error">Cannot write config file to: <code>%s</code></p>', INSTALLDIR);
|
||||||
foreach ($fileSubdirs as $fileSubdir) {
|
printf('<p>On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR);
|
||||||
$fileFullPath = INSTALLDIR."/$fileSubdir/";
|
$pass = false;
|
||||||
if (!is_writable($fileFullPath)) {
|
}
|
||||||
?><p class="error">Cannot write <?php echo $fileSubdir; ?> directory: <code><?php echo $fileFullPath; ?></code></p>
|
|
||||||
<p>On your server, try this command: <code>chmod a+w <?php echo $fileFullPath; ?></code></p>
|
|
||||||
<?php
|
|
||||||
$pass = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pass;
|
// Check the subdirs used for file uploads
|
||||||
|
$fileSubdirs = array('avatar', 'background', 'file');
|
||||||
|
foreach ($fileSubdirs as $fileSubdir) {
|
||||||
|
$fileFullPath = INSTALLDIR."/$fileSubdir/";
|
||||||
|
if (!is_writable($fileFullPath)) {
|
||||||
|
printf('<p class="error">Cannot write to %s directory: <code>%s</code></p>', $fileSubdir, $fileFullPath);
|
||||||
|
printf('<p>On your server, try this command: <code>chmod a+w %s</code></p>', $fileFullPath);
|
||||||
|
$pass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a php extension is both installed and loaded
|
||||||
|
*
|
||||||
|
* @param string $name of extension to check
|
||||||
|
*
|
||||||
|
* @return boolean whether extension is installed and loaded
|
||||||
|
*/
|
||||||
function checkExtension($name)
|
function checkExtension($name)
|
||||||
{
|
{
|
||||||
if (!extension_loaded($name)) {
|
if (!extension_loaded($name)) {
|
||||||
@ -275,15 +336,20 @@ function checkExtension($name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show list of libraries
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
function showLibs()
|
function showLibs()
|
||||||
{
|
{
|
||||||
global $external_libraries;
|
global $external_libraries;
|
||||||
$present_libraries=array();
|
$present_libraries=array();
|
||||||
$absent_libraries=array();
|
$absent_libraries=array();
|
||||||
foreach($external_libraries as $external_library){
|
foreach ($external_libraries as $external_library) {
|
||||||
if(haveExternalLibrary($external_library)){
|
if (haveExternalLibrary($external_library)) {
|
||||||
$present_libraries[]=$external_library;
|
$present_libraries[]=$external_library;
|
||||||
}else{
|
} else {
|
||||||
$absent_libraries[]=$external_library;
|
$absent_libraries[]=$external_library;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,22 +364,21 @@ function showLibs()
|
|||||||
<h2>Absent Libraries</h2>
|
<h2>Absent Libraries</h2>
|
||||||
<ul id="absent_libraries">
|
<ul id="absent_libraries">
|
||||||
E_O_T;
|
E_O_T;
|
||||||
foreach($absent_libraries as $library)
|
foreach ($absent_libraries as $library) {
|
||||||
{
|
|
||||||
echo '<li>';
|
echo '<li>';
|
||||||
if($library['url']){
|
if (isset($library['url'])) {
|
||||||
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
|
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
|
||||||
}else{
|
} else {
|
||||||
echo htmlentities($library['name']);
|
echo htmlentities($library['name']);
|
||||||
}
|
}
|
||||||
echo '<ul>';
|
echo '<ul>';
|
||||||
if($library['deb']){
|
if (isset($library['deb'])) {
|
||||||
echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>';
|
echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>';
|
||||||
}
|
}
|
||||||
if($library['rpm']){
|
if (isset($library['rpm'])) {
|
||||||
echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>';
|
echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>';
|
||||||
}
|
}
|
||||||
if($library['pear']){
|
if (isset($library['pear'])) {
|
||||||
echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>';
|
echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>';
|
||||||
}
|
}
|
||||||
echo '</ul>';
|
echo '</ul>';
|
||||||
@ -323,12 +388,11 @@ E_O_T;
|
|||||||
<h2>Installed Libraries</h2>
|
<h2>Installed Libraries</h2>
|
||||||
<ul id="present_libraries">
|
<ul id="present_libraries">
|
||||||
E_O_T;
|
E_O_T;
|
||||||
foreach($present_libraries as $library)
|
foreach ($present_libraries as $library) {
|
||||||
{
|
|
||||||
echo '<li>';
|
echo '<li>';
|
||||||
if($library['url']){
|
if ($library['url']) {
|
||||||
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
|
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
|
||||||
}else{
|
} else {
|
||||||
echo htmlentities($library['name']);
|
echo htmlentities($library['name']);
|
||||||
}
|
}
|
||||||
echo '</li>';
|
echo '</li>';
|
||||||
@ -340,6 +404,15 @@ E_O_T;
|
|||||||
|
|
||||||
function showForm()
|
function showForm()
|
||||||
{
|
{
|
||||||
|
global $dbModules;
|
||||||
|
$dbRadios = '';
|
||||||
|
$checked = 'checked="checked" '; // Check the first one which exists
|
||||||
|
foreach ($dbModules as $type => $info) {
|
||||||
|
if (checkExtension($info['check_module'])) {
|
||||||
|
$dbRadios .= "<input type=\"radio\" name=\"dbtype\" id=\"dbtype-$type\" value=\"$type\" $checked/> $info[name]<br />\n";
|
||||||
|
$checked = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
echo<<<E_O_T
|
echo<<<E_O_T
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
@ -376,8 +449,7 @@ function showForm()
|
|||||||
<li>
|
<li>
|
||||||
|
|
||||||
<label for="dbtype">Type</label>
|
<label for="dbtype">Type</label>
|
||||||
<input type="radio" name="dbtype" id="fancy-mysql" value="mysql" checked='checked' /> MySQL<br />
|
$dbRadios
|
||||||
<input type="radio" name="dbtype" id="dbtype-pgsql" value="pgsql" /> PostgreSQL<br />
|
|
||||||
<p class="form_guide">Database type</p>
|
<p class="form_guide">Database type</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@ -406,17 +478,11 @@ E_O_T;
|
|||||||
|
|
||||||
function updateStatus($status, $error=false)
|
function updateStatus($status, $error=false)
|
||||||
{
|
{
|
||||||
?>
|
echo '<li' . ($error ? ' class="error"': '' ) . ">$status</li>";
|
||||||
<li <?php echo ($error) ? 'class="error"': ''; ?>><?php echo $status;?></li>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePost()
|
function handlePost()
|
||||||
{
|
{
|
||||||
?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$host = $_POST['host'];
|
$host = $_POST['host'];
|
||||||
$dbtype = $_POST['dbtype'];
|
$dbtype = $_POST['dbtype'];
|
||||||
$database = $_POST['database'];
|
$database = $_POST['database'];
|
||||||
@ -427,55 +493,41 @@ function handlePost()
|
|||||||
$server = $_SERVER['HTTP_HOST'];
|
$server = $_SERVER['HTTP_HOST'];
|
||||||
$path = substr(dirname($_SERVER['PHP_SELF']), 1);
|
$path = substr(dirname($_SERVER['PHP_SELF']), 1);
|
||||||
|
|
||||||
?>
|
echo <<<STR
|
||||||
<dl class="system_notice">
|
<dl class="system_notice">
|
||||||
<dt>Page notice</dt>
|
<dt>Page notice</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<ul>
|
<ul>
|
||||||
<?php
|
STR;
|
||||||
$fail = false;
|
$fail = false;
|
||||||
|
|
||||||
if (empty($host)) {
|
if (empty($host)) {
|
||||||
updateStatus("No hostname specified.", true);
|
updateStatus("No hostname specified.", true);
|
||||||
$fail = true;
|
$fail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($database)) {
|
if (empty($database)) {
|
||||||
updateStatus("No database specified.", true);
|
updateStatus("No database specified.", true);
|
||||||
$fail = true;
|
$fail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($username)) {
|
if (empty($username)) {
|
||||||
updateStatus("No username specified.", true);
|
updateStatus("No username specified.", true);
|
||||||
$fail = true;
|
$fail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (empty($password)) {
|
|
||||||
// updateStatus("No password specified.", true);
|
|
||||||
// $fail = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (empty($sitename)) {
|
if (empty($sitename)) {
|
||||||
updateStatus("No sitename specified.", true);
|
updateStatus("No sitename specified.", true);
|
||||||
$fail = true;
|
$fail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($fail){
|
if ($fail) {
|
||||||
showForm();
|
showForm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: use PEAR::DB or PDO instead of our own switch
|
global $dbModules;
|
||||||
|
$db = call_user_func($dbModules[$dbtype]['installer'], $host, $database, $username, $password);
|
||||||
switch($dbtype) {
|
|
||||||
case 'mysql':
|
|
||||||
$db = mysql_db_installer($host, $database, $username, $password);
|
|
||||||
break;
|
|
||||||
case 'pgsql':
|
|
||||||
$db = pgsql_db_installer($host, $database, $username, $password);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$db) {
|
if (!$db) {
|
||||||
// database connection failed, do not move on to create config file.
|
// database connection failed, do not move on to create config file.
|
||||||
@ -498,112 +550,110 @@ function handlePost()
|
|||||||
|
|
||||||
updateStatus("StatusNet has been installed at $link");
|
updateStatus("StatusNet has been installed at $link");
|
||||||
updateStatus("You can visit your <a href='$link'>new StatusNet site</a>.");
|
updateStatus("You can visit your <a href='$link'>new StatusNet site</a>.");
|
||||||
?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pgsql_db_installer($host, $database, $username, $password) {
|
function Pgsql_Db_installer($host, $database, $username, $password)
|
||||||
$connstring = "dbname=$database host=$host user=$username";
|
{
|
||||||
|
$connstring = "dbname=$database host=$host user=$username";
|
||||||
|
|
||||||
//No password would mean trust authentication used.
|
//No password would mean trust authentication used.
|
||||||
if (!empty($password)) {
|
if (!empty($password)) {
|
||||||
$connstring .= " password=$password";
|
$connstring .= " password=$password";
|
||||||
}
|
}
|
||||||
updateStatus("Starting installation...");
|
updateStatus("Starting installation...");
|
||||||
updateStatus("Checking database...");
|
updateStatus("Checking database...");
|
||||||
$conn = pg_connect($connstring);
|
$conn = pg_connect($connstring);
|
||||||
|
|
||||||
if ($conn ===false) {
|
if ($conn ===false) {
|
||||||
updateStatus("Failed to connect to database: $connstring");
|
updateStatus("Failed to connect to database: $connstring");
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ensure database encoding is UTF8
|
//ensure database encoding is UTF8
|
||||||
$record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding'));
|
$record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding'));
|
||||||
if ($record->server_encoding != 'UTF8') {
|
if ($record->server_encoding != 'UTF8') {
|
||||||
updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
|
updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus("Running database script...");
|
updateStatus("Running database script...");
|
||||||
//wrap in transaction;
|
//wrap in transaction;
|
||||||
pg_query($conn, 'BEGIN');
|
pg_query($conn, 'BEGIN');
|
||||||
$res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
|
$res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
|
||||||
|
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
updateStatus("Can't run database script.", true);
|
updateStatus("Can't run database script.", true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
foreach (array('sms_carrier' => 'SMS carrier',
|
foreach (array('sms_carrier' => 'SMS carrier',
|
||||||
'notice_source' => 'notice source',
|
'notice_source' => 'notice source',
|
||||||
'foreign_services' => 'foreign service')
|
'foreign_services' => 'foreign service')
|
||||||
as $scr => $name) {
|
as $scr => $name) {
|
||||||
updateStatus(sprintf("Adding %s data to database...", $name));
|
updateStatus(sprintf("Adding %s data to database...", $name));
|
||||||
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
|
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
updateStatus(sprintf("Can't run %d script.", $name), true);
|
updateStatus(sprintf("Can't run %d script.", $name), true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pg_query($conn, 'COMMIT');
|
pg_query($conn, 'COMMIT');
|
||||||
|
|
||||||
if (empty($password)) {
|
if (empty($password)) {
|
||||||
$sqlUrl = "pgsql://$username@$host/$database";
|
$sqlUrl = "pgsql://$username@$host/$database";
|
||||||
}
|
} else {
|
||||||
else {
|
$sqlUrl = "pgsql://$username:$password@$host/$database";
|
||||||
$sqlUrl = "pgsql://$username:$password@$host/$database";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$db = array('type' => 'pgsql', 'database' => $sqlUrl);
|
$db = array('type' => 'pgsql', 'database' => $sqlUrl);
|
||||||
|
|
||||||
return $db;
|
return $db;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mysql_db_installer($host, $database, $username, $password) {
|
function Mysql_Db_installer($host, $database, $username, $password)
|
||||||
updateStatus("Starting installation...");
|
{
|
||||||
updateStatus("Checking database...");
|
updateStatus("Starting installation...");
|
||||||
|
updateStatus("Checking database...");
|
||||||
|
|
||||||
$conn = mysql_connect($host, $username, $password);
|
$conn = mysql_connect($host, $username, $password);
|
||||||
if (!$conn) {
|
if (!$conn) {
|
||||||
updateStatus("Can't connect to server '$host' as '$username'.", true);
|
updateStatus("Can't connect to server '$host' as '$username'.", true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
updateStatus("Changing to database...");
|
updateStatus("Changing to database...");
|
||||||
$res = mysql_select_db($database, $conn);
|
$res = mysql_select_db($database, $conn);
|
||||||
if (!$res) {
|
if (!$res) {
|
||||||
updateStatus("Can't change to database.", true);
|
updateStatus("Can't change to database.", true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
updateStatus("Running database script...");
|
updateStatus("Running database script...");
|
||||||
$res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
|
$res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
updateStatus("Can't run database script.", true);
|
updateStatus("Can't run database script.", true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
foreach (array('sms_carrier' => 'SMS carrier',
|
foreach (array('sms_carrier' => 'SMS carrier',
|
||||||
'notice_source' => 'notice source',
|
'notice_source' => 'notice source',
|
||||||
'foreign_services' => 'foreign service')
|
'foreign_services' => 'foreign service')
|
||||||
as $scr => $name) {
|
as $scr => $name) {
|
||||||
updateStatus(sprintf("Adding %s data to database...", $name));
|
updateStatus(sprintf("Adding %s data to database...", $name));
|
||||||
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
|
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
updateStatus(sprintf("Can't run %d script.", $name), true);
|
updateStatus(sprintf("Can't run %d script.", $name), true);
|
||||||
showForm();
|
showForm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sqlUrl = "mysqli://$username:$password@$host/$database";
|
$sqlUrl = "mysqli://$username:$password@$host/$database";
|
||||||
$db = array('type' => 'mysql', 'database' => $sqlUrl);
|
$db = array('type' => 'mysql', 'database' => $sqlUrl);
|
||||||
return $db;
|
return $db;
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeConf($sitename, $server, $path, $fancy, $db)
|
function writeConf($sitename, $server, $path, $fancy, $db)
|
||||||
@ -634,7 +684,16 @@ function writeConf($sitename, $server, $path, $fancy, $db)
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function runDbScript($filename, $conn, $type = 'mysql')
|
/**
|
||||||
|
* Install schema into the database
|
||||||
|
*
|
||||||
|
* @param string $filename location of database schema file
|
||||||
|
* @param dbconn $conn connection to database
|
||||||
|
* @param string $type type of database, currently mysql or pgsql
|
||||||
|
*
|
||||||
|
* @return boolean - indicating success or failure
|
||||||
|
*/
|
||||||
|
function runDbScript($filename, $conn, $type = 'mysqli')
|
||||||
{
|
{
|
||||||
$sql = trim(file_get_contents($filename));
|
$sql = trim(file_get_contents($filename));
|
||||||
$stmts = explode(';', $sql);
|
$stmts = explode(';', $sql);
|
||||||
@ -645,7 +704,7 @@ function runDbScript($filename, $conn, $type = 'mysql')
|
|||||||
}
|
}
|
||||||
// FIXME: use PEAR::DB or PDO instead of our own switch
|
// FIXME: use PEAR::DB or PDO instead of our own switch
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'mysql':
|
case 'mysqli':
|
||||||
$res = mysql_query($stmt, $conn);
|
$res = mysql_query($stmt, $conn);
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
$error = mysql_error();
|
$error = mysql_error();
|
||||||
|
@ -284,6 +284,8 @@ $config =
|
|||||||
array('contentlimit' => null),
|
array('contentlimit' => null),
|
||||||
'message' =>
|
'message' =>
|
||||||
array('contentlimit' => null),
|
array('contentlimit' => null),
|
||||||
|
'http' =>
|
||||||
|
array('client' => 'curl'), // XXX: should this be the default?
|
||||||
);
|
);
|
||||||
|
|
||||||
$config['db'] = &PEAR::getStaticProperty('DB_DataObject','options');
|
$config['db'] = &PEAR::getStaticProperty('DB_DataObject','options');
|
||||||
|
179
lib/curlclient.php
Normal file
179
lib/curlclient.php
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
n<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Utility class for wrapping Curl
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category HTTP
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
define(CURLCLIENT_VERSION, "0.1");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for Curl
|
||||||
|
*
|
||||||
|
* Makes Curl HTTP client calls within our HTTPClient framework
|
||||||
|
*
|
||||||
|
* @category HTTP
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CurlClient extends HTTPClient
|
||||||
|
{
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function head($url, $headers=null)
|
||||||
|
{
|
||||||
|
$ch = curl_init($url);
|
||||||
|
|
||||||
|
$this->setup($ch);
|
||||||
|
|
||||||
|
curl_setopt_array($ch,
|
||||||
|
array(CURLOPT_NOBODY => true));
|
||||||
|
|
||||||
|
if (!is_null($headers)) {
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = curl_exec($ch);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $this->parseResults($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($url, $headers=null)
|
||||||
|
{
|
||||||
|
$ch = curl_init($url);
|
||||||
|
|
||||||
|
$this->setup($ch);
|
||||||
|
|
||||||
|
if (!is_null($headers)) {
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = curl_exec($ch);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $this->parseResults($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function post($url, $headers=null, $body=null)
|
||||||
|
{
|
||||||
|
$ch = curl_init($url);
|
||||||
|
|
||||||
|
$this->setup($ch);
|
||||||
|
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
|
||||||
|
if (!is_null($body)) {
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($headers)) {
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = curl_exec($ch);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $this->parseResults($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup($ch)
|
||||||
|
{
|
||||||
|
curl_setopt_array($ch,
|
||||||
|
array(CURLOPT_USERAGENT => $this->userAgent(),
|
||||||
|
CURLOPT_HEADER => true,
|
||||||
|
CURLOPT_RETURNTRANSFER => true));
|
||||||
|
}
|
||||||
|
|
||||||
|
function userAgent()
|
||||||
|
{
|
||||||
|
$version = curl_version();
|
||||||
|
return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseResults($results)
|
||||||
|
{
|
||||||
|
$resp = new HTTPResponse();
|
||||||
|
|
||||||
|
$lines = explode("\r\n", $results);
|
||||||
|
|
||||||
|
if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) {
|
||||||
|
$resp->code = $match[1];
|
||||||
|
} else {
|
||||||
|
throw Exception("Bad format: initial line is not HTTP status line");
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastk = null;
|
||||||
|
|
||||||
|
for ($i = 1; $i < count($lines); $i++) {
|
||||||
|
$l =& $lines[$i];
|
||||||
|
if (mb_strlen($l) == 0) {
|
||||||
|
$resp->body = implode("\r\n", array_slice($lines, $i + 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) {
|
||||||
|
$k = $match[1];
|
||||||
|
$v = $match[2];
|
||||||
|
|
||||||
|
if (array_key_exists($k, $resp->headers)) {
|
||||||
|
if (is_array($resp->headers[$k])) {
|
||||||
|
$resp->headers[$k][] = $v;
|
||||||
|
} else {
|
||||||
|
$resp->headers[$k] = array($resp->headers[$k], $v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$resp->headers[$k] = $v;
|
||||||
|
}
|
||||||
|
$lastk = $k;
|
||||||
|
} else if (preg_match("#^\s+(.*)$#", $l, $match)) {
|
||||||
|
// continuation line
|
||||||
|
if (is_null($lastk)) {
|
||||||
|
throw Exception("Bad format: initial whitespace in headers");
|
||||||
|
}
|
||||||
|
$h =& $resp->headers[$lastk];
|
||||||
|
if (is_array($h)) {
|
||||||
|
$n = count($h);
|
||||||
|
$h[$n-1] .= $match[1];
|
||||||
|
} else {
|
||||||
|
$h .= $match[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resp;
|
||||||
|
}
|
||||||
|
}
|
122
lib/httpclient.php
Normal file
122
lib/httpclient.php
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Utility for doing HTTP-related things
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful structure for HTTP responses
|
||||||
|
*
|
||||||
|
* We make HTTP calls in several places, and we have several different
|
||||||
|
* ways of doing them. This class hides the specifics of what underlying
|
||||||
|
* library (curl or PHP-HTTP or whatever) that's used.
|
||||||
|
*
|
||||||
|
* @category HTTP
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class HTTPResponse
|
||||||
|
{
|
||||||
|
public $code = null;
|
||||||
|
public $headers = null;
|
||||||
|
public $body = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for doing HTTP client stuff
|
||||||
|
*
|
||||||
|
* We make HTTP calls in several places, and we have several different
|
||||||
|
* ways of doing them. This class hides the specifics of what underlying
|
||||||
|
* library (curl or PHP-HTTP or whatever) that's used.
|
||||||
|
*
|
||||||
|
* @category HTTP
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class HTTPClient
|
||||||
|
{
|
||||||
|
static $_client = null;
|
||||||
|
|
||||||
|
static function start()
|
||||||
|
{
|
||||||
|
if (!is_null(self::$_client)) {
|
||||||
|
return self::$_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = common_config('http', 'client');
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'curl':
|
||||||
|
self::$_client = new CurlClient();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown HTTP client type '$type'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
function head($url, $headers)
|
||||||
|
{
|
||||||
|
throw new Exception("HEAD method unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($url, $headers)
|
||||||
|
{
|
||||||
|
throw new Exception("GET method unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
function post($url, $headers, $body)
|
||||||
|
{
|
||||||
|
throw new Exception("POST method unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
function put($url, $headers, $body)
|
||||||
|
{
|
||||||
|
throw new Exception("PUT method unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($url, $headers)
|
||||||
|
{
|
||||||
|
throw new Exception("DELETE method unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
function userAgent()
|
||||||
|
{
|
||||||
|
return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
|
||||||
|
}
|
||||||
|
}
|
11
lib/omb.php
11
lib/omb.php
@ -80,14 +80,9 @@ function omb_broadcast_notice($notice)
|
|||||||
$posted = array();
|
$posted = array();
|
||||||
|
|
||||||
while ($rp->fetch()) {
|
while ($rp->fetch()) {
|
||||||
if (!array_key_exists($rp->postnoticeurl, $posted)) {
|
if (isset($posted[$rp->postnoticeurl])) {
|
||||||
common_log(LOG_DEBUG, 'Posting to ' . $rp->postnoticeurl);
|
/* We already posted to this url. */
|
||||||
if (omb_post_notice_keys($notice, $rp->postnoticeurl, $rp->token, $rp->secret)) {
|
continue;
|
||||||
common_log(LOG_DEBUG, 'Finished to ' . $rp->postnoticeurl);
|
|
||||||
$posted[$rp->postnoticeurl] = true;
|
|
||||||
} else {
|
|
||||||
common_log(LOG_DEBUG, 'Failed posting to ' . $rp->postnoticeurl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
common_debug('Posting to ' . $rp->postnoticeurl, __FILE__);
|
common_debug('Posting to ' . $rp->postnoticeurl, __FILE__);
|
||||||
|
|
||||||
|
@ -265,12 +265,12 @@ class Router
|
|||||||
$m->connect('api/statuses/:method',
|
$m->connect('api/statuses/:method',
|
||||||
array('action' => 'api',
|
array('action' => 'api',
|
||||||
'apiaction' => 'statuses'),
|
'apiaction' => 'statuses'),
|
||||||
array('method' => '(public_timeline|friends_timeline|user_timeline|update|replies|mentions|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
|
array('method' => '(public_timeline|home_timeline|friends_timeline|user_timeline|update|replies|mentions|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
|
||||||
|
|
||||||
$m->connect('api/statuses/:method/:argument',
|
$m->connect('api/statuses/:method/:argument',
|
||||||
array('action' => 'api',
|
array('action' => 'api',
|
||||||
'apiaction' => 'statuses'),
|
'apiaction' => 'statuses'),
|
||||||
array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
||||||
|
|
||||||
// users
|
// users
|
||||||
|
|
||||||
@ -429,7 +429,7 @@ class Router
|
|||||||
$m->connect('api/statuses/:method/:argument',
|
$m->connect('api/statuses/:method/:argument',
|
||||||
array('action' => 'api',
|
array('action' => 'api',
|
||||||
'apiaction' => 'statuses'),
|
'apiaction' => 'statuses'),
|
||||||
array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
||||||
|
|
||||||
$m->connect('api/statusnet/groups/:method/:argument',
|
$m->connect('api/statusnet/groups/:method/:argument',
|
||||||
array('action' => 'api',
|
array('action' => 'api',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Laconica, the distributed open-source microblogging tool
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
*
|
*
|
||||||
* PHP version 5
|
* PHP version 5
|
||||||
*
|
*
|
||||||
@ -18,14 +18,14 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* @category Plugin
|
* @category Plugin
|
||||||
* @package Laconica
|
* @package StatusNet
|
||||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2009 Control Yourself, Inc.
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://laconi.ca/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('LACONICA')) {
|
if (!defined('STATUSNET')) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,10 +36,10 @@ if (!defined('LACONICA')) {
|
|||||||
* and identity system.
|
* and identity system.
|
||||||
*
|
*
|
||||||
* @category Plugin
|
* @category Plugin
|
||||||
* @package Laconica
|
* @package StatusNet
|
||||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://laconi.ca/
|
* @link http://status.net/
|
||||||
* @link http://openid.net/
|
* @link http://openid.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** Howto: create a statusnet theme
|
/** Howto: create a statusnet theme
|
||||||
*
|
*
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
* @copyright 2009 Control Yourself, Inc.
|
* @copyright 2009 Control Yourself, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
|
Loading…
Reference in New Issue
Block a user