]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/Irc/ircmanager.php
Update translator documentation.
[quix0rs-gnu-social.git] / plugins / Irc / ircmanager.php
index 96c019b7fc0400718e43e3664fafa8d5761d1dd7..3c0a504eb06c80a384e5c39ae271c017c1a312f0 100644 (file)
@@ -28,14 +28,17 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
  * In a multi-site queuedaemon.php run, one connection will be instantiated
  * for each site being handled by the current process that has IRC enabled.
  */
-
 class IrcManager extends ImManager {
     protected $conn = null;
     protected $lastPing = null;
+    protected $messageWaiting = true;
+    protected $lastMessage = null;
 
     protected $regChecks = array();
     protected $regChecksLookup = array();
 
+    protected $connected = false;
+
     /**
      * Initialize connection to server.
      *
@@ -65,16 +68,55 @@ 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() {
-        if (empty($this->lastPing) || time() - $this->lastPing > 120) {
+        // 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 +132,7 @@ class IrcManager extends ImManager {
         try {
             $this->conn->handleEvents();
         } catch (Phergie_Driver_Exception $e) {
+            $this->connected = false;
             $this->conn->reconnect();
         }
     }
@@ -133,7 +176,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 +186,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
                 )
@@ -150,6 +195,7 @@ class IrcManager extends ImManager {
             $this->conn->setConfig($config);
             $this->conn->connect();
             $this->lastPing = time();
+            $this->lastMessage = time();
         }
         return $this->conn;
     }
@@ -162,7 +208,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;
     }
 
@@ -182,9 +228,10 @@ class IrcManager extends ImManager {
         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'));
+                // TRANS: Message given when using an unregistered IRC nickname.
+                $this->plugin->sendMessage($screenname, _m('Your nickname is not registered so IRC connectivity cannot be enabled.'));
 
                 $confirm = new Confirm_address();
 
@@ -196,8 +243,8 @@ 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.'));
+                        // TRANS: Server error thrown on database error when deleting IRC nickname confirmation.
+                        $this->serverError(_m('Could not delete confirmation.'));
                         return;
                     }
                 }
@@ -211,6 +258,40 @@ class IrcManager extends ImManager {
         }
     }
 
+    /**
+    * 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__);
+            // TRANS: Server exception thrown when an IRC waiting queue item could not be added to the database.
+            throw new ServerException(_m('Database error inserting IRC waiting queue item.'));
+        }
+
+        return true;
+    }
+
     /**
      * Send a message using the daemon
      *
@@ -223,28 +304,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;
     }