From b1402896e7dac59ab1eecae4babf83a06d2f256d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 09:13:21 -0800 Subject: [PATCH 01/24] 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 8c8b8da6dc..2bc4b892bd 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)); From 5c0560a7fc7d5e7bb9c91da7cc273d2dc89e32b2 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 19:50:08 -0800 Subject: [PATCH 02/24] 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 16e28e94d3..6c212453e4 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) From fbd52111e1cc68a1a2710701ae0a146bcce5580e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 19:58:33 -0800 Subject: [PATCH 03/24] 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 6b364fb5ce..90e3e76ef3 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1378,8 +1378,6 @@ class Notice extends Memcached_DataObject } $reply->free(); - - return $ids; } function clearRepeats() From c2c262e4b47f5a4965317148b66ff390f4fc85fd Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 28 Jan 2010 04:46:10 +0000 Subject: [PATCH 04/24] Move faceboookapp.js to the Facebook plugin --- plugins/Facebook/facebookaction.php | 4 +--- {js => plugins/Facebook}/facebookapp.js | 0 2 files changed, 1 insertion(+), 3 deletions(-) rename {js => plugins/Facebook}/facebookapp.js (100%) diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index 389e1ea81f..8437a705a7 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/js/facebookapp.js b/plugins/Facebook/facebookapp.js similarity index 100% rename from js/facebookapp.js rename to plugins/Facebook/facebookapp.js From 7347381183bfee96db8b2f89a4ba0ce5d04f76e2 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 27 Jan 2010 21:42:13 -0800 Subject: [PATCH 05/24] 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 b4e4a653c8..b482464aac 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); From dcce323d18d4b779d2456f32aa99dfac5e2b7520 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 15:05:23 +0100 Subject: [PATCH 06/24] 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 78abf34a76..85c169716a 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'); From 5b1245a32a04de602196d2216b9d25ac32e0fd3b Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 15:06:03 +0100 Subject: [PATCH 07/24] 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 90ff67073a..c529193860 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)); From c6f8b94fa91e3e5559a9b79766e7320b096b839e Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:02:39 +0100 Subject: [PATCH 08/24] 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 65dd159900..3c51deb312 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 3aebb239d3..06711850fc 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 2818196c20..1ac96ab5be 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 { From 61114ceff7c4124519cb5aa59b4d06ec73127e9d Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:39:20 +0100 Subject: [PATCH 09/24] 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 6357e55b4e..471ac580d9 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%; From d4289cb34e9aefe7ffea3ca506ea0223f7858cb6 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:41:28 +0100 Subject: [PATCH 10/24] 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 471ac580d9..2d4ac85ba6 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; From b969fba2f5de4edf43e514e23565e1a90f916d04 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 16:49:33 +0100 Subject: [PATCH 11/24] 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 2d4ac85ba6..47845421a3 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 7ea4515769..7a53b02bfc 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); From e881888789be64576cb299611c80a0d191fa5682 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:08:24 +0100 Subject: [PATCH 12/24] 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 47845421a3..4ce7b49caa 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 7a53b02bfc..4dfd25a996 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%; } From 6e556e502a13a1cfef51492707932635322f4bc4 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:09:35 +0100 Subject: [PATCH 13/24] 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 4ce7b49caa..ec8ca22f5f 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; From 83087e9d9b14b4425368dbd2f95ff6fcc909e7f6 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:12:48 +0100 Subject: [PATCH 14/24] 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 ec8ca22f5f..d5873b0b07 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; From 156efda37a2a6d2e16b061180fea828581691560 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:16:11 +0100 Subject: [PATCH 15/24] Updated biz theme to use dialogbox styles --- theme/biz/css/base.css | 43 ++++++++++++++++++++++++++++++++++++++ theme/biz/css/display.css | 44 ++++++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index d5873b0b07..a8834ca570 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 4dfd25a996..52f36ab54a 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -40,25 +40,35 @@ border-color:#DDDDDD; background:none; } -input.submit, -#form_notice.warning #notice_text-count, -.form_settings .form_note, -.entity_remote_subscribe { -background-color:#9BB43E; -} - -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); -} -input.submit, -.entity_remote_subscribe, -#site_nav_local_views a { +input.submit { color:#FFFFFF; } +.entity_actions input.submit { +border-color:transparent; +text-shadow:none; +} +.dialogbox .submit_dialogbox, +input.submit, +.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] { background-position:0 -1780px; From d955fb5e374d94526f9af928d28514e7b9a27a8f Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:22:01 +0100 Subject: [PATCH 16/24] Updated biz theme entity_actions styles --- theme/biz/css/base.css | 110 ++++++++++++++++++++++++++++---------- theme/biz/css/display.css | 41 +++++++------- 2 files changed, 104 insertions(+), 47 deletions(-) diff --git a/theme/biz/css/base.css b/theme/biz/css/base.css index a8834ca570..bd70c083e2 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,42 +634,97 @@ 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; } - -.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_edit a, -.entity_send-a-message a, -.entity_nudge p { -padding:4px 4px 4px 23px; -} - -.entity_remote_subscribe { -padding:4px; -border-width:2px; -border-style:solid; +.entity_actions a, +.entity_actions input { border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px; } + +.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_actions .accept { margin-bottom:18px; } +.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_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 { list-style-type:none; display:inline; diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index 52f36ab54a..7fd78470f5 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; From d29af38a0be2f0944297898b166e86d0cebd9bd2 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:28:11 +0100 Subject: [PATCH 17/24] 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 7fd78470f5..0b7c17de76 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, From 1662aa11139517cccc600d65b9e8eba07c541ea7 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:32:24 +0100 Subject: [PATCH 18/24] 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 bd70c083e2..8a34425be2 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 0b7c17de76..7768d5146a 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; } From b4babedd29661a15a8dd135a20ffaf7059b7fa50 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 17:36:33 +0100 Subject: [PATCH 19/24] 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 8a34425be2..366339db28 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 { From 22d9c32e7e755c36817912cb9e20554b23d211d4 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 28 Jan 2010 18:39:30 +0100 Subject: [PATCH 20/24] 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 366339db28..2c2ab33a01 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 7768d5146a..f133ac30b9 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; } From 558bf0f48907ad463872075c778c12bc5821f510 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 28 Jan 2010 18:11:44 +0000 Subject: [PATCH 21/24] 'Sign in with Twitter' button img --- .../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 0000000000000000000000000000000000000000..297bb03404f2d7462ee9355aae38f5f5f3e47fbd GIT binary patch literal 2490 zcmV;r2}SmaP)dbVG7wVRUJ4ZXi@?ZDjy8FEKeU zFgbGL({lg-0338hSaefwW^{L9a%BKPWN%_+AVz6&Wp{6KYjYq&Q#1y$)1UwV2@^>~ zK~!jg?VEdWl+_u=f8X9WA)72QVM!vF1VSK4AZQ?nK}o}NseS3JN$f zgRQMIo!W~OJ6`ZouvAJ_K&eH%O=zU35Dd9+OGJ}EvYTu++57IdU;kJVc9XpY6B?a; zX3k{ZIp=-eC+|7m`<-)kR{+>vQ7sWi9D|5ebEgWz_KIq$s4!>9f*d_|j-lj_V|e1| zv2!Q@e7>PCTvsDT9K#C=07>!<2 zJRT3v{^4m(e0B`AMuXes=AQD^+;C$tPj22q>4H*zdfz>`#KAid3>9xAeo+*W%jE#P zv+pgwyLbU*^X6iX@D|vxdJPV{BV^y=rMIzo>FtA}CzL%H7|@3PC-uR0k{o`MEpT&+ zmiCUwd$DjaD&G5mR^R=5Ugy>A zFL6`pd;osE=`rd~)-ZEc5shchvh}x5aZ~9nJpS;;UjCggyhMFX4IM@k^;K2OnpeX9 zJ+G59W-M>Ndx+<@J`*QB2?^MN1N-(fead7?=HEi6T!B@Box5IR=L;`>Ej{PX zHuTf??pp_V_K#2V&%f=WuDXUP)2>6K(eP;bS}ruV@b7*5sr;ydIrB8I2tIsDgsYdEB~aA*X6k7? zxX|2;qp^|Gwe@`Y#d&IupCC)EqUw`l7)GU&uTKu*U$o?QG#U*z%qZYj8`hDRoCLu8 zhbzgOI5DbLyT^;&?d{E@=<{Loc(HlBWQ@7?YwIarxgyB6oH@guS9eiXI-mWozJlq( z1uEY@fC2%N(MZ*iqs%Lw&3$(-XHs%f#Ci8GF3A_N^~J`q@N(Yec4#`>p8;Rm>`^(w z^()mX);zY6A1}KTOQ(hBpZ+tI2M_vvC6EgOasg^TuSW9u`2L~=xMTvlF=IdirA&q( z01}jz+(`M#6-+Id=Jypvl2wZSngV!x>{xvBuA7QRt)c4kYU--0D3~!Fhr>aA^+`_G z)iHDWG@POs#IMsQgCL+*sYp&si#>KieJ zAZPaXZl!3>9M-SjNX7dfvh?=bdf)$&1YWO*1jqy#ZFVPakM~lt{ns24pi(Mnce*e+ zoV|U5)IWA0uWtapa=C)>xf3{EU4zZ(WX19y(%RC@hySVMd_x1@*}REPr@KGD1PCBr zszd|P3jULJU(P|*6JUEpf1ZUYMN@b5y{gO~R0`R^ zzo2^1b1iYS>vBugsL9qPM&yVTyCwWp(Uo=ev@y*W7rS{ZmOePbh#j}_&X%YtxeZa(=9L5<&(e8Bi z<5wsYm^&^0MKr*8(egMLdIIf9`S}2Jn9Y=xl~T570XoAdF4!DlHH6a}anEJ-cv*VQ z<;7KRgYq-}Q)5qi@;qcECS38JtLDV#Y+3g(n;(3LUp}&dB%O}ct5)I-xFV2%>k11g zTUf@C&yKTa*KVdw^(R50loR*{_b2SKCHeZt4jkLpj^;ZlKOe6sQZ!>aT9uM(b0*;N zdYL_=0IS=B(gj7|CTgIo3w=s5DLNgUE;lDl z=6*ck(9~r1FRqNt5);TzP2p%4ylH~wfExv!+`pk8s}?!j(i+mgrP)GJVGd2L zrifxR3OQ=I9MLCX4Ray;#3LJ#2{HtkfT^vG#S0hk#JUIhwAC2&WDQrS)2nfk*V=iQ!Y2K(sVlqHpM%x^1{ck;y4Kin5jc`W;@8<8AFx4+YWs z?QSo2A}4+Q<6F?#y0F{r Date: Thu, 28 Jan 2010 18:34:25 +0000 Subject: [PATCH 22/24] 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 6f03a9beda..9b7d058614 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')); From 155a5d446f96651abf3eb62f9b5748e4bdfa0a76 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 28 Jan 2010 16:49:32 -0800 Subject: [PATCH 23/24] 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 8de8b10977..c01508695b 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 c9233843a4..3d38953fd2 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 4e2b586025..ec150bbb6e 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; } } } From d13d73c5630244963f0c3bd9db68dd6c6451821a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 28 Jan 2010 18:40:38 -0500 Subject: [PATCH 24/24] 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 90e3e76ef3..a60dd5bcd7 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); + } + } }