]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/Irc/ircmanager.php
Localisation updates from http://translatewiki.net.
[quix0rs-gnu-social.git] / plugins / Irc / ircmanager.php
index bd6242a6a579ac55a87ebacd0a2a2e8a4b40b0da..d9637352515d291a6408fb8b67f01281f2cfc2a4 100644 (file)
@@ -32,9 +32,13 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
 class IrcManager extends ImManager {
     protected $conn = null;
     protected $lastPing = null;
+    protected $messageWaiting = true;
+    protected $lastMessage = null;
 
-    protected $regchecks = array();
-    protected $regchecksLookup = array();
+    protected $regChecks = array();
+    protected $regChecksLookup = array();
+
+    protected $connected = false;
 
     /**
      * Initialize connection to server.
@@ -65,15 +69,54 @@ class IrcManager extends ImManager {
         }
     }
 
+    /**
+     * Request a maximum timeout for listeners before the next idle period.
+     *
+     * @return integer Maximum timeout
+     */
+    public function timeout() {
+        if ($this->messageWaiting) {
+            return 1;
+        } else {
+            return $this->plugin->pinginterval;
+        }
+    }
+
     /**
      * Idle processing for io manager's execution loop.
-     * Send keepalive pings to server.
      *
      * @return void
      */
-    public function idle($timeout = 0) {
-        if (empty($this->lastPing) || time() - $this->lastPing > 120) {
-            $this->send_ping();
+    public function idle() {
+        // Send a ping if necessary
+        if (empty($this->lastPing) || time() - $this->lastPing > $this->plugin->pinginterval) {
+            $this->sendPing();
+        }
+
+        if ($this->connected) {
+            // Send a waiting message if appropriate
+            if ($this->messageWaiting && time() - $this->lastMessage > 1) {
+                $wm = Irc_waiting_message::top();
+                if ($wm === NULL) {
+                    $this->messageWaiting = false;
+                    return;
+                }
+
+                $data = unserialize($wm->data);
+                $wm->incAttempts();
+
+                if ($this->send_raw_message($data)) {
+                    $wm->delete();
+                } else {
+                    if ($wm->attempts <= common_config('queue', 'max_retries')) {
+                        // Try again next idle
+                        $wm->releaseClaim();
+                    } else {
+                        // Exceeded the maximum number of retries
+                        $wm->delete();
+                    }
+                }
+            }
         }
     }
 
@@ -90,6 +133,7 @@ class IrcManager extends ImManager {
         try {
             $this->conn->handleEvents();
         } catch (Phergie_Driver_Exception $e) {
+            $this->connected = false;
             $this->conn->reconnect();
         }
     }
@@ -133,7 +177,8 @@ class IrcManager extends ImManager {
 
                     'plugins.autoload' => true,
 
-                    'ui.enabled' => true,
+                    // Uncomment to enable debugging output
+                    //'ui.enabled' => true,
 
                     'nickserv.password' => $this->plugin->nickservpassword,
                     'nickserv.identify_message' => $this->plugin->nickservidentifyregexp,
@@ -142,6 +187,7 @@ class IrcManager extends ImManager {
 
                     'statusnet.messagecallback' => array($this, 'handle_irc_message'),
                     'statusnet.regcallback' => array($this, 'handle_reg_response'),
+                    'statusnet.connectedcallback' => array($this, 'handle_connected'),
                     'statusnet.unregregexp' => $this->plugin->unregregexp,
                     'statusnet.regregexp' => $this->plugin->regregexp
                 )
@@ -149,6 +195,8 @@ class IrcManager extends ImManager {
 
             $this->conn->setConfig($config);
             $this->conn->connect();
+            $this->lastPing = time();
+            $this->lastMessage = time();
         }
         return $this->conn;
     }
@@ -161,7 +209,7 @@ class IrcManager extends ImManager {
     * @return boolean
     */
     public function handle_irc_message($data) {
-        $this->plugin->enqueue_incoming_raw($data);
+        $this->plugin->enqueueIncomingRaw($data);
         return true;
     }
 
@@ -175,15 +223,15 @@ class IrcManager extends ImManager {
     public function handle_reg_response($data) {
         // Retrieve data
         $screenname = $data['screenname'];
-        $nickdata = $this->regchecks[$screenname];
+        $nickdata = $this->regChecks[$screenname];
         $usernick = $nickdata['user']->nickname;
 
-        if (isset($this->regchecksLookup[$usernick])) {
+        if (isset($this->regChecksLookup[$usernick])) {
             if ($data['registered']) {
                 // Send message
-                $this->plugin->send_confirmation_code($screenname, $nickdata['code'], $nickdata['user'], true);
+                $this->plugin->sendConfirmationCode($screenname, $nickdata['code'], $nickdata['user'], true);
             } else {
-                $this->plugin->send_message($screenname, _m('Your nickname is not registered so IRC connectivity cannot be enabled'));
+                $this->plugin->sendMessage($screenname, _m('Your nickname is not registered so IRC connectivity cannot be enabled'));
 
                 $confirm = new Confirm_address();
 
@@ -196,20 +244,53 @@ class IrcManager extends ImManager {
                     if (!$result) {
                         common_log_db_error($confirm, 'DELETE', __FILE__);
                         // TRANS: Server error thrown on database error canceling IM address confirmation.
-                        $this->serverError(_('Couldn\'t delete confirmation.'));
+                        $this->serverError(_m('Could not delete confirmation.'));
                         return;
                     }
                 }
             }
 
             // Unset lookup value
-            unset($this->regchecksLookup[$usernick]);
+            unset($this->regChecksLookup[$usernick]);
 
             // Unset data
-            unset($this->regchecks[$screename]);
+            unset($this->regChecks[$screename]);
         }
     }
 
+    /**
+    * Called when the connection is established
+    *
+    * @return void
+    */
+    public function handle_connected() {
+        $this->connected = true;
+    }
+
+    /**
+    * Enters a message into the database for sending when ready
+    *
+    * @param string $command Command
+    * @param array $args Arguments
+    * @return boolean
+    */
+    protected function enqueue_waiting_message($data) {
+        $wm = new Irc_waiting_message();
+
+        $wm->data       = serialize($data);
+        $wm->prioritise = $data['prioritise'];
+        $wm->attempts   = 0;
+        $wm->created    = common_sql_now();
+        $result         = $wm->insert();
+
+        if (!$result) {
+            common_log_db_error($wm, 'INSERT', __FILE__);
+            throw new ServerException('DB error inserting IRC waiting queue item');
+        }
+
+        return true;
+    }
+
     /**
      * Send a message using the daemon
      *
@@ -222,28 +303,45 @@ class IrcManager extends ImManager {
             return false;
         }
 
-        if ($data['type'] != 'message') {
-            // Nick checking
-            $nickdata = $data['nickdata'];
-            $usernick = $nickdata['user']->nickname;
-            $screenname = $nickdata['screenname'];
+        if ($data['type'] != 'delayedmessage') {
+            if ($data['type'] != 'message') {
+                // Nick checking
+                $nickdata = $data['nickdata'];
+                $usernick = $nickdata['user']->nickname;
+                $screenname = $nickdata['screenname'];
+
+                // Cancel any existing checks for this user
+                if (isset($this->regChecksLookup[$usernick])) {
+                    unset($this->regChecks[$this->regChecksLookup[$usernick]]);
+                }
 
-            // Cancel any existing checks for this user
-            if (isset($this->regchecksLookup[$usernick])) {
-                unset($this->regchecks[$this->regchecksLookup[$usernick]]);
+                $this->regChecks[$screenname] = $nickdata;
+                $this->regChecksLookup[$usernick] = $screenname;
             }
 
-            $this->regchecks[$screenname] = $nickdata;
-            $this->regchecksLookup[$usernick] = $screenname;
+            // If there is a backlog or we need to wait, queue the message
+            if ($this->messageWaiting || time() - $this->lastMessage < 1) {
+                $this->enqueue_waiting_message(
+                    array(
+                        'type' => 'delayedmessage',
+                        'prioritise' => $data['prioritise'],
+                        'data' => $data['data']
+                    )
+                );
+                $this->messageWaiting = true;
+                return true;
+            }
         }
 
         try {
             $this->conn->send($data['data']['command'], $data['data']['args']);
         } catch (Phergie_Driver_Exception $e) {
+            $this->connected = false;
             $this->conn->reconnect();
             return false;
         }
 
+        $this->lastMessage = time();
         return true;
     }
 
@@ -252,7 +350,7 @@ class IrcManager extends ImManager {
     *
     * @return void
     */
-    protected function send_ping() {
+    protected function sendPing() {
         $this->lastPing = time();
         $this->conn->send('PING', $this->lastPing);
     }