Merge branch '0.8.x' into userdesign

* 0.8.x:
  a little better query handling in redirect code
  a little better query handling in redirect code
  forgot some functions aren't available at status time
  redirect on non-canonical server name
  don't show create-a-group link if not logged in
  allow a configured base for cache keys
  Missing call to getProfile() caused verify_credentials to fail.
  change mods for setup script
  Script to set up new status networks
  strncmp -> strcasecmp
  Return network from network setup function
  Configurable avatar directory
This commit is contained in:
Zach Copley 2009-06-15 21:24:22 -07:00
commit 44343986c3
9 changed files with 142 additions and 15 deletions

13
README
View File

@ -1008,6 +1008,12 @@ avatar
For configuring avatar access.
dir: Directory to look for avatar files and to put them into.
Defaults to avatar subdirectory of install directory; if
you change it, make sure to change path, too.
path: Path to avatars. Defaults to path for avatar subdirectory,
but you can change it if you wish. Note that this will
be included with the avatar server, too.
server: If set, defines another server where avatars are stored in the
root directory. Note that the 'avatar' subdir still has to be
writeable. You'd typically use this to split HTTP requests on
@ -1100,6 +1106,13 @@ database data in memcached <http://www.danga.com/memcached/>.
enabled: Set to true to enable. Default false.
server: a string with the hostname of the memcached server. Can also
be an array of hostnames, if you've got more than one server.
base: memcached uses key-value pairs to store data. We build long,
funny-looking keys to make sure we don't have any conflicts. The
base of the key is usually a simplified version of the site name
(like "Identi.ca" => "identica"), but you can overwrite this if
you need to. You can safely ignore it if you only have one
Laconica site using your memcached server.
port: Port to connect to; defaults to 11211.
sphinx
------

View File

@ -100,11 +100,13 @@ class GroupsAction extends Action
function showContent()
{
$this->elementStart('p', array('id' => 'new_group'));
$this->element('a', array('href' => common_local_url('newgroup'),
'class' => 'more'),
_('Create a new group'));
$this->elementEnd('p');
if (common_logged_in()) {
$this->elementStart('p', array('id' => 'new_group'));
$this->element('a', array('href' => common_local_url('newgroup'),
'class' => 'more'),
_('Create a new group'));
$this->elementEnd('p');
}
$offset = ($this->page-1) * GROUPS_PER_PAGE;
$limit = GROUPS_PER_PAGE + 1;

View File

@ -58,7 +58,7 @@ class TwitapiusersAction extends TwitterapiAction
return;
}
$twitter_user = $this->twitter_user_array($profile, true);
$twitter_user = $this->twitter_user_array($user->getProfile(), true);
if ($apidata['content-type'] == 'xml') {
$this->init_document('xml');

View File

@ -55,19 +55,43 @@ class Avatar extends Memcached_DataObject
static function path($filename)
{
return INSTALLDIR . '/avatar/' . $filename;
$dir = common_config('avatar', 'dir');
if ($dir[strlen($dir)-1] != '/') {
$dir .= '/';
}
return $dir . $filename;
}
static function url($filename)
{
return common_path('avatar/'.$filename);
$path = common_config('avatar', 'path');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('avatar', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
function displayUrl()
{
$server = common_config('avatar', 'server');
if ($server) {
return 'http://'.$server.'/'.$this->filename;
return Avatar::url($this->filename);
} else {
return $this->url;
}

View File

@ -43,17 +43,27 @@ class Status_network extends DB_DataObject
{
global $config;
$sn = null;
// XXX I18N, probably not crucial for hostnames
// XXX This probably needs a tune up
if (0 == strncasecmp(strrev($wildcard), strrev($servername), strlen($wildcard))) {
$parts = explode('.', $servername);
$sn = Status_network::staticGet('nickname', strtolower($parts[0]));
// special case for exact match
if (0 == strcasecmp($servername, $wildcard)) {
$sn = Status_network::staticGet('nickname', '');
} else {
$parts = explode('.', $servername);
$sn = Status_network::staticGet('nickname', strtolower($parts[0]));
}
} else {
$sn = Status_network::staticGet('hostname', strtolower($servername));
}
if (!empty($sn)) {
if (!empty($sn->hostname) && 0 != strcasecmp($sn->hostname, $servername)) {
$sn->redirectToHostname();
}
$dbhost = (empty($sn->dbhost)) ? 'localhost' : $sn->dbhost;
$dbuser = (empty($sn->dbuser)) ? $sn->nickname : $sn->dbuser;
$dbpass = $sn->dbpass;
@ -70,9 +80,37 @@ class Status_network extends DB_DataObject
$config['site']['logo'] = $sn->logo;
}
return true;
return $sn;
} else {
return false;
return null;
}
}
// Code partially mooked from http://www.richler.de/en/php-redirect/
// (C) 2006 by Heiko Richler http://www.richler.de/
// LGPL
function redirectToHostname()
{
$destination = 'http://'.$this->hostname;
$destination .= $_SERVER['REQUEST_URI'];
$old = 'http'.
(($_SERVER['HTTPS'] == 'on') ? 'S' : '').
'://'.
$_SERVER['HTTP_HOST'].
$_SERVER['REQUEST_URI'].
$_SERVER['QUERY_STRING'];
if ($old == $destination) { // this would be a loop!
// error_log(...) ?
return false;
}
header('HTTP/1.1 301 Moved Permanently');
header("Location: $destination");
print "<a href='$destination'>$destination</a>\n";
exit;
}
}

View File

@ -116,7 +116,9 @@ $config =
'profile' =>
array('banned' => array()),
'avatar' =>
array('server' => null),
array('server' => null,
'dir' => INSTALLDIR . '/avatar/',
'path' => $_path . '/avatar/'),
'public' =>
array('localonly' => true,
'blacklist' => array(),
@ -158,6 +160,7 @@ $config =
'memcached' =>
array('enabled' => false,
'server' => 'localhost',
'base' => null,
'port' => 11211),
'ping' =>
array('notify' => array()),

View File

@ -1322,7 +1322,13 @@ function common_session_token()
function common_cache_key($extra)
{
return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra;
$base_key = common_config('memcached', 'base');
if (empty($base_key)) {
$base_key = common_keyize(common_config('site', 'name'));
}
return 'laconica:' . $base_key . ':' . $extra;
}
function common_keyize($str)

11
scripts/setup.cfg.sample Normal file
View File

@ -0,0 +1,11 @@
# CONFIGURATION FILE for setup_status_network.sh
# Base database name; full name will include nickname
export DBBASE=_example_net
export USERBASE=_example_net
export ADMIN=root
export ADMINPASS=yourpassword
export SITEDB=example_net_site
export AVATARBASE=/var/www/avatar.example.net

30
scripts/setup_status_network.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
source ./setup.cfg
export nickname=$1
export sitename=$2
export password=`pwgen 20`
export database=$nickname$DBBASE
export username=$nickname$USERBASE
# Create the db
mysqladmin -u $ADMIN --password=$ADMINPASS create $database
for f in laconica.sql sms_carrier.sql foreign_services.sql notice_source.sql; do
mysql -u $ADMIN --password=$ADMINPASS $database < ../db/$f;
done
mysql -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'localhost' IDENTIFIED BY '$password';
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'%' IDENTIFIED BY '$password';
INSERT INTO status_network (nickname, dbhost, dbuser, dbpass, dbname, sitename, created)
VALUES ('$nickname', '$DBHOST', '$username', '$password', '$database', '$sitename', now());
ENDOFCOMMANDS
mkdir $AVATARBASE/$nickname
chmod a+w $AVATARBASE/$nickname