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

This commit is contained in:
Brion Vibber 2009-09-20 21:13:00 -07:00
commit f7f8ac87a7
19 changed files with 739 additions and 389 deletions

View File

@ -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';
@ -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(
'allrss', array(
'nickname' =>
$this->user->nickname)
),
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)), sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url('api', array('apiaction' => 'statuses', common_local_url(
'api', array(
'apiaction' => 'statuses',
'method' => 'friends_timeline', 'method' => 'friends_timeline',
'argument' => $this->user->nickname.'.rss')), 'argument' => $this->user->nickname.'.rss'
)
),
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)), sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url('api', array('apiaction' => 'statuses', common_local_url(
'api', array(
'apiaction' => 'statuses',
'method' => 'friends_timeline', 'method' => 'friends_timeline',
'argument' => $this->user->nickname.'.atom')), 'argument' => $this->user->nickname.'.atom'
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))); )
),
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));
} }
} }

View File

@ -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
{ {
@ -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();
@ -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,34 +227,28 @@ 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')) {
elseif ( isset($authorization_header) && strstr(substr($authorization_header, 0,5),'Basic') )
{
// decode the HTTP_AUTHORIZATION header on php-cgi server self // decode the HTTP_AUTHORIZATION header on php-cgi server self
// on fcgid server the header name is AUTHORIZATION // 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;
} }
} }

View File

@ -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']);
}
} }

View File

@ -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;

View File

@ -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);

View File

@ -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
View 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
View 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
View File

View 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()),

View File

@ -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'];
@ -55,18 +72,25 @@ function handleError($error)
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, '. ) {
$msg = sprintf(
_(
'The database for %s isn\'t responding correctly, '.
'so the site won\'t work properly. '. 'so the site won\'t work properly. '.
'The site admins probably know about the problem, '. 'The site admins probably know about the problem, '.
'but you can contact them at %s to make sure. '. 'but you can contact them at %s to make sure. '.
'Otherwise, wait a few minutes and try again.'), 'Otherwise, wait a few minutes and try again.'
),
common_config('site', 'name'), common_config('site', 'name'),
common_config('site', 'email')); 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);
@ -129,8 +153,9 @@ function main()
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;
@ -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;
} }

View File

@ -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,15 +199,32 @@ $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') {
@ -200,9 +235,16 @@ 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'])) {
@ -214,18 +256,22 @@ function haveExternalLibrary($external_library)
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 &quot;config.php&quot; already exists.</p> printf('<p class="error">Config file &quot;config.php&quot; 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;
} }
@ -234,19 +280,28 @@ 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;
$missingExtensions = array();
foreach ($dbModules as $type => $info) {
if (!checkExtension($info['check_module'])) {
$missingExtensions[] = $info['check_module'];
}
}
if (count($missingExtensions) == count($dbModules)) {
$req = implode(', ', $missingExtensions);
printf('<p class="error">Cannot find mysql or pgsql extension. You need one or the other.');
$pass = false; $pass = false;
} }
if (!is_writable(INSTALLDIR)) { if (!is_writable(INSTALLDIR)) {
?><p class="error">Cannot write config file to: <code><?php echo INSTALLDIR; ?></code></p> printf('<p class="error">Cannot write config file to: <code>%s</code></p>', INSTALLDIR);
<p>On your server, try this command: <code>chmod a+w <?php echo INSTALLDIR; ?></code> printf('<p>On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR);
<?php
$pass = false; $pass = false;
} }
@ -255,9 +310,8 @@ function checkPrereqs()
foreach ($fileSubdirs as $fileSubdir) { foreach ($fileSubdirs as $fileSubdir) {
$fileFullPath = INSTALLDIR."/$fileSubdir/"; $fileFullPath = INSTALLDIR."/$fileSubdir/";
if (!is_writable($fileFullPath)) { if (!is_writable($fileFullPath)) {
?><p class="error">Cannot write <?php echo $fileSubdir; ?> directory: <code><?php echo $fileFullPath; ?></code></p> printf('<p class="error">Cannot write to %s directory: <code>%s</code></p>', $fileSubdir, $fileFullPath);
<p>On your server, try this command: <code>chmod a+w <?php echo $fileFullPath; ?></code></p> printf('<p>On your server, try this command: <code>chmod a+w %s</code></p>', $fileFullPath);
<?php
$pass = false; $pass = false;
} }
} }
@ -265,6 +319,13 @@ function checkPrereqs()
return $pass; 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,6 +336,11 @@ function checkExtension($name)
return true; return true;
} }
/**
* Show list of libraries
*
* @return void
*/
function showLibs() function showLibs()
{ {
global $external_libraries; global $external_libraries;
@ -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,8 +388,7 @@ 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>';
@ -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,12 +493,12 @@ 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)) {
@ -450,11 +516,6 @@ function handlePost()
$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;
@ -465,17 +526,8 @@ function handlePost()
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,12 +550,10 @@ 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.
@ -554,8 +604,7 @@ function pgsql_db_installer($host, $database, $username, $password) {
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";
} }
@ -564,7 +613,8 @@ function pgsql_db_installer($host, $database, $username, $password) {
return $db; return $db;
} }
function mysql_db_installer($host, $database, $username, $password) { function Mysql_Db_installer($host, $database, $username, $password)
{
updateStatus("Starting installation..."); updateStatus("Starting installation...");
updateStatus("Checking database..."); updateStatus("Checking database...");
@ -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();

View File

@ -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
View 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
View 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.")";
}
}

View File

@ -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__);

View 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',

View File

@ -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/
*/ */

View File

@ -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/