]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
IM cleanup on 1.0.x branch:
authorBrion Vibber <brion@pobox.com>
Fri, 30 Apr 2010 21:41:54 +0000 (14:41 -0700)
committerBrion Vibber <brion@pobox.com>
Fri, 30 Apr 2010 22:29:05 +0000 (15:29 -0700)
* Fake_XMPP back to Queued_XMPP, refactor how we use it and don't create objects and load classes until we need them.
* fix fatal error in IM settings while waiting for a Jabber confirmation.
* Caching fix for user_im_prefs
* fix for saving multiple transport settings
* some fixes for AIM & using normalized addresses for lookups

actions/imsettings.php
classes/User_im_prefs.php
classes/statusnet.ini
lib/implugin.php
plugins/Aim/AimPlugin.php
plugins/Aim/README
plugins/Xmpp/Fake_XMPP.php [deleted file]
plugins/Xmpp/Queued_XMPP.php [new file with mode: 0644]
plugins/Xmpp/XmppPlugin.php

index 2c2606b76c78765a93f69c74ff8a7ef96b37d5f1..662b1063e72b5cd7578a74ea727441ed829f1a02 100644 (file)
@@ -133,8 +133,7 @@ class ImsettingsAction extends ConnectSettingsAction
                                              'message with further instructions. '.
                                              '(Did you add %s to your buddy list?)'),
                                              $transport_info['display'],
-                                             $transport_info['daemon_screenname'],
-                                             jabber_daemon_address()));
+                                             $transport_info['daemon_screenname']));
                     $this->hidden('screenname', $confirm->address);
                     // TRANS: Button label to cancel an IM address confirmation procedure.
                     $this->submit('cancel', _m('BUTTON','Cancel'));
@@ -163,12 +162,11 @@ class ImsettingsAction extends ConnectSettingsAction
                                               'action' =>
                                               common_local_url('imsettings')));
             $this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
-            $this->element('legend', null, _('Preferences'));
+            // TRANS: Header for IM preferences form.
+            $this->element('legend', null, _('IM Preferences'));
             $this->hidden('token', common_session_token());
             $this->elementStart('table');
             $this->elementStart('tr');
-            // TRANS: Header for IM preferences form.
-            $this->element('th', null, _('IM Preferences'));
             foreach($user_im_prefs_by_transport as $transport=>$user_im_prefs)
             {
                 $this->element('th', null, $transports[$transport]['display']);
@@ -278,19 +276,20 @@ class ImsettingsAction extends ConnectSettingsAction
         $user = common_current_user();
 
         $user_im_prefs = new User_im_prefs();
+        $user_im_prefs->query('BEGIN');
         $user_im_prefs->user_id = $user->id;
         if($user_im_prefs->find() && $user_im_prefs->fetch())
         {
             $preferences = array('notify', 'updatefrompresence', 'replies', 'microid');
-            $user_im_prefs->query('BEGIN');
             do
             {
                 $original = clone($user_im_prefs);
+                $new = clone($user_im_prefs);
                 foreach($preferences as $preference)
                 {
-                    $user_im_prefs->$preference = $this->boolean($user_im_prefs->transport . '_' . $preference);
+                    $new->$preference = $this->boolean($new->transport . '_' . $preference);
                 }
-                $result = $user_im_prefs->update($original);
+                $result = $new->update($original);
 
                 if ($result === false) {
                     common_log_db_error($user, 'UPDATE', __FILE__);
@@ -299,8 +298,8 @@ class ImsettingsAction extends ConnectSettingsAction
                     return;
                 }
             }while($user_im_prefs->fetch());
-            $user_im_prefs->query('COMMIT');
         }
+        $user_im_prefs->query('COMMIT');
         // TRANS: Confirmation message for successful IM preferences save.
         $this->showForm(_('Preferences saved.'), true);
     }
index 8ecdfe9fab74494d3e29ea1a7069066de872ebce..75be8969e05d7e3da8a25b6de180f1d371c03a78 100644 (file)
@@ -68,4 +68,27 @@ class User_im_prefs extends Memcached_DataObject
     {
         return array(false,false);
     }
+
+    /**
+     * We have two compound keys with unique constraints:
+     * (transport, user_id) which is our primary key, and
+     * (transport, screenname) which is an additional constraint.
+     * 
+     * Currently there's not a way to represent that second key
+     * in the general keys list, so we're adding it here to the
+     * list of keys to use for caching, ensuring that it gets
+     * cleared as well when we change.
+     * 
+     * @return array of cache keys
+     */
+    function _allCacheKeys()
+    {
+        $ukeys = 'transport,screenname';
+        $uvals = $this->transport . ',' . $this->screenname;
+
+        $ckeys = parent::_allCacheKeys();
+        $ckeys[] = $this->cacheKey($this->tableName(), $ukeys, $uvals);
+        return $ckeys;
+    }
+
 }
index d13fdfa526acb31ba624c59b3800f9b8af7d1d3a..b57d8622631645e999a38881380e9542c1688b74 100644 (file)
@@ -647,8 +647,10 @@ modified = 384
 [user_im_prefs__keys]
 user_id = K
 transport = K
-transport = U
-screenname = U
+; There's another unique index on (transport, screenname)
+; but we have no way to represent a compound index other than
+; the primary key in here. To ensure proper cache purging,
+; we need to tweak the class.
 
 [user_urlshortener_prefs]
 user_id = 129
index 7302859a47d73d728d0e1045ec7b0df9621d84ef..7125aaee8d8c19ab8489c719d42328e757c886b2 100644 (file)
@@ -107,10 +107,15 @@ abstract class ImPlugin extends Plugin
      * receive a raw message
      * Raw IM data is taken from the incoming queue, and passed to this function.
      * It should parse the raw message and call handle_incoming()
+     * 
+     * Returning false may CAUSE REPROCESSING OF THE QUEUE ITEM, and should
+     * be used for temporary failures only. For permanent failures such as
+     * unrecognized addresses, return true to indicate your processing has
+     * completed.
      *
      * @param object $data raw IM data
      *
-     * @return boolean success value
+     * @return boolean true if processing completed, false for temporary failures
      */
     abstract function receive_raw_message($data);
 
@@ -185,9 +190,12 @@ abstract class ImPlugin extends Plugin
      */
     function get_user_im_prefs_from_screenname($screenname)
     {
-        if($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $this->transport, 'screenname' => $screenname) )){
+        $user_im_prefs = User_im_prefs::pkeyGet(
+            array('transport' => $this->transport,
+                  'screenname' => $this->normalize($screenname)));
+        if ($user_im_prefs) {
             return $user_im_prefs;
-        }else{
+        } else {
             return false;
         }
     }
@@ -203,9 +211,9 @@ abstract class ImPlugin extends Plugin
     function get_screenname($user)
     {
         $user_im_prefs = $this->get_user_im_prefs_from_user($user);
-        if($user_im_prefs){
+        if ($user_im_prefs) {
             return $user_im_prefs->screenname;
-        }else{
+        } else {
             return false;
         }
     }
@@ -220,9 +228,12 @@ abstract class ImPlugin extends Plugin
      */
     function get_user_im_prefs_from_user($user)
     {
-        if($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $this->transport, 'user_id' => $user->id) )){
+        $user_im_prefs = User_im_prefs::pkeyGet(
+            array('transport' => $this->transport,
+                  'user_id' => $user->id));
+        if ($user_im_prefs){
             return $user_im_prefs;
-        }else{
+        } else {
             return false;
         }
     }
index 3855d1fb054e33c535e48245a36ca443c23802e2..30da1dbc794dbc8ec9966541d0b12fd543692354 100644 (file)
@@ -126,6 +126,11 @@ class AimPlugin extends ImPlugin
         return true;
     }
 
+    /**
+     * Accept a queued input message.
+     *
+     * @return true if processing completed, false if message should be reprocessed
+     */
     function receive_raw_message($message)
     {
         $info=Aim::getMessageInfo($message);
@@ -133,7 +138,9 @@ class AimPlugin extends ImPlugin
         $user = $this->get_user($from);
         $notice_text = $info['message'];
 
-        return $this->handle_incoming($from, $notice_text);
+        $this->handle_incoming($from, $notice_text);
+
+        return true;
     }
 
     function initialize(){
index 0465917383d2f4bd27cea5b3db7a2c81af6fbc4a..7d486a036660b749bc6b41b047586b713548ca2d 100644 (file)
@@ -6,7 +6,7 @@ add "addPlugin('aim',
     array('setting'=>'value', 'setting2'=>'value2', ...);"
 to the bottom of your config.php
 
-The daemon included with this plugin must be running. It will be started by
+scripts/imdaemon.php included with StatusNet must be running. It will be started by
 the plugin along with their other daemons when you run scripts/startdaemons.sh.
 See the StatusNet README for more about queuing and daemons.
 
diff --git a/plugins/Xmpp/Fake_XMPP.php b/plugins/Xmpp/Fake_XMPP.php
deleted file mode 100644 (file)
index 0f7cfd3..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Instead of sending XMPP messages, retrieve the raw XML that would be sent
- *
- * PHP version 5
- *
- * LICENCE: 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 <http://www.gnu.org/licenses/>.
- *
- * @category  Network
- * @package   StatusNet
- * @author    Brion Vibber <brion@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link      http://status.net/
- */
-
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-class Fake_XMPP extends XMPPHP_XMPP
-{
-    public $would_be_sent = null;
-
-       /**
-        * Constructor
-        *
-        * @param string  $host
-        * @param integer $port
-        * @param string  $user
-        * @param string  $password
-        * @param string  $resource
-        * @param string  $server
-        * @param boolean $printlog
-        * @param string  $loglevel
-        */
-       public function __construct($host, $port, $user, $password, $resource, $server = null, $printlog = false, $loglevel = null)
-       {
-        parent::__construct($host, $port, $user, $password, $resource, $server, $printlog, $loglevel);
-
-        // We use $host to connect, but $server to build JIDs if specified.
-        // This seems to fix an upstream bug where $host was used to build
-        // $this->basejid, never seen since it isn't actually used in the base
-        // classes.
-        if (!$server) {
-            $server = $this->host;
-        }
-        $this->basejid = $this->user . '@' . $server;
-
-        // Normally the fulljid is filled out by the server at resource binding
-        // time, but we need to do it since we're not talking to a real server.
-        $this->fulljid = "{$this->basejid}/{$this->resource}";
-    }
-
-    /**
-     * Send a formatted message to the outgoing queue for later forwarding
-     * to a real XMPP connection.
-     *
-     * @param string $msg
-     */
-    public function send($msg, $timeout=NULL)
-    {
-        $this->would_be_sent = $msg;
-    }
-
-    //@{
-    /**
-     * Stream i/o functions disabled; only do output
-     */
-    public function connect($timeout = 30, $persistent = false, $sendinit = true)
-    {
-        throw new Exception("Can't connect to server from fake XMPP.");
-    }
-
-    public function disconnect()
-    {
-        throw new Exception("Can't connect to server from fake XMPP.");
-    }
-
-    public function process()
-    {
-        throw new Exception("Can't read stream from fake XMPP.");
-    }
-
-    public function processUntil($event, $timeout=-1)
-    {
-        throw new Exception("Can't read stream from fake XMPP.");
-    }
-
-    public function read()
-    {
-        throw new Exception("Can't read stream from fake XMPP.");
-    }
-
-    public function readyToProcess()
-    {
-        throw new Exception("Can't read stream from fake XMPP.");
-    }
-    //@}
-}
-
diff --git a/plugins/Xmpp/Queued_XMPP.php b/plugins/Xmpp/Queued_XMPP.php
new file mode 100644 (file)
index 0000000..73eff22
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Queue-mediated proxy class for outgoing XMPP messages.
+ *
+ * PHP version 5
+ *
+ * LICENCE: 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 <http://www.gnu.org/licenses/>.
+ *
+ * @category  Network
+ * @package   StatusNet
+ * @author    Brion Vibber <brion@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+class Queued_XMPP extends XMPPHP_XMPP
+{
+    /**
+     * Reference to the XmppPlugin object we're hooked up to.
+     */
+    public $plugin;
+
+       /**
+        * Constructor
+        *
+     * @param XmppPlugin $plugin
+        * @param string  $host
+        * @param integer $port
+        * @param string  $user
+        * @param string  $password
+        * @param string  $resource
+        * @param string  $server
+        * @param boolean $printlog
+        * @param string  $loglevel
+        */
+       public function __construct($plugin, $host, $port, $user, $password, $resource, $server = null, $printlog = false, $loglevel = null)
+       {
+        $this->plugin = $plugin;
+
+        parent::__construct($host, $port, $user, $password, $resource, $server, $printlog, $loglevel);
+
+        // We use $host to connect, but $server to build JIDs if specified.
+        // This seems to fix an upstream bug where $host was used to build
+        // $this->basejid, never seen since it isn't actually used in the base
+        // classes.
+        if (!$server) {
+            $server = $this->host;
+        }
+        $this->basejid = $this->user . '@' . $server;
+
+        // Normally the fulljid is filled out by the server at resource binding
+        // time, but we need to do it since we're not talking to a real server.
+        $this->fulljid = "{$this->basejid}/{$this->resource}";
+    }
+
+    /**
+     * Send a formatted message to the outgoing queue for later forwarding
+     * to a real XMPP connection.
+     *
+     * @param string $msg
+     */
+    public function send($msg, $timeout=NULL)
+    {
+        $this->plugin->enqueue_outgoing_raw($msg);
+    }
+
+    //@{
+    /**
+     * Stream i/o functions disabled; only do output
+     */
+    public function connect($timeout = 30, $persistent = false, $sendinit = true)
+    {
+        throw new Exception("Can't connect to server from fake XMPP.");
+    }
+
+    public function disconnect()
+    {
+        throw new Exception("Can't connect to server from fake XMPP.");
+    }
+
+    public function process()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function processUntil($event, $timeout=-1)
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function read()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+
+    public function readyToProcess()
+    {
+        throw new Exception("Can't read stream from fake XMPP.");
+    }
+    //@}
+
+}
+
index 03bf47feacea0061f793d08bba4c90b388d339b1..a2521536bcfdbbd240932636263406c097a6b3b4 100644 (file)
@@ -60,8 +60,6 @@ class XmppPlugin extends ImPlugin
 
     public $transport = 'xmpp';
 
-    protected $fake_xmpp;
-
     function getDisplayName(){
         return _m('XMPP/Jabber/GTalk');
     }
@@ -292,7 +290,7 @@ class XmppPlugin extends ImPlugin
             require_once 'XMPP.php';
             return false;
         case 'Sharing_XMPP':
-        case 'Fake_XMPP':
+        case 'Queued_XMPP':
             require_once $dir . '/'.$cls.'.php';
             return false;
         case 'XmppManager':
@@ -317,9 +315,7 @@ class XmppPlugin extends ImPlugin
 
     function send_message($screenname, $body)
     {
-        $this->fake_xmpp->message($screenname, $body, 'chat');
-        $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
-        return true;
+        $this->queuedConnection()->message($screenname, $body, 'chat');
     }
 
     function send_notice($screenname, $notice)
@@ -327,8 +323,7 @@ class XmppPlugin extends ImPlugin
         $msg   = $this->format_notice($notice);
         $entry = $this->format_entry($notice);
         
-        $this->fake_xmpp->message($screenname, $msg, 'chat', null, $entry);
-        $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
+        $this->queuedConnection()->message($screenname, $msg, 'chat', null, $entry);
         return true;
     }
 
@@ -385,10 +380,19 @@ class XmppPlugin extends ImPlugin
             return true;
         }
 
-        return $this->handle_incoming($from, $pl['body']);
+        $this->handle_incoming($from, $pl['body']);
+        
+        return true;
     }
 
-    function initialize(){
+    /**
+     * Build a queue-proxied XMPP interface object. Any outgoing messages
+     * will be run back through us for enqueing rather than sent directly.
+     * 
+     * @return Queued_XMPP
+     * @throws Exception if server settings are invalid.
+     */
+    function queuedConnection(){
         if(!isset($this->server)){
             throw new Exception("must specify a server");
         }
@@ -402,7 +406,7 @@ class XmppPlugin extends ImPlugin
             throw new Exception("must specify a password");
         }
 
-        $this->fake_xmpp = new Fake_XMPP($this->host ?
+        return new Queued_XMPP($this, $this->host ?
                                     $this->host :
                                     $this->server,
                                     $this->port,
@@ -415,7 +419,6 @@ class XmppPlugin extends ImPlugin
                                     $this->debug ?
                                     XMPPHP_Log::LEVEL_VERBOSE :  null
                                     );
-        return true;
     }
 
     function onPluginVersion(&$versions)