]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - scripts/xmppdaemon.php
reformat Notice.php
[quix0rs-gnu-social.git] / scripts / xmppdaemon.php
index 3eecfec29a13725aa46684428b30dc1d301b3052..b2efc07c38c644092b4a1549761efb01af99c330 100755 (executable)
@@ -1,8 +1,8 @@
 #!/usr/bin/env php
 <?php
 /*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, 2009, Control Yourself, Inc.
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2008, 2009, StatusNet, Inc.
  *
  * 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
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-$shortoptions = 'i::';
-$longoptions = array('id::');
+$shortoptions = 'fi::';
+$longoptions = array('id::', 'foreground');
 
 $helptext = <<<END_OF_XMPP_HELP
 Daemon script for receiving new notices from Jabber users.
 
     -i --id           Identity (default none)
+    -f --foreground   Stay in the foreground (default background)
 
 END_OF_XMPP_HELP;
 
@@ -42,8 +43,10 @@ require_once INSTALLDIR . '/lib/daemon.php';
 
 class XMPPDaemon extends Daemon
 {
-    function XMPPDaemon($resource=null)
+    function __construct($resource=null, $daemonize=true)
     {
+        parent::__construct($daemonize);
+
         static $attrs = array('server', 'port', 'user', 'password', 'host');
 
         foreach ($attrs as $attr)
@@ -57,12 +60,13 @@ class XMPPDaemon extends Daemon
             $this->resource = common_config('xmpp', 'resource') . 'daemon';
         }
 
-        $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->user}@{$this->server}/{$this->resource}");
+        $this->jid = $this->user.'@'.$this->server.'/'.$this->resource;
+
+        $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->jid}");
     }
 
     function connect()
     {
-
         $connect_to = ($this->host) ? $this->host : $this->server;
 
         $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port");
@@ -73,10 +77,17 @@ class XMPPDaemon extends Daemon
             return false;
         }
 
+        $this->log(LOG_INFO, "Connected");
+
         $this->conn->setReconnectTimeout(600);
 
+        $this->log(LOG_INFO, "Sending initial presence.");
+
         jabber_send_presence("Send me a message to post a notice", 'available',
                              null, 'available', 100);
+
+        $this->log(LOG_INFO, "Done connecting.");
+
         return !$this->conn->isDisconnected();
     }
 
@@ -89,18 +100,44 @@ class XMPPDaemon extends Daemon
     {
         if ($this->connect()) {
 
+            $this->log(LOG_DEBUG, "Initializing stanza handlers.");
+
             $this->conn->addEventHandler('message', 'handle_message', $this);
             $this->conn->addEventHandler('presence', 'handle_presence', $this);
             $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
 
-            $this->conn->process();
+            $this->log(LOG_DEBUG, "Beginning processing loop.");
+
+            while ($this->conn->processTime(60)) {
+                $this->sendPing();
+            }
         }
     }
 
+    function sendPing()
+    {
+        if (!isset($this->pingid)) {
+            $this->pingid = 0;
+        } else {
+            $this->pingid++;
+        }
+
+        $this->log(LOG_DEBUG, "Sending ping #{$this->pingid}");
+
+               $this->conn->send("<iq from='{$this->jid}' to='{$this->server}' id='ping_{$this->pingid}' type='get'><ping xmlns='urn:xmpp:ping'/></iq>");
+    }
+
     function handle_reconnect(&$pl)
     {
+        $this->log(LOG_DEBUG, "Got reconnection callback.");
         $this->conn->processUntil('session_start');
+        $this->log(LOG_DEBUG, "Sending reconnection presence.");
         $this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100);
+        unset($pl['xml']);
+        $pl['xml'] = null;
+
+        $pl = null;
+        unset($pl);
     }
 
     function get_user($from)
@@ -111,27 +148,37 @@ class XMPPDaemon extends Daemon
 
     function handle_message(&$pl)
     {
+        $from = jabber_normalize_jid($pl['from']);
+
         if ($pl['type'] != 'chat') {
+            $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from.");
             return;
         }
+
         if (mb_strlen($pl['body']) == 0) {
+            $this->log(LOG_WARNING, "Ignoring message with empty body from $from.");
             return;
         }
 
-        $from = jabber_normalize_jid($pl['from']);
-
         # Forwarded from another daemon (probably a broadcaster) for
         # us to handle
 
         if ($this->is_self($from)) {
+            $this->log(LOG_INFO, "Got forwarded notice from self ($from).");
             $from = $this->get_ofrom($pl);
+            $this->log(LOG_INFO, "Originally sent by $from.");
             if (is_null($from) || $this->is_self($from)) {
+                $this->log(LOG_INFO, "Ignoring notice originally sent by $from.");
                 return;
             }
         }
 
         $user = $this->get_user($from);
 
+        // For common_current_user to work
+        global $_cur;
+        $_cur = $user;
+
         if (!$user) {
             $this->from_site($from, 'Unknown user; go to ' .
                              common_local_url('imsettings') .
@@ -140,6 +187,7 @@ class XMPPDaemon extends Daemon
             return;
         }
         if ($this->handle_command($user, $pl['body'])) {
+            $this->log(LOG_INFO, "Command messag by $from handled.");
             return;
         } else if ($this->is_autoreply($pl['body'])) {
             $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from);
@@ -148,17 +196,32 @@ class XMPPDaemon extends Daemon
             $this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
             return;
         } else if ($this->is_direct($pl['body'])) {
+            $this->log(LOG_INFO, 'Got a direct message ' . $from);
+
             preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to);
 
             $to = preg_replace('/^d([\ ])*/', '', $to[0][0]);
             $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']);
+
+            $this->log(LOG_INFO, 'Direct message from '. $user->nickname . ' to ' . $to);
+
             $this->add_direct($user, $body, $to, $from);
         } else {
+
+            $this->log(LOG_INFO, 'Posting a notice from ' . $user->nickname);
+
             $this->add_notice($user, $pl);
         }
 
         $user->free();
         unset($user);
+        unset($_cur);
+
+        unset($pl['xml']);
+        $pl['xml'] = null;
+
+        $pl = null;
+        unset($pl);
     }
 
     function is_self($from)
@@ -253,16 +316,22 @@ class XMPPDaemon extends Daemon
     {
         $body = trim($pl['body']);
         $content_shortened = common_shorten_links($body);
-        if (mb_strlen($content_shortened) > 140) {
+        if (Notice::contentTooLong($content_shortened)) {
           $from = jabber_normalize_jid($pl['from']);
-          $this->from_site($from, "Message too long - maximum is 140 characters, you sent ".mb_strlen($content_shortened));
+          $this->from_site($from, sprintf(_("Message too long - maximum is %d characters, you sent %d"),
+                                          Notice::maxContent(),
+                                          mb_strlen($content_shortened)));
           return;
         }
-        $notice = Notice::saveNew($user->id, $content_shortened, 'xmpp');
-        if (is_string($notice)) {
-            $this->log(LOG_ERR, $notice);
+
+        try {
+            $notice = Notice::saveNew($user->id, $content_shortened, 'xmpp');
+        } catch (Exception $e) {
+            $this->log(LOG_ERR, $e->getMessage());
+            $this->from_site($user->jabber, $e->getMessage());
             return;
         }
+
         common_broadcast_notice($notice);
         $this->log(LOG_INFO,
                    'Added notice ' . $notice->id . ' from user ' . $user->nickname);
@@ -303,11 +372,23 @@ class XMPPDaemon extends Daemon
             }
             break;
         }
+        unset($pl['xml']);
+        $pl['xml'] = null;
+
+        $pl = null;
+        unset($pl);
     }
 
     function log($level, $msg)
     {
-        common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg);
+        $text = 'XMPPDaemon('.$this->resource.'): '.$msg;
+        common_log($level, $text);
+        if (!$this->daemonize)
+        {
+            $line = common_log_line($level, $text);
+            echo $line;
+            echo "\n";
+        }
     }
 
     function subscribed($to)
@@ -323,16 +404,16 @@ if (common_config('xmpp','enabled')==false) {
     exit();
 }
 
-if (have_option('i')) {
-    $id = get_option_value('i');
-} else if (have_option('--id')) {
-    $id = get_option_value('--id');
+if (have_option('i', 'id')) {
+    $id = get_option_value('i', 'id');
 } else if (count($args) > 0) {
     $id = $args[0];
 } else {
     $id = null;
 }
 
-$daemon = new XMPPDaemon($id);
+$foreground = have_option('f', 'foreground');
+
+$daemon = new XMPPDaemon($id, !$foreground);
 
 $daemon->runOnce();