diff --git a/README b/README index 8fb4a941cf..57ff72f665 100644 --- a/README +++ b/README @@ -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 . 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 ------ diff --git a/actions/groups.php b/actions/groups.php index 26b52a5fcd..b49d80f377 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -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; diff --git a/actions/twitapiusers.php b/actions/twitapiusers.php index 13a8746cd0..21a56a9a58 100644 --- a/actions/twitapiusers.php +++ b/actions/twitapiusers.php @@ -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'); diff --git a/classes/Avatar.php b/classes/Avatar.php index db9d78e47f..5e8b315fe6 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -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; } diff --git a/classes/Status_network.php b/classes/Status_network.php index d2b942bfb1..17b6887408 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -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 "$destination\n"; + + exit; + } } diff --git a/lib/common.php b/lib/common.php index eb3bf4e4dc..1381d80477 100644 --- a/lib/common.php +++ b/lib/common.php @@ -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()), diff --git a/lib/util.php b/lib/util.php index 49c6ae108e..1d5708bd69 100644 --- a/lib/util.php +++ b/lib/util.php @@ -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) diff --git a/scripts/setup.cfg.sample b/scripts/setup.cfg.sample new file mode 100644 index 0000000000..4194bc146d --- /dev/null +++ b/scripts/setup.cfg.sample @@ -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 + diff --git a/scripts/setup_status_network.sh b/scripts/setup_status_network.sh new file mode 100755 index 0000000000..d80612b940 --- /dev/null +++ b/scripts/setup_status_network.sh @@ -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