From 4f6052d8d8bd3d64d395e7849a31183371040eb8 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Feb 2010 05:53:05 -0800 Subject: Apply xopher's fix to add 'sitetype' parameter to setup_status_network.sh, exposed to the email --- scripts/setup_status_network.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/setup_status_network.sh b/scripts/setup_status_network.sh index 4ad808011..bacf3c3e7 100755 --- a/scripts/setup_status_network.sh +++ b/scripts/setup_status_network.sh @@ -13,6 +13,11 @@ export sitename="$2" export tags="$3" export email="$4" export fullname="$5" +export sitetype="$6" + +if [ "$sitetype" == '' ]; then + sitetype='single-user' +fi # Fixme: if this is changed later we need to update profile URLs # for the created user. @@ -71,6 +76,7 @@ then sed "s/\$nickname/$nickname/" | \ sed "s/\$sitename/$sitename/" | \ sed "s/\$userpass/$userpass/" | \ + sed "s/\$sitetype/$sitetype/" | \ php $PHPBASE/scripts/sendemail.php \ -s"$server" \ -n"$nickname" \ -- cgit v1.2.3-54-g00ecf From 51c3606715573d8cea3c79ff7bc989a4ba86acc5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Feb 2010 09:30:15 -0800 Subject: Fix regression breaking file attachments. This is what I get for rushing fixes and not properly testing them. :P --- classes/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/File.php b/classes/File.php index 6dd9e0c06..ee418a802 100644 --- a/classes/File.php +++ b/classes/File.php @@ -181,7 +181,7 @@ class File extends Memcached_DataObject */ static function validFilename($filename) { - return preg_match('^/[A-Za-z0-9._-]+$/', $filename); + return preg_match('/^[A-Za-z0-9._-]+$/', $filename); } /** -- cgit v1.2.3-54-g00ecf From 6215b9788c8d1f523d4d173ecf40f185bd024bca Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 11:53:31 -0500 Subject: add nickname as unique key for user_group table --- classes/statusnet.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 6203650a6..e28424ce2 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -585,6 +585,7 @@ modified = 384 [user_group__keys] id = N +nickname = U [user_openid] canonical = 130 -- cgit v1.2.3-54-g00ecf From 644a9163831938518ed3473c7a6d74251d254e8b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 11:55:54 -0500 Subject: change 'sitetype' to 'siteplan' to use consistent language --- scripts/setup_status_network.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/setup_status_network.sh b/scripts/setup_status_network.sh index bacf3c3e7..89d15415f 100755 --- a/scripts/setup_status_network.sh +++ b/scripts/setup_status_network.sh @@ -13,10 +13,10 @@ export sitename="$2" export tags="$3" export email="$4" export fullname="$5" -export sitetype="$6" +export siteplan="$6" -if [ "$sitetype" == '' ]; then - sitetype='single-user' +if [ "$siteplan" == '' ]; then + siteplan='single-user' fi # Fixme: if this is changed later we need to update profile URLs @@ -76,7 +76,7 @@ then sed "s/\$nickname/$nickname/" | \ sed "s/\$sitename/$sitename/" | \ sed "s/\$userpass/$userpass/" | \ - sed "s/\$sitetype/$sitetype/" | \ + sed "s/\$siteplan/$siteplan/" | \ php $PHPBASE/scripts/sendemail.php \ -s"$server" \ -n"$nickname" \ -- cgit v1.2.3-54-g00ecf From aee73d87ee33d1743a74fbe87f964bfc46ba1873 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 12:13:07 -0500 Subject: showcache.php column flag was conflicting with default flag --- scripts/showcache.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/showcache.php b/scripts/showcache.php index f17979572..93b57a484 100644 --- a/scripts/showcache.php +++ b/scripts/showcache.php @@ -20,14 +20,14 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = "t:c:v:k:"; +$shortoptions = "t:l:v:k:"; $helptext = << shows the cached object based on the args -t table Table to look up - -c column Column to look up, default "id" + -l column Column to look up, default "id" -v value Value to look up -k key Key to look up; other args are ignored @@ -44,7 +44,7 @@ if (!empty($karg)) { if (empty($table)) { die("No table or key specified\n"); } - $column = get_option_value('c'); + $column = get_option_value('l'); if (empty($column)) { $column = 'id'; } -- cgit v1.2.3-54-g00ecf From 0e0beea5aa75e58de251752b2720d4ea6a8c89f7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 12:13:20 -0500 Subject: clearcache.php column flag was conflicting with default flag --- scripts/clearcache.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/clearcache.php b/scripts/clearcache.php index 702c1e3d6..0fb75daa0 100644 --- a/scripts/clearcache.php +++ b/scripts/clearcache.php @@ -20,35 +20,35 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = "t:c:v:k:"; +$shortoptions = "t:l:v:k:"; -$helptext = << clears the cached object based on the args -t table Table to look up - -c column Column to look up, default "id" + -l column Column to look up, default "id" -v value Value to look up -k key Key to look up; other args are ignored -ENDOFHELP; +END_OF_CLEARCACHE_HELP; require_once INSTALLDIR.'/scripts/commandline.inc'; -$karg = get_option_value('k'); +$karg = get_option_value('k', 'key'); if (!empty($karg)) { $k = common_cache_key($karg); } else { - $table = get_option_value('t'); + $table = get_option_value('t', 'table'); if (empty($table)) { die("No table or key specified\n"); } - $column = get_option_value('c'); + $column = get_option_value('l', 'column'); if (empty($column)) { $column = 'id'; } - $value = get_option_value('v'); + $value = get_option_value('v', 'value'); $k = Memcached_DataObject::cacheKey($table, $column, $value); } -- cgit v1.2.3-54-g00ecf From dbeb388adefec94c3bb34e99305a004d845b719c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 12:31:25 -0500 Subject: clear cache for Profile::hasRepeated() at Notice::insert() time --- classes/Notice.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/classes/Notice.php b/classes/Notice.php index 42878d94f..f9f386357 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1468,4 +1468,25 @@ class Notice extends Memcached_DataObject $handler->handle($this); } } + + function insert() + { + $result = parent::insert(); + + if ($result) { + // Profile::hasRepeated() abuses pkeyGet(), so we + // have to clear manually + if (!empty($this->repeat_of)) { + $c = self::memcache(); + if (!empty($c)) { + $ck = self::multicacheKey('Notice', + array('profile_id' => $this->profile_id, + 'repeat_of' => $this->repeat_of)); + $c->delete($ck); + } + } + } + + return $result; + } } -- cgit v1.2.3-54-g00ecf From 7a7e2162dd7eed59e60d9360d8692abc111d940c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 3 Feb 2010 14:58:29 -0500 Subject: Script to update profile URLs --- scripts/updateprofileurl.php | 99 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 scripts/updateprofileurl.php diff --git a/scripts/updateprofileurl.php b/scripts/updateprofileurl.php new file mode 100644 index 000000000..2fc6828e6 --- /dev/null +++ b/scripts/updateprofileurl.php @@ -0,0 +1,99 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +$shortoptions = 'i:n:a'; +$longoptions = array('id=', 'nickname=', 'all'); + +$helptext = <<find()) { + while ($user->fetch()) { + updateProfileURL($user); + } + } + } else { + show_help(); + exit(1); + } +} catch (Exception $e) { + print $e->getMessage()."\n"; + exit(1); +} + +function updateProfileURL($user) +{ + $profile = $user->getProfile(); + + if (empty($profile)) { + throw new Exception("Can't find profile for user $user->nickname ($user->id)"); + } + + $orig = clone($profile); + + $profile->profileurl = common_profile_url($user->nickname); + + if (!have_option('q', 'quiet')) { + print "Updating profile url for $user->nickname ($user->id) ". + "from $orig->profileurl to $profile->profileurl..."; + } + + $result = $profile->update($orig); + + if (!$result) { + print "FAIL.\n"; + common_log_db_error($profile, 'UPDATE', __FILE__); + throw new Exception("Can't update profile for user $user->nickname ($user->id)"); + } + + common_broadcast_profile($profile); + + print "OK.\n"; +} -- cgit v1.2.3-54-g00ecf From d2dc3e41c571cb4e9edef18b3bb1918633a9ce39 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 4 Feb 2010 16:27:34 +0000 Subject: Fixes minor remote subscription profile layout --- actions/userauthorization.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/actions/userauthorization.php b/actions/userauthorization.php index 4321f1302..7f71c60db 100644 --- a/actions/userauthorization.php +++ b/actions/userauthorization.php @@ -127,10 +127,10 @@ class UserauthorizationAction extends Action $location = $params->getLocation(); $avatar = $params->getAvatarURL(); - $this->elementStart('div', array('class' => 'profile')); $this->elementStart('div', 'entity_profile vcard'); - $this->elementStart('a', array('href' => $profile, - 'class' => 'url')); + $this->elementStart('dl', 'entity_depiction'); + $this->element('dt', null, _('Photo')); + $this->elementStart('dd'); if ($avatar) { $this->element('img', array('src' => $avatar, 'class' => 'photo avatar', @@ -138,11 +138,19 @@ class UserauthorizationAction extends Action 'height' => AVATAR_PROFILE_SIZE, 'alt' => $nickname)); } + $this->elementEnd('dd'); + $this->elementEnd('dl'); + + $this->elementStart('dl', 'entity_nickname'); + $this->element('dt', null, _('Nickname')); + $this->elementStart('dd'); $hasFN = ($fullname !== '') ? 'nickname' : 'fn nickname'; - $this->elementStart('span', $hasFN); + $this->elementStart('a', array('href' => $profile, + 'class' => 'url '.$hasFN)); $this->raw($nickname); - $this->elementEnd('span'); $this->elementEnd('a'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); if (!is_null($fullname)) { $this->elementStart('dl', 'entity_fn'); @@ -214,7 +222,6 @@ class UserauthorizationAction extends Action $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementEnd('div'); - $this->elementEnd('div'); } function sendAuthorization() @@ -350,4 +357,4 @@ class UserauthorizationAction extends Action } } } -} \ No newline at end of file +} -- cgit v1.2.3-54-g00ecf From c56250fb33e2e43a7c0f16bb78810e4ed70cf792 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 4 Feb 2010 16:51:51 +0000 Subject: Added accept and reject icons to remote subscription authorization --- theme/base/images/icons/icons-01.gif | Bin 3758 -> 3870 bytes theme/base/images/icons/twotone/green/against.gif | Bin 0 -> 85 bytes theme/base/images/icons/twotone/green/checkmark.gif | Bin 0 -> 76 bytes theme/default/css/display.css | 9 ++++++++- theme/identica/css/display.css | 9 ++++++++- 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 theme/base/images/icons/twotone/green/against.gif create mode 100644 theme/base/images/icons/twotone/green/checkmark.gif diff --git a/theme/base/images/icons/icons-01.gif b/theme/base/images/icons/icons-01.gif index 01a729c10..6f284f023 100644 Binary files a/theme/base/images/icons/icons-01.gif and b/theme/base/images/icons/icons-01.gif differ diff --git a/theme/base/images/icons/twotone/green/against.gif b/theme/base/images/icons/twotone/green/against.gif new file mode 100644 index 000000000..ca796c8a3 Binary files /dev/null and b/theme/base/images/icons/twotone/green/against.gif differ diff --git a/theme/base/images/icons/twotone/green/checkmark.gif b/theme/base/images/icons/twotone/green/checkmark.gif new file mode 100644 index 000000000..892429d48 Binary files /dev/null and b/theme/base/images/icons/twotone/green/checkmark.gif differ diff --git a/theme/default/css/display.css b/theme/default/css/display.css index 6954de7ba..82eb13531 100644 --- a/theme/default/css/display.css +++ b/theme/default/css/display.css @@ -192,7 +192,8 @@ button.minimize, .form_reset_key input.submit, .entity_clear input.submit, .entity_flag input.submit, -.entity_flag p { +.entity_flag p, +.entity_subscribe input.submit { background-image:url(../../base/images/icons/icons-01.gif); background-repeat:no-repeat; background-color:transparent; @@ -348,6 +349,12 @@ background-position: 5px -2039px; .entity_flag p { background-position: 5px -2105px; } +.entity_subscribe input.accept { +background-position: 5px -2171px; +} +.entity_subscribe input.reject { +background-position: 5px -2237px; +} /* NOTICES */ .notice .attachment { diff --git a/theme/identica/css/display.css b/theme/identica/css/display.css index 9ac2730bd..44ae4953b 100644 --- a/theme/identica/css/display.css +++ b/theme/identica/css/display.css @@ -192,7 +192,8 @@ button.minimize, .form_reset_key input.submit, .entity_clear input.submit, .entity_flag input.submit, -.entity_flag p { +.entity_flag p, +.entity_subscribe input.submit { background-image:url(../../base/images/icons/icons-01.gif); background-repeat:no-repeat; background-color:transparent; @@ -347,6 +348,12 @@ background-position: 5px -2039px; .entity_flag p { background-position: 5px -2105px; } +.entity_subscribe input.accept { +background-position: 5px -2171px; +} +.entity_subscribe input.reject { +background-position: 5px -2237px; +} /* NOTICES */ .notice .attachment { -- cgit v1.2.3-54-g00ecf From 5a1cbdc6f1e32be7b8430924a1125422d8457584 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Feb 2010 11:06:01 -0800 Subject: Add time-based cutoffs for public tag cloud, favorited lists to speed up those queries. Defaulting to only looking at last 90 days of activity, can be adjusted up or down. $config['tag']['cutoff'] = 86400 * 90; $config['popular']['cutoff'] = 86400 * 90; Per-user and per-group tag clouds do not use the cutoff (and it doesn't help with indexing on them). --- actions/favorited.php | 3 +++ actions/publictagcloud.php | 3 +++ lib/default.php | 6 ++++-- lib/grouptagcloudsection.php | 1 + lib/personaltagcloudsection.php | 1 + lib/popularnoticesection.php | 7 +++++-- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/actions/favorited.php b/actions/favorited.php index 9ffa5b844..d8980440d 100644 --- a/actions/favorited.php +++ b/actions/favorited.php @@ -186,10 +186,13 @@ class FavoritedAction extends Action function showContent() { $weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff')); + $cutoff = sprintf("fave.modified > '%s'", + common_sql_date(time() - common_config('popular', 'cutoff'))); $qry = 'SELECT notice.*, '. $weightexpr . ' as weight ' . 'FROM notice JOIN fave ON notice.id = fave.notice_id ' . + "WHERE $cutoff " . 'GROUP BY id,profile_id,uri,content,rendered,url,created,notice.modified,reply_to,is_local,source,notice.conversation ' . 'ORDER BY weight DESC'; diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php index 9e4478dbb..9993b2d3f 100644 --- a/actions/publictagcloud.php +++ b/actions/publictagcloud.php @@ -106,7 +106,10 @@ class PublictagcloudAction extends Action #Add the aggregated columns... $tags->selectAdd('max(notice_id) as last_notice_id'); $calc = common_sql_weight('created', common_config('tag', 'dropoff')); + $cutoff = sprintf("notice_tag.created > '%s'", + common_sql_date(time() - common_config('tag', 'cutoff'))); $tags->selectAdd($calc . ' as weight'); + $tags->addWhere($cutoff); $tags->groupBy('tag'); $tags->orderBy('weight DESC'); diff --git a/lib/default.php b/lib/default.php index 2bedc4bf0..485a08ba4 100644 --- a/lib/default.php +++ b/lib/default.php @@ -144,9 +144,11 @@ $default = 'invite' => array('enabled' => true), 'tag' => - array('dropoff' => 864000.0), + array('dropoff' => 864000.0, # controls weighting based on age + 'cutoff' => 86400 * 90), # only look at notices posted in last 90 days 'popular' => - array('dropoff' => 864000.0), + array('dropoff' => 864000.0, # controls weighting based on age + 'cutoff' => 86400 * 90), # only look at notices favorited in last 90 days 'daemon' => array('piddir' => '/var/run', 'user' => false, diff --git a/lib/grouptagcloudsection.php b/lib/grouptagcloudsection.php index 14ceda085..f1106cc7b 100644 --- a/lib/grouptagcloudsection.php +++ b/lib/grouptagcloudsection.php @@ -59,6 +59,7 @@ class GroupTagCloudSection extends TagCloudSection function getTags() { $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); + // @fixme should we use the cutoff too? Doesn't help with indexing per-group. $names = $this->group->getAliases(); diff --git a/lib/personaltagcloudsection.php b/lib/personaltagcloudsection.php index 091425f92..5ea3f188d 100644 --- a/lib/personaltagcloudsection.php +++ b/lib/personaltagcloudsection.php @@ -59,6 +59,7 @@ class PersonalTagCloudSection extends TagCloudSection function getTags() { $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); + // @fixme should we use the cutoff too? Doesn't help with indexing per-user. $qry = 'SELECT notice_tag.tag, '. $weightexpr . ' as weight ' . diff --git a/lib/popularnoticesection.php b/lib/popularnoticesection.php index fbf9a60ab..296ddbbb5 100644 --- a/lib/popularnoticesection.php +++ b/lib/popularnoticesection.php @@ -59,12 +59,15 @@ class PopularNoticeSection extends NoticeSection } } $weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff')); + $cutoff = sprintf("fave.modified > '%s'", + common_sql_date(time() - common_config('popular', 'cutoff'))); $qry = "SELECT notice.*, $weightexpr as weight "; if(isset($tag)) { $qry .= 'FROM notice_tag, notice JOIN fave ON notice.id = fave.notice_id ' . - "WHERE notice.id = notice_tag.notice_id and '$tag' = notice_tag.tag"; + "WHERE $cutoff and notice.id = notice_tag.notice_id and '$tag' = notice_tag.tag"; } else { - $qry .= 'FROM notice JOIN fave ON notice.id = fave.notice_id'; + $qry .= 'FROM notice JOIN fave ON notice.id = fave.notice_id ' . + "WHERE $cutoff"; } $qry .= ' GROUP BY notice.id,notice.profile_id,notice.content,notice.uri,' . 'notice.rendered,notice.url,notice.created,notice.modified,' . -- cgit v1.2.3-54-g00ecf From 5bdc6fa5d456c3f520d8124950684220d8f440a3 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 4 Feb 2010 19:39:46 +0000 Subject: Moved hardcoded identica theme out of MobileProfile. In this case, it will use whichever theme is loaded as its base and then add its own mobile styles. Of course, if a theme comes with its own mobile styles, it will use that instead as an addition to its own base. --- plugins/MobileProfile/MobileProfilePlugin.php | 10 ++++++++++ plugins/MobileProfile/mp-screen.css | 5 +---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 5c913836d..cd2531fa7 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -240,6 +240,8 @@ class MobileProfilePlugin extends WAP20Plugin return true; } + $action->cssLink('css/display.css'); + if (file_exists(Theme::file('css/mp-screen.css'))) { $action->cssLink('css/mp-screen.css', null, 'screen'); } else { @@ -256,6 +258,14 @@ class MobileProfilePlugin extends WAP20Plugin } + function onStartShowUAStyles($action) { + if (!$this->serveMobile) { + return true; + } + + return false; + } + function onStartShowHeader($action) { if (!$this->serveMobile) { diff --git a/plugins/MobileProfile/mp-screen.css b/plugins/MobileProfile/mp-screen.css index 04fa5fb00..0fc801612 100644 --- a/plugins/MobileProfile/mp-screen.css +++ b/plugins/MobileProfile/mp-screen.css @@ -1,15 +1,12 @@ /** theme: mobile profile screen * * @package StatusNet - * @author Sarven Capadisli + * @author Sarven Capadisli * @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/ */ -@import url(../../theme/base/css/display.css); -@import url(../../theme/identica/css/display.css); - #wrap { min-width:0; max-width:100%; -- cgit v1.2.3-54-g00ecf From 239b88025ef1368bb871871ee903d6b078493f76 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Feb 2010 13:08:34 -0800 Subject: Should fix spurious 'nickname taken' and 'email taken' errors on registration. Form's checks for existing nicks & emails would incorrectly return true on the second lookup due to bad interaction with negative caching. (was checking $obj !== false but we return null now on negative cache hits, with false for cache misses) --- actions/register.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/register.php b/actions/register.php index 698137346..ccab76cf0 100644 --- a/actions/register.php +++ b/actions/register.php @@ -280,7 +280,7 @@ class RegisterAction extends Action function nicknameExists($nickname) { $user = User::staticGet('nickname', $nickname); - return ($user !== false); + return is_object($user); } /** @@ -300,7 +300,7 @@ class RegisterAction extends Action return false; } $user = User::staticGet('email', $email); - return ($user !== false); + return is_object($user); } // overrrided to add entry-title class -- cgit v1.2.3-54-g00ecf From 37f3a3d558ba55a085c9ee5427948b572c197bc3 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 16 Jan 2010 11:56:07 -0500 Subject: Missed change when refactoring groups. Thanks macno --- actions/apigroupjoin.php | 2 +- actions/apigroupleave.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/apigroupjoin.php b/actions/apigroupjoin.php index 3309d63e7..374cf83df 100644 --- a/actions/apigroupjoin.php +++ b/actions/apigroupjoin.php @@ -145,7 +145,7 @@ class ApiGroupJoinAction extends ApiAuthAction switch($this->format) { case 'xml': - $this->show_single_xml_group($this->group); + $this->showSingleXmlGroup($this->group); break; case 'json': $this->showSingleJsonGroup($this->group); diff --git a/actions/apigroupleave.php b/actions/apigroupleave.php index 6f8d40527..9848ece05 100644 --- a/actions/apigroupleave.php +++ b/actions/apigroupleave.php @@ -131,7 +131,7 @@ class ApiGroupLeaveAction extends ApiAuthAction switch($this->format) { case 'xml': - $this->show_single_xml_group($this->group); + $this->showSingleXmlGroup($this->group); break; case 'json': $this->showSingleJsonGroup($this->group); -- cgit v1.2.3-54-g00ecf From 2eadeca74515802dccc63d7ec84af1bc7d1338d9 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 16 Jan 2010 11:56:07 -0500 Subject: Missed change when refactoring groups. Thanks macno --- actions/apigroupjoin.php | 2 +- actions/apigroupleave.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/apigroupjoin.php b/actions/apigroupjoin.php index 3309d63e7..374cf83df 100644 --- a/actions/apigroupjoin.php +++ b/actions/apigroupjoin.php @@ -145,7 +145,7 @@ class ApiGroupJoinAction extends ApiAuthAction switch($this->format) { case 'xml': - $this->show_single_xml_group($this->group); + $this->showSingleXmlGroup($this->group); break; case 'json': $this->showSingleJsonGroup($this->group); diff --git a/actions/apigroupleave.php b/actions/apigroupleave.php index 6f8d40527..9848ece05 100644 --- a/actions/apigroupleave.php +++ b/actions/apigroupleave.php @@ -131,7 +131,7 @@ class ApiGroupLeaveAction extends ApiAuthAction switch($this->format) { case 'xml': - $this->show_single_xml_group($this->group); + $this->showSingleXmlGroup($this->group); break; case 'json': $this->showSingleJsonGroup($this->group); -- cgit v1.2.3-54-g00ecf From 9554b4ccbf0783516ea1735a7c999919be33c280 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Feb 2010 14:50:20 -0800 Subject: Inbox::streamNotices() with deletion compensation: inbox paging should more or less work with deleted items now. No change in efficiency for the common case where nothing's deleted: does the same bulk fetch of just the notices we think we'll need as before, then if we turned up short keeps checking one by one until we've filled up to our $limit. This can leave us with overlap between pages, but we already have that when new messages come in between clicks; seems to be the lesser of evils versus not getting a 'before' button. More permanent fix for that will be to switch timeline paging in the UI to use notice IDs. --- classes/Inbox.php | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- classes/User.php | 14 ++++-------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/classes/Inbox.php b/classes/Inbox.php index 26b27d2b5..029410799 100644 --- a/classes/Inbox.php +++ b/classes/Inbox.php @@ -32,6 +32,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; class Inbox extends Memcached_DataObject { const BOXCAR = 128; + const MAX_NOTICES = 1024; ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -81,7 +82,7 @@ class Inbox extends Memcached_DataObject $ni->selectAdd(); $ni->selectAdd('notice_id'); $ni->orderBy('notice_id DESC'); - $ni->limit(0, 1024); + $ni->limit(0, self::MAX_NOTICES); if ($ni->find()) { while($ni->fetch()) { @@ -115,9 +116,11 @@ class Inbox extends Memcached_DataObject $result = $inbox->query(sprintf('UPDATE inbox '. 'set notice_ids = concat(cast(0x%08x as binary(4)), '. - 'substr(notice_ids, 1, 4092)) '. + 'substr(notice_ids, 1, %d)) '. 'WHERE user_id = %d', - $notice_id, $user_id)); + $notice_id, + 4 * (self::MAX_NOTICES - 1), + $user_id)); if ($result) { self::blow('inbox:user_id:%d', $user_id); @@ -173,4 +176,61 @@ class Inbox extends Memcached_DataObject return $ids; } + + /** + * Wrapper for Inbox::stream() and Notice::getStreamByIds() returning + * additional items up to the limit if we were short due to deleted + * notices still being listed in the inbox. + * + * The fast path (when no items are deleted) should be just as fast; the + * offset parameter is applied *before* lookups for maximum efficiency. + * + * This means offset-based paging may show duplicates, but similar behavior + * already exists when new notices are posted between page views, so we + * think people will be ok with this until id-based paging is introduced + * to the user interface. + * + * @param int $user_id + * @param int $offset skip past the most recent N notices (after since_id checks) + * @param int $limit + * @param mixed $since_id return only notices after but not including this id + * @param mixed $max_id return only notices up to and including this id + * @param mixed $since obsolete/ignored + * @param mixed $own ignored? + * @return array of Notice objects + * + * @todo consider repacking the inbox when this happens? + */ + function streamNotices($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) + { + $ids = self::stream($user_id, $offset, self::MAX_NOTICES, $since_id, $max_id, $since, $own); + + // Do a bulk lookup for the first $limit items + // Fast path when nothing's deleted. + $firstChunk = array_slice($ids, 0, $limit); + $notices = Notice::getStreamByIds($firstChunk); + + $wanted = count($firstChunk); // raw entry count in the inbox up to our $limit + if ($notices->N >= $wanted) { + common_log(LOG_DEBUG, __METHOD__ . " ok got $wanted items"); + return $notices; + } + + common_log(LOG_DEBUG, __METHOD__ . " got $notices->N of $wanted items, getting more"); + // There were deleted notices, we'll need to look for more. + assert($notices instanceof ArrayWrapper); + $items = $notices->_items; + $remainder = array_slice($ids, $limit); + + while (count($items) < $wanted && count($remainder) > 0) { + $notice = Notice::staticGet(array_shift($remainder)); + if ($notice) { + common_log(LOG_DEBUG, __METHOD__ . " got another one"); + $items[] = $notice; + } else { + common_log(LOG_DEBUG, __METHOD__ . " skipping another deleted one"); + } + } + return new ArrayWrapper($items); + } } diff --git a/classes/User.php b/classes/User.php index 0ab816b57..72c3f39e9 100644 --- a/classes/User.php +++ b/classes/User.php @@ -502,28 +502,22 @@ class User extends Memcached_DataObject function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); } function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); } function friendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); } function ownFriendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); } function blowFavesCache() -- cgit v1.2.3-54-g00ecf From bb16898b1c73073e0442de72f2af133a3bd39713 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Feb 2010 14:50:20 -0800 Subject: Inbox::streamNotices() with deletion compensation: inbox paging should more or less work with deleted items now. No change in efficiency for the common case where nothing's deleted: does the same bulk fetch of just the notices we think we'll need as before, then if we turned up short keeps checking one by one until we've filled up to our $limit. This can leave us with overlap between pages, but we already have that when new messages come in between clicks; seems to be the lesser of evils versus not getting a 'before' button. More permanent fix for that will be to switch timeline paging in the UI to use notice IDs. --- classes/Inbox.php | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- classes/User.php | 14 ++++-------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/classes/Inbox.php b/classes/Inbox.php index 26b27d2b5..029410799 100644 --- a/classes/Inbox.php +++ b/classes/Inbox.php @@ -32,6 +32,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; class Inbox extends Memcached_DataObject { const BOXCAR = 128; + const MAX_NOTICES = 1024; ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -81,7 +82,7 @@ class Inbox extends Memcached_DataObject $ni->selectAdd(); $ni->selectAdd('notice_id'); $ni->orderBy('notice_id DESC'); - $ni->limit(0, 1024); + $ni->limit(0, self::MAX_NOTICES); if ($ni->find()) { while($ni->fetch()) { @@ -115,9 +116,11 @@ class Inbox extends Memcached_DataObject $result = $inbox->query(sprintf('UPDATE inbox '. 'set notice_ids = concat(cast(0x%08x as binary(4)), '. - 'substr(notice_ids, 1, 4092)) '. + 'substr(notice_ids, 1, %d)) '. 'WHERE user_id = %d', - $notice_id, $user_id)); + $notice_id, + 4 * (self::MAX_NOTICES - 1), + $user_id)); if ($result) { self::blow('inbox:user_id:%d', $user_id); @@ -173,4 +176,61 @@ class Inbox extends Memcached_DataObject return $ids; } + + /** + * Wrapper for Inbox::stream() and Notice::getStreamByIds() returning + * additional items up to the limit if we were short due to deleted + * notices still being listed in the inbox. + * + * The fast path (when no items are deleted) should be just as fast; the + * offset parameter is applied *before* lookups for maximum efficiency. + * + * This means offset-based paging may show duplicates, but similar behavior + * already exists when new notices are posted between page views, so we + * think people will be ok with this until id-based paging is introduced + * to the user interface. + * + * @param int $user_id + * @param int $offset skip past the most recent N notices (after since_id checks) + * @param int $limit + * @param mixed $since_id return only notices after but not including this id + * @param mixed $max_id return only notices up to and including this id + * @param mixed $since obsolete/ignored + * @param mixed $own ignored? + * @return array of Notice objects + * + * @todo consider repacking the inbox when this happens? + */ + function streamNotices($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) + { + $ids = self::stream($user_id, $offset, self::MAX_NOTICES, $since_id, $max_id, $since, $own); + + // Do a bulk lookup for the first $limit items + // Fast path when nothing's deleted. + $firstChunk = array_slice($ids, 0, $limit); + $notices = Notice::getStreamByIds($firstChunk); + + $wanted = count($firstChunk); // raw entry count in the inbox up to our $limit + if ($notices->N >= $wanted) { + common_log(LOG_DEBUG, __METHOD__ . " ok got $wanted items"); + return $notices; + } + + common_log(LOG_DEBUG, __METHOD__ . " got $notices->N of $wanted items, getting more"); + // There were deleted notices, we'll need to look for more. + assert($notices instanceof ArrayWrapper); + $items = $notices->_items; + $remainder = array_slice($ids, $limit); + + while (count($items) < $wanted && count($remainder) > 0) { + $notice = Notice::staticGet(array_shift($remainder)); + if ($notice) { + common_log(LOG_DEBUG, __METHOD__ . " got another one"); + $items[] = $notice; + } else { + common_log(LOG_DEBUG, __METHOD__ . " skipping another deleted one"); + } + } + return new ArrayWrapper($items); + } } diff --git a/classes/User.php b/classes/User.php index 0ab816b57..72c3f39e9 100644 --- a/classes/User.php +++ b/classes/User.php @@ -502,28 +502,22 @@ class User extends Memcached_DataObject function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); } function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); } function friendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, false); } function ownFriendsTimeline($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $ids = Inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - - return Notice::getStreamByIds($ids); + return Inbox::streamNotices($this->id, $offset, $limit, $since_id, $before_id, $since, true); } function blowFavesCache() -- cgit v1.2.3-54-g00ecf From 4502bea9a86fe5992eb9b359d90f0c1f004998c1 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Feb 2010 15:16:27 -0800 Subject: drop debug messages from inbox deletion fix --- classes/Inbox.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/classes/Inbox.php b/classes/Inbox.php index 029410799..be62611a1 100644 --- a/classes/Inbox.php +++ b/classes/Inbox.php @@ -212,11 +212,9 @@ class Inbox extends Memcached_DataObject $wanted = count($firstChunk); // raw entry count in the inbox up to our $limit if ($notices->N >= $wanted) { - common_log(LOG_DEBUG, __METHOD__ . " ok got $wanted items"); return $notices; } - common_log(LOG_DEBUG, __METHOD__ . " got $notices->N of $wanted items, getting more"); // There were deleted notices, we'll need to look for more. assert($notices instanceof ArrayWrapper); $items = $notices->_items; @@ -225,10 +223,8 @@ class Inbox extends Memcached_DataObject while (count($items) < $wanted && count($remainder) > 0) { $notice = Notice::staticGet(array_shift($remainder)); if ($notice) { - common_log(LOG_DEBUG, __METHOD__ . " got another one"); $items[] = $notice; } else { - common_log(LOG_DEBUG, __METHOD__ . " skipping another deleted one"); } } return new ArrayWrapper($items); -- cgit v1.2.3-54-g00ecf