From 3371e243165df54f41febcb1a8ab578ca5950a18 Mon Sep 17 00:00:00 2001
From: Brion Vibber <brion@pobox.com>
Date: Sat, 24 Oct 2009 16:42:29 -0700
Subject: Add .DS_Store to .gitignore list; these are desktop metadata files
 maintained by Mac OS X Finder.

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 1cde3a625..217622c84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,4 @@ config-*.php
 good-config.php
 lac08.log
 php.log
-
+.DS_Store
-- 
cgit v1.2.3-54-g00ecf


From 0b4390e7f2322a15f16919425de039d555b3e516 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Mon, 26 Oct 2009 10:31:12 -0400
Subject: Make email domain checking optional, as some statusnet installations
 (such as those behind restrictive corporate firewalls, or on home systems on
 restrictive connections) cannot connect to any mail systems, and this check
 will always fail.

---
 actions/emailsettings.php            | 2 +-
 actions/invite.php                   | 2 +-
 actions/register.php                 | 2 +-
 config.php.sample                    | 4 ++++
 lib/default.php                      | 3 ++-
 plugins/OpenID/finishopenidlogin.php | 2 +-
 plugins/OpenID/openid.php            | 2 +-
 7 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/actions/emailsettings.php b/actions/emailsettings.php
index 6eff06c0d..67b991cdc 100644
--- a/actions/emailsettings.php
+++ b/actions/emailsettings.php
@@ -326,7 +326,7 @@ class EmailsettingsAction extends AccountSettingsAction
             $this->showForm(_('Cannot normalize that email address'));
             return;
         }
-        if (!Validate::email($email, true)) {
+        if (!Validate::email($email, common_config('email', 'check_domain'))) {
             $this->showForm(_('Not a valid email address'));
             return;
         } else if ($user->email == $email) {
diff --git a/actions/invite.php b/actions/invite.php
index 788130c58..3015202e9 100644
--- a/actions/invite.php
+++ b/actions/invite.php
@@ -68,7 +68,7 @@ class InviteAction extends CurrentUserDesignAction
 
         foreach ($addresses as $email) {
             $email = trim($email);
-            if (!Validate::email($email, true)) {
+            if (!Validate::email($email, common_config('email', 'check_domain'))) {
                 $this->showForm(sprintf(_('Invalid email address: %s'), $email));
                 return;
             }
diff --git a/actions/register.php b/actions/register.php
index 100ab7424..a6c1a903a 100644
--- a/actions/register.php
+++ b/actions/register.php
@@ -191,7 +191,7 @@ class RegisterAction extends Action
             if (!$this->boolean('license')) {
                 $this->showForm(_('You can\'t register if you don\'t '.
                                   'agree to the license.'));
-            } else if ($email && !Validate::email($email, true)) {
+            } else if ($email && !Validate::email($email, common_config('email', 'check_domain'))) {
                 $this->showForm(_('Not a valid email address.'));
             } else if (!Validate::string($nickname, array('min_length' => 1,
                                                           'max_length' => 64,
diff --git a/config.php.sample b/config.php.sample
index 997c9d6b0..9fccb84f3 100644
--- a/config.php.sample
+++ b/config.php.sample
@@ -104,6 +104,10 @@ $config['sphinx']['port'] = 3312;
 // $config['site']['timezone'] = 'Pacific/Auckland';
 // $config['site']['language'] = 'en_NZ';
 
+// When validating user supplied email addresses, validate if the domain
+// is running an SMTP server.
+// $config['mail']['check_domain'] = true;
+
 // Email info, used for all outbound email
 // $config['mail']['notifyfrom'] = 'microblog@example.net';
 // $config['mail']['domain'] = 'microblog.example.net';
diff --git a/lib/default.php b/lib/default.php
index 30e43eefb..9f64cc9e4 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -84,7 +84,8 @@ $default =
               'image' => 'http://i.creativecommons.org/l/by/3.0/80x15.png'),
         'mail' =>
         array('backend' => 'mail',
-              'params' => null),
+              'params' => null,
+              'domain_check' => true),
         'nickname' =>
         array('blacklist' => array(),
               'featured' => array()),
diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php
index 50a9c15c8..ff0b451d3 100644
--- a/plugins/OpenID/finishopenidlogin.php
+++ b/plugins/OpenID/finishopenidlogin.php
@@ -265,7 +265,7 @@ class FinishopenidloginAction extends Action
             $fullname = '';
         }
 
-        if (!empty($sreg['email']) && Validate::email($sreg['email'], true)) {
+        if (!empty($sreg['email']) && Validate::email($sreg['email'], common_config('email', 'check_domain'))) {
             $email = $sreg['email'];
         } else {
             $email = '';
diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php
index 0944117c0..b76497c28 100644
--- a/plugins/OpenID/openid.php
+++ b/plugins/OpenID/openid.php
@@ -241,7 +241,7 @@ function oid_update_user(&$user, &$sreg)
 
     $orig_user = clone($user);
 
-    if ($sreg['email'] && Validate::email($sreg['email'], true)) {
+    if ($sreg['email'] && Validate::email($sreg['email'], common_config('email', 'check_domain'))) {
         $user->email = $sreg['email'];
     }
 
-- 
cgit v1.2.3-54-g00ecf


From 0e029d728429009e7791ae052df4e9998e309fab Mon Sep 17 00:00:00 2001
From: Sarven Capadisli <csarven@status.net>
Date: Tue, 27 Oct 2009 14:59:58 +0100
Subject: Some CSS updates for FB app

---
 theme/base/css/facebookapp.css | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/theme/base/css/facebookapp.css b/theme/base/css/facebookapp.css
index e6b1c9ee5..47c63d823 100644
--- a/theme/base/css/facebookapp.css
+++ b/theme/base/css/facebookapp.css
@@ -5,8 +5,8 @@ font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
 
 #wrap {
 background-color:#F0F2F5;
-padding-left:18px;
-padding-right:18px;
+padding-left:1.795%;
+padding-right:1.795%;
 width:auto;
 }
 
@@ -15,8 +15,16 @@ h1,h2,h3,h4,h5,h6 {
 color:#000;
 }
 
+#header {
+width:131%;
+}
+
 #content {
-width:95%;
+width:92.7%;
+}
+
+#aside_primary {
+display:none;
 }
 
 #site_nav_local_views a {
@@ -26,6 +34,22 @@ background-color:#D0DFE7;
 background-color:#FAFBFC;
 }
 
+#form_notice .form_note + label {
+position:absolute;
+top:25px;
+right:10.5%;
+cursor:pointer;
+text-indent:-9999px;
+width:16px;
+height:16px;
+background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
+}
+
+#form_notice #notice_action-submit {
+height:47px !important;
+}
+
+
 span.facebook-button {
 border: 2px solid #aaa;
 padding: 3px;
-- 
cgit v1.2.3-54-g00ecf


From 0c8990b435695654131d6ae7a734e3059febb0b6 Mon Sep 17 00:00:00 2001
From: Sarven Capadisli <csarven@status.net>
Date: Tue, 27 Oct 2009 16:32:09 +0100
Subject: Slight alignment

---
 theme/default/css/display.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/theme/default/css/display.css b/theme/default/css/display.css
index 6833373b4..a5f1fd6e4 100644
--- a/theme/default/css/display.css
+++ b/theme/default/css/display.css
@@ -18,7 +18,7 @@ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
 font-size:1em;
 }
 address {
-margin-right:5.8%;
+margin-right:5.7%;
 }
 
 input, textarea, select, option {
-- 
cgit v1.2.3-54-g00ecf


From c370f0aadffd136ac80ad732bab05e415afd20c8 Mon Sep 17 00:00:00 2001
From: Sarven Capadisli <csarven@status.net>
Date: Tue, 27 Oct 2009 17:44:55 +0100
Subject: Removed attachment UI

---
 theme/base/css/facebookapp.css | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/theme/base/css/facebookapp.css b/theme/base/css/facebookapp.css
index 47c63d823..8cd06f78a 100644
--- a/theme/base/css/facebookapp.css
+++ b/theme/base/css/facebookapp.css
@@ -34,15 +34,9 @@ background-color:#D0DFE7;
 background-color:#FAFBFC;
 }
 
-#form_notice .form_note + label {
-position:absolute;
-top:25px;
-right:10.5%;
-cursor:pointer;
-text-indent:-9999px;
-width:16px;
-height:16px;
-background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
+#form_notice .form_note + label,
+#form_notice #notice_data-attach {
+display:none;
 }
 
 #form_notice #notice_action-submit {
-- 
cgit v1.2.3-54-g00ecf


From 4de05f1e475ef21fabd0fc607dec31506ad8dbf8 Mon Sep 17 00:00:00 2001
From: Zach Copley <zach@status.net>
Date: Tue, 27 Oct 2009 21:00:26 +0000
Subject: Forgot to move the facebookapp.css file into the new Facebook plugin

---
 plugins/Facebook/facebookaction.php |   4 +-
 plugins/Facebook/facebookapp.css    | 115 ++++++++++++++++++++++++++++++++++++
 theme/base/css/facebookapp.css      | 115 ------------------------------------
 3 files changed, 117 insertions(+), 117 deletions(-)
 create mode 100644 plugins/Facebook/facebookapp.css
 delete mode 100644 theme/base/css/facebookapp.css

diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php
index f5ad3d06b..a10fdf90d 100644
--- a/plugins/Facebook/facebookaction.php
+++ b/plugins/Facebook/facebookaction.php
@@ -83,8 +83,8 @@ class FacebookAction extends Action
     function showStylesheets()
     {
         $this->cssLink('css/display.css', 'base');
-        $this->cssLink('css/display.css',null,'screen, projection, tv');
-        $this->cssLink('css/facebookapp.css', 'base');
+        $this->cssLink('css/display.css', null, 'screen, projection, tv');
+        $this->cssLink('plugins/Facebook/facebookapp.css');
     }
 
     function showScripts()
diff --git a/plugins/Facebook/facebookapp.css b/plugins/Facebook/facebookapp.css
new file mode 100644
index 000000000..8cd06f78a
--- /dev/null
+++ b/plugins/Facebook/facebookapp.css
@@ -0,0 +1,115 @@
+* {
+font-size:14px;
+font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
+}
+
+#wrap {
+background-color:#F0F2F5;
+padding-left:1.795%;
+padding-right:1.795%;
+width:auto;
+}
+
+p,label,
+h1,h2,h3,h4,h5,h6 {
+color:#000;
+}
+
+#header {
+width:131%;
+}
+
+#content {
+width:92.7%;
+}
+
+#aside_primary {
+display:none;
+}
+
+#site_nav_local_views a {
+background-color:#D0DFE7;
+}
+#site_nav_local_views a:hover {
+background-color:#FAFBFC;
+}
+
+#form_notice .form_note + label,
+#form_notice #notice_data-attach {
+display:none;
+}
+
+#form_notice #notice_action-submit {
+height:47px !important;
+}
+
+
+span.facebook-button {
+border: 2px solid #aaa;
+padding: 3px;
+display: block;
+float: left;
+margin-right: 20px;
+-moz-border-radius: 4px; 
+border-radius:4px; 
+-webkit-border-radius:4px;
+font-weight: bold;
+background-color:#A9BF4F;
+color:#fff;
+font-size:1.2em
+}
+
+span.facebook-button a { color:#fff }
+
+.facebook_guide {
+margin-bottom:18px;
+}
+.facebook_guide p {
+font-weight:bold;
+}
+
+
+input {
+height:auto !important;
+}
+
+#facebook-friends {
+float:left;
+width:100%;
+}
+
+#facebook-friends li {
+float:left;
+margin-right:2%;
+margin-bottom:11px;
+width:18%;
+height:115px;
+}
+#facebook-friends li a {
+float:left;
+}
+
+#add_to_profile {
+position:absolute;
+right:18px;
+top:10px;
+z-index:2;
+}
+
+.notice div.entry-content dl,
+.notice div.entry-content dt, 
+.notice div.entry-content dd {
+margin-right:5px;
+}
+
+#content_inner p {
+margin-bottom:18px;
+}
+
+#content_inner ul {
+list-style-type:none;
+}
+
+.form_settings label {
+margin-right:18px;
+}
diff --git a/theme/base/css/facebookapp.css b/theme/base/css/facebookapp.css
deleted file mode 100644
index 8cd06f78a..000000000
--- a/theme/base/css/facebookapp.css
+++ /dev/null
@@ -1,115 +0,0 @@
-* {
-font-size:14px;
-font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
-}
-
-#wrap {
-background-color:#F0F2F5;
-padding-left:1.795%;
-padding-right:1.795%;
-width:auto;
-}
-
-p,label,
-h1,h2,h3,h4,h5,h6 {
-color:#000;
-}
-
-#header {
-width:131%;
-}
-
-#content {
-width:92.7%;
-}
-
-#aside_primary {
-display:none;
-}
-
-#site_nav_local_views a {
-background-color:#D0DFE7;
-}
-#site_nav_local_views a:hover {
-background-color:#FAFBFC;
-}
-
-#form_notice .form_note + label,
-#form_notice #notice_data-attach {
-display:none;
-}
-
-#form_notice #notice_action-submit {
-height:47px !important;
-}
-
-
-span.facebook-button {
-border: 2px solid #aaa;
-padding: 3px;
-display: block;
-float: left;
-margin-right: 20px;
--moz-border-radius: 4px; 
-border-radius:4px; 
--webkit-border-radius:4px;
-font-weight: bold;
-background-color:#A9BF4F;
-color:#fff;
-font-size:1.2em
-}
-
-span.facebook-button a { color:#fff }
-
-.facebook_guide {
-margin-bottom:18px;
-}
-.facebook_guide p {
-font-weight:bold;
-}
-
-
-input {
-height:auto !important;
-}
-
-#facebook-friends {
-float:left;
-width:100%;
-}
-
-#facebook-friends li {
-float:left;
-margin-right:2%;
-margin-bottom:11px;
-width:18%;
-height:115px;
-}
-#facebook-friends li a {
-float:left;
-}
-
-#add_to_profile {
-position:absolute;
-right:18px;
-top:10px;
-z-index:2;
-}
-
-.notice div.entry-content dl,
-.notice div.entry-content dt, 
-.notice div.entry-content dd {
-margin-right:5px;
-}
-
-#content_inner p {
-margin-bottom:18px;
-}
-
-#content_inner ul {
-list-style-type:none;
-}
-
-.form_settings label {
-margin-right:18px;
-}
-- 
cgit v1.2.3-54-g00ecf


From a1798039b23ed5d4b92458478bd76c7055d601e2 Mon Sep 17 00:00:00 2001
From: Zach Copley <zach@status.net>
Date: Tue, 27 Oct 2009 21:07:17 +0000
Subject: Specify the number of cols for the Facebook app's multi-friend
 inviter widget so it fits better into Facebook's new layout.

---
 plugins/Facebook/facebookinvite.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plugins/Facebook/facebookinvite.php b/plugins/Facebook/facebookinvite.php
index ecda1717c..3380b4c85 100644
--- a/plugins/Facebook/facebookinvite.php
+++ b/plugins/Facebook/facebookinvite.php
@@ -105,6 +105,7 @@ class FacebookinviteAction extends FacebookAction
         $multi_params = array('showborder' => 'false');
         $multi_params['actiontext'] = $actiontext;
         $multi_params['bypass'] = 'cancel';
+        $multi_params['cols'] = 4;
 
         // Get a list of users who are already using the app for exclusion
         $exclude_ids = $this->facebook->api_client->friends_getAppUsers();
-- 
cgit v1.2.3-54-g00ecf


From 922ee7b3b292689806b0b94a9eb94fe08a204751 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Tue, 27 Oct 2009 21:48:56 -0400
Subject: Implemented reply # command, allowing users to favorite specific
 notices by the notice id

---
 lib/command.php | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/lib/command.php b/lib/command.php
index 11d40b8e1..6ece01b96 100644
--- a/lib/command.php
+++ b/lib/command.php
@@ -124,18 +124,30 @@ class FavCommand extends Command
 
     function execute($channel)
     {
+        if(substr($this->other,0,1)=='#'){
+            //replying to a specific notice_id
 
-        $recipient =
-          common_relative_profile($this->user, common_canonical_nickname($this->other));
+            $notice = Notice::staticGet(substr($this->other,1));
+            if (!$notice) {
+                $channel->error($this->user, _('Notice with that id does not exist'));
+                return;
+            }
+            $recipient = $notice->getProfile();
+        }else{
+            //replying to a given user's last notice
 
-        if (!$recipient) {
-            $channel->error($this->user, _('No such user.'));
-            return;
-        }
-        $notice = $recipient->getCurrentNotice();
-        if (!$notice) {
-            $channel->error($this->user, _('User has no last notice'));
-            return;
+            $recipient =
+              common_relative_profile($this->user, common_canonical_nickname($this->other));
+
+            if (!$recipient) {
+                $channel->error($this->user, _('No such user.'));
+                return;
+            }
+            $notice = $recipient->getCurrentNotice();
+            if (!$notice) {
+                $channel->error($this->user, _('User has no last notice'));
+                return;
+            }
         }
 
         $fave = Fave::addNew($this->user, $notice);
@@ -497,6 +509,7 @@ class HelpCommand extends Command
                            "get <nickname> - get last notice from user\n".
                            "whois <nickname> - get profile info on user\n".
                            "fav <nickname> - add user's last notice as a 'fave'\n".
+                           "fav #<notice_id> - add notice with the given id as a 'fave'\n".
                            "join <group> - join group\n".
                            "drop <group> - leave group\n".
                            "stats - get your stats\n".
-- 
cgit v1.2.3-54-g00ecf


From 7b30e3c00f9fea529ee71a9783006956960ca5e2 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Tue, 27 Oct 2009 22:02:55 -0400
Subject: Shorten the notice text after command processing is done

---
 actions/newnotice.php | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/actions/newnotice.php b/actions/newnotice.php
index 9ee031f93..fe7df0938 100644
--- a/actions/newnotice.php
+++ b/actions/newnotice.php
@@ -160,18 +160,12 @@ class NewnoticeAction extends Action
 
         if (!$content) {
             $this->clientError(_('No content!'));
-        } else {
-            $content_shortened = common_shorten_links($content);
-            if (Notice::contentTooLong($content_shortened)) {
-                $this->clientError(sprintf(_('That\'s too long. '.
-                                             'Max notice size is %d chars.'),
-                                           Notice::maxContent()));
-            }
+            return;
         }
 
         $inter = new CommandInterpreter();
 
-        $cmd = $inter->handle_command($user, $content_shortened);
+        $cmd = $inter->handle_command($user, $content);
 
         if ($cmd) {
             if ($this->boolean('ajax')) {
@@ -182,6 +176,13 @@ class NewnoticeAction extends Action
             return;
         }
 
+        $content_shortened = common_shorten_links($content);
+        if (Notice::contentTooLong($content_shortened)) {
+            $this->clientError(sprintf(_('That\'s too long. '.
+                                         'Max notice size is %d chars.'),
+                                       Notice::maxContent()));
+        }
+
         $replyto = $this->trimmed('inreplyto');
         #If an ID of 0 is wrongly passed here, it will cause a database error,
         #so override it...
-- 
cgit v1.2.3-54-g00ecf


From da16dc05a81e2fcc1ed89fe16717f2652265f23a Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Tue, 27 Oct 2009 22:30:21 -0400
Subject: Added a new "reply" command

---
 lib/command.php            | 71 ++++++++++++++++++++++++++++++++++++++++++++--
 lib/commandinterpreter.php | 11 +++++++
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/lib/command.php b/lib/command.php
index 6ece01b96..d7ae11361 100644
--- a/lib/command.php
+++ b/lib/command.php
@@ -125,7 +125,7 @@ class FavCommand extends Command
     function execute($channel)
     {
         if(substr($this->other,0,1)=='#'){
-            //replying to a specific notice_id
+            //favoriting a specific notice_id
 
             $notice = Notice::staticGet(substr($this->other,1));
             if (!$notice) {
@@ -134,7 +134,7 @@ class FavCommand extends Command
             }
             $recipient = $notice->getProfile();
         }else{
-            //replying to a given user's last notice
+            //favoriting a given user's last notice
 
             $recipient =
               common_relative_profile($this->user, common_canonical_nickname($this->other));
@@ -359,6 +359,71 @@ class MessageCommand extends Command
     }
 }
 
+class ReplyCommand extends Command
+{
+    var $other = null;
+    var $text = null;
+    function __construct($user, $other, $text)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+        $this->text = $text;
+    }
+
+    function execute($channel)
+    {
+        if(substr($this->other,0,1)=='#'){
+            //replying to a specific notice_id
+
+            $notice = Notice::staticGet(substr($this->other,1));
+            if (!$notice) {
+                $channel->error($this->user, _('Notice with that id does not exist'));
+                return;
+            }
+            $recipient = $notice->getProfile();
+        }else{
+            //replying to a given user's last notice
+
+            $recipient =
+              common_relative_profile($this->user, common_canonical_nickname($this->other));
+
+            if (!$recipient) {
+                $channel->error($this->user, _('No such user.'));
+                return;
+            }
+            $notice = $recipient->getCurrentNotice();
+            if (!$notice) {
+                $channel->error($this->user, _('User has no last notice'));
+                return;
+            }
+        }
+
+        $len = mb_strlen($this->text);
+
+        if ($len == 0) {
+            $channel->error($this->user, _('No content!'));
+            return;
+        }
+
+        $this->text = common_shorten_links($this->text);
+
+        if (Notice::contentTooLong($this->text)) {
+            $channel->error($this->user, sprintf(_('Notice too long - maximum is %d characters, you sent %d'),
+                                                 Notice::maxContent(), mb_strlen($this->text)));
+            return;
+        }
+
+        $notice = Notice::saveNew($this->user->id, $this->text, $channel->source(), 1,
+                                  $notice->id);
+        if ($notice) {
+            $channel->output($this->user, sprintf(_('Reply to %s sent'), $recipient->nickname));
+        } else {
+            $channel->error($this->user, _('Error saving notice.'));
+        }
+        common_broadcast_notice($notice);
+    }
+}
+
 class GetCommand extends Command
 {
 
@@ -510,6 +575,8 @@ class HelpCommand extends Command
                            "whois <nickname> - get profile info on user\n".
                            "fav <nickname> - add user's last notice as a 'fave'\n".
                            "fav #<notice_id> - add notice with the given id as a 'fave'\n".
+                           "reply #<notice_id> - reply to notice with a given id\n".
+                           "reply <nickname> - reply to the last notice from user\n".
                            "join <group> - join group\n".
                            "drop <group> - leave group\n".
                            "stats - get your stats\n".
diff --git a/lib/commandinterpreter.php b/lib/commandinterpreter.php
index 60fc4c3c4..b921a17cc 100644
--- a/lib/commandinterpreter.php
+++ b/lib/commandinterpreter.php
@@ -134,6 +134,17 @@ class CommandInterpreter
             } else {
                 return new MessageCommand($user, $other, $extra);
             }
+         case 'r':
+         case 'reply':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = $this->split_arg($arg);
+            if (!$extra) {
+                return null;
+            } else {
+                return new ReplyCommand($user, $other, $extra);
+            }
          case 'whois':
             if (!$arg) {
                 return null;
-- 
cgit v1.2.3-54-g00ecf


From 5f42023f97fca2c3b5fbd0da2d5e333e4cc2f109 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Tue, 27 Oct 2009 22:45:00 -0400
Subject: implement the nudge command

---
 lib/command.php | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/lib/command.php b/lib/command.php
index d7ae11361..9efa40696 100644
--- a/lib/command.php
+++ b/lib/command.php
@@ -73,7 +73,7 @@ class UntrackCommand extends UnimplementedCommand
     }
 }
 
-class NudgeCommand extends UnimplementedCommand
+class NudgeCommand extends Command
 {
     var $other = null;
     function __construct($user, $other)
@@ -81,6 +81,26 @@ class NudgeCommand extends UnimplementedCommand
         parent::__construct($user);
         $this->other = $other;
     }
+    function execute($channel)
+    {
+        $recipient = User::staticGet('nickname', $this->other);
+        if(! $recipient){
+            $channel->error($this->user, sprintf(_('Could not find a user with nickname %s'),
+                               $this->other));
+        }else{
+            if ($recipient->id == $this->user->id) {
+                $channel->error($this->user, _('It does not make a lot of sense to nudge yourself!'));
+            }else{
+                if ($recipient->email && $recipient->emailnotifynudge) {
+                    mail_notify_nudge($this->user, $recipient);
+                }
+                // XXX: notify by IM
+                // XXX: notify by SMS
+                $channel->output($this->user, sprintf(_('Nudge sent to %s'),
+                               $recipient->nickname));
+            }
+        }
+    }
 }
 
 class InviteCommand extends UnimplementedCommand
@@ -587,7 +607,7 @@ class HelpCommand extends Command
                            "last <nickname> - same as 'get'\n".
                            "on <nickname> - not yet implemented.\n".
                            "off <nickname> - not yet implemented.\n".
-                           "nudge <nickname> - not yet implemented.\n".
+                           "nudge <nickname> - remind a user to update.\n".
                            "invite <phone number> - not yet implemented.\n".
                            "track <word> - not yet implemented.\n".
                            "untrack <word> - not yet implemented.\n".
-- 
cgit v1.2.3-54-g00ecf


From 5fd7ed5b149ba74d9f5044f1d5d18f7adf48ff78 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Tue, 27 Oct 2009 23:31:49 -0400
Subject: Display user avatar in the XMPP message Include notice id and
 conversation link the XMPP message

Thanks to Deepspawn for this idea and initial code
---
 lib/jabber.php | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/jabber.php b/lib/jabber.php
index 3dcdce5db..73f2ec660 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -176,6 +176,7 @@ function jabber_format_entry($profile, $notice)
     $xs = new XMLStringer();
     $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
     $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
+    $xs->element("img", array('src'=> $profile->avatarUrl(AVATAR_MINI_SIZE) , 'alt' => $profile->nickname));
     $xs->element('a', array('href' => $profile->profileurl),
                  $profile->nickname);
     $xs->text(": ");
@@ -184,6 +185,11 @@ function jabber_format_entry($profile, $notice)
     } else {
         $xs->raw(common_render_content($notice->content, $notice));
     }
+    $xs->raw(" ");
+    $xs->element('a', array(
+        'href'=>common_local_url('conversation',
+            array('id' => $notice->conversation)).'#notice-'.$notice->id
+         ),sprintf(_('notice id: %s'),$notice->id));
     $xs->elementEnd('body');
     $xs->elementEnd('html');
 
-- 
cgit v1.2.3-54-g00ecf


From bf701b8235c22e648e44adfed8a9cb8e30cf9eab Mon Sep 17 00:00:00 2001
From: Carlos Perilla <deepspawn@valkertown.org>
Date: Mon, 31 Aug 2009 23:01:36 -0500
Subject: Enable welcome bot to broadcast it's notices

---
 classes/User.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/classes/User.php b/classes/User.php
index 0a70c9801..9481399f8 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -319,6 +319,7 @@ class User extends Memcached_DataObject
                                                   common_config('site', 'name'),
                                                   $user->nickname),
                                           'system');
+                common_broadcast_notice($notice);
             }
         }
 
-- 
cgit v1.2.3-54-g00ecf