From b1402896e7dac59ab1eecae4babf83a06d2f256d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 09:13:21 -0800 Subject: Set default 24-hour expiry on Memcached objects where not specified. --- plugins/MemcachePlugin.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/MemcachePlugin.php b/plugins/MemcachePlugin.php index 8c8b8da6d..2bc4b892b 100644 --- a/plugins/MemcachePlugin.php +++ b/plugins/MemcachePlugin.php @@ -59,6 +59,8 @@ class MemcachePlugin extends Plugin public $persistent = null; + public $defaultExpiry = 86400; // 24h + /** * Initialize the plugin * @@ -110,6 +112,9 @@ class MemcachePlugin extends Plugin function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) { $this->_ensureConn(); + if ($expiry === null) { + $expiry = $this->defaultExpiry; + } $success = $this->_conn->set($key, $value, $flag, $expiry); Event::handle('EndCacheSet', array($key, $value, $flag, $expiry)); -- cgit v1.2.3-54-g00ecf From 5c0560a7fc7d5e7bb9c91da7cc273d2dc89e32b2 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 19:50:08 -0800 Subject: fix for fix for bad realtime JS load --- plugins/Realtime/RealtimePlugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 16e28e94d..6c212453e 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -87,7 +87,7 @@ class RealtimePlugin extends Plugin $scripts = $this->_getScripts(); foreach ($scripts as $script) { - $action->script(common_path($script)); + $action->script($script); } $user = common_current_user(); @@ -307,7 +307,7 @@ class RealtimePlugin extends Plugin function _getScripts() { - return array('plugins/Realtime/realtimeupdate.js'); + return array(common_path('plugins/Realtime/realtimeupdate.js')); } function _updateInitialize($timeline, $user_id) -- cgit v1.2.3-54-g00ecf From fbd52111e1cc68a1a2710701ae0a146bcce5580e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 19:58:33 -0800 Subject: fix notice -- drop unused return value of variable that isn't initialized :) thx @ g0 for the catch --- classes/Notice.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index 6b364fb5c..90e3e76ef 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1378,8 +1378,6 @@ class Notice extends Memcached_DataObject } $reply->free(); - - return $ids; } function clearRepeats() -- cgit v1.2.3-54-g00ecf From c2c262e4b47f5a4965317148b66ff390f4fc85fd Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 28 Jan 2010 04:46:10 +0000 Subject: Move faceboookapp.js to the Facebook plugin --- js/facebookapp.js | 33 --------------------------------- plugins/Facebook/facebookaction.php | 4 +--- plugins/Facebook/facebookapp.js | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 36 deletions(-) delete mode 100644 js/facebookapp.js create mode 100644 plugins/Facebook/facebookapp.js diff --git a/js/facebookapp.js b/js/facebookapp.js deleted file mode 100644 index 5deb6e42b..000000000 --- a/js/facebookapp.js +++ /dev/null @@ -1,33 +0,0 @@ -/* -* StatusNet - a distributed open-source microblogging tool -* Copyright (C) 2008, StatusNet, Inc. -* -* 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 . -*/ - -var max = 140; -var noticeBox = document.getElementById('notice_data-text'); - -if (noticeBox) { - noticeBox.addEventListener('keyup', keypress); - noticeBox.addEventListener('keydown', keypress); - noticeBox.addEventListener('keypress', keypress); - noticeBox.addEventListener('change', keypress); -} - -// Do our the countdown -function keypress(evt) { - document.getElementById('notice_text-count').setTextValue( - max - noticeBox.getValue().length); -} diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index 389e1ea81..8437a705a 100644 --- a/plugins/Facebook/facebookaction.php +++ b/plugins/Facebook/facebookaction.php @@ -89,7 +89,7 @@ class FacebookAction extends Action function showScripts() { - $this->script('facebookapp.js'); + $this->script(common_path('plugins/Facebook/facebookapp.js')); } /** @@ -397,8 +397,6 @@ class FacebookAction extends Action return; } - - } } diff --git a/plugins/Facebook/facebookapp.js b/plugins/Facebook/facebookapp.js new file mode 100644 index 000000000..5deb6e42b --- /dev/null +++ b/plugins/Facebook/facebookapp.js @@ -0,0 +1,33 @@ +/* +* StatusNet - a distributed open-source microblogging tool +* Copyright (C) 2008, StatusNet, Inc. +* +* 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 . +*/ + +var max = 140; +var noticeBox = document.getElementById('notice_data-text'); + +if (noticeBox) { + noticeBox.addEventListener('keyup', keypress); + noticeBox.addEventListener('keydown', keypress); + noticeBox.addEventListener('keypress', keypress); + noticeBox.addEventListener('change', keypress); +} + +// Do our the countdown +function keypress(evt) { + document.getElementById('notice_text-count').setTextValue( + max - noticeBox.getValue().length); +} -- cgit v1.2.3-54-g00ecf From 7347381183bfee96db8b2f89a4ba0ce5d04f76e2 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 21:42:13 -0800 Subject: Fix for Mapstraction plugin's zoomed map links Move definition of NICKNAME_FMT above plugin initialization but below loading of Validate package. A merge error when refactoring setup lead to this not being defined yet when plugins were initialized, causing the router setup in MapstractionPlugin which tried to use this constant to fail. Result was bogus links and if you hit the URL directly the action would be "unrecognized". --- lib/common.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/common.php b/lib/common.php index b4e4a653c..b482464aa 100644 --- a/lib/common.php +++ b/lib/common.php @@ -115,6 +115,10 @@ function __autoload($cls) require_once 'Validate.php'; require_once 'markdown.php'; +// XXX: other formats here + +define('NICKNAME_FMT', VALIDATE_NUM.VALIDATE_ALPHA_LOWER); + require_once INSTALLDIR.'/lib/util.php'; require_once INSTALLDIR.'/lib/action.php'; require_once INSTALLDIR.'/lib/mail.php'; @@ -136,6 +140,3 @@ try { exit; } -// XXX: other formats here - -define('NICKNAME_FMT', VALIDATE_NUM.VALIDATE_ALPHA_LOWER); -- cgit v1.2.3-54-g00ecf From dcce323d18d4b779d2456f32aa99dfac5e2b7520 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 15:05:23 +0100 Subject: Removed unused variable assignment for avatar URL and added missing fn --- lib/noticelist.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/noticelist.php b/lib/noticelist.php index 78abf34a7..85c169716 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -555,11 +555,8 @@ class NoticeListItem extends Widget $this->out->raw(_('Repeated by')); - $avatar = $repeater->getAvatar(AVATAR_MINI_SIZE); - $this->out->elementStart('a', $attrs); - - $this->out->element('span', 'nickname', $repeater->nickname); + $this->out->element('span', 'fn nickname', $repeater->nickname); $this->out->elementEnd('a'); $this->out->elementEnd('span'); -- cgit v1.2.3-54-g00ecf From 5b1245a32a04de602196d2216b9d25ac32e0fd3b Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 15:06:03 +0100 Subject: Removed avatar from repeat of username (matches noticelist) --- actions/showstream.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/actions/showstream.php b/actions/showstream.php index 90ff67073..c52919386 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -291,23 +291,6 @@ class ProfileNoticeListItem extends NoticeListItem $this->out->elementStart('span', 'repeat'); - $this->out->elementStart('a', $attrs); - - $avatar = $this->profile->getAvatar(AVATAR_MINI_SIZE); - - $this->out->element('img', array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_MINI_SIZE), - 'class' => 'avatar photo', - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'alt' => - ($this->profile->fullname) ? - $this->profile->fullname : - $this->profile->nickname)); - - $this->out->elementEnd('a'); - $text_link = XMLStringer::estring('a', $attrs, $this->profile->nickname); $this->out->raw(sprintf(_('Repeat of %s'), $text_link)); -- cgit v1.2.3-54-g00ecf From c6f8b94fa91e3e5559a9b79766e7320b096b839e Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:02:39 +0100 Subject: Showing processing indicator for form_repeat on submit instead of form --- theme/base/css/display.css | 11 ++++++++++- theme/default/css/display.css | 9 +++++---- theme/identica/css/display.css | 9 +++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 65dd15990..3c51deb31 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -1127,8 +1127,17 @@ top:3px; } .dialogbox .submit_dialogbox { -text-indent:0; font-weight:bold; +text-indent:0; +min-width:46px; +} + +#wrap form.processing input.submit, +.entity_actions a.processing, +.dialogbox.processing .submit_dialogbox { +cursor:wait; +outline:none; +text-indent:-9999px; } .notice-options { diff --git a/theme/default/css/display.css b/theme/default/css/display.css index 3aebb239d..06711850f 100644 --- a/theme/default/css/display.css +++ b/theme/default/css/display.css @@ -196,11 +196,12 @@ background-color:transparent; } #wrap form.processing input.submit, -.entity_actions a.processing { +.entity_actions a.processing, +.dialogbox.processing .submit_dialogbox { background:#FFFFFF url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%; -cursor:wait; -text-indent:-9999px; -outline:none; +} +.notice-options .form_repeat.processing { +background-image:none; } #content { diff --git a/theme/identica/css/display.css b/theme/identica/css/display.css index 2818196c2..1ac96ab5b 100644 --- a/theme/identica/css/display.css +++ b/theme/identica/css/display.css @@ -196,11 +196,12 @@ background-color:transparent; } #wrap form.processing input.submit, -.entity_actions a.processing { +.entity_actions a.processing, +.dialogbox.processing .submit_dialogbox { background:#FFFFFF url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%; -cursor:wait; -text-indent:-9999px; -outline:none; +} +.notice-options .form_repeat.processing { +background-image:none; } #content { -- cgit v1.2.3-54-g00ecf From 61114ceff7c4124519cb5aa59b4d06ec73127e9d Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:39:20 +0100 Subject: Fixed layout for powered by statusnet in biz --- theme/biz/css/base.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 6357e55b4..471ac580d 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -224,6 +224,15 @@ font-weight:bold; address img + .fn { display:none; } +address .poweredby { +float:left; +clear:left; +display:block; +position:relative; +top:7px; +margin-right:-47px; +} + #header { width:100%; -- cgit v1.2.3-54-g00ecf From d4289cb34e9aefe7ffea3ca506ea0223f7858cb6 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:41:28 +0100 Subject: Fixed layout when ad plugin is on for biz --- theme/biz/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 471ac580d..2d4ac85ba 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -396,7 +396,7 @@ margin-bottom:1em; } #content { -width:51.009%; +width:50%; min-height:259px; padding:1.795%; float:left; -- cgit v1.2.3-54-g00ecf From b969fba2f5de4edf43e514e23565e1a90f916d04 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:49:33 +0100 Subject: Updated geo sharing styles for biz --- theme/biz/css/base.css | 21 +++++++++++++++++++++ theme/biz/css/display.css | 15 ++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 2d4ac85ba..47845421a 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -518,6 +518,27 @@ margin-bottom:0; line-height:1.618; } +.form_notice #notice_data-geo_wrap label, +.form_notice #notice_data-geo_wrap input { +position:absolute; +top:25px; +right:4px; +left:auto; +cursor:pointer; +width:16px; +height:16px; +display:block; +} +.form_notice #notice_data-geo_wrap input { +visibility:hidden; +} +.form_notice #notice_data-geo_wrap label { +font-weight:normal; +font-size:1em; +margin-bottom:0; +text-indent:-9999px; +} + /* entity_profile */ .entity_profile { position:relative; diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 7ea451576..7a53b02bf 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -60,6 +60,13 @@ input.submit, color:#FFFFFF; } +.form_notice label[for=notice_data-geo] { +background-position:0 -1780px; +} +.form_notice label[for=notice_data-geo].checked { +background-position:0 -1846px; +} + a, #site_nav_local_views .current a, div.notice-options input, @@ -115,6 +122,12 @@ text-indent:-9999px; outline:none; } +.form_notice label[for=notice_data-geo] { +background-image:url(../../base/images/icons/icons-01.gif); +background-repeat:no-repeat; +background-color:transparent; +} + #content { box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); -moz-box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); @@ -130,7 +143,7 @@ border-color:#FFFFFF; background-color:#FFFFFF; } -#site_nav_local_views li { +#site_nav_local_views li.current { box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); -moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); -webkit-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); -- cgit v1.2.3-54-g00ecf From e881888789be64576cb299611c80a0d191fa5682 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:08:24 +0100 Subject: Updated biz theme to use the single icons file --- theme/biz/css/base.css | 20 +++---- theme/biz/css/display.css | 132 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 110 insertions(+), 42 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 47845421a..4ce7b49ca 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -911,25 +911,21 @@ margin-right:11px; .notice-options a { float:left; } -.notice-options .notice_delete, .notice-options .notice_reply, +.notice-options .form_repeat, .notice-options .form_favor, -.notice-options .form_disfavor { -position:absolute; -top:0; +.notice-options .form_disfavor, +.notice-options .repeated { +float:left; +margin-left:14.2%; } .notice-options .form_favor, .notice-options .form_disfavor { -left:0; -} -.notice-options .notice_reply { -left:29px; -} -.notice-options .notice_delete { -right:0; +margin-left:0; } .notice-options input, -.notice-options a { +.notice-options a, +.notice-options .repeated { text-indent:-9999px; outline:none; } diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 7a53b02bf..4dfd25a99 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -108,26 +108,63 @@ color:#333333; #form_notice.warning #notice_text-count { color:#000000; } -#form_notice label[for=notice_data-attach] { -background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%; +.form_notice label[for=notice_data-attach] { +background-position:0 -328px; } -#form_notice #notice_data-attach { +.form_notice #notice_data-attach { opacity:0; } -#wrap form.processing input.submit { -background:#FFFFFF url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%; -cursor:wait; -text-indent:-9999px; -outline:none; -} - -.form_notice label[for=notice_data-geo] { +.form_notice label[for=notice_data-attach], +#export_data li a.rss, +#export_data li a.atom, +#export_data li a.foaf, +.entity_edit a, +.entity_send-a-message a, +.entity_nudge p, +.form_user_nudge input.submit, +.form_user_block input.submit, +.form_user_unblock input.submit, +.form_group_block input.submit, +.form_group_unblock input.submit, +.form_make_admin input.submit, +.notice .attachment, +.notice-options .notice_reply, +.notice-options form.form_favor input.submit, +.notice-options form.form_disfavor input.submit, +.notice-options .notice_delete, +.notice-options form.form_repeat input.submit, +#new_group a, +.pagination .nav_prev a, +.pagination .nav_next a, +button.close, +.form_group_leave input.submit, +.form_user_unsubscribe input.submit, +.form_group_join input.submit, +.form_user_subscribe input.submit, +.entity_subscribe a, +.entity_moderation p, +.entity_sandbox input.submit, +.entity_silence input.submit, +.entity_delete input.submit, +.notice-options .repeated, +.form_notice label[for=notice_data-geo], +button.minimize, +.form_reset_key input.submit { background-image:url(../../base/images/icons/icons-01.gif); background-repeat:no-repeat; background-color:transparent; } +#wrap form.processing input.submit, +.entity_actions a.processing, +.dialogbox.processing .submit_dialogbox { +background:#FFFFFF url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%; +} +.notice-options .form_repeat.processing { +background-image:none; +} + #content { box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); -moz-box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); @@ -175,13 +212,13 @@ background-repeat:no-repeat; background-position:0 45%; } #export_data li a.rss { -background-image:url(../../base/images/icons/icon_rss.png); +background-position:0 -130px; } #export_data li a.atom { -background-image:url(../../base/images/icons/icon_atom.png); +background-position:0 -64px; } #export_data li a.foaf { -background-image:url(../../base/images/icons/icon_foaf.gif); +background-position:0 1px; } .entity_edit a, @@ -211,43 +248,65 @@ background-color:#87B4C8; } .entity_edit a { -background-image:url(../../base/images/icons/twotone/green/edit.gif); +background-position: 5px -718px; } .entity_send-a-message a { -background-image:url(../../base/images/icons/twotone/green/quote.gif); +background-position: 5px -852px; } + .entity_nudge p, .form_user_nudge input.submit { -background-image:url(../../base/images/icons/twotone/green/mail.gif); +background-position: 5px -785px; } .form_user_block input.submit, .form_user_unblock input.submit, .form_group_block input.submit, .form_group_unblock input.submit { -background-image:url(../../base/images/icons/twotone/green/shield.gif); +background-position: 5px -918px; } .form_make_admin input.submit { -background-image:url(../../base/images/icons/twotone/green/admin.gif); +background-position: 5px -983px; +} +.entity_moderation p { +background-position: 5px -1313px; +} +.entity_sandbox input.submit { +background-position: 5px -1380px; +} +.entity_silence input.submit { +background-position: 5px -1445px; +} +.entity_delete input.submit { +background-position: 5px -1511px; +} +.form_reset_key input.submit { +background-position: 5px -1973px; } /* NOTICES */ .notice .attachment { -background:transparent url(../../base/images/icons/twotone/green/clip-02.gif) no-repeat 0 45%; +background-position:0 -394px; } #attachments .attachment { background:none; } .notice-options .notice_reply { -background:transparent url(../../base/images/icons/twotone/green/reply.gif) no-repeat 0 45%; +background-position:0 -592px; } .notice-options form.form_favor input.submit { -background:transparent url(../../base/images/icons/twotone/green/favourite.gif) no-repeat 0 45%; +background-position:0 -460px; } .notice-options form.form_disfavor input.submit { -background:transparent url(../../base/images/icons/twotone/green/disfavourite.gif) no-repeat 0 45%; +background-position:0 -526px; } .notice-options .notice_delete { -background:transparent url(../../base/images/icons/twotone/green/trash.gif) no-repeat 0 45%; +background-position:0 -658px; +} +.notice-options form.form_repeat input.submit { +background-position:0 -1582px; +} +.notice-options .repeated { +background-position:0 -1648px; } .notices div.entry-content, @@ -284,19 +343,32 @@ background-color:rgba(200, 200, 200, 0.300); /*END: NOTICES */ #new_group a { -background:transparent url(../../base/images/icons/twotone/green/news.gif) no-repeat 0 45%; +background-position:0 -1054px; } .pagination .nav_prev a, .pagination .nav_next a { background-repeat:no-repeat; -border-color:#CEE1E9; +box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +-webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); } .pagination .nav_prev a { -background-image:url(../../base/images/icons/twotone/green/arrow-left.gif); -background-position:10% 45%; +background-position:10% -187px; } .pagination .nav_next a { -background-image:url(../../base/images/icons/twotone/green/arrow-right.gif); -background-position:90% 45%; +background-position:105% -252px; +} +.pagination .nav .processing { +background-image:url(../../base/images/icons/icon_processing.gif); +box-shadow:none; +-moz-box-shadow:none; +-webkit-box-shadow:none; +outline:none; +} +.pagination .nav_next a.processing { +background-position:90% 47%; +} +.pagination .nav_prev a.processing { +background-position:10% 47%; } -- cgit v1.2.3-54-g00ecf From 6e556e502a13a1cfef51492707932635322f4bc4 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:09:35 +0100 Subject: Updated biz theme to hide form_repeat legend --- theme/biz/css/base.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 4ce7b49ca..ec8ca22f5 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -942,17 +942,18 @@ padding-left:16px; width:16px; padding:2px 0; } +.notice-options .form_repeat legend, .notice-options .form_favor legend, .notice-options .form_disfavor legend { display:none; } +.notice-options .form_repeat fieldset, .notice-options .form_favor fieldset, .notice-options .form_disfavor fieldset { border:0; padding:0; } - #usergroups #new_group { float: left; margin-right: 2em; -- cgit v1.2.3-54-g00ecf From 83087e9d9b14b4425368dbd2f95ff6fcc909e7f6 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:12:48 +0100 Subject: Updated biz theme notice options --- theme/biz/css/base.css | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index ec8ca22f5..d5873b0b0 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -903,9 +903,10 @@ text-transform:lowercase; .notice-options { position:relative; font-size:0.95em; -width:90px; +width:113px; float:right; -margin-right:11px; +margin-top:3px; +margin-right:4px; } .notice-options a { @@ -936,11 +937,17 @@ border:0; .notice-options .notice_reply, .notice-options .notice_delete { text-decoration:none; -padding-left:16px; +} +.notice .notice-options .notice_delete { +float:right; } .notice-options form input.submit { width:16px; -padding:2px 0; +height:16px; +padding:0; +border-radius:0; +-moz-border-radius:0; +-webkit-border-radius:0; } .notice-options .form_repeat legend, .notice-options .form_favor legend, @@ -953,6 +960,11 @@ display:none; border:0; padding:0; } +.notice-options a, +.notice-options .repeated { +width:16px; +height:16px; +} #usergroups #new_group { float: left; -- cgit v1.2.3-54-g00ecf From 156efda37a2a6d2e16b061180fea828581691560 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:16:11 +0100 Subject: Updated biz theme to use dialogbox styles --- theme/biz/css/base.css | 43 +++++++++++++++++++++++++++++++++++++++++++ theme/biz/css/display.css | 40 +++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index d5873b0b0..a8834ca57 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -900,6 +900,49 @@ display:inline-block; text-transform:lowercase; } +.dialogbox { +position:absolute; +top:-4px; +right:29px; +z-index:9; +min-width:199px; +float:none; +background-color:#FFF; +padding:11px; +border-radius:7px; +-moz-border-radius:7px; +-webkit-border-radius:7px; +border-style:solid; +border-width:1px; +border-color:#DDDDDD; +-moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7); +} + +.dialogbox legend { +display:block !important; +margin-right:18px; +} + +.dialogbox button.close { +position:absolute; +right:3px; +top:3px; +} + +.dialogbox .submit_dialogbox { +font-weight:bold; +text-indent:0; +min-width:46px; +} + +#wrap form.processing input.submit, +.entity_actions a.processing, +.dialogbox.processing .submit_dialogbox { +cursor:wait; +outline:none; +text-indent:-9999px; +} + .notice-options { position:relative; font-size:0.95em; diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 4dfd25a99..52f36ab54 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -40,24 +40,34 @@ border-color:#DDDDDD; background:none; } -input.submit, -#form_notice.warning #notice_text-count, -.form_settings .form_note, -.entity_remote_subscribe { -background-color:#9BB43E; +input.submit { +color:#FFFFFF; } - -input:focus, textarea:focus, select:focus, -#form_notice.warning #notice_data-text { -border-color:#9BB43E; -box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); --moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); --webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +.entity_actions input.submit { +border-color:transparent; +text-shadow:none; } +.dialogbox .submit_dialogbox, input.submit, -.entity_remote_subscribe, -#site_nav_local_views a { -color:#FFFFFF; +.form_notice input.submit { +background:#AAAAAA url(../../base/images/illustrations/illu_pattern-01.png) 0 0 repeat-x; +text-shadow:0 1px 0 #FFFFFF; +color:#000000; +border-color:#AAAAAA; +border-top-color:#CCCCCC; +border-left-color:#CCCCCC; +} +.dialogbox .submit_dialogbox:hover, +input.submit:hover { +background-position:0 -5px; +} +.dialogbox .submit_dialogbox:focus, +input.submit:focus { +background-position:0 -15px; +box-shadow:3px 3px 3px rgba(194, 194, 194, 0.1); +-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.1); +-webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.1); +text-shadow:none; } .form_notice label[for=notice_data-geo] { -- cgit v1.2.3-54-g00ecf From d955fb5e374d94526f9af928d28514e7b9a27a8f Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:22:01 +0100 Subject: Updated biz theme entity_actions styles --- theme/biz/css/base.css | 102 +++++++++++++++++++++++++++++++++++----------- theme/biz/css/display.css | 41 ++++++++++--------- 2 files changed, 100 insertions(+), 43 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index a8834ca57..bd70c083e 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -605,8 +605,9 @@ display:none; /*entity_actions*/ .entity_actions { float:right; -margin-left:4.35%; -max-width:25%; +margin-left:2%; +margin-bottom:18px; +min-width:21%; } .entity_actions h2 { display:none; @@ -615,7 +616,7 @@ display:none; list-style-type:none; } .entity_actions li { -margin-bottom:4px; +margin-bottom:7px; } .entity_actions li:first-child { border-top:0; @@ -633,40 +634,95 @@ display:block; text-align:left; width:100%; } -.entity_actions a, -.entity_nudge p, -.entity_remote_subscribe { +.entity_actions a { text-decoration:none; font-weight:bold; display:block; } +.entity_actions a, +.entity_actions input { +border-radius:4px; +-moz-border-radius:4px; +-webkit-border-radius:4px; +} -.form_user_block input.submit, -.form_user_unblock input.submit, -.entity_send-a-message a, -.entity_edit a, -.form_user_nudge input.submit, -.entity_nudge p { -border:0; -padding-left:20px; +.entity_actions a, +.entity_actions input, +.entity_actions p { +border-width:2px; +border-style:solid; +padding-left:23px; +} + +.entity_actions a, +.entity_actions p { +padding:2px 4px 1px 26px; } -.entity_edit a, -.entity_send-a-message a, -.entity_nudge p { -padding:4px 4px 4px 23px; +.entity_actions .accept { +margin-bottom:18px; } -.entity_remote_subscribe { -padding:4px; -border-width:2px; +.entity_send-a-message button { +position:absolute; +top:3px; +right:3px; +} + +.entity_send-a-message .form_notice { +position:absolute; +top:34px; +right:-1px; +padding:1.795%; +width:65%; +z-index:2; + border-radius:7px; +-moz-border-radius:7px; +-webkit-border-radius:7px; +border-width:1px; border-style:solid; +} +.entity_send-a-message .form_notice legend { +display:block; +margin-bottom:11px; +} + +.entity_send-a-message .form_notice label, +.entity_send-a-message .form_notice select { +display:none; +} +.entity_send-a-message .form_notice input.submit { +text-align:center; +} + +.entity_moderation { +position:relative; +} +.entity_moderation p { border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px; +font-weight:bold; +padding-bottom:2px; +margin-bottom:7px; } -.entity_actions .accept { -margin-bottom:18px; +.entity_moderation ul { +display:none; +} +.entity_moderation:hover ul { +display:block; +min-width:21%; +width:100%; +padding:11px; +position:absolute; +top:-1px; +right:-1px; +z-index:1; +border-width:1px; +border-style:solid; +border-radius:7px; +-moz-border-radius:7px; +-webkit-border-radius:7px; } .entity_tags ul { diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 52f36ab54..7fd78470f 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -186,7 +186,9 @@ box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); border-color:#FFFFFF; } #content, -#site_nav_local_views .current a { +#site_nav_local_views .current a, +.entity_send-a-message .form_notice, +.entity_moderation:hover ul { background-color:#FFFFFF; } @@ -231,30 +233,22 @@ background-position:0 -64px; background-position:0 1px; } -.entity_edit a, -.entity_send-a-message a, -.form_user_nudge input.submit, -.form_user_block input.submit, -.form_user_unblock input.submit, -.form_group_block input.submit, -.form_group_unblock input.submit, -.entity_nudge p, -.form_make_admin input.submit { -background-position: 0 40%; -background-repeat: no-repeat; -background-color:transparent; -} .form_group_join input.submit, -.form_group_leave input.submit +.form_group_leave input.submit, .form_user_subscribe input.submit, -.form_user_unsubscribe input.submit { -background-color:#9BB43E; +.form_user_unsubscribe input.submit, +.entity_subscribe a { +background-color:#AAAAAA; color:#FFFFFF; } -.form_user_unsubscribe input.submit, .form_group_leave input.submit, -.form_user_authorization input.reject { -background-color:#87B4C8; +.form_user_unsubscribe input.submit { +background-position:5px -1246px; +} +.form_group_join input.submit, +.form_user_subscribe input.submit, +.entity_subscribe a { +background-position:5px -1181px; } .entity_edit a { @@ -263,6 +257,12 @@ background-position: 5px -718px; .entity_send-a-message a { background-position: 5px -852px; } +.entity_send-a-message .form_notice, +.entity_moderation:hover ul { +box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7); +-moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7); +-webkit-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7); +} .entity_nudge p, .form_user_nudge input.submit { @@ -293,6 +293,7 @@ background-position: 5px -1511px; background-position: 5px -1973px; } + /* NOTICES */ .notice .attachment { background-position:0 -394px; -- cgit v1.2.3-54-g00ecf From d29af38a0be2f0944297898b166e86d0cebd9bd2 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:28:11 +0100 Subject: Update to biz theme's input styles --- theme/biz/css/display.css | 69 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 7fd78470f..0b7c17de7 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -25,14 +25,33 @@ address { margin-right:7.18%; } +input, textarea, select { +border-width:2px; +border-style: solid; +border-radius:4px; +-moz-border-radius:4px; +-webkit-border-radius:4px; +} input, textarea, select, option { font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; } -input, textarea, select, -.entity_remote_subscribe { +input, textarea, select { border-color:#AAAAAA; } -#filter_tags ul li { + +.form_settings fieldset fieldset { +background:rgba(240, 240, 240, 0.2); +box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); +-moz-box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); +-webkit-box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); +} + +#filter_tags ul li, +.entity_send-a-message .form_notice, +.pagination .nav_prev a, +.pagination .nav_next a, +.form_settings fieldset fieldset, +.entity_moderation:hover ul { border-color:#DDDDDD; } @@ -40,6 +59,34 @@ border-color:#DDDDDD; background:none; } +.form_notice.warning #notice_text-count, +.form_settings .form_note { +background-color:#9BB43E; +} +input.submit, +.form_notice.warning #notice_text-count, +.form_settings .form_note, +.entity_actions a, +.entity_actions input, +.entity_moderation p, +button { +box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +-webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); +} +.entity_actions a, +.entity_actions input, +.entity_actions p { +border-color:transparent; +background-color:transparent; +} +input:focus, textarea:focus, select:focus, +.form_notice.warning #notice_data-text, +.form_notice.warning #notice_text-count, +.form_settings .form_note { +border-color:#9BB43E; +} + input.submit { color:#FFFFFF; } @@ -78,18 +125,12 @@ background-position:0 -1846px; } a, -#site_nav_local_views .current a, -div.notice-options input, -.form_user_block input.submit, -.form_user_unblock input.submit, -.form_group_block input.submit, -.form_group_unblock input.submit, -.entity_send-a-message a, -.form_user_nudge input.submit, -.entity_nudge p, .form_settings input.form_action-primary, -.form_make_admin input.submit { -color:#002E6E; +.notice-options input, +.entity_actions a, +.entity_actions input, +.entity_moderation p { +color:#002FA7; } #header a, -- cgit v1.2.3-54-g00ecf From 1662aa11139517cccc600d65b9e8eba07c541ea7 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:32:24 +0100 Subject: Update to biz theme button close and minimize styles --- theme/biz/css/base.css | 17 +++++++++++++++++ theme/biz/css/display.css | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index bd70c083e..8a34425be 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -518,6 +518,11 @@ margin-bottom:0; line-height:1.618; } +.form_notice #notice_data-attach_selected button.close { +float:right; +font-size:0.8em; +} + .form_notice #notice_data-geo_wrap label, .form_notice #notice_data-geo_wrap input { position:absolute; @@ -539,6 +544,18 @@ margin-bottom:0; text-indent:-9999px; } +button.close, +button.minimize { +width:16px; +height:16px; +text-indent:-9999px; +padding:0; +border:0; +text-align:center; +font-weight:bold; +cursor:pointer; +} + /* entity_profile */ .entity_profile { position:relative; diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 0b7c17de7..7768d5146 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -256,6 +256,13 @@ background-color:#F7E8E8; background-color:#EFF3DC; } +button.close { +background-position:0 -1120px; +} +button.minimize { +background-position:0 -1912px; +} + #anon_notice { color:#FFFFFF; } -- cgit v1.2.3-54-g00ecf From b4babedd29661a15a8dd135a20ffaf7059b7fa50 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:36:33 +0100 Subject: Update to notice item in biz theme --- theme/biz/css/base.css | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 8a34425be..366339db2 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -903,6 +903,16 @@ float:left; #shownotice .vcard .photo { margin-bottom:4px; } +#content .notice .author .photo { +position:absolute; +top:11px; +left:0; +float:none; +} +#content .notice .entry-title { +margin-left:59px; +} + .vcard .url { text-decoration:none; } @@ -911,12 +921,22 @@ text-decoration:underline; } .notice .entry-title { -float:left; -width:100%; overflow:hidden; } +.notice .entry-title.ov { +overflow:visible; +} +#showstream .notice .entry-title, +#showstream .notice div.entry-content { +margin-left:0; +} #shownotice .notice .entry-title { +margin-left:110px; font-size:2.2em; +min-height:123px; +} +#shownotice .notice div.entry-content { +margin-left:0; } .notice p.entry-content { @@ -939,7 +959,7 @@ clear:left; float:left; font-size:0.95em; margin-left:59px; -width:65%; +width:64%; } #showstream .notice div.entry-content, #shownotice .notice div.entry-content { -- cgit v1.2.3-54-g00ecf From 22d9c32e7e755c36817912cb9e20554b23d211d4 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 18:39:30 +0100 Subject: Update to aside styles in biz theme --- theme/biz/css/base.css | 2 +- theme/biz/css/display.css | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index 366339db2..2c2ab33a0 100644 --- a/theme/biz/css/base.css +++ b/theme/biz/css/base.css @@ -422,7 +422,7 @@ float:left; width:29.917%; min-height:259px; float:left; -margin-left:0.385%; +margin-left:1%; } #form_notice { diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 7768d5146..f133ac30b 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -138,10 +138,22 @@ color:#002FA7; color:#87B4C8; } + + .notice, -.profile { -border-top-color:#CEE1E9; +.profile, +.application, +#content tbody tr { +border-top-color:#C8D1D5; +} +.mark-top { +border-color:#AAAAAA; } + +#aside_primary { +background-color:#144A6E; +} + .section .profile { border-top-color:#87B4C8; } -- cgit v1.2.3-54-g00ecf From 558bf0f48907ad463872075c778c12bc5821f510 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 28 Jan 2010 18:11:44 +0000 Subject: 'Sign in with Twitter' button img --- plugins/TwitterBridge/Sign-in-with-Twitter-lighter.png | Bin 0 -> 2490 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/TwitterBridge/Sign-in-with-Twitter-lighter.png diff --git a/plugins/TwitterBridge/Sign-in-with-Twitter-lighter.png b/plugins/TwitterBridge/Sign-in-with-Twitter-lighter.png new file mode 100644 index 000000000..297bb0340 Binary files /dev/null and b/plugins/TwitterBridge/Sign-in-with-Twitter-lighter.png differ -- cgit v1.2.3-54-g00ecf From d773ed8193ee63db360386507e0511d1742b2dd1 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 28 Jan 2010 18:34:25 +0000 Subject: Remove redundant session token field from form (was already being added by base class). --- lib/applicationeditform.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/applicationeditform.php b/lib/applicationeditform.php index 6f03a9bed..9b7d05861 100644 --- a/lib/applicationeditform.php +++ b/lib/applicationeditform.php @@ -168,8 +168,6 @@ class ApplicationEditForm extends Form $this->access_type = ''; } - $this->out->hidden('token', common_session_token()); - $this->out->elementStart('ul', 'form_data'); $this->out->elementStart('li', array('id' => 'application_icon')); -- cgit v1.2.3-54-g00ecf From 155a5d446f96651abf3eb62f9b5748e4bdfa0a76 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 28 Jan 2010 16:49:32 -0800 Subject: Manual failover for stomp queues. If an array of multiple servers is put in $config['queue']['stomp_server'], enqueues will pick a random server to send to (failing over automatically if any are down). Queue handling daemons connect all servers so they get events no matter where they were delivered. In case of disconnection, daemons should now handle it gracefully and attempt to reconnect every 60 seconds or so, automatically resubscribing to all queues once it's back up. Can put to 'native' failover for reads as well by disabling $config['stomp']['manual_failover'] = false; but this is untested and may explode in addition to requiring that your ActiveMQ cluster actually be set up to handle its own data distribution. Additionally, can choose which queues to mark as persistent by setting $config['stomp']['persistent'] to an array of queue names. --- lib/default.php | 1 + lib/liberalstomp.php | 24 +++- lib/stompqueuemanager.php | 354 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 299 insertions(+), 80 deletions(-) diff --git a/lib/default.php b/lib/default.php index 8de8b1097..c01508695 100644 --- a/lib/default.php +++ b/lib/default.php @@ -85,6 +85,7 @@ $default = 'stomp_username' => null, 'stomp_password' => null, 'stomp_persistent' => true, // keep items across queue server restart, if persistence is enabled + 'stomp_manual_failover' => true, // if multiple servers are listed, treat them as separate (enqueue on one randomly, listen on all) 'monitor' => null, // URL to monitor ping endpoint (work in progress) 'softlimit' => '90%', // total size or % of memory_limit at which to restart queue threads gracefully 'debug_memory' => false, // true to spit memory usage to log diff --git a/lib/liberalstomp.php b/lib/liberalstomp.php index c9233843a..3d38953fd 100644 --- a/lib/liberalstomp.php +++ b/lib/liberalstomp.php @@ -33,6 +33,22 @@ class LiberalStomp extends Stomp return $this->_socket; } + /** + * Return the host we're currently connected to. + * + * @return string + */ + function getServer() + { + $idx = $this->_currentHost; + if ($idx >= 0) { + $host = $this->_hosts[$idx]; + return "$host[0]:$host[1]"; + } else { + return '[unconnected]'; + } + } + /** * Make socket connection to the server * We also set the stream to non-blocking mode, since we'll be @@ -71,10 +87,12 @@ class LiberalStomp extends Stomp // @fixme this sometimes hangs in blocking mode... // shouldn't we have been idle until we found there's more data? $read = fread($this->_socket, $rb); - if ($read === false) { - $this->_reconnect(); + if ($read === false || ($read === '' && feof($this->_socket))) { + // @fixme possibly attempt an auto reconnect as old code? + throw new StompException("Error reading"); + //$this->_reconnect(); // @fixme this will lose prior items - return $this->readFrames(); + //return $this->readFrames(); } $data .= $read; if (strpos($data, "\x00") !== false) { diff --git a/lib/stompqueuemanager.php b/lib/stompqueuemanager.php index 4e2b58602..ec150bbb6 100644 --- a/lib/stompqueuemanager.php +++ b/lib/stompqueuemanager.php @@ -29,28 +29,37 @@ */ require_once 'Stomp.php'; +require_once 'Stomp/Exception.php'; class StompQueueManager extends QueueManager { - var $server = null; - var $username = null; - var $password = null; - var $base = null; - var $con = null; + protected $servers; + protected $username; + protected $password; + protected $base; protected $control; + + protected $useTransactions = true; protected $sites = array(); protected $subscriptions = array(); - protected $useTransactions = true; - protected $transaction = null; - protected $transactionCount = 0; + protected $cons = array(); // all open connections + protected $disconnect = array(); + protected $transaction = array(); + protected $transactionCount = array(); + protected $defaultIdx = 0; function __construct() { parent::__construct(); - $this->server = common_config('queue', 'stomp_server'); + $server = common_config('queue', 'stomp_server'); + if (is_array($server)) { + $this->servers = $server; + } else { + $this->servers = array($server); + } $this->username = common_config('queue', 'stomp_username'); $this->password = common_config('queue', 'stomp_password'); $this->base = common_config('queue', 'queue_basename'); @@ -99,9 +108,9 @@ class StompQueueManager extends QueueManager $message .= ':' . $param; } $this->_connect(); - $result = $this->con->send($this->control, - $message, - array ('created' => common_sql_now())); + $result = $this->_send($this->control, + $message, + array ('created' => common_sql_now())); if ($result) { $this->_log(LOG_INFO, "Sent control ping to queue daemons: $message"); return true; @@ -166,29 +175,59 @@ class StompQueueManager extends QueueManager /** * Saves a notice object reference into the queue item table. * @return boolean true on success + * @throws StompException on connection or send error */ public function enqueue($object, $queue) + { + $this->_connect(); + return $this->_doEnqueue($object, $queue, $this->defaultIdx); + } + + /** + * Saves a notice object reference into the queue item table + * on the given connection. + * + * @return boolean true on success + * @throws StompException on connection or send error + */ + protected function _doEnqueue($object, $queue, $idx) { $msg = $this->encode($object); $rep = $this->logrep($object); - $this->_connect(); - $props = array('created' => common_sql_now()); - if (common_config('queue', 'stomp_persistent')) { + if ($this->isPersistent($queue)) { $props['persistent'] = 'true'; } - $result = $this->con->send($this->queueName($queue), - $msg, // BODY of the message - $props); + + $con = $this->cons[$idx]; + $host = $con->getServer(); + $result = $con->send($this->queueName($queue), $msg, $props); if (!$result) { - common_log(LOG_ERR, "Error sending $rep to $queue queue"); + common_log(LOG_ERR, "Error sending $rep to $queue queue on $host"); return false; } - common_log(LOG_DEBUG, "complete remote queueing $rep for $queue"); + common_log(LOG_DEBUG, "complete remote queueing $rep for $queue on $host"); $this->stats('enqueued', $queue); + return true; + } + + /** + * Determine whether messages to this queue should be marked as persistent. + * Actual persistent storage depends on the queue server's configuration. + * @param string $queue + * @return bool + */ + protected function isPersistent($queue) + { + $mode = common_config('queue', 'stomp_persistent'); + if (is_array($mode)) { + return in_array($queue, $mode); + } else { + return (bool)$mode; + } } /** @@ -199,7 +238,29 @@ class StompQueueManager extends QueueManager */ public function getSockets() { - return array($this->con->getSocket()); + $sockets = array(); + foreach ($this->cons as $con) { + if ($con) { + $sockets[] = $con->getSocket(); + } + } + return $sockets; + } + + /** + * Get the Stomp connection object associated with the given socket. + * @param resource $socket + * @return int index into connections list + * @throws Exception + */ + protected function connectionFromSocket($socket) + { + foreach ($this->cons as $i => $con) { + if ($con && $con->getSocket() === $socket) { + return $i; + } + } + throw new Exception(__CLASS__ . " asked to read from unrecognized socket"); } /** @@ -211,27 +272,56 @@ class StompQueueManager extends QueueManager */ public function handleInput($socket) { - assert($socket === $this->con->getSocket()); + $idx = $this->connectionFromSocket($socket); + $con = $this->cons[$idx]; + $host = $con->getServer(); + $ok = true; - $frames = $this->con->readFrames(); + try { + $frames = $con->readFrames(); + } catch (StompException $e) { + common_log(LOG_ERR, "Lost connection to $host: " . $e->getMessage()); + $this->cons[$idx] = null; + $this->transaction[$idx] = null; + $this->disconnect[$idx] = time(); + return false; + } foreach ($frames as $frame) { $dest = $frame->headers['destination']; if ($dest == $this->control) { - if (!$this->handleControlSignal($frame)) { + if (!$this->handleControlSignal($idx, $frame)) { // We got a control event that requests a shutdown; // close out and stop handling anything else! break; } } else { - $ok = $ok && $this->handleItem($frame); + $ok = $ok && $this->handleItem($idx, $frame); } } return $ok; } + /** + * Attempt to reconnect in background if we lost a connection. + */ + function idle() + { + $now = time(); + foreach ($this->cons as $idx => $con) { + if (empty($con)) { + $age = $now - $this->disconnect[$idx]; + if ($age >= 60) { + $this->_reconnect($idx); + } + } + } + return true; + } + /** * Initialize our connection and subscribe to all the queues - * we're going to need to handle... + * we're going to need to handle... If multiple queue servers + * are configured for failover, we'll listen to all of them. * * Side effects: in multi-site mode, may reset site configuration. * @@ -241,10 +331,14 @@ class StompQueueManager extends QueueManager public function start($master) { parent::start($master); - $this->_connect(); + $this->_connectAll(); common_log(LOG_INFO, "Subscribing to $this->control"); - $this->con->subscribe($this->control); + foreach ($this->cons as $con) { + if ($con) { + $con->subscribe($this->control); + } + } if ($this->sites) { foreach ($this->sites as $server) { StatusNet::init($server); @@ -253,7 +347,11 @@ class StompQueueManager extends QueueManager } else { $this->doSubscribe(); } - $this->begin(); + foreach ($this->cons as $i => $con) { + if ($con) { + $this->begin($i); + } + } return true; } @@ -268,8 +366,12 @@ class StompQueueManager extends QueueManager { // If there are any outstanding delivered messages we haven't processed, // free them for another thread to take. - $this->rollback(); - $this->con->unsubscribe($this->control); + foreach ($this->cons as $i => $con) { + if ($con) { + $this->rollback($i); + $con->unsubscribe($this->control); + } + } if ($this->sites) { foreach ($this->sites as $server) { StatusNet::init($server); @@ -291,23 +393,106 @@ class StompQueueManager extends QueueManager } /** - * Lazy open connection to Stomp queue server. + * Lazy open a single connection to Stomp queue server. + * If multiple servers are configured, we let the Stomp client library + * worry about finding a working connection among them. */ protected function _connect() { - if (empty($this->con)) { - $this->_log(LOG_INFO, "Connecting to '$this->server' as '$this->username'..."); - $this->con = new LiberalStomp($this->server); - - if ($this->con->connect($this->username, $this->password)) { - $this->_log(LOG_INFO, "Connected."); + if (empty($this->cons)) { + $list = $this->servers; + if (count($list) > 1) { + shuffle($list); // Randomize to spread load + $url = 'failover://(' . implode(',', $list) . ')'; } else { - $this->_log(LOG_ERR, 'Failed to connect to queue server'); - throw new ServerException('Failed to connect to queue server'); + $url = $list[0]; } + $con = $this->_doConnect($url); + $this->cons = array($con); + $this->transactionCount = array(0); + $this->transaction = array(null); + $this->disconnect = array(null); } } + /** + * Lazy open connections to all Stomp servers, if in manual failover + * mode. This means the queue servers don't speak to each other, so + * we have to listen to all of them to make sure we get all events. + */ + protected function _connectAll() + { + if (!common_config('queue', 'stomp_manual_failover')) { + return $this->_connect(); + } + if (empty($this->cons)) { + $this->cons = array(); + $this->transactionCount = array(); + $this->transaction = array(); + foreach ($this->servers as $idx => $server) { + try { + $this->cons[] = $this->_doConnect($server); + $this->disconnect[] = null; + } catch (Exception $e) { + // s'okay, we'll live + $this->cons[] = null; + $this->disconnect[] = time(); + } + $this->transactionCount[] = 0; + $this->transaction[] = null; + } + if (empty($this->cons)) { + throw new ServerException("No queue servers reachable..."); + return false; + } + } + } + + protected function _reconnect($idx) + { + try { + $con = $this->_doConnect($this->servers[$idx]); + } catch (Exception $e) { + $this->_log(LOG_ERR, $e->getMessage()); + $con = null; + } + if ($con) { + $this->cons[$idx] = $con; + $this->disconnect[$idx] = null; + + // now we have to listen to everything... + // @fixme refactor this nicer. :P + $host = $con->getServer(); + $this->_log(LOG_INFO, "Resubscribing to $this->control on $host"); + $con->subscribe($this->control); + foreach ($this->subscriptions as $site => $queues) { + foreach ($queues as $queue) { + $this->_log(LOG_INFO, "Resubscribing to $queue on $host"); + $con->subscribe($queue); + } + } + $this->begin($idx); + } else { + // Try again later... + $this->disconnect[$idx] = time(); + } + } + + protected function _doConnect($server) + { + $this->_log(LOG_INFO, "Connecting to '$server' as '$this->username'..."); + $con = new LiberalStomp($server); + + if ($con->connect($this->username, $this->password)) { + $this->_log(LOG_INFO, "Connected."); + } else { + $this->_log(LOG_ERR, 'Failed to connect to queue server'); + throw new ServerException('Failed to connect to queue server'); + } + + return $con; + } + /** * Subscribe to all enabled notice queues for the current site. */ @@ -319,7 +504,11 @@ class StompQueueManager extends QueueManager $rawqueue = $this->queueName($queue); $this->subscriptions[$site][$queue] = $rawqueue; $this->_log(LOG_INFO, "Subscribing to $rawqueue"); - $this->con->subscribe($rawqueue); + foreach ($this->cons as $con) { + if ($con) { + $con->subscribe($rawqueue); + } + } } } @@ -333,7 +522,11 @@ class StompQueueManager extends QueueManager if (!empty($this->subscriptions[$site])) { foreach ($this->subscriptions[$site] as $queue => $rawqueue) { $this->_log(LOG_INFO, "Unsubscribing from $rawqueue"); - $this->con->unsubscribe($rawqueue); + foreach ($this->cons as $con) { + if ($con) { + $con->unsubscribe($rawqueue); + } + } unset($this->subscriptions[$site][$queue]); } } @@ -348,27 +541,31 @@ class StompQueueManager extends QueueManager * Side effects: in multi-site mode, may reset site configuration to * match the site that queued the event. * + * @param int $idx connection index * @param StompFrame $frame * @return bool */ - protected function handleItem($frame) + protected function handleItem($idx, $frame) { + $this->defaultIdx = $idx; + list($site, $queue) = $this->parseDestination($frame->headers['destination']); if ($site != $this->currentSite()) { $this->stats('switch'); StatusNet::init($site); } + $host = $this->cons[$idx]->getServer(); if (is_numeric($frame->body)) { $id = intval($frame->body); - $info = "notice $id posted at {$frame->headers['created']} in queue $queue"; + $info = "notice $id posted at {$frame->headers['created']} in queue $queue from $host"; $notice = Notice::staticGet('id', $id); if (empty($notice)) { $this->_log(LOG_WARNING, "Skipping missing $info"); - $this->ack($frame); - $this->commit(); - $this->begin(); + $this->ack($idx, $frame); + $this->commit($idx); + $this->begin($idx); $this->stats('badnotice', $queue); return false; } @@ -376,16 +573,16 @@ class StompQueueManager extends QueueManager $item = $notice; } else { // @fixme should we serialize, or json, or what here? - $info = "string posted at {$frame->headers['created']} in queue $queue"; + $info = "string posted at {$frame->headers['created']} in queue $queue from $host"; $item = $frame->body; } $handler = $this->getHandler($queue); if (!$handler) { $this->_log(LOG_ERR, "Missing handler class; skipping $info"); - $this->ack($frame); - $this->commit(); - $this->begin(); + $this->ack($idx, $frame); + $this->commit($idx); + $this->begin($idx); $this->stats('badhandler', $queue); return false; } @@ -397,18 +594,18 @@ class StompQueueManager extends QueueManager // FIXME we probably shouldn't have to do // this kind of queue management ourselves; // if we don't ack, it should resend... - $this->ack($frame); + $this->ack($idx, $frame); $this->enqueue($item, $queue); - $this->commit(); - $this->begin(); + $this->commit($idx); + $this->begin($idx); $this->stats('requeued', $queue); return false; } $this->_log(LOG_INFO, "Successfully handled $info"); - $this->ack($frame); - $this->commit(); - $this->begin(); + $this->ack($idx, $frame); + $this->commit($idx); + $this->begin($idx); $this->stats('handled', $queue); return true; } @@ -416,10 +613,11 @@ class StompQueueManager extends QueueManager /** * Process a control signal broadcast. * + * @param int $idx connection index * @param array $frame Stomp frame * @return bool true to continue; false to stop further processing. */ - protected function handleControlSignal($frame) + protected function handleControlSignal($idx, $frame) { $message = trim($frame->body); if (strpos($message, ':') !== false) { @@ -443,9 +641,9 @@ class StompQueueManager extends QueueManager $this->_log(LOG_ERR, "Ignoring unrecognized control message: $message"); } - $this->ack($frame); - $this->commit(); - $this->begin(); + $this->ack($idx, $frame); + $this->commit($idx); + $this->begin($idx); return $shutdown; } @@ -522,47 +720,49 @@ class StompQueueManager extends QueueManager common_log($level, 'StompQueueManager: '.$msg); } - protected function begin() + protected function begin($idx) { if ($this->useTransactions) { - if ($this->transaction) { + if (!empty($this->transaction[$idx])) { throw new Exception("Tried to start transaction in the middle of a transaction"); } - $this->transactionCount++; - $this->transaction = $this->master->id . '-' . $this->transactionCount . '-' . time(); - $this->con->begin($this->transaction); + $this->transactionCount[$idx]++; + $this->transaction[$idx] = $this->master->id . '-' . $this->transactionCount[$idx] . '-' . time(); + $this->cons[$idx]->begin($this->transaction[$idx]); } } - protected function ack($frame) + protected function ack($idx, $frame) { if ($this->useTransactions) { - if (!$this->transaction) { + if (empty($this->transaction[$idx])) { throw new Exception("Tried to ack but not in a transaction"); } + $this->cons[$idx]->ack($frame, $this->transaction[$idx]); + } else { + $this->cons[$idx]->ack($frame); } - $this->con->ack($frame, $this->transaction); } - protected function commit() + protected function commit($idx) { if ($this->useTransactions) { - if (!$this->transaction) { + if (empty($this->transaction[$idx])) { throw new Exception("Tried to commit but not in a transaction"); } - $this->con->commit($this->transaction); - $this->transaction = null; + $this->cons[$idx]->commit($this->transaction[$idx]); + $this->transaction[$idx] = null; } } - protected function rollback() + protected function rollback($idx) { if ($this->useTransactions) { - if (!$this->transaction) { + if (empty($this->transaction[$idx])) { throw new Exception("Tried to rollback but not in a transaction"); } - $this->con->commit($this->transaction); - $this->transaction = null; + $this->cons[$idx]->commit($this->transaction[$idx]); + $this->transaction[$idx] = null; } } } -- cgit v1.2.3-54-g00ecf From d13d73c5630244963f0c3bd9db68dd6c6451821a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 28 Jan 2010 18:40:38 -0500 Subject: Last-chance distribution if enqueueing fails --- classes/Notice.php | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index 90e3e76ef..a60dd5bcd 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -326,13 +326,7 @@ class Notice extends Memcached_DataObject # XXX: someone clever could prepend instead of clearing the cache $notice->blowOnInsert(); - if (common_config('queue', 'inboxes')) { - $qm = QueueManager::get(); - $qm->enqueue($notice, 'distrib'); - } else { - $handler = new DistribQueueHandler(); - $handler->handle($notice); - } + $notice->distribute(); return $notice; } @@ -1447,4 +1441,31 @@ class Notice extends Memcached_DataObject $gi->free(); } + + function distribute() + { + if (common_config('queue', 'inboxes')) { + // If there's a failure, we want to _force_ + // distribution at this point. + try { + $qm = QueueManager::get(); + $qm->enqueue($this, 'distrib'); + } catch (Exception $e) { + // If the exception isn't transient, this + // may throw more exceptions as DQH does + // its own enqueueing. So, we ignore them! + try { + $handler = new DistribQueueHandler(); + $handler->handle($this); + } catch (Exception $e) { + common_log(LOG_ERR, "emergency redistribution resulted in " . $e->getMessage()); + } + // Re-throw so somebody smarter can handle it. + throw $e; + } + } else { + $handler = new DistribQueueHandler(); + $handler->handle($this); + } + } } -- cgit v1.2.3-54-g00ecf